* cygheap.h (cygheap_user::issetuid): New method.

* dtable.cc (dtable::vfork_child_dup): Use new method to determine if we are in
"setuid mode."
* fork.cc (fork_parent): Ditto.
* spawn.cc (spawn_guts): Ditto.
* syscalls.cc (seteuid32): Ditto.
(setegid32): Ditto.
* environ.cc (spenv::retrieve): (Suggested by Pierre Humblet) Do potential
recalculation of cygheap_user stuff when in setuid mode.  Return special value
when environment variable exists but should not be added.
(build_env): Don't add retrieved value to dstp if it is 'dont_add'.
This commit is contained in:
Christopher Faylor 2002-06-16 23:34:43 +00:00
parent 45e9463a38
commit e40670ee48
7 changed files with 51 additions and 26 deletions

View File

@ -1,3 +1,18 @@
2002-06-16 Christopher Faylor <cgf@redhat.com>
* cygheap.h (cygheap_user::issetuid): New method.
* dtable.cc (dtable::vfork_child_dup): Use new method to determine if
we are in "setuid mode."
* fork.cc (fork_parent): Ditto.
* spawn.cc (spawn_guts): Ditto.
* syscalls.cc (seteuid32): Ditto.
(setegid32): Ditto.
* environ.cc (spenv::retrieve): (Suggested by Pierre Humblet) Do
potential recalculation of cygheap_user stuff when in setuid mode.
Return special value when environment variable exists but should not be
added.
(build_env): Don't add retrieved value to dstp if it is 'dont_add'.
2002-06-16 Christopher Faylor <cgf@redhat.com> 2002-06-16 Christopher Faylor <cgf@redhat.com>
Changes suggested by Pierre Humblet. Changes suggested by Pierre Humblet.

View File

@ -144,6 +144,10 @@ public:
PSID sid () const { return psid; } PSID sid () const { return psid; }
PSID orig_sid () const { return orig_psid; } PSID orig_sid () const { return orig_psid; }
const char *ontherange (homebodies what, struct passwd * = NULL); const char *ontherange (homebodies what, struct passwd * = NULL);
bool issetuid () const
{
return impersonated && token != INVALID_HANDLE_VALUE;
}
}; };
/* cwd cache stuff. */ /* cwd cache stuff. */

View File

@ -618,7 +618,7 @@ dtable::vfork_child_dup ()
int res = 1; int res = 1;
/* Remove impersonation */ /* Remove impersonation */
if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE) if (cygheap->user.issetuid ())
RevertToSelf (); RevertToSelf ();
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
@ -638,7 +638,7 @@ dtable::vfork_child_dup ()
out: out:
/* Restore impersonation */ /* Restore impersonation */
if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE) if (cygheap->user.issetuid ())
ImpersonateLoggedOnUser (cygheap->user.token); ImpersonateLoggedOnUser (cygheap->user.token);
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup");

View File

