* cygheap.h (enum impersonation): New enum.
(cygheap_user::token): Delete. (cygheap_user::impersonated): Delete. (cygheap_user::external_token): New member. (cygheap_user::internal_token): New member. (cygheap_user::impersonation_state): New member. (cygheap_user::issetuid): Modify. (cygheap_user::token): New method. (cygheap_user::deimpersonate): New method. (cygheap_user::reimpersonate): New method. (cygheap_user::has_impersonation_tokens): New method. (cygheap_user::close_impersonation_tokens): New method. * dtable.cc (dtable::vfork_child_dup): Use new cygheap_user methods. * fhandler_socket.cc (fhandler_socket::dup): Ditto. * fork.cc (fork_child): Ditto. (fork_parent): Ditto. * grp.cc (internal_getgroups): Ditto. * security.cc (verify_token): Ditto. (check_file_access): Ditto. (cygwin_set_impersonation_token): Detect conflicts. Set user.external_token. * spawn.cc (spawn_guts): Use new cygheap_user methods. * syscalls.cc (seteuid32): Rearrange to use the two tokens in cygheap_user. (setegid32): Use new cygheap_user methods. * uinfo.cc: (internal_getlogin): Ditto.
This commit is contained in:
		| @@ -1,3 +1,32 @@ | ||||
