* syscalls.cc (seteuid): Do not take allow_ntsec into account.
Attempt to use an existing or new token even when the uid matches orig_uid, but the gid is not in the process token. Major reorganization after several incremental changes. (setegid): Do not take allow_ntsec into account. Minor reorganization after several incremental changes.
This commit is contained in:
		| @@ -1,3 +1,12 @@ | ||||
| 2002-05-22  Pierre Humblet <pierre.humblet@ieee.org> | ||||
|  | ||||
| 	* syscalls.cc (seteuid): Do not take allow_ntsec into account. | ||||
| 	Attempt to use an existing or new token even when the uid | ||||
| 	matches orig_uid, but the gid is not in the process token. | ||||
| 	Major reorganization after several incremental changes. | ||||
| 	(setegid): Do not take allow_ntsec into account. Minor | ||||
| 	reorganization after several incremental changes. | ||||
|  | ||||
| 2002-05-26  Christopher Faylor  <cgf@redhat.com> | ||||
|  | ||||
| 	* debug.h (being_debugged): New macro. | ||||
|   | ||||
| @@ -1938,274 +1938,248 @@ extern struct passwd *internal_getlogin (cygheap_user &user); | ||||
| extern "C" int | ||||
| seteuid (__uid16_t uid) | ||||
| { | ||||
|   sigframe thisframe (mainthread); | ||||
|   if (wincap.has_security ()) | ||||
|   if (!wincap.has_security ()) return 0; | ||||
|  | ||||
|   if (uid == ILLEGAL_UID) | ||||
|     { | ||||
|       char orig_username[UNLEN + 1]; | ||||
|       char orig_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | ||||
|       char username[UNLEN + 1]; | ||||
|       DWORD ulen = UNLEN + 1; | ||||
|       char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | ||||
|       DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1; | ||||
|       SID_NAME_USE use; | ||||
|       debug_printf ("new euid == illegal euid, nothing happens"); | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|       if (uid == ILLEGAL_UID || uid == myself->uid) | ||||
| 	{ | ||||
| 	  debug_printf ("new euid == current euid, nothing happens"); | ||||
| 	  return 0; | ||||
| 	} | ||||
|       struct passwd *pw_new = getpwuid (uid); | ||||
|       if (!pw_new) | ||||
| 	{ | ||||
| 	  set_errno (EINVAL); | ||||
| 	  return -1; | ||||
|   sigframe thisframe (mainthread); | ||||
|   DWORD ulen = UNLEN + 1; | ||||
|   DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1; | ||||
|   char orig_username[UNLEN + 1]; | ||||
|   char orig_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | ||||
|   char username[UNLEN + 1]; | ||||
|   char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | ||||
|   cygsid usersid, pgrpsid; | ||||
|   HANDLE ptok, sav_token; | ||||
|   BOOL sav_impersonated, sav_token_is_internal_token; | ||||
|   BOOL process_ok, explicitly_created_token = FALSE; | ||||
|   struct passwd * pw_new, * pw_cur; | ||||
|   cygheap_user user; | ||||
|   PSID origpsid, psid2 = NO_SID; | ||||
|  | ||||
|   debug_printf ("uid: %d myself->gid: %d", uid, myself->gid); | ||||
|  | ||||
|   pw_new = getpwuid (uid); | ||||
|   if (!usersid.getfrompw (pw_new) || | ||||
|       (!pgrpsid.getfromgr (getgrgid (myself->gid)))) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       return -1; | ||||
|     } | ||||
|   /* Save current information */ | ||||
|   sav_token = cygheap->user.token; | ||||
|   sav_impersonated = cygheap->user.impersonated; | ||||
|   char *env; | ||||
|   orig_username[0] = orig_domain[0] = '\0'; | ||||
|   if ((env = getenv ("USERNAME"))) | ||||
|     strlcpy (orig_username, env, sizeof(orig_username)); | ||||
|   if ((env = getenv ("USERDOMAIN"))) | ||||
|     strlcpy (orig_domain, env, sizeof(orig_domain)); | ||||
|  | ||||
|   RevertToSelf(); | ||||
|   if (!OpenProcessToken (GetCurrentProcess (), | ||||
| 			 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, pgrpsid); | ||||
|   debug_printf("Process token %sverified", process_ok?"":"not "); | ||||
|   if (process_ok) | ||||
|     { | ||||
|       if (cygheap->user.token == INVALID_HANDLE_VALUE || | ||||
| 	  ! cygheap->user.impersonated ) | ||||
|         { | ||||
| 	  CloseHandle (ptok); | ||||
| 	  return 0; /* No change */ | ||||
| 	} | ||||
|       else cygheap->user.impersonated = FALSE; | ||||
|     } | ||||
|  | ||||
|       cygsid tok_usersid; | ||||
|       DWORD siz; | ||||
|  | ||||
|       char *env; | ||||
|       orig_username[0] = orig_domain[0] = '\0'; | ||||
|       if ((env = getenv ("USERNAME"))) | ||||
| 	strncat (orig_username, env, UNLEN + 1); | ||||
|       if ((env = getenv ("USERDOMAIN"))) | ||||
| 	strncat (orig_domain, env, INTERNET_MAX_HOST_NAME_LENGTH + 1); | ||||
|       if (uid == cygheap->user.orig_uid) | ||||
| 	{ | ||||
|  | ||||
| 	  debug_printf ("RevertToSelf () (uid == orig_uid, token=%d)", | ||||
| 			cygheap->user.token); | ||||
| 	  RevertToSelf (); | ||||
| 	  if (cygheap->user.token != INVALID_HANDLE_VALUE) | ||||
| 	    cygheap->user.impersonated = FALSE; | ||||
|  | ||||
| 	  HANDLE ptok = INVALID_HANDLE_VALUE; | ||||
| 	  if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)) | ||||
| 	    debug_printf ("OpenProcessToken(): %E\n"); | ||||
| 	  else if (!GetTokenInformation (ptok, TokenUser, &tok_usersid, | ||||
| 					 sizeof tok_usersid, &siz)) | ||||
| 	    debug_printf ("GetTokenInformation(): %E"); | ||||
| 	  else if (!LookupAccountSid (NULL, tok_usersid, username, &ulen, | ||||
| 				      domain, &dlen, &use)) | ||||
| 	    debug_printf ("LookupAccountSid(): %E"); | ||||
| 	  else | ||||
| 	    { | ||||
| 	      setenv ("USERNAME", username, 1); | ||||
| 	      setenv ("USERDOMAIN", domain, 1); | ||||
| 	    } | ||||
| 	  if (ptok != INVALID_HANDLE_VALUE) | ||||
|   if (!process_ok && cygheap->user.token != INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|       /* Verify if the current tokem is suitable */ | ||||
|       BOOL token_ok = verify_token (cygheap->user.token, usersid, pgrpsid, | ||||
| 				    & sav_token_is_internal_token); | ||||
|       debug_printf("Thread token %d %sverified", | ||||
| 		   cygheap->user.token, token_ok?"":"not "); | ||||
|       if (token_ok) | ||||
|         { | ||||
| 	  /* Return if current token is valid */ | ||||
| 	  if (cygheap->user.impersonated) | ||||
| 	  { | ||||
| 	    CloseHandle (ptok); | ||||
| 	    if (!ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
| 	      system_printf ("Impersonating in seteuid failed: %E"); | ||||
| 	    return 0; /* No change */ | ||||
| 	  } | ||||
| 	} | ||||
|       else cygheap->user.token = INVALID_HANDLE_VALUE; | ||||
|     } | ||||
|  | ||||
|   /* Set process def dacl to allow access to impersonated token */ | ||||
|   char dacl_buf[MAX_DACL_LEN(5)]; | ||||
|   if (usersid != (origpsid =  cygheap->user.orig_sid())) psid2 = usersid; | ||||
|   if (sec_acl ((PACL) dacl_buf, FALSE, origpsid, psid2)) | ||||
|     { | ||||
|       TOKEN_DEFAULT_DACL tdacl; | ||||
|       tdacl.DefaultDacl = (PACL) dacl_buf; | ||||
|       if (!SetTokenInformation (ptok, TokenDefaultDacl, | ||||
| 				&tdacl, sizeof dacl_buf)) | ||||
| 	debug_printf ("SetTokenInformation" | ||||
| 		      "(TokenDefaultDacl): %E"); | ||||
|     } | ||||
|   CloseHandle (ptok); | ||||
|  | ||||
|   if (!process_ok && cygheap->user.token == INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|       /* If no impersonation token is available, try to | ||||
| 	 authenticate using NtCreateToken() or subauthentication. */ | ||||
|       cygheap->user.token = create_token (usersid, pgrpsid); | ||||
|       if (cygheap->user.token != INVALID_HANDLE_VALUE) | ||||
| 	explicitly_created_token = TRUE; | ||||
|       else | ||||
| 	{ | ||||
| 	  cygsid usersid, pgrpsid, origsid; | ||||
| 	  HANDLE sav_token = INVALID_HANDLE_VALUE; | ||||
| 	  BOOL sav_impersonation; | ||||
| 	  BOOL current_token_is_internal_token = FALSE; | ||||
| 	  BOOL explicitely_created_token = FALSE; | ||||
|  | ||||
| 	  struct __group16 *gr = getgrgid (myself->gid); | ||||
| 	  debug_printf ("myself->gid: %d, gr: %d", myself->gid, gr); | ||||
|  | ||||
| 	  usersid.getfrompw (pw_new); | ||||
| 	  pgrpsid.getfromgr (gr); | ||||
|  | ||||
| 	  /* Only when ntsec is ON! */ | ||||
| 	  /* Check if new user == user of impersonation token and | ||||
| 	     - if reasonable - new pgrp == pgrp of impersonation token. */ | ||||
| 	  if (allow_ntsec && cygheap->user.token != INVALID_HANDLE_VALUE) | ||||
| 	    { | ||||
| 	      if (!verify_token(cygheap->user.token, usersid, pgrpsid, | ||||
| 				& current_token_is_internal_token)) | ||||
| 		{ | ||||
| 		  /* If not, RevertToSelf and close old token. */ | ||||
| 		  debug_printf ("tsid != usersid"); | ||||
| 		  RevertToSelf (); | ||||
| 		  sav_token = cygheap->user.token; | ||||
| 		  sav_impersonation = cygheap->user.impersonated; | ||||
| 		  cygheap->user.token = INVALID_HANDLE_VALUE; | ||||
| 		  cygheap->user.impersonated = FALSE; | ||||
| 		} | ||||
| 	    } | ||||
|  | ||||
| 	  /* Only when ntsec is ON! */ | ||||
| 	  /* If no impersonation token is available, try to | ||||
| 	     authenticate using NtCreateToken() or subauthentication. */ | ||||
| 	  if (allow_ntsec && cygheap->user.token == INVALID_HANDLE_VALUE) | ||||
| 	    { | ||||
| 	      HANDLE ptok = INVALID_HANDLE_VALUE; | ||||
|  | ||||
| 	      ptok = create_token (usersid, pgrpsid); | ||||
| 	      if (ptok != INVALID_HANDLE_VALUE) | ||||
| 		explicitely_created_token = TRUE; | ||||
| 	      else | ||||
| 		{ | ||||
| 		  /* create_token failed. Try subauthentication. */ | ||||
| 		  debug_printf ("create token failed, try subauthentication."); | ||||
| 		  ptok = subauth (pw_new); | ||||
| 		} | ||||
| 	      if (ptok != INVALID_HANDLE_VALUE) | ||||
| 		{ | ||||
| 		  cygwin_set_impersonation_token (ptok); | ||||
| 		  /* If sav_token was internally created, destroy it. */ | ||||
| 		  if (sav_token != INVALID_HANDLE_VALUE && | ||||
| 		      current_token_is_internal_token) | ||||
| 		    CloseHandle (sav_token); | ||||
| 		} | ||||
| 	      else if (sav_token != INVALID_HANDLE_VALUE) | ||||
| 		cygheap->user.token = sav_token; | ||||
| 	    } | ||||
| 	  /* If no impersonation is active but an impersonation | ||||
| 	     token is available, try to impersonate. */ | ||||
| 	  if (cygheap->user.token != INVALID_HANDLE_VALUE && | ||||
| 	      !cygheap->user.impersonated) | ||||
| 	    { | ||||
| 	      debug_printf ("Impersonate (uid == %d)", uid); | ||||
| 	      RevertToSelf (); | ||||
|  | ||||
| 	      /* If the token was explicitely created, all information has | ||||
| 		 already been set correctly. */ | ||||
| 	      if (!explicitely_created_token) | ||||
| 		{ | ||||
| 		  /* Try setting owner to same value as user. */ | ||||
| 		  if (usersid && | ||||
| 		      !SetTokenInformation (cygheap->user.token, TokenOwner, | ||||
| 					    &usersid, sizeof usersid)) | ||||
| 		    debug_printf ("SetTokenInformation(user.token, " | ||||
| 				  "TokenOwner): %E"); | ||||
| 		  /* Try setting primary group in token to current group | ||||
| 		     if token not explicitely created. */ | ||||
| 		  if (pgrpsid && | ||||
| 		      !SetTokenInformation (cygheap->user.token, | ||||
| 					    TokenPrimaryGroup, | ||||
| 					    &pgrpsid, sizeof pgrpsid)) | ||||
| 		    debug_printf ("SetTokenInformation(user.token, " | ||||
| 				  "TokenPrimaryGroup): %E"); | ||||
| 		} | ||||
| 	      /* Set process def dacl to allow access to impersonated token */ | ||||
| 	      char dacl_buf[MAX_DACL_LEN(5)]; | ||||
| 	      origsid = cygheap->user.orig_sid (); | ||||
| 	      if (usersid && origsid && | ||||
| 		  sec_acl((PACL) dacl_buf, FALSE, origsid, usersid)) | ||||
| 	        { | ||||
| 		  HANDLE ptok = INVALID_HANDLE_VALUE; | ||||
| 		  TOKEN_DEFAULT_DACL tdacl; | ||||
| 		  tdacl.DefaultDacl = (PACL) dacl_buf; | ||||
| 		  if (!OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_DEFAULT, | ||||
| 					 &ptok)) | ||||
| 		    debug_printf ("OpenProcessToken(): %E"); | ||||
| 		  else | ||||
| 		    { | ||||
| 		      if (!SetTokenInformation (ptok, TokenDefaultDacl, | ||||
| 						&tdacl, sizeof dacl_buf)) | ||||
| 			debug_printf ("SetTokenInformation" | ||||
| 				      "(TokenDefaultDacl): %E"); | ||||
| 		    } | ||||
| 		  if (ptok != INVALID_HANDLE_VALUE) CloseHandle (ptok); | ||||
| 		} | ||||
| 	      /* Now try to impersonate. */ | ||||
| 	      if (!LookupAccountSid (NULL, usersid, username, &ulen, | ||||
| 				     domain, &dlen, &use)) | ||||
| 		debug_printf ("LookupAccountSid (): %E"); | ||||
| 	      else if (!ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
| 		system_printf ("Impersonating (%d) in set(e)uid failed: %E", | ||||
| 			       cygheap->user.token); | ||||
| 	      else | ||||
| 		{ | ||||
| 		  cygheap->user.impersonated = TRUE; | ||||
| 		  setenv ("USERNAME", username, 1); | ||||
| 		  setenv ("USERDOMAIN", domain, 1); | ||||
| 		} | ||||
| 	    } | ||||
|         { | ||||
| 	  /* 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) goto failed; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|       cygheap_user user; | ||||
|       /* user.token is used in internal_getlogin () to determine if | ||||
| 	 impersonation is active. If so, the token is used for | ||||
| 	 retrieving user's SID. */ | ||||
|       user.token = cygheap->user.impersonated ? cygheap->user.token | ||||
| 					      : INVALID_HANDLE_VALUE; | ||||
|       /* Unsetting these both env vars is necessary to get NetUserGetInfo() | ||||
| 	 called in internal_getlogin ().  Otherwise the wrong path is used | ||||
| 	 after a user switch, probably. */ | ||||
|       unsetenv ("HOMEDRIVE"); | ||||
|       unsetenv ("HOMEPATH"); | ||||
|       struct passwd *pw_cur = internal_getlogin (user); | ||||
|       if (pw_cur != pw_new) | ||||
| 	{ | ||||
| 	  debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d", | ||||
| 			cygheap->user.token, pw_cur->pw_uid, | ||||
| 			pw_new->pw_uid, cygheap->user.orig_uid); | ||||
| 	  setenv ("USERNAME", orig_username, 1); | ||||
| 	  setenv ("USERDOMAIN", orig_domain, 1); | ||||
| 	  set_errno (EPERM); | ||||
| 	  return -1; | ||||
|   /* Lookup username and domain before impersonating, | ||||
|      LookupAccountSid() returns a different answer afterwards. */ | ||||
|   SID_NAME_USE use; | ||||
|   if (!LookupAccountSid (NULL, usersid, username, &ulen, | ||||
| 			 domain, &dlen, &use)) | ||||
|     { | ||||
|       debug_printf ("LookupAccountSid (): %E"); | ||||
|       __seterrno (); | ||||
|       goto failed; | ||||
|     } | ||||
|   /* If using the token, set info and impersonate */ | ||||
|   if (! process_ok ) | ||||
|     { | ||||
|       /* If the token was explicitly created, all information has | ||||
| 	 already been set correctly. */ | ||||
|       if (!explicitly_created_token) | ||||
|         { | ||||
| 	  /* Try setting owner to same value as user. */ | ||||
| 	  if (!SetTokenInformation (cygheap->user.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, | ||||
| 				    TokenPrimaryGroup, | ||||
| 				    &pgrpsid, sizeof pgrpsid)) | ||||
| 	    debug_printf ("SetTokenInformation(user.token, " | ||||
| 			  "TokenPrimaryGroup): %E"); | ||||
| 	} | ||||
|       /* Now try to impersonate. */ | ||||
|       if (!ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
|         { | ||||
| 	  debug_printf ("ImpersonateLoggedOnUser %E"); | ||||
| 	  __seterrno (); | ||||
| 	  goto failed; | ||||
| 	} | ||||
|       cygheap->user.impersonated = TRUE; | ||||
|     } | ||||
|  | ||||
|   /* user.token is used in internal_getlogin () to determine if | ||||
|      impersonation is active. If so, the token is used for | ||||
|      retrieving user's SID. */ | ||||
|   user.token = cygheap->user.impersonated ? cygheap->user.token | ||||
|                                           : INVALID_HANDLE_VALUE; | ||||
|   /* Unsetting these two env vars is necessary to get NetUserGetInfo() | ||||
|      called in internal_getlogin ().  Otherwise the wrong path is used | ||||
|      after a user switch, probably. */ | ||||
|   unsetenv ("HOMEDRIVE"); | ||||
|   unsetenv ("HOMEPATH"); | ||||
|   setenv ("USERDOMAIN", domain, 1); | ||||
|   setenv ("USERNAME", username, 1); | ||||
|   pw_cur = internal_getlogin (user); | ||||
|   if (pw_cur == pw_new) | ||||
|     { | ||||
|       /* 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); | ||||
|       myself->uid = uid; | ||||
|       cygheap->user = user; | ||||
|       return 0; | ||||
|     } | ||||
|   else | ||||
|     set_errno (ENOSYS); | ||||
|   debug_printf ("real: %d, effective: %d", cygheap->user.real_uid, myself->uid); | ||||
|   return 0; | ||||
|   debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d", | ||||
| 		cygheap->user.token, pw_cur->pw_uid, | ||||
| 		pw_new->pw_uid, cygheap->user.orig_uid); | ||||
|   set_errno (EPERM); | ||||
|  | ||||
|  failed: | ||||
|   setenv ("USERNAME", orig_username, 1); | ||||
|   setenv ("USERDOMAIN", orig_domain, 1); | ||||
|   cygheap->user.token = sav_token; | ||||
|   cygheap->user.impersonated = sav_impersonated; | ||||
|   if ( cygheap->user.token != INVALID_HANDLE_VALUE && | ||||
|        cygheap->user.impersonated && | ||||
|        !ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
|     system_printf ("Impersonating in seteuid failed: %E"); | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
| /* setegid: from System V.  */ | ||||
| extern "C" int | ||||
| setegid (__gid16_t gid) | ||||
| { | ||||
|   if ((!wincap.has_security ()) || | ||||
|       (gid == ILLEGAL_GID)) | ||||
|     return 0; | ||||
|  | ||||
|   sigframe thisframe (mainthread); | ||||
|   if (wincap.has_security ()) | ||||
|   cygsid gsid; | ||||
|   HANDLE ptok; | ||||
|  | ||||
|   if (!(gsid.getfromgr (getgrgid (gid)))) | ||||
|     { | ||||
|       if (gid != ILLEGAL_GID) | ||||
| 	{ | ||||
| 	  struct __group16 *gr; | ||||
|  | ||||
| 	  if (!(gr = getgrgid (gid))) | ||||
| 	    { | ||||
| 	      set_errno (EINVAL); | ||||
| 	      return -1; | ||||
| 	    } | ||||
| 	  myself->gid = gid; | ||||
| 	  if (allow_ntsec) | ||||
| 	    { | ||||
| 	      cygsid gsid; | ||||
| 	      HANDLE ptok; | ||||
|  | ||||
| 	      if (gsid.getfromgr (gr)) | ||||
| 		{ | ||||
| 		  /* Remove impersonation */ | ||||
| 		  if (cygheap->user.token != INVALID_HANDLE_VALUE | ||||
| 		      && cygheap->user.impersonated) | ||||
| 		    { | ||||
| 		      if (!SetTokenInformation (cygheap->user.token, | ||||
| 						TokenPrimaryGroup, | ||||
| 						&gsid, sizeof gsid)) | ||||
| 			debug_printf ("SetTokenInformation(primary, " | ||||
| 				      "TokenPrimaryGroup): %E"); | ||||
| 		      RevertToSelf (); | ||||
| 		    } | ||||
| 		  if (!OpenProcessToken (GetCurrentProcess (), | ||||
| 					 TOKEN_ADJUST_DEFAULT, | ||||
| 					 &ptok)) | ||||
| 		    debug_printf ("OpenProcessToken(): %E\n"); | ||||
| 		  else | ||||
| 		    { | ||||
| 		      if (!SetTokenInformation (ptok, TokenPrimaryGroup, | ||||
| 						&gsid, sizeof gsid)) | ||||
| 			debug_printf ("SetTokenInformation(process, " | ||||
| 				      "TokenPrimaryGroup): %E"); | ||||
| 		      CloseHandle (ptok); | ||||
| 		    } | ||||
| 		  if (cygheap->user.token != INVALID_HANDLE_VALUE | ||||
| 		      && cygheap->user.impersonated) | ||||
| 		    ImpersonateLoggedOnUser (cygheap->user.token); | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|       set_errno (EINVAL); | ||||
|       return -1; | ||||
|     } | ||||
|   myself->gid = gid; | ||||
|  | ||||
|   /* If impersonated, update primary group and revert */ | ||||
|   if (cygheap->user.token != INVALID_HANDLE_VALUE | ||||
|       && cygheap->user.impersonated) | ||||
|     { | ||||
|       if (!SetTokenInformation (cygheap->user.token, | ||||
| 				TokenPrimaryGroup, | ||||
| 				&gsid, sizeof gsid)) | ||||
| 	debug_printf ("SetTokenInformation(thread, " | ||||
| 		      "TokenPrimaryGroup): %E"); | ||||
|       RevertToSelf (); | ||||
|     } | ||||
|   if (!OpenProcessToken (GetCurrentProcess (), | ||||
| 			 TOKEN_ADJUST_DEFAULT, | ||||
| 			 &ptok)) | ||||
|     debug_printf ("OpenProcessToken(): %E\n"); | ||||
|   else | ||||
|     set_errno (ENOSYS); | ||||
|     { | ||||
|       if (!SetTokenInformation (ptok, TokenPrimaryGroup, | ||||
| 				&gsid, sizeof gsid)) | ||||
| 	debug_printf ("SetTokenInformation(process, " | ||||
| 		      "TokenPrimaryGroup): %E"); | ||||
|       CloseHandle (ptok); | ||||
|     } | ||||
|   if (cygheap->user.token != INVALID_HANDLE_VALUE | ||||
|       && cygheap->user.impersonated | ||||
|       && !ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
|     system_printf ("Impersonating in setegid failed: %E"); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user