@ -760,6 +760,8 @@ struct spenv
__attribute__ ((regparm (3))); __attribute__ ((regparm (3)));
}; };
char env_dontadd[] = "";
/* Keep this list in upper case and sorted */ /* Keep this list in upper case and sorted */
static NO_COPY spenv spenvs[] = static NO_COPY spenv spenvs[] =
{ {
@ -781,6 +783,8 @@ spenv::retrieve (bool no_envblock, const char *const envname)
if (from_cygheap) if (from_cygheap)
{ {
const char *p; const char *p;
if (!cygheap->user.issetuid ())
{
if (!envname) if (!envname)
return NULL; /* No need to force these into the return NULL; /* No need to force these into the
environment */ environment */
@ -788,11 +792,12 @@ spenv::retrieve (bool no_envblock, const char *const envname)
if (no_envblock) if (no_envblock)
return cstrdup1 (envname); /* Don't really care what it's set to return cstrdup1 (envname); /* Don't really care what it's set to
if we're calling a cygwin program */ if we're calling a cygwin program */
}
/* Make a FOO=BAR entry from the value returned by the cygheap_user /* Calculate (potentially) value for given environment variable. */
method. */ p = (cygheap->user.*from_cygheap) ();
if (!(p = (cygheap->user.*from_cygheap) ())) if (!p || (no_envblock && !envname))
return NULL; return env_dontadd;
char *s = (char *) cmalloc (HEAP_1_STR, namelen + strlen (p) + 1); char *s = (char *) cmalloc (HEAP_1_STR, namelen + strlen (p) + 1);
strcpy (s, name); strcpy (s, name);
(void) strcpy (s + namelen, p); (void) strcpy (s + namelen, p);
@ -846,23 +851,28 @@ build_env (const char * const *envp, char *&envblock, int &envc,
int tl = 0; int tl = 0;
/* Iterate over input list, generating a new environment list and refreshing /* Iterate over input list, generating a new environment list and refreshing
"special" entries, if necessary. */ "special" entries, if necessary. */
for (srcp = envp, dstp = newenv; *srcp; srcp++, dstp++) for (srcp = envp, dstp = newenv; *srcp; srcp++)
{ {
/* Look for entries that require special attention */ /* Look for entries that require special attention */
for (unsigned i = 0; i < SPENVS_SIZE; i++) for (unsigned i = 0; i < SPENVS_SIZE; i++)
if (!saw_spenv[i] && (*dstp = spenvs[i].retrieve (no_envblock, *srcp))) if (!saw_spenv[i] && (*dstp = spenvs[i].retrieve (no_envblock, *srcp)))
{ {
saw_spenv[i] = 1; saw_spenv[i] = 1;
goto next; if (*dstp == env_dontadd)
goto next1;
goto next0;
} }
/* Add entry to new environment */ /* Add entry to new environment */
*dstp = cstrdup1 (*srcp); *dstp = cstrdup1 (*srcp);
next: next0:
/* If necessary, calculate rough running total for envblock size */ /* If necessary, calculate rough running total for envblock size */
if (!no_envblock) if (!no_envblock)
tl += strlen (*dstp) + 1; tl += strlen (*dstp) + 1;
dstp++;
next1:
continue;
} }
/* Fill in any required-but-missing environment variables. */ /* Fill in any required-but-missing environment variables. */
@ -870,7 +880,7 @@ build_env (const char * const *envp, char *&envblock, int &envc,
if (!saw_spenv[i]) if (!saw_spenv[i])
{ {
*dstp = spenvs[i].retrieve (no_envblock); *dstp = spenvs[i].retrieve (no_envblock);
if (*dstp) if (*dstp && *dstp != env_dontadd)
{ {
if (!no_envblock) if (!no_envblock)
tl += strlen (*dstp) + 1; tl += strlen (*dstp) + 1;

View File

@ -441,7 +441,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
si.cbReserved2 = sizeof(ch); si.cbReserved2 = sizeof(ch);
/* Remove impersonation */ /* Remove impersonation */
if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE) if (cygheap->user.issetuid ())
RevertToSelf (); RevertToSelf ();
ch.parent = hParent; ch.parent = hParent;
@ -490,8 +490,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
ForceCloseHandle(subproc_ready); ForceCloseHandle(subproc_ready);
ForceCloseHandle(forker_finished); ForceCloseHandle(forker_finished);
/* Restore impersonation */ /* Restore impersonation */
if (cygheap->user.impersonated if (cygheap->user.issetuid ())
&& cygheap->user.token != INVALID_HANDLE_VALUE)
ImpersonateLoggedOnUser (cygheap->user.token); ImpersonateLoggedOnUser (cygheap->user.token);
cygheap_setup_for_child_cleanup (newheap, &ch, 0); cygheap_setup_for_child_cleanup (newheap, &ch, 0);
return -1; return -1;
@ -519,7 +518,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
strcpy(forked->progname, myself->progname); strcpy(forked->progname, myself->progname);
/* Restore impersonation */ /* Restore impersonation */
if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE) if (cygheap->user.issetuid ())
ImpersonateLoggedOnUser (cygheap->user.token); ImpersonateLoggedOnUser (cygheap->user.token);
ProtectHandle (pi.hThread); ProtectHandle (pi.hThread);

View File

@ -610,7 +610,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
cygbench ("spawn-guts"); cygbench ("spawn-guts");
ciresrv.mount_h = cygwin_mount_h; ciresrv.mount_h = cygwin_mount_h;
if (!cygheap->user.impersonated || cygheap->user.token == INVALID_HANDLE_VALUE) if (!cygheap->user.issetuid ())
{ {
PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf); PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf);
ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc, ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc,

View File

@ -2093,9 +2093,8 @@ seteuid32 (__uid32_t uid)
failed: failed:
cygheap->user.token = sav_token; cygheap->user.token = sav_token;
cygheap->user.impersonated = sav_impersonated; cygheap->user.impersonated = sav_impersonated;
if ( cygheap->user.token != INVALID_HANDLE_VALUE && if (cygheap->user.issetuid ()
cygheap->user.impersonated && && !ImpersonateLoggedOnUser (cygheap->user.token))
!ImpersonateLoggedOnUser (cygheap->user.token))
system_printf ("Impersonating in seteuid failed: %E"); system_printf ("Impersonating in seteuid failed: %E");
return -1; return -1;
} }
@ -2144,8 +2143,7 @@ setegid32 (__gid32_t gid)
myself->gid = gid; myself->gid = gid;
/* If impersonated, update primary group and revert */ /* If impersonated, update primary group and revert */
if (cygheap->user.token != INVALID_HANDLE_VALUE if (cygheap->user.issetuid ())
&& cygheap->user.impersonated)
{ {
if (!SetTokenInformation (cygheap->user.token, if (!SetTokenInformation (cygheap->user.token,
TokenPrimaryGroup, TokenPrimaryGroup,
@ -2166,8 +2164,7 @@ setegid32 (__gid32_t gid)
"TokenPrimaryGroup): %E"); "TokenPrimaryGroup): %E");
CloseHandle (ptok); CloseHandle (ptok);
} }
if (cygheap->user.token != INVALID_HANDLE_VALUE if (cygheap->user.issetuid ()
&& cygheap->user.impersonated
&& !ImpersonateLoggedOnUser (cygheap->user.token)) && !ImpersonateLoggedOnUser (cygheap->user.token))
system_printf ("Impersonating in setegid failed: %E"); system_printf ("Impersonating in setegid failed: %E");
return 0; return 0;