* spawn.cc (spawn_guts): Call CreateProcess while impersonated,

when the real {u,g}ids and the groups are original.
	Move RevertToSelf and ImpersonateLoggedOnUser to the main line.
	* uinfo.cc (uinfo_init): Reorganize. If CreateProcess was called
	while impersonated, preserve the uids and gids and call
	ImpersonateLoggedOnUser. Preserve the uids and gids on Win9X.

	* exceptions.cc (error_start_init): Quote the pgm in the command.
This commit is contained in:
Corinna Vinschen 2003-06-09 13:29:12 +00:00
parent 32173f7ec4
commit 271c1935b3
4 changed files with 50 additions and 20 deletions

View File

@ -1,3 +1,14 @@
2003-06-09 Pierre Humblet <pierre.humblet@ieee.org>
* spawn.cc (spawn_guts): Call CreateProcess while impersonated,
when the real {u,g}ids and the groups are original.
Move RevertToSelf and ImpersonateLoggedOnUser to the main line.
* uinfo.cc (uinfo_init): Reorganize. If CreateProcess was called
while impersonated, preserve the uids and gids and call
ImpersonateLoggedOnUser. Preserve the uids and gids on Win9X.
* exceptions.cc (error_start_init): Quote the pgm in the command.
2003-06-07 Christopher Faylor <cgf@redhat.com> 2003-06-07 Christopher Faylor <cgf@redhat.com>
* poll.cc: Define FD_SETSIZE to ridiculously large number so that there * poll.cc: Define FD_SETSIZE to ridiculously large number so that there
@ -42,10 +53,10 @@
2003-06-03 Pierre Humblet <pierre.humblet@ieee.org> 2003-06-03 Pierre Humblet <pierre.humblet@ieee.org>
* fhandler_disk_file.cc (fhandler_disk_file::fstat): Mark the pc * fhandler_disk_file.cc (fhandler_disk_file::fstat): Mark the pc
as non-executable if the file cannot be opened for read. Retry query as non-executable if the file cannot be opened for read. Retry query
open only if errno is EACCES. Never change the mode, even if it is 000 open only if errno is EACCES. Never change the mode, even if it is 000
when query open() fails. when query open() fails.
2003-06-03 Christopher Faylor <cgf@redhat.com> 2003-06-03 Christopher Faylor <cgf@redhat.com>

View File

@ -154,7 +154,7 @@ error_start_init (const char *buf)
for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\')) for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\'))
*p = '/'; *p = '/';
__small_sprintf (debugger_command, "%s %s", buf, pgm); __small_sprintf (debugger_command, "%s \"%s\"", buf, pgm);
} }
static void static void

View File

@ -622,7 +622,17 @@ spawn_guts (const char * prog_arg, const char *const *argv,
cygbench ("spawn-guts"); cygbench ("spawn-guts");
cygheap->fdtab.set_file_pointers_for_exec (); cygheap->fdtab.set_file_pointers_for_exec ();
if (!cygheap->user.issetuid ()) if (cygheap->user.issetuid ())
RevertToSelf ();
/* When ruid != euid we create the new process under the current original
account and impersonate in child, this way maintaining the different
effective vs. real ids.
FIXME: If ruid != euid and ruid != orig_uid we currently give
up on ruid. The new process will have ruid == euid. */
if (!cygheap->user.issetuid ()
|| (cygheap->user.orig_uid == cygheap->user.real_uid
&& cygheap->user.orig_gid == cygheap->user.real_gid
&& !cygheap->user.groups.issetgroups ()))
{ {
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,
@ -646,8 +656,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
/* Set security attributes with sid */ /* Set security attributes with sid */
PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf, sid); PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf, sid);
RevertToSelf ();
/* Load users registry hive. */ /* Load users registry hive. */
load_registry_hive (sid); load_registry_hive (sid);
@ -682,11 +690,11 @@ spawn_guts (const char * prog_arg, const char *const *argv,
0, /* use current drive/directory */ 0, /* use current drive/directory */
&si, &si,
&pi); &pi);
/* Restore impersonation. In case of _P_OVERLAY this isn't
allowed since it would overwrite child data. */
if (mode != _P_OVERLAY)
ImpersonateLoggedOnUser (cygheap->user.token);
} }
/* Restore impersonation. In case of _P_OVERLAY this isn't
allowed since it would overwrite child data. */
if (mode != _P_OVERLAY && cygheap->user.issetuid ())
ImpersonateLoggedOnUser (cygheap->user.token);
MALLOC_CHECK; MALLOC_CHECK;
if (envblock) if (envblock)

View File

@ -103,18 +103,29 @@ internal_getlogin (cygheap_user &user)
void void
uinfo_init () uinfo_init ()
{ {
if (!child_proc_info || cygheap->user.token != INVALID_HANDLE_VALUE) if (child_proc_info && cygheap->user.token == INVALID_HANDLE_VALUE)
return;
if (!child_proc_info)
internal_getlogin (cygheap->user); /* Set the cygheap->user. */
/* Conditions must match those in spawn to allow starting child
processes with ruid != euid and rgid != egid. */
else if (cygheap->user.issetuid ()
&& cygheap->user.orig_uid == cygheap->user.real_uid
&& cygheap->user.orig_gid == cygheap->user.real_gid
&& !cygheap->user.groups.issetgroups ())
{ {
if (!child_proc_info) if (!ImpersonateLoggedOnUser (cygheap->user.token))
internal_getlogin (cygheap->user); /* Set the cygheap->user. */ system_printf ("ImpersonateLoggedOnUser: %E");
else return;
CloseHandle (cygheap->user.token);
cygheap->user.set_orig_sid (); /* Update the original sid */
cygheap->user.token = INVALID_HANDLE_VALUE; /* No token present */
} }
/* Real and effective uid/gid are identical on process start up. */ else
CloseHandle (cygheap->user.token);
cygheap->user.orig_uid = cygheap->user.real_uid = myself->uid; cygheap->user.orig_uid = cygheap->user.real_uid = myself->uid;
cygheap->user.orig_gid = cygheap->user.real_gid = myself->gid; cygheap->user.orig_gid = cygheap->user.real_gid = myself->gid;
cygheap->user.set_orig_sid (); /* Update the original sid */
cygheap->user.token = INVALID_HANDLE_VALUE; /* No token present */
} }
extern "C" char * extern "C" char *