| 2003-06-30  Pierre Humblet  <pierre.humblet@ieee.org> | ||||
|  | ||||
| 	* cygheap.h (enum impersonation): New enum. | ||||
| 	(cygheap_user::token): Delete. | ||||
| 	(cygheap_user::impersonated): Delete. | ||||
| 	(cygheap_user::external_token): New member. | ||||
| 	(cygheap_user::internal_token): New member. | ||||
| 	(cygheap_user::impersonation_state): New member. | ||||
| 	(cygheap_user::issetuid): Modify. | ||||
| 	(cygheap_user::token): New method.    | ||||
| 	(cygheap_user::deimpersonate): New method. | ||||
| 	(cygheap_user::reimpersonate): New method. | ||||
| 	(cygheap_user::has_impersonation_tokens): New method. | ||||
| 	(cygheap_user::close_impersonation_tokens): New method. | ||||
| 	* dtable.cc (dtable::vfork_child_dup): Use new cygheap_user methods. | ||||
| 	* fhandler_socket.cc (fhandler_socket::dup): Ditto. | ||||
| 	* fork.cc (fork_child): Ditto. | ||||
| 	(fork_parent): Ditto. | ||||
| 	* grp.cc (internal_getgroups): Ditto. | ||||
| 	* security.cc (verify_token): Ditto. | ||||
| 	(check_file_access): Ditto. | ||||
| 	(cygwin_set_impersonation_token): Detect conflicts. Set | ||||
| 	user.external_token. | ||||
| 	* spawn.cc (spawn_guts): Use new cygheap_user methods. | ||||
| 	* syscalls.cc (seteuid32): Rearrange to use the two tokens | ||||
| 	in cygheap_user. | ||||
| 	(setegid32): Use new cygheap_user methods. | ||||
| 	* uinfo.cc: (internal_getlogin): Ditto. | ||||
|  | ||||
| 2003-06-25  Doru Carastan  <doru.carastan@mvista.com> | ||||
|  | ||||
| 	* Makefile.in: Use INSTALL_PROGRAM to install the cygwin DLL. | ||||
|   | ||||
| @@ -92,7 +92,13 @@ enum homebodies | ||||
|   CH_HOME | ||||
| }; | ||||
|  | ||||
| struct passwd; | ||||
| enum impersonation | ||||
| { | ||||
|   IMP_BAD = -1, | ||||
|   IMP_NONE = 0, | ||||
|   IMP_EXTERNAL, | ||||
|   IMP_INTERNAL | ||||
| }; | ||||
|  | ||||
| class cygheap_user | ||||
| { | ||||
| @@ -117,8 +123,9 @@ public: | ||||
|  | ||||
|   /* token is needed if set(e)uid should be called. It can be set by a call | ||||
|      to `set_impersonation_token()'. */ | ||||
|   HANDLE token; | ||||
|   BOOL   impersonated; | ||||
|   HANDLE external_token; | ||||
|   HANDLE internal_token; | ||||
|   enum impersonation impersonation_state; | ||||
|  | ||||
|   /* CGF 2002-06-27.  I removed the initializaton from this constructor | ||||
|      since this class is always allocated statically.  That means that everything | ||||
| @@ -165,7 +172,40 @@ public: | ||||
|   const char *ontherange (homebodies what, struct passwd * = NULL); | ||||
|   bool issetuid () const | ||||
|   { | ||||
|     return impersonated && token != INVALID_HANDLE_VALUE; | ||||
|     return impersonation_state > IMP_NONE; | ||||
|   } | ||||
|   HANDLE token () | ||||
|   { | ||||
|     if (impersonation_state == IMP_EXTERNAL) | ||||
|       return external_token; | ||||
|     if (impersonation_state == IMP_INTERNAL) | ||||
|       return internal_token; | ||||
|     return INVALID_HANDLE_VALUE; | ||||
|   } | ||||
|   void deimpersonate () | ||||
|   { | ||||
|     if (impersonation_state > IMP_NONE) | ||||
|       RevertToSelf (); | ||||
|   } | ||||
|   void reimpersonate () | ||||
|   { | ||||
|     if (impersonation_state > IMP_NONE | ||||
| 	&& !ImpersonateLoggedOnUser (token ())) | ||||
|       system_printf ("ImpersonateLoggedOnUser: %E"); | ||||
|   } | ||||
|   bool has_impersonation_tokens () { return external_token || internal_token; } | ||||
|   void close_impersonation_tokens () | ||||
|   { | ||||
|     if (external_token) | ||||
|       { | ||||
| 	CloseHandle (external_token); | ||||
| 	external_token = 0; | ||||
|       } | ||||
|     if (internal_token) | ||||
|       { | ||||
| 	CloseHandle (internal_token); | ||||
| 	internal_token = 0; | ||||
|       } | ||||
|   } | ||||
|   const char *cygheap_user::test_uid (char *&, const char *, size_t) | ||||
|     __attribute__ ((regparm (3))); | ||||
|   | ||||
| @@ -634,8 +634,7 @@ dtable::vfork_child_dup () | ||||
|   int res = 1; | ||||
|  | ||||
|   /* Remove impersonation */ | ||||
|   if (cygheap->user.issetuid ()) | ||||
|     RevertToSelf (); | ||||
|   cygheap->user.deimpersonate (); | ||||
|  | ||||
|   for (size_t i = 0; i < size; i++) | ||||
|     if (not_open (i)) | ||||
| @@ -654,8 +653,7 @@ dtable::vfork_child_dup () | ||||
|  | ||||
| out: | ||||
|   /* Restore impersonation */ | ||||
|   if (cygheap->user.issetuid ()) | ||||
|     ImpersonateLoggedOnUser (cygheap->user.token); | ||||
|   cygheap->user.reimpersonate (); | ||||
|  | ||||
|   ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); | ||||
|   return 1; | ||||
|   | ||||
| @@ -330,12 +330,10 @@ fhandler_socket::dup (fhandler_base *child) | ||||
| 	 If WSADuplicateSocket() still fails for some reason, we fall back | ||||
| 	 to DuplicateHandle(). */ | ||||
|       WSASetLastError (0); | ||||
|       if (cygheap->user.issetuid ()) | ||||
| 	RevertToSelf (); | ||||
|       cygheap->user.deimpersonate (); | ||||
|       fhs->set_io_handle (get_io_handle ()); | ||||
|       fhs->fixup_before_fork_exec (GetCurrentProcessId ()); | ||||
|       if (cygheap->user.issetuid ()) | ||||
| 	ImpersonateLoggedOnUser (cygheap->user.token); | ||||
|       cygheap->user.reimpersonate (); | ||||
|       if (!WSAGetLastError ()) | ||||
| 	{ | ||||
| 	  fhs->fixup_after_fork (hMainProc); | ||||
|   | ||||
| @@ -236,14 +236,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls) | ||||
|  | ||||
|   /* Restore the inheritance state as in parent | ||||
|      Don't call setuid here! The flags are already set. */ | ||||
|   if (cygheap->user.impersonated) | ||||
|     { | ||||
|       debug_printf ("Impersonation of child, token: %d", cygheap->user.token); | ||||
|       if (cygheap->user.token == INVALID_HANDLE_VALUE) | ||||
| 	RevertToSelf (); // probably not needed | ||||
|       else if (!ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
| 	system_printf ("Impersonate for forked child failed: %E"); | ||||
|     } | ||||
|   cygheap->user.reimpersonate (); | ||||
|  | ||||
|   sync_with_parent ("after longjmp.", TRUE); | ||||
|   sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent, | ||||
| @@ -436,8 +429,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, | ||||
|   si.cbReserved2 = sizeof (ch); | ||||
|  | ||||
|   /* Remove impersonation */ | ||||
|   if (cygheap->user.issetuid ()) | ||||
|     RevertToSelf (); | ||||
|   cygheap->user.deimpersonate (); | ||||
|  | ||||
|   ch.parent = hParent; | ||||
| #ifdef DEBUGGING | ||||
| @@ -485,8 +477,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, | ||||
|       ForceCloseHandle (subproc_ready); | ||||
|       ForceCloseHandle (forker_finished); | ||||
|       /* Restore impersonation */ | ||||
|       if (cygheap->user.issetuid ()) | ||||
| 	ImpersonateLoggedOnUser (cygheap->user.token); | ||||
|       cygheap->user.reimpersonate (); | ||||
|       cygheap_setup_for_child_cleanup (newheap, &ch, 0); | ||||
|       return -1; | ||||
|     } | ||||
| @@ -513,8 +504,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, | ||||
|   strcpy (forked->progname, myself->progname); | ||||
|  | ||||
|   /* Restore impersonation */ | ||||
|   if (cygheap->user.issetuid ()) | ||||
|     ImpersonateLoggedOnUser (cygheap->user.token); | ||||
|   cygheap->user.reimpersonate (); | ||||
|  | ||||
|   ProtectHandle (pi.hThread); | ||||
|   /* Protect the handle but name it similarly to the way it will | ||||
|   | ||||
| @@ -261,7 +261,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) | ||||
|     { | ||||
|       /* If impersonated, use impersonation token. */ | ||||
|       if (cygheap->user.issetuid ()) | ||||
| 	hToken = cygheap->user.token; | ||||
| 	hToken = cygheap->user.token (); | ||||
|       else if (!OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken)) | ||||
| 	hToken = NULL; | ||||
|     } | ||||
| @@ -295,7 +295,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) | ||||
| 			  ++cnt; | ||||
| 			  if (gidsetsize && cnt > gidsetsize) | ||||
| 			    { | ||||
| 			      if (hToken != cygheap->user.token) | ||||
| 			      if (!cygheap->user.issetuid ()) | ||||
| 				CloseHandle (hToken); | ||||
| 			      goto error; | ||||
| 			    } | ||||
| @@ -305,7 +305,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) | ||||
| 	} | ||||
|       else | ||||
| 	debug_printf ("%d = GetTokenInformation(NULL) %E", size); | ||||
|       if (hToken != cygheap->user.token) | ||||
|       if (!cygheap->user.issetuid ()) | ||||
| 	CloseHandle (hToken); | ||||
|       return cnt; | ||||
|     } | ||||
|   | ||||
| @@ -70,10 +70,16 @@ extern "C" void | ||||
| cygwin_set_impersonation_token (const HANDLE hToken) | ||||
| { | ||||
|   debug_printf ("set_impersonation_token (%d)", hToken); | ||||
|   if (cygheap->user.token != hToken) | ||||
|   if (cygheap->user.impersonation_state == IMP_EXTERNAL | ||||
|       && cygheap->user.external_token != hToken) | ||||
|     { | ||||
|       cygheap->user.token = hToken; | ||||
|       cygheap->user.impersonated = FALSE; | ||||
|       set_errno (EPERM); | ||||
|       return; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       cygheap->user.external_token = hToken; | ||||
|       return; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -717,7 +723,7 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, BOOL *pintern) | ||||
|   if (pintern) | ||||
|     { | ||||
|       TOKEN_SOURCE ts; | ||||
|       if (!GetTokenInformation (cygheap->user.token, TokenSource, | ||||
|       if (!GetTokenInformation (token, TokenSource, | ||||
| 				&ts, sizeof ts, &size)) | ||||
| 	debug_printf ("GetTokenInformation(): %E"); | ||||
|       else | ||||
| @@ -1906,7 +1912,7 @@ check_file_access (const char *fn, int flags) | ||||
|     goto done; | ||||
|  | ||||
|   if (cygheap->user.issetuid ()) | ||||
|     hToken = cygheap->user.token; | ||||
|     hToken = cygheap->user.token (); | ||||
|   else if (!OpenProcessToken (hMainProc, TOKEN_DUPLICATE, &hToken)) | ||||
|     { | ||||
|       __seterrno (); | ||||
| @@ -1914,7 +1920,7 @@ check_file_access (const char *fn, int flags) | ||||
|     } | ||||
|   if (!(status = DuplicateToken (hToken, SecurityIdentification, &hIToken))) | ||||
|     __seterrno (); | ||||
|   if (hToken != cygheap->user.token) | ||||
|   if (!cygheap->user.issetuid ()) | ||||
|     CloseHandle (hToken); | ||||
|   if (!status) | ||||
|     goto done; | ||||
|   | ||||
| @@ -621,8 +621,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, | ||||
|   cygbench ("spawn-guts"); | ||||
|  | ||||
|   cygheap->fdtab.set_file_pointers_for_exec (); | ||||
|   if (cygheap->user.issetuid ()) | ||||
|     RevertToSelf (); | ||||
|   cygheap->user.deimpersonate (); | ||||
|   /* 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. | ||||
| @@ -678,7 +677,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, | ||||
|       ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc, | ||||
| 					  real_path.iscygexec ()); | ||||
|       newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ()); | ||||
|       rc = CreateProcessAsUser (cygheap->user.token, | ||||
|       rc = CreateProcessAsUser (cygheap->user.token (), | ||||
| 		       runpath,		/* image name - with full path */ | ||||
| 		       one_line.buf,	/* what was passed to exec */ | ||||
| 		       sec_attribs,     /* process security attrs */ | ||||
| @@ -692,8 +691,8 @@ spawn_guts (const char * prog_arg, const char *const *argv, | ||||
|     } | ||||
|   /* 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); | ||||
|   if (mode != _P_OVERLAY) | ||||
|       cygheap->user.reimpersonate (); | ||||
|  | ||||
|   MALLOC_CHECK; | ||||
|   if (envblock) | ||||
|   | ||||
| @@ -2057,66 +2057,52 @@ seteuid32 (__uid32_t uid) | ||||
|   sigframe thisframe (mainthread); | ||||
|   cygsid usersid; | ||||
|   user_groups &groups = cygheap->user.groups; | ||||
|   HANDLE ptok, sav_token; | ||||
|   BOOL sav_impersonated, sav_token_is_internal_token; | ||||
|   BOOL process_ok, explicitly_created_token = FALSE; | ||||
|   HANDLE ptok, new_token = INVALID_HANDLE_VALUE; | ||||
|   struct passwd * pw_new; | ||||
|   PSID origpsid, psid2 = NO_SID; | ||||
|   enum impersonation new_state = IMP_BAD; | ||||
|   BOOL token_is_internal; | ||||
|  | ||||
|   pw_new = internal_getpwuid (uid); | ||||
|   if (!wincap.has_security () && pw_new) | ||||
|     goto success; | ||||
|     goto success_9x; | ||||
|   if (!usersid.getfrompw (pw_new)) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       return -1; | ||||
|     } | ||||
|   /* Save current information */ | ||||
|   sav_token = cygheap->user.token; | ||||
|   sav_impersonated = cygheap->user.impersonated; | ||||
|  | ||||
|   RevertToSelf (); | ||||
|   if (!OpenProcessToken (hMainProc, TOKEN_QUERY | TOKEN_ADJUST_DEFAULT, &ptok)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       goto failed; | ||||
|     } | ||||
|   /* Verify if the process token is suitable. | ||||
|      Currently we do not try to differentiate between | ||||
| 	 internal tokens and others */ | ||||
|   process_ok = verify_token (ptok, usersid, groups); | ||||
|   debug_printf ("Process token %sverified", process_ok ? "" : "not "); | ||||
|   if (process_ok) | ||||
|     { | ||||
|       if (cygheap->user.issetuid ()) | ||||
| 	cygheap->user.impersonated = FALSE; | ||||
|       else | ||||
| 	{ | ||||
| 	  CloseHandle (ptok); | ||||
| 	  goto success; /* No change */ | ||||
| 	} | ||||
|       goto failed_ptok;; | ||||
|     } | ||||
|  | ||||
|   if (!process_ok && cygheap->user.token != INVALID_HANDLE_VALUE) | ||||
|   /* Verify if the process token is suitable. */ | ||||
|   if (verify_token (ptok, usersid, groups)) | ||||
|     new_state = IMP_NONE; | ||||
|   /* Verify if a current token is suitable */ | ||||
|   else if (cygheap->user.external_token | ||||
| 	   && verify_token (cygheap->user.external_token, usersid, groups)) | ||||
|     { | ||||
|       /* Verify if the current tokem is suitable */ | ||||
|       BOOL token_ok = verify_token (cygheap->user.token, usersid, groups, | ||||
| 				    &sav_token_is_internal_token); | ||||
|       debug_printf ("Thread token %d %sverified", | ||||
| 		   cygheap->user.token, token_ok?"":"not "); | ||||
|       if (!token_ok) | ||||
| 	cygheap->user.token = INVALID_HANDLE_VALUE; | ||||
|       else | ||||
| 	{ | ||||
| 	  /* Return if current token is valid */ | ||||
| 	  if (cygheap->user.impersonated) | ||||
| 	    { | ||||
| 	      CloseHandle (ptok); | ||||
| 	      if (!ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
| 		system_printf ("Impersonating in seteuid failed: %E"); | ||||
| 	      goto success; /* No change */ | ||||
| 	    } | ||||
| 	} | ||||
|       new_token = cygheap->user.external_token; | ||||
|       new_state = IMP_EXTERNAL; | ||||
|     } | ||||
|   else if (cygheap->user.internal_token | ||||
| 	   && verify_token (cygheap->user.internal_token, usersid, groups, | ||||
| 			    &token_is_internal)) | ||||
|     { | ||||
|       new_token = cygheap->user.internal_token; | ||||
|       new_state = IMP_INTERNAL; | ||||
|     } | ||||
|  | ||||
|   debug_printf ("New token %d, state %d", new_token, new_state); | ||||
|   /* Return if current token is valid */ | ||||
|   if (cygheap->user.impersonation_state == new_state) | ||||
|     { | ||||
|       cygheap->user.reimpersonate (); | ||||
|       goto success; /* No change */ | ||||
|     } | ||||
|  | ||||
|   /* Set process def dacl to allow access to impersonated token */ | ||||
| @@ -2132,72 +2118,72 @@ seteuid32 (__uid32_t uid) | ||||
| 	debug_printf ("SetTokenInformation" | ||||
| 		      "(TokenDefaultDacl): %E"); | ||||
|     } | ||||
|   CloseHandle (ptok); | ||||
|  | ||||
|   if (!process_ok && cygheap->user.token == INVALID_HANDLE_VALUE) | ||||
|   if (new_state == IMP_BAD) | ||||
|     { | ||||
|       /* If no impersonation token is available, try to | ||||
| 	 authenticate using NtCreateToken () or subauthentication. */ | ||||
|       cygheap->user.token = create_token (usersid, groups, pw_new); | ||||
|       if (cygheap->user.token != INVALID_HANDLE_VALUE) | ||||
| 	explicitly_created_token = TRUE; | ||||
|       else | ||||
|       new_token = create_token (usersid, groups, pw_new); | ||||
|       if (new_token == INVALID_HANDLE_VALUE) | ||||
| 	{ | ||||
| 	  /* create_token failed. Try subauthentication. */ | ||||
| 	  debug_printf ("create token failed, try subauthentication."); | ||||
| 	  cygheap->user.token = subauth (pw_new); | ||||
| 	  if (cygheap->user.token == INVALID_HANDLE_VALUE) | ||||
| 	  new_token = subauth (pw_new); | ||||
| 	  if (new_token == INVALID_HANDLE_VALUE) | ||||
| 	    goto failed; | ||||
| 	} | ||||
|       new_state = IMP_INTERNAL; | ||||
|     } | ||||
|  | ||||
|   /* If using the token, set info and impersonate */ | ||||
|   if (!process_ok) | ||||
|   if (new_state != IMP_NONE) | ||||
|     { | ||||
|       /* If the token was explicitly created, all information has | ||||
| 	 already been set correctly. */ | ||||
|       if (!explicitly_created_token) | ||||
|       if (new_state == IMP_EXTERNAL) | ||||
| 	{ | ||||
| 	  /* Try setting owner to same value as user. */ | ||||
| 	  if (!SetTokenInformation (cygheap->user.token, TokenOwner, | ||||
| 	  if (!SetTokenInformation (new_token, TokenOwner, | ||||
| 				    &usersid, sizeof usersid)) | ||||
| 	    debug_printf ("SetTokenInformation(user.token, " | ||||
| 			  "TokenOwner): %E"); | ||||
| 	  /* Try setting primary group in token to current group */ | ||||
| 	  if (!SetTokenInformation (cygheap->user.token, | ||||
| 	  if (!SetTokenInformation (new_token, | ||||
| 				    TokenPrimaryGroup, | ||||
| 				    &groups.pgsid, sizeof (cygsid))) | ||||
| 	    debug_printf ("SetTokenInformation(user.token, " | ||||
| 			  "TokenPrimaryGroup): %E"); | ||||
| 	} | ||||
|       /* Now try to impersonate. */ | ||||
|       if (!ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
|       /* Try to impersonate. */ | ||||
|       if (!ImpersonateLoggedOnUser (new_token)) | ||||
| 	{ | ||||
| 	  debug_printf ("ImpersonateLoggedOnUser %E"); | ||||
| 	  __seterrno (); | ||||
| 	  goto failed; | ||||
| 	} | ||||
|       cygheap->user.impersonated = TRUE; | ||||
|       /* Keep at most one internal token */ | ||||
|       if (new_state == IMP_INTERNAL) | ||||
|         { | ||||
| 	  if (cygheap->user.internal_token) | ||||
| 	    CloseHandle (cygheap->user.internal_token); | ||||
| 	  cygheap->user.internal_token = new_token; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   /* If sav_token was internally created and is replaced, destroy it. */ | ||||
|   if (sav_token != INVALID_HANDLE_VALUE && | ||||
|       sav_token != cygheap->user.token && | ||||
|       sav_token_is_internal_token) | ||||
|       CloseHandle (sav_token); | ||||
|   cygheap->user.set_sid (usersid); | ||||
|  | ||||
| success: | ||||
|   CloseHandle (ptok); | ||||
|   cygheap->user.impersonation_state = new_state; | ||||
| success_9x: | ||||
|   cygheap->user.set_name (pw_new->pw_name); | ||||
|   myself->uid = uid; | ||||
|   groups.ischanged = FALSE; | ||||
|   return 0; | ||||
|  | ||||
| failed: | ||||
|   cygheap->user.token = sav_token; | ||||
|   cygheap->user.impersonated = sav_impersonated; | ||||
|   if (cygheap->user.issetuid () | ||||
|       && !ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
|     system_printf ("Impersonating in seteuid failed: %E"); | ||||
|   CloseHandle (ptok); | ||||
| failed_ptok: | ||||
|   cygheap->user.reimpersonate (); | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
| @@ -2278,7 +2264,7 @@ setegid32 (__gid32_t gid) | ||||
|   /* If impersonated, update primary group and revert */ | ||||
|   if (cygheap->user.issetuid ()) | ||||
|     { | ||||
|       if (!SetTokenInformation (cygheap->user.token, | ||||
|       if (!SetTokenInformation (cygheap->user.token (), | ||||
| 				TokenPrimaryGroup, | ||||
| 				&gsid, sizeof gsid)) | ||||
| 	debug_printf ("SetTokenInformation(thread, " | ||||
| @@ -2296,7 +2282,7 @@ setegid32 (__gid32_t gid) | ||||
|       CloseHandle (ptok); | ||||
|     } | ||||
|   if (cygheap->user.issetuid () | ||||
|       && !ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
|       && !ImpersonateLoggedOnUser (cygheap->user.token ())) | ||||
|     system_printf ("Impersonating in setegid failed: %E"); | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -102,7 +102,7 @@ internal_getlogin (cygheap_user &user) | ||||
| void | ||||
| uinfo_init () | ||||
| { | ||||
|   if (child_proc_info && cygheap->user.token == INVALID_HANDLE_VALUE) | ||||
|   if (child_proc_info && !cygheap->user.has_impersonation_tokens ()) | ||||
|     return; | ||||
|  | ||||
|   if (!child_proc_info) | ||||
| @@ -114,17 +114,16 @@ uinfo_init () | ||||
| 	   && cygheap->user.orig_gid == cygheap->user.real_gid | ||||
| 	   && !cygheap->user.groups.issetgroups ()) | ||||
|     { | ||||
|       if (!ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
| 	system_printf ("ImpersonateLoggedOnUser: %E"); | ||||
|       cygheap->user.reimpersonate (); | ||||
|       return; | ||||
|     } | ||||
|   else | ||||
|     CloseHandle (cygheap->user.token); | ||||
|     cygheap->user.close_impersonation_tokens (); | ||||
|  | ||||
|   cygheap->user.orig_uid = cygheap->user.real_uid = myself->uid; | ||||
|   cygheap->user.orig_gid = cygheap->user.real_gid = myself->gid; | ||||
|   cygheap->user.impersonation_state = IMP_NONE; | ||||
|   cygheap->user.set_orig_sid ();	/* Update the original sid */ | ||||
|   cygheap->user.token = INVALID_HANDLE_VALUE; /* No token present */ | ||||
| } | ||||
|  | ||||
| extern "C" char * | ||||
|   | ||||
		Reference in New Issue
	
	Block a user