|  |  |  | @@ -47,6 +47,22 @@ BOOL allow_ntsec = true; | 
		
	
		
			
				|  |  |  |  |    The default is TRUE to reflect the old behaviour. */ | 
		
	
		
			
				|  |  |  |  | BOOL allow_smbntsec; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | cygsid * | 
		
	
		
			
				|  |  |  |  | cygsidlist::alloc_sids (int n) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   if (n > 0) | 
		
	
		
			
				|  |  |  |  |     return (cygsid *) cmalloc (HEAP_STR, n * sizeof (cygsid)); | 
		
	
		
			
				|  |  |  |  |   else | 
		
	
		
			
				|  |  |  |  |     return NULL; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | void | 
		
	
		
			
				|  |  |  |  | cygsidlist::free_sids () | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   if (sids) | 
		
	
		
			
				|  |  |  |  |     cfree (sids); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | extern "C" void | 
		
	
		
			
				|  |  |  |  | cygwin_set_impersonation_token (const HANDLE hToken) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -64,7 +80,7 @@ extract_nt_dom_user (const struct passwd *pw, char *domain, char *user) | 
		
	
		
			
				|  |  |  |  |   char *d, *u, *c; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   domain[0] = 0; | 
		
	
		
			
				|  |  |  |  |   strlcpy (user, pw->pw_name, UNLEN+1); | 
		
	
		
			
				|  |  |  |  |   strlcpy (user, pw->pw_name, UNLEN + 1); | 
		
	
		
			
				|  |  |  |  |   debug_printf ("pw_gecos = %x (%s)", pw->pw_gecos, pw->pw_gecos); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if ((d = strstr (pw->pw_gecos, "U-")) != NULL && | 
		
	
	
		
			
				
					
					|  |  |  | @@ -74,11 +90,11 @@ extract_nt_dom_user (const struct passwd *pw, char *domain, char *user) | 
		
	
		
			
				|  |  |  |  |       if ((u = strchr (d + 2, '\\')) == NULL || (c != NULL && u > c)) | 
		
	
		
			
				|  |  |  |  | 	u = d + 1; | 
		
	
		
			
				|  |  |  |  |       else if (u - d <= INTERNET_MAX_HOST_NAME_LENGTH + 2) | 
		
	
		
			
				|  |  |  |  | 	strlcpy(domain, d + 2, u - d - 1); | 
		
	
		
			
				|  |  |  |  | 	strlcpy (domain, d + 2, u - d - 1); | 
		
	
		
			
				|  |  |  |  |       if (c == NULL) | 
		
	
		
			
				|  |  |  |  | 	c = u + UNLEN + 1; | 
		
	
		
			
				|  |  |  |  |       if (c - u <= UNLEN + 1) | 
		
	
		
			
				|  |  |  |  | 	strlcpy(user, u + 1, c - u); | 
		
	
		
			
				|  |  |  |  | 	strlcpy (user, u + 1, c - u); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   if (domain[0]) | 
		
	
		
			
				|  |  |  |  |     return; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -112,9 +128,9 @@ cygwin_logon_user (const struct passwd *pw, const char *password) | 
		
	
		
			
				|  |  |  |  |   extract_nt_dom_user (pw, nt_domain, nt_user); | 
		
	
		
			
				|  |  |  |  |   debug_printf ("LogonUserA (%s, %s, %s, ...)", nt_user, nt_domain, password); | 
		
	
		
			
				|  |  |  |  |   if (!LogonUserA (nt_user, *nt_domain ? nt_domain : NULL, (char *) password, | 
		
	
		
			
				|  |  |  |  | 		    LOGON32_LOGON_INTERACTIVE, | 
		
	
		
			
				|  |  |  |  | 		    LOGON32_PROVIDER_DEFAULT, | 
		
	
		
			
				|  |  |  |  | 		    &hToken) | 
		
	
		
			
				|  |  |  |  | 		   LOGON32_LOGON_INTERACTIVE, | 
		
	
		
			
				|  |  |  |  | 		   LOGON32_PROVIDER_DEFAULT, | 
		
	
		
			
				|  |  |  |  | 		   &hToken) | 
		
	
		
			
				|  |  |  |  |       || !SetHandleInformation (hToken, | 
		
	
		
			
				|  |  |  |  | 				HANDLE_FLAG_INHERIT, | 
		
	
		
			
				|  |  |  |  | 				HANDLE_FLAG_INHERIT)) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -152,7 +168,7 @@ str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr) | 
		
	
		
			
				|  |  |  |  |   sys_mbstowcs (buf, srcstr, tgt.MaximumLength); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #if 0 //unused | 
		
	
		
			
				|  |  |  |  | #if 0				/* unused */ | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | lsa2wchar (WCHAR *tgt, LSA_UNICODE_STRING &src, int size) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -194,7 +210,7 @@ close_local_policy (LSA_HANDLE &lsa) | 
		
	
		
			
				|  |  |  |  |   lsa = INVALID_HANDLE_VALUE; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #if 0 // unused | 
		
	
		
			
				|  |  |  |  | #if 0 /* unused */ | 
		
	
		
			
				|  |  |  |  | static BOOL | 
		
	
		
			
				|  |  |  |  | get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -226,7 +242,8 @@ get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain) | 
		
	
		
			
				|  |  |  |  |      not member of a domain.  The name in the primary domain info is the | 
		
	
		
			
				|  |  |  |  |      name of the workgroup then. */ | 
		
	
		
			
				|  |  |  |  |   if (pdi->Sid && | 
		
	
		
			
				|  |  |  |  |       (ret = NetGetDCName (NULL, primary, (LPBYTE *) &buf)) == STATUS_SUCCESS) | 
		
	
		
			
				|  |  |  |  |       (ret = | 
		
	
		
			
				|  |  |  |  |        NetGetDCName (NULL, primary, (LPBYTE *) &buf)) == STATUS_SUCCESS) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       sys_wcstombs (name, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1); | 
		
	
		
			
				|  |  |  |  |       strcpy (logonserver, name); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -271,7 +288,8 @@ get_logon_server (const char *domain, char *server, WCHAR *wserver) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       sys_wcstombs (server, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1); | 
		
	
		
			
				|  |  |  |  |       if (wserver) | 
		
	
		
			
				|  |  |  |  | 	for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++); ) {} | 
		
	
		
			
				|  |  |  |  | 	for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++);) | 
		
	
		
			
				|  |  |  |  | 	  ; | 
		
	
		
			
				|  |  |  |  |       NetApiBufferFree (buf); | 
		
	
		
			
				|  |  |  |  |       return TRUE; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -280,7 +298,8 @@ get_logon_server (const char *domain, char *server, WCHAR *wserver) | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static BOOL | 
		
	
		
			
				|  |  |  |  | get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user, char *domain) | 
		
	
		
			
				|  |  |  |  | get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user, | 
		
	
		
			
				|  |  |  |  | 		 char *domain) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   char dgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2]; | 
		
	
		
			
				|  |  |  |  |   WCHAR wuser[UNLEN + 1]; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -313,11 +332,12 @@ get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user, char *do | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |       sys_wcstombs (dgroup + len, buf[i].grui0_name, GNLEN + 1); | 
		
	
		
			
				|  |  |  |  |       if (!LookupAccountName (NULL, dgroup, gsid, &glen, domain, &dlen, &use)) | 
		
	
		
			
				|  |  |  |  | 	  debug_printf ("LookupAccountName(%s): %E", dgroup); | 
		
	
		
			
				|  |  |  |  | 	debug_printf ("LookupAccountName(%s): %E", dgroup); | 
		
	
		
			
				|  |  |  |  |       else if (legal_sid_type (use)) | 
		
	
		
			
				|  |  |  |  | 	  grp_list += gsid; | 
		
	
		
			
				|  |  |  |  |       else debug_printf ("Global group %s invalid. Domain: %s Use: %d", | 
		
	
		
			
				|  |  |  |  | 			dgroup, domain, use); | 
		
	
		
			
				|  |  |  |  | 	grp_list += gsid; | 
		
	
		
			
				|  |  |  |  |       else | 
		
	
		
			
				|  |  |  |  | 	debug_printf ("Global group %s invalid. Domain: %s Use: %d", | 
		
	
		
			
				|  |  |  |  | 		      dgroup, domain, use); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   NetApiBufferFree (buf); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -369,10 +389,10 @@ get_user_local_groups (cygsidlist &grp_list, PSID pusersid) | 
		
	
		
			
				|  |  |  |  |   char lgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2]; | 
		
	
		
			
				|  |  |  |  |   const DWORD blen = sizeof ("BUILTIN\\") - 1; | 
		
	
		
			
				|  |  |  |  |   DWORD llen = INTERNET_MAX_HOST_NAME_LENGTH + 1; | 
		
	
		
			
				|  |  |  |  |   if (!GetComputerNameA(lgroup, & llen)) | 
		
	
		
			
				|  |  |  |  |   if (!GetComputerNameA (lgroup, &llen)) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |        __seterrno (); | 
		
	
		
			
				|  |  |  |  |        return FALSE; | 
		
	
		
			
				|  |  |  |  |       __seterrno (); | 
		
	
		
			
				|  |  |  |  |       return FALSE; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   lgroup[llen++] = '\\'; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -389,11 +409,11 @@ get_user_local_groups (cygsidlist &grp_list, PSID pusersid) | 
		
	
		
			
				|  |  |  |  | 	if (!LookupAccountName (NULL, bgroup, gsid, &glen, domain, &dlen, &use)) | 
		
	
		
			
				|  |  |  |  | 	  { | 
		
	
		
			
				|  |  |  |  | 	    if (GetLastError () != ERROR_NONE_MAPPED) | 
		
	
		
			
				|  |  |  |  |               debug_printf ("LookupAccountName(%s): %E", bgroup); | 
		
	
		
			
				|  |  |  |  | 	      debug_printf ("LookupAccountName(%s): %E", bgroup); | 
		
	
		
			
				|  |  |  |  | 	    strcpy (lgroup + llen, bgroup + blen); | 
		
	
		
			
				|  |  |  |  | 	    if (!LookupAccountName (NULL, lgroup, gsid, &glen, | 
		
	
		
			
				|  |  |  |  | 				    domain, &dlen, &use)) | 
		
	
		
			
				|  |  |  |  |               debug_printf ("LookupAccountName(%s): %E", lgroup); | 
		
	
		
			
				|  |  |  |  | 	      debug_printf ("LookupAccountName(%s): %E", lgroup); | 
		
	
		
			
				|  |  |  |  | 	  } | 
		
	
		
			
				|  |  |  |  | 	if (!legal_sid_type (use)) | 
		
	
		
			
				|  |  |  |  | 	  debug_printf ("Rejecting local %s. use: %d", bgroup + blen, use); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -415,7 +435,7 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygsid &sid) | 
		
	
		
			
				|  |  |  |  |   return FALSE; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #if 0 /* Unused */ | 
		
	
		
			
				|  |  |  |  | #if 0				/* Unused */ | 
		
	
		
			
				|  |  |  |  | static BOOL | 
		
	
		
			
				|  |  |  |  | get_user_primary_group (WCHAR *wlogonserver, const char *user, | 
		
	
		
			
				|  |  |  |  | 			PSID pusersid, cygsid &pgrpsid) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -441,7 +461,8 @@ get_user_primary_group (WCHAR *wlogonserver, const char *user, | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   pgrpsid = pusersid; | 
		
	
		
			
				|  |  |  |  |   if (IsValidSid (pgrpsid) && (count = *GetSidSubAuthorityCount (pgrpsid)) > 1) | 
		
	
		
			
				|  |  |  |  |   if (IsValidSid (pgrpsid) | 
		
	
		
			
				|  |  |  |  |       && (count = *GetSidSubAuthorityCount (pgrpsid)) > 1) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       *GetSidSubAuthority (pgrpsid, count - 1) = buf->usri3_primary_group_id; | 
		
	
		
			
				|  |  |  |  |       retval = TRUE; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -473,57 +494,63 @@ get_unix_group_sidlist (struct passwd *pw, cygsidlist &grp_list) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static BOOL | 
		
	
		
			
				|  |  |  |  | get_group_sidlist (cygsidlist &grp_list, | 
		
	
		
			
				|  |  |  |  | 		   cygsid &usersid, cygsid &pgrpsid, struct passwd *pw, | 
		
	
		
			
				|  |  |  |  | 		   PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos, | 
		
	
		
			
				|  |  |  |  | 		   BOOL *special_pgrp) | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps, | 
		
	
		
			
				|  |  |  |  | 			 LUID auth_luid, int &auth_pos) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   char user[UNLEN + 1]; | 
		
	
		
			
				|  |  |  |  |   char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | 
		
	
		
			
				|  |  |  |  |   WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3]; | 
		
	
		
			
				|  |  |  |  |   char server[INTERNET_MAX_HOST_NAME_LENGTH + 3]; | 
		
	
		
			
				|  |  |  |  |   cygsidlist sup_list; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   auth_pos = -1; | 
		
	
		
			
				|  |  |  |  |   if (my_grps) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       if (sid_in_token_groups (my_grps, well_known_local_sid)) | 
		
	
		
			
				|  |  |  |  | 	grp_list += well_known_local_sid; | 
		
	
		
			
				|  |  |  |  |       if (sid_in_token_groups (my_grps, well_known_dialup_sid)) | 
		
	
		
			
				|  |  |  |  | 	grp_list += well_known_dialup_sid; | 
		
	
		
			
				|  |  |  |  |       if (sid_in_token_groups (my_grps, well_known_network_sid)) | 
		
	
		
			
				|  |  |  |  | 	grp_list += well_known_network_sid; | 
		
	
		
			
				|  |  |  |  |       if (sid_in_token_groups (my_grps, well_known_batch_sid)) | 
		
	
		
			
				|  |  |  |  | 	grp_list += well_known_batch_sid; | 
		
	
		
			
				|  |  |  |  |       if (sid_in_token_groups (my_grps, well_known_interactive_sid)) | 
		
	
		
			
				|  |  |  |  | 	grp_list += well_known_interactive_sid; | 
		
	
		
			
				|  |  |  |  |       if (sid_in_token_groups (my_grps, well_known_service_sid)) | 
		
	
		
			
				|  |  |  |  | 	grp_list += well_known_service_sid; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   else | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       grp_list += well_known_local_sid; | 
		
	
		
			
				|  |  |  |  |       grp_list += well_known_interactive_sid; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   if (auth_luid.QuadPart != 999) /* != SYSTEM_LUID */ | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       char buf[64]; | 
		
	
		
			
				|  |  |  |  |       __small_sprintf (buf, "S-1-5-5-%u-%u", auth_luid.HighPart, | 
		
	
		
			
				|  |  |  |  | 		       auth_luid.LowPart); | 
		
	
		
			
				|  |  |  |  |       grp_list += buf; | 
		
	
		
			
				|  |  |  |  |       auth_pos = grp_list.count - 1; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static BOOL | 
		
	
		
			
				|  |  |  |  | get_initgroups_sidlist (cygsidlist &grp_list, | 
		
	
		
			
				|  |  |  |  | 			PSID usersid, PSID pgrpsid, struct passwd *pw, | 
		
	
		
			
				|  |  |  |  | 			PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos, | 
		
	
		
			
				|  |  |  |  | 			BOOL &special_pgrp) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   grp_list += well_known_world_sid; | 
		
	
		
			
				|  |  |  |  |   grp_list += well_known_authenticated_users_sid; | 
		
	
		
			
				|  |  |  |  |   if (usersid == well_known_system_sid) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       auth_pos = -1; | 
		
	
		
			
				|  |  |  |  |       grp_list += well_known_admins_sid; | 
		
	
		
			
				|  |  |  |  |       get_unix_group_sidlist (pw, grp_list); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   else | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       if (my_grps) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 	  if (sid_in_token_groups (my_grps, well_known_local_sid)) | 
		
	
		
			
				|  |  |  |  | 	    grp_list += well_known_local_sid; | 
		
	
		
			
				|  |  |  |  | 	  if (sid_in_token_groups (my_grps, well_known_dialup_sid)) | 
		
	
		
			
				|  |  |  |  | 	    grp_list += well_known_dialup_sid; | 
		
	
		
			
				|  |  |  |  | 	  if (sid_in_token_groups (my_grps, well_known_network_sid)) | 
		
	
		
			
				|  |  |  |  | 	    grp_list += well_known_network_sid; | 
		
	
		
			
				|  |  |  |  | 	  if (sid_in_token_groups (my_grps, well_known_batch_sid)) | 
		
	
		
			
				|  |  |  |  | 	    grp_list += well_known_batch_sid; | 
		
	
		
			
				|  |  |  |  | 	  if (sid_in_token_groups (my_grps, well_known_interactive_sid)) | 
		
	
		
			
				|  |  |  |  | 	    grp_list += well_known_interactive_sid; | 
		
	
		
			
				|  |  |  |  | 	  if (sid_in_token_groups (my_grps, well_known_service_sid)) | 
		
	
		
			
				|  |  |  |  | 	    grp_list += well_known_service_sid; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |       else | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 	  grp_list += well_known_local_sid; | 
		
	
		
			
				|  |  |  |  | 	  grp_list += well_known_interactive_sid; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |       if (auth_luid.QuadPart != 999) /* != SYSTEM_LUID */ | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 	  char buf[64]; | 
		
	
		
			
				|  |  |  |  | 	  __small_sprintf (buf, "S-1-5-5-%u-%u", auth_luid.HighPart, | 
		
	
		
			
				|  |  |  |  | 						 auth_luid.LowPart); | 
		
	
		
			
				|  |  |  |  | 	  grp_list += buf; | 
		
	
		
			
				|  |  |  |  | 	  auth_pos = grp_list.count - 1; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |       char user[UNLEN + 1]; | 
		
	
		
			
				|  |  |  |  |       char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | 
		
	
		
			
				|  |  |  |  |       WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3]; | 
		
	
		
			
				|  |  |  |  |       char server[INTERNET_MAX_HOST_NAME_LENGTH + 3]; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |       get_token_group_sidlist (grp_list, my_grps, auth_luid, auth_pos); | 
		
	
		
			
				|  |  |  |  |       extract_nt_dom_user (pw, domain, user); | 
		
	
		
			
				|  |  |  |  |       if (get_logon_server (domain, server, wserver)) | 
		
	
		
			
				|  |  |  |  | 	get_user_groups (wserver, grp_list, user, domain); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -531,16 +558,26 @@ get_group_sidlist (cygsidlist &grp_list, | 
		
	
		
			
				|  |  |  |  |       if (!get_user_local_groups (grp_list, usersid)) | 
		
	
		
			
				|  |  |  |  | 	return FALSE; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   /* special_pgrp true if pgrpsid is not null and not in normal groups */ | 
		
	
		
			
				|  |  |  |  |   *special_pgrp = FALSE; | 
		
	
		
			
				|  |  |  |  |   if (pgrpsid && !grp_list.contains (pgrpsid)) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |        *special_pgrp = TRUE; | 
		
	
		
			
				|  |  |  |  |        grp_list += pgrpsid; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   /* special_pgrp true if pgrpsid is not in normal groups */ | 
		
	
		
			
				|  |  |  |  |   if ((special_pgrp = !grp_list.contains (pgrpsid))) | 
		
	
		
			
				|  |  |  |  |     grp_list += pgrpsid; | 
		
	
		
			
				|  |  |  |  |   return TRUE; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | get_setgroups_sidlist (cygsidlist &tmp_list, PTOKEN_GROUPS my_grps, | 
		
	
		
			
				|  |  |  |  | 		       user_groups &groups, LUID auth_luid, int &auth_pos) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   PSID pgpsid = groups.pgsid; | 
		
	
		
			
				|  |  |  |  |   tmp_list += well_known_world_sid; | 
		
	
		
			
				|  |  |  |  |   tmp_list += well_known_authenticated_users_sid; | 
		
	
		
			
				|  |  |  |  |   get_token_group_sidlist (tmp_list, my_grps, auth_luid, auth_pos); | 
		
	
		
			
				|  |  |  |  |   for (int gidx = 0; gidx < groups.sgsids.count; gidx++) | 
		
	
		
			
				|  |  |  |  |     tmp_list += groups.sgsids.sids[gidx]; | 
		
	
		
			
				|  |  |  |  |   if (!groups.sgsids.contains (pgpsid)) | 
		
	
		
			
				|  |  |  |  |     tmp_list += pgpsid; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static const char *sys_privs[] = { | 
		
	
		
			
				|  |  |  |  |   SE_TCB_NAME, | 
		
	
		
			
				|  |  |  |  |   SE_ASSIGNPRIMARYTOKEN_NAME, | 
		
	
	
		
			
				
					
					|  |  |  | @@ -569,8 +606,8 @@ PTOKEN_PRIVILEGES | 
		
	
		
			
				|  |  |  |  | get_system_priv_list (cygsidlist &grp_list) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   LUID priv; | 
		
	
		
			
				|  |  |  |  |   PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES) malloc (sizeof (ULONG) + | 
		
	
		
			
				|  |  |  |  | 					    20 * sizeof (LUID_AND_ATTRIBUTES)); | 
		
	
		
			
				|  |  |  |  |   PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES) | 
		
	
		
			
				|  |  |  |  |     malloc (sizeof (ULONG) + 20 * sizeof (LUID_AND_ATTRIBUTES)); | 
		
	
		
			
				|  |  |  |  |   if (!privs) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       debug_printf ("malloc (system_privs) failed."); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -583,7 +620,7 @@ get_system_priv_list (cygsidlist &grp_list) | 
		
	
		
			
				|  |  |  |  |       { | 
		
	
		
			
				|  |  |  |  | 	privs->Privileges[privs->PrivilegeCount].Luid = priv; | 
		
	
		
			
				|  |  |  |  | 	privs->Privileges[privs->PrivilegeCount].Attributes = | 
		
	
		
			
				|  |  |  |  | 		      SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; | 
		
	
		
			
				|  |  |  |  | 	  SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; | 
		
	
		
			
				|  |  |  |  | 	++privs->PrivilegeCount; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |   return privs; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -605,8 +642,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       if (grp == -1) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 	  if ((ret = LsaEnumerateAccountRights (lsa, usersid, &privstrs, &cnt)) | 
		
	
		
			
				|  |  |  |  | 	      != STATUS_SUCCESS) | 
		
	
		
			
				|  |  |  |  | 	  if ((ret = LsaEnumerateAccountRights (lsa, usersid, &privstrs, | 
		
	
		
			
				|  |  |  |  | 						&cnt)) != STATUS_SUCCESS) | 
		
	
		
			
				|  |  |  |  | 	    continue; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |       else if ((ret = LsaEnumerateAccountRights (lsa, grp_list.sids[grp], | 
		
	
	
		
			
				
					
					|  |  |  | @@ -629,8 +666,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	  tmp_count = privs ? privs->PrivilegeCount : 0; | 
		
	
		
			
				|  |  |  |  | 	  tmp = (PTOKEN_PRIVILEGES) | 
		
	
		
			
				|  |  |  |  | 		realloc (privs, sizeof (ULONG) + | 
		
	
		
			
				|  |  |  |  | 				(tmp_count + 1) * sizeof (LUID_AND_ATTRIBUTES)); | 
		
	
		
			
				|  |  |  |  | 	    realloc (privs, sizeof (ULONG) + | 
		
	
		
			
				|  |  |  |  | 		     (tmp_count + 1) * sizeof (LUID_AND_ATTRIBUTES)); | 
		
	
		
			
				|  |  |  |  | 	  if (!tmp) | 
		
	
		
			
				|  |  |  |  | 	    { | 
		
	
		
			
				|  |  |  |  | 	      if (privs) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -643,7 +680,7 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list) | 
		
	
		
			
				|  |  |  |  | 	  privs = tmp; | 
		
	
		
			
				|  |  |  |  | 	  privs->Privileges[privs->PrivilegeCount].Luid = priv; | 
		
	
		
			
				|  |  |  |  | 	  privs->Privileges[privs->PrivilegeCount].Attributes = | 
		
	
		
			
				|  |  |  |  | 		      SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; | 
		
	
		
			
				|  |  |  |  | 	    SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; | 
		
	
		
			
				|  |  |  |  | 	  ++privs->PrivilegeCount; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	next_account_right: | 
		
	
	
		
			
				
					
					|  |  |  | @@ -654,8 +691,21 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list) | 
		
	
		
			
				|  |  |  |  |   return privs; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /* Accept a token if | 
		
	
		
			
				|  |  |  |  |    - the requested usersid matches the TokenUser and | 
		
	
		
			
				|  |  |  |  |    - if setgroups has been called: | 
		
	
		
			
				|  |  |  |  |         the token groups that are listed in /etc/group match the union of | 
		
	
		
			
				|  |  |  |  | 	the requested primary and supplementary groups in gsids. | 
		
	
		
			
				|  |  |  |  |    - else the (unknown) implicitly requested supplementary groups and those | 
		
	
		
			
				|  |  |  |  |         in the token are the groups associated with the usersid. We assume | 
		
	
		
			
				|  |  |  |  | 	they match and verify only the primary groups. | 
		
	
		
			
				|  |  |  |  | 	The requested primary group must appear in the token. | 
		
	
		
			
				|  |  |  |  | 	The primary group in the token is a group associated with the usersid, | 
		
	
		
			
				|  |  |  |  | 	except if the token is internal and the group is in the token SD | 
		
	
		
			
				|  |  |  |  | 	(see create_token). In that latter case that group must match the | 
		
	
		
			
				|  |  |  |  | 	requested primary group.  */ | 
		
	
		
			
				|  |  |  |  | BOOL | 
		
	
		
			
				|  |  |  |  | verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern) | 
		
	
		
			
				|  |  |  |  | verify_token (HANDLE token, cygsid &usersid, user_groups &groups, BOOL *pintern) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   DWORD size; | 
		
	
		
			
				|  |  |  |  |   BOOL intern = FALSE; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -666,36 +716,39 @@ verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern) | 
		
	
		
			
				|  |  |  |  |       if (!GetTokenInformation (cygheap->user.token, TokenSource, | 
		
	
		
			
				|  |  |  |  | 				&ts, sizeof ts, &size)) | 
		
	
		
			
				|  |  |  |  | 	debug_printf ("GetTokenInformation(): %E"); | 
		
	
		
			
				|  |  |  |  |       else *pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8); | 
		
	
		
			
				|  |  |  |  |       else | 
		
	
		
			
				|  |  |  |  | 	*pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   /* Verify usersid */ | 
		
	
		
			
				|  |  |  |  |   cygsid tok_usersid = NO_SID; | 
		
	
		
			
				|  |  |  |  |   if (!GetTokenInformation (token, TokenUser, | 
		
	
		
			
				|  |  |  |  | 			    &tok_usersid, sizeof tok_usersid, &size)) | 
		
	
		
			
				|  |  |  |  |       debug_printf ("GetTokenInformation(): %E"); | 
		
	
		
			
				|  |  |  |  |   if (usersid != tok_usersid) return FALSE; | 
		
	
		
			
				|  |  |  |  |     debug_printf ("GetTokenInformation(): %E"); | 
		
	
		
			
				|  |  |  |  |   if (usersid != tok_usersid) | 
		
	
		
			
				|  |  |  |  |     return FALSE; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* In an internal token, if the sd group is not well_known_null_sid, | 
		
	
		
			
				|  |  |  |  |      it must match pgrpsid */ | 
		
	
		
			
				|  |  |  |  |   if (intern) | 
		
	
		
			
				|  |  |  |  |   /* For an internal token, if setgroups was not called and if the sd group | 
		
	
		
			
				|  |  |  |  |      is not well_known_null_sid, it must match pgrpsid */ | 
		
	
		
			
				|  |  |  |  |   if (intern && !groups.issetgroups ()) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |        char sd_buf[MAX_SID_LEN + sizeof (SECURITY_DESCRIPTOR)]; | 
		
	
		
			
				|  |  |  |  |        PSID gsid = NO_SID; | 
		
	
		
			
				|  |  |  |  |        if (!GetKernelObjectSecurity (token, GROUP_SECURITY_INFORMATION, | 
		
	
		
			
				|  |  |  |  |       char sd_buf[MAX_SID_LEN + sizeof (SECURITY_DESCRIPTOR)]; | 
		
	
		
			
				|  |  |  |  |       PSID gsid = NO_SID; | 
		
	
		
			
				|  |  |  |  |       if (!GetKernelObjectSecurity (token, GROUP_SECURITY_INFORMATION, | 
		
	
		
			
				|  |  |  |  | 				    (PSECURITY_DESCRIPTOR) sd_buf, | 
		
	
		
			
				|  |  |  |  | 				    sizeof sd_buf, &size)) | 
		
	
		
			
				|  |  |  |  | 	   debug_printf ("GetKernelObjectSecurity(): %E"); | 
		
	
		
			
				|  |  |  |  |        else if (!GetSecurityDescriptorGroup ((PSECURITY_DESCRIPTOR) sd_buf, | 
		
	
		
			
				|  |  |  |  | 	debug_printf ("GetKernelObjectSecurity(): %E"); | 
		
	
		
			
				|  |  |  |  |       else if (!GetSecurityDescriptorGroup ((PSECURITY_DESCRIPTOR) sd_buf, | 
		
	
		
			
				|  |  |  |  | 					    &gsid, (BOOL *) &size)) | 
		
	
		
			
				|  |  |  |  | 	   debug_printf ("GetSecurityDescriptorGroup(): %E"); | 
		
	
		
			
				|  |  |  |  |        if (well_known_null_sid != gsid) return pgrpsid == gsid; | 
		
	
		
			
				|  |  |  |  | 	debug_printf ("GetSecurityDescriptorGroup(): %E"); | 
		
	
		
			
				|  |  |  |  |       if (well_known_null_sid != gsid) | 
		
	
		
			
				|  |  |  |  | 	return gsid == groups.pgsid; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   /* See if the pgrpsid is the tok_usersid in the token groups */ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   PTOKEN_GROUPS my_grps = NULL; | 
		
	
		
			
				|  |  |  |  |   BOOL ret = FALSE; | 
		
	
		
			
				|  |  |  |  |   char saw_buf[NGROUPS_MAX] = {}; | 
		
	
		
			
				|  |  |  |  |   char *saw = saw_buf, sawpg = FALSE; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if ( pgrpsid == tok_usersid) | 
		
	
		
			
				|  |  |  |  |     return TRUE; | 
		
	
		
			
				|  |  |  |  |   if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size) && | 
		
	
		
			
				|  |  |  |  |       GetLastError () != ERROR_INSUFFICIENT_BUFFER) | 
		
	
		
			
				|  |  |  |  |     debug_printf ("GetTokenInformation(token, TokenGroups): %E\n"); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -703,38 +756,70 @@ verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern) | 
		
	
		
			
				|  |  |  |  |     debug_printf ("malloc (my_grps) failed."); | 
		
	
		
			
				|  |  |  |  |   else if (!GetTokenInformation (token, TokenGroups, my_grps, size, &size)) | 
		
	
		
			
				|  |  |  |  |     debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n"); | 
		
	
		
			
				|  |  |  |  |   else | 
		
	
		
			
				|  |  |  |  |     ret = sid_in_token_groups (my_grps, pgrpsid); | 
		
	
		
			
				|  |  |  |  |   else if (!groups.issetgroups ()) /* setgroups was never called */ | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       ret = sid_in_token_groups (my_grps, groups.pgsid); | 
		
	
		
			
				|  |  |  |  |       if (ret == FALSE) | 
		
	
		
			
				|  |  |  |  | 	ret = (groups.pgsid == tok_usersid); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   else /* setgroups was called */ | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       struct __group32 *gr; | 
		
	
		
			
				|  |  |  |  |       cygsid gsid; | 
		
	
		
			
				|  |  |  |  |       if (groups.sgsids.count > (int) sizeof (saw_buf) && | 
		
	
		
			
				|  |  |  |  | 	  !(saw = (char *) calloc (groups.sgsids.count, sizeof (char)))) | 
		
	
		
			
				|  |  |  |  | 	goto done; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |       /* token groups found in /etc/group match the user.gsids ? */ | 
		
	
		
			
				|  |  |  |  |       for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) | 
		
	
		
			
				|  |  |  |  | 	if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid)) | 
		
	
		
			
				|  |  |  |  | 	  { | 
		
	
		
			
				|  |  |  |  | 	    int pos = groups.sgsids.position (gsid); | 
		
	
		
			
				|  |  |  |  | 	    if (pos >= 0) | 
		
	
		
			
				|  |  |  |  | 	      saw[pos] = TRUE; | 
		
	
		
			
				|  |  |  |  | 	    else if (groups.pgsid == gsid) | 
		
	
		
			
				|  |  |  |  | 	      sawpg = TRUE; | 
		
	
		
			
				|  |  |  |  | 	    else | 
		
	
		
			
				|  |  |  |  | 	      goto done; | 
		
	
		
			
				|  |  |  |  | 	  } | 
		
	
		
			
				|  |  |  |  |       for (int gidx = 0; gidx < groups.sgsids.count; gidx++) | 
		
	
		
			
				|  |  |  |  | 	if (!saw[gidx]) | 
		
	
		
			
				|  |  |  |  | 	  goto done; | 
		
	
		
			
				|  |  |  |  |       if (sawpg || groups.sgsids.contains (groups.pgsid)) | 
		
	
		
			
				|  |  |  |  | 	ret = TRUE; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | done: | 
		
	
		
			
				|  |  |  |  |   if (my_grps) | 
		
	
		
			
				|  |  |  |  |     free (my_grps); | 
		
	
		
			
				|  |  |  |  |   if (saw != saw_buf) | 
		
	
		
			
				|  |  |  |  |     free (saw); | 
		
	
		
			
				|  |  |  |  |   return ret; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | HANDLE | 
		
	
		
			
				|  |  |  |  | create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw) | 
		
	
		
			
				|  |  |  |  | create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   NTSTATUS ret; | 
		
	
		
			
				|  |  |  |  |   LSA_HANDLE lsa = INVALID_HANDLE_VALUE; | 
		
	
		
			
				|  |  |  |  |   int old_priv_state; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   cygsidlist grpsids; | 
		
	
		
			
				|  |  |  |  |   cygsidlist tmp_gsids (cygsidlist_auto, 12); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   SECURITY_QUALITY_OF_SERVICE sqos = | 
		
	
		
			
				|  |  |  |  |     { sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE }; | 
		
	
		
			
				|  |  |  |  |   OBJECT_ATTRIBUTES oa = | 
		
	
		
			
				|  |  |  |  |     { sizeof oa, 0, 0, 0, 0, &sqos }; | 
		
	
		
			
				|  |  |  |  |   OBJECT_ATTRIBUTES oa = { sizeof oa, 0, 0, 0, 0, &sqos }; | 
		
	
		
			
				|  |  |  |  |   PSECURITY_ATTRIBUTES psa; | 
		
	
		
			
				|  |  |  |  |   BOOL special_pgrp; | 
		
	
		
			
				|  |  |  |  |   BOOL special_pgrp = FALSE; | 
		
	
		
			
				|  |  |  |  |   char sa_buf[1024]; | 
		
	
		
			
				|  |  |  |  |   LUID auth_luid = SYSTEM_LUID; | 
		
	
		
			
				|  |  |  |  |   LARGE_INTEGER exp = { QuadPart:0x7fffffffffffffffLL  }; | 
		
	
		
			
				|  |  |  |  |   LARGE_INTEGER exp = { QuadPart:0x7fffffffffffffffLL }; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   TOKEN_USER user; | 
		
	
		
			
				|  |  |  |  |   PTOKEN_GROUPS grps = NULL; | 
		
	
		
			
				|  |  |  |  |   PTOKEN_GROUPS new_tok_gsids = NULL; | 
		
	
		
			
				|  |  |  |  |   PTOKEN_PRIVILEGES privs = NULL; | 
		
	
		
			
				|  |  |  |  |   TOKEN_OWNER owner; | 
		
	
		
			
				|  |  |  |  |   TOKEN_PRIMARY_GROUP pgrp; | 
		
	
		
			
				|  |  |  |  |   char acl_buf[MAX_DACL_LEN(5)]; | 
		
	
		
			
				|  |  |  |  |   char acl_buf[MAX_DACL_LEN (5)]; | 
		
	
		
			
				|  |  |  |  |   TOKEN_DEFAULT_DACL dacl; | 
		
	
		
			
				|  |  |  |  |   TOKEN_SOURCE source; | 
		
	
		
			
				|  |  |  |  |   TOKEN_STATISTICS stats; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -746,7 +831,7 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw) | 
		
	
		
			
				|  |  |  |  |   HANDLE primary_token = INVALID_HANDLE_VALUE; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   HANDLE my_token = INVALID_HANDLE_VALUE; | 
		
	
		
			
				|  |  |  |  |   PTOKEN_GROUPS my_grps = NULL; | 
		
	
		
			
				|  |  |  |  |   PTOKEN_GROUPS my_tok_gsids = NULL; | 
		
	
		
			
				|  |  |  |  |   DWORD size; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */ | 
		
	
	
		
			
				
					
					|  |  |  | @@ -768,68 +853,73 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw) | 
		
	
		
			
				|  |  |  |  |   else | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       /* Switching user context to SYSTEM doesn't inherit the authentication | 
		
	
		
			
				|  |  |  |  | 	 id of the user account running current process. */ | 
		
	
		
			
				|  |  |  |  |          id of the user account running current process. */ | 
		
	
		
			
				|  |  |  |  |       if (usersid != well_known_system_sid) | 
		
	
		
			
				|  |  |  |  | 	if (!GetTokenInformation (my_token, TokenStatistics, | 
		
	
		
			
				|  |  |  |  | 				  &stats, sizeof stats, &size)) | 
		
	
		
			
				|  |  |  |  | 	  debug_printf ("GetTokenInformation(my_token, TokenStatistics): %E\n"); | 
		
	
		
			
				|  |  |  |  | 	  debug_printf | 
		
	
		
			
				|  |  |  |  | 	    ("GetTokenInformation(my_token, TokenStatistics): %E\n"); | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
		
			
				|  |  |  |  | 	  auth_luid = stats.AuthenticationId; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |       /* Retrieving current processes group list to be able to inherit | 
		
	
		
			
				|  |  |  |  | 	 some important well known group sids. */ | 
		
	
		
			
				|  |  |  |  |          some important well known group sids. */ | 
		
	
		
			
				|  |  |  |  |       if (!GetTokenInformation (my_token, TokenGroups, NULL, 0, &size) && | 
		
	
		
			
				|  |  |  |  | 	  GetLastError () != ERROR_INSUFFICIENT_BUFFER) | 
		
	
		
			
				|  |  |  |  | 	debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n"); | 
		
	
		
			
				|  |  |  |  |       else if (!(my_grps = (PTOKEN_GROUPS) malloc (size))) | 
		
	
		
			
				|  |  |  |  | 	debug_printf ("malloc (my_grps) failed."); | 
		
	
		
			
				|  |  |  |  |       else if (!GetTokenInformation (my_token, TokenGroups, my_grps, | 
		
	
		
			
				|  |  |  |  |       else if (!(my_tok_gsids = (PTOKEN_GROUPS) malloc (size))) | 
		
	
		
			
				|  |  |  |  | 	debug_printf ("malloc (my_tok_gsids) failed."); | 
		
	
		
			
				|  |  |  |  |       else if (!GetTokenInformation (my_token, TokenGroups, my_tok_gsids, | 
		
	
		
			
				|  |  |  |  | 				     size, &size)) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 	  debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n"); | 
		
	
		
			
				|  |  |  |  | 	  free (my_grps); | 
		
	
		
			
				|  |  |  |  | 	  my_grps = NULL; | 
		
	
		
			
				|  |  |  |  | 	  free (my_tok_gsids); | 
		
	
		
			
				|  |  |  |  | 	  my_tok_gsids = NULL; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |       CloseHandle (my_token); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Create list of groups, the user is member in. */ | 
		
	
		
			
				|  |  |  |  |   int auth_pos; | 
		
	
		
			
				|  |  |  |  |   if (!get_group_sidlist (grpsids, usersid, pgrpsid, pw, | 
		
	
		
			
				|  |  |  |  | 			  my_grps, auth_luid, auth_pos, &special_pgrp)) | 
		
	
		
			
				|  |  |  |  |   if (new_groups.issetgroups ()) | 
		
	
		
			
				|  |  |  |  |     get_setgroups_sidlist (tmp_gsids, my_tok_gsids, new_groups, auth_luid, | 
		
	
		
			
				|  |  |  |  | 			   auth_pos); | 
		
	
		
			
				|  |  |  |  |   else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, pw, | 
		
	
		
			
				|  |  |  |  | 				    my_tok_gsids, auth_luid, auth_pos, | 
		
	
		
			
				|  |  |  |  | 				    special_pgrp)) | 
		
	
		
			
				|  |  |  |  |     goto out; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Primary group. */ | 
		
	
		
			
				|  |  |  |  |   pgrp.PrimaryGroup = pgrpsid; | 
		
	
		
			
				|  |  |  |  |   pgrp.PrimaryGroup = new_groups.pgsid; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Create a TOKEN_GROUPS list from the above retrieved list of sids. */ | 
		
	
		
			
				|  |  |  |  |   char grps_buf[sizeof (ULONG) + grpsids.count * sizeof (SID_AND_ATTRIBUTES)]; | 
		
	
		
			
				|  |  |  |  |   grps = (PTOKEN_GROUPS) grps_buf; | 
		
	
		
			
				|  |  |  |  |   grps->GroupCount = grpsids.count; | 
		
	
		
			
				|  |  |  |  |   for (DWORD i = 0; i < grps->GroupCount; ++i) | 
		
	
		
			
				|  |  |  |  |   char grps_buf[sizeof (ULONG) + tmp_gsids.count * sizeof (SID_AND_ATTRIBUTES)]; | 
		
	
		
			
				|  |  |  |  |   new_tok_gsids = (PTOKEN_GROUPS) grps_buf; | 
		
	
		
			
				|  |  |  |  |   new_tok_gsids->GroupCount = tmp_gsids.count; | 
		
	
		
			
				|  |  |  |  |   for (DWORD i = 0; i < new_tok_gsids->GroupCount; ++i) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       grps->Groups[i].Sid = grpsids.sids[i]; | 
		
	
		
			
				|  |  |  |  |       grps->Groups[i].Attributes = SE_GROUP_MANDATORY | | 
		
	
		
			
				|  |  |  |  | 				   SE_GROUP_ENABLED_BY_DEFAULT | | 
		
	
		
			
				|  |  |  |  | 				   SE_GROUP_ENABLED; | 
		
	
		
			
				|  |  |  |  |       if (auth_pos >= 0 && i == (DWORD) auth_pos) | 
		
	
		
			
				|  |  |  |  | 	grps->Groups[i].Attributes |= SE_GROUP_LOGON_ID; | 
		
	
		
			
				|  |  |  |  |       new_tok_gsids->Groups[i].Sid = tmp_gsids.sids[i]; | 
		
	
		
			
				|  |  |  |  |       new_tok_gsids->Groups[i].Attributes = SE_GROUP_MANDATORY | | 
		
	
		
			
				|  |  |  |  | 	SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   if (auth_pos >= 0) | 
		
	
		
			
				|  |  |  |  |     new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Retrieve list of privileges of that user. */ | 
		
	
		
			
				|  |  |  |  |   if (!(privs = get_priv_list (lsa, usersid, grpsids))) | 
		
	
		
			
				|  |  |  |  |   if (!(privs = get_priv_list (lsa, usersid, tmp_gsids))) | 
		
	
		
			
				|  |  |  |  |     goto out; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Create default dacl. */ | 
		
	
		
			
				|  |  |  |  |   if (!sec_acl ((PACL) acl_buf, FALSE, | 
		
	
		
			
				|  |  |  |  | 		grpsids.contains (well_known_admins_sid)?well_known_admins_sid:usersid)) | 
		
	
		
			
				|  |  |  |  | 		tmp_gsids.contains (well_known_admins_sid) ? | 
		
	
		
			
				|  |  |  |  | 		well_known_admins_sid : usersid)) | 
		
	
		
			
				|  |  |  |  |     goto out; | 
		
	
		
			
				|  |  |  |  |   dacl.DefaultDacl = (PACL) acl_buf; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Let's be heroic... */ | 
		
	
		
			
				|  |  |  |  |   ret = NtCreateToken (&token, TOKEN_ALL_ACCESS, &oa, TokenImpersonation, | 
		
	
		
			
				|  |  |  |  | 		       &auth_luid, &exp, &user, grps, privs, &owner, &pgrp, | 
		
	
		
			
				|  |  |  |  | 		       &dacl, &source); | 
		
	
		
			
				|  |  |  |  | 		       &auth_luid, &exp, &user, new_tok_gsids, privs, &owner, | 
		
	
		
			
				|  |  |  |  | 		       &pgrp, &dacl, &source); | 
		
	
		
			
				|  |  |  |  |   if (ret) | 
		
	
		
			
				|  |  |  |  |     __seterrno_from_win_error (RtlNtStatusToDosError (ret)); | 
		
	
		
			
				|  |  |  |  |   else if (GetLastError () == ERROR_PROC_NOT_FOUND) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -842,13 +932,15 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw) | 
		
	
		
			
				|  |  |  |  |       /* Set security descriptor and primary group */ | 
		
	
		
			
				|  |  |  |  |       psa = __sec_user (sa_buf, usersid, TRUE); | 
		
	
		
			
				|  |  |  |  |       if (psa->lpSecurityDescriptor && | 
		
	
		
			
				|  |  |  |  | 	  !SetSecurityDescriptorGroup ( | 
		
	
		
			
				|  |  |  |  | 	      (PSECURITY_DESCRIPTOR) psa->lpSecurityDescriptor, | 
		
	
		
			
				|  |  |  |  | 	      special_pgrp ? pgrpsid : well_known_null_sid, FALSE)) | 
		
	
		
			
				|  |  |  |  | 	  debug_printf ("SetSecurityDescriptorGroup %E"); | 
		
	
		
			
				|  |  |  |  | 	  !SetSecurityDescriptorGroup ((PSECURITY_DESCRIPTOR) | 
		
	
		
			
				|  |  |  |  | 				       psa->lpSecurityDescriptor, | 
		
	
		
			
				|  |  |  |  | 				       special_pgrp ? new_groups.pgsid | 
		
	
		
			
				|  |  |  |  | 						    : well_known_null_sid, | 
		
	
		
			
				|  |  |  |  | 				       FALSE)) | 
		
	
		
			
				|  |  |  |  | 	debug_printf ("SetSecurityDescriptorGroup %E"); | 
		
	
		
			
				|  |  |  |  |       /* Convert to primary token. */ | 
		
	
		
			
				|  |  |  |  |       if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, psa, | 
		
	
		
			
				|  |  |  |  | 			     SecurityImpersonation, TokenPrimary, &primary_token)) | 
		
	
		
			
				|  |  |  |  |       if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, psa, SecurityImpersonation, | 
		
	
		
			
				|  |  |  |  | 			     TokenPrimary, &primary_token)) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 	  __seterrno (); | 
		
	
		
			
				|  |  |  |  | 	  debug_printf ("DuplicateTokenEx %E"); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -862,8 +954,8 @@ out: | 
		
	
		
			
				|  |  |  |  |     CloseHandle (token); | 
		
	
		
			
				|  |  |  |  |   if (privs) | 
		
	
		
			
				|  |  |  |  |     free (privs); | 
		
	
		
			
				|  |  |  |  |   if (my_grps) | 
		
	
		
			
				|  |  |  |  |     free (my_grps); | 
		
	
		
			
				|  |  |  |  |   if (my_tok_gsids) | 
		
	
		
			
				|  |  |  |  |     free (my_tok_gsids); | 
		
	
		
			
				|  |  |  |  |   close_local_policy (lsa); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   debug_printf ("%d = create_token ()", primary_token); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -946,13 +1038,13 @@ subauth (struct passwd *pw) | 
		
	
		
			
				|  |  |  |  |   str2buf2uni (subbuf.auth.Workstation, subbuf.wkstbuf, ""); | 
		
	
		
			
				|  |  |  |  |   memcpy (subbuf.auth.ChallengeToClient, "12345678", MSV1_0_CHALLENGE_LENGTH); | 
		
	
		
			
				|  |  |  |  |   str2buf2lsa (subbuf.auth.CaseSensitiveChallengeResponse, subbuf.authinf1, ""); | 
		
	
		
			
				|  |  |  |  |   str2buf2lsa (subbuf.auth.CaseInsensitiveChallengeResponse, subbuf.authinf2,""); | 
		
	
		
			
				|  |  |  |  |   str2buf2lsa (subbuf.auth.CaseInsensitiveChallengeResponse,subbuf.authinf2,""); | 
		
	
		
			
				|  |  |  |  |   subbuf.auth.ParameterControl = 0 | (subauth_id << 24); | 
		
	
		
			
				|  |  |  |  |   /* Try to logon... */ | 
		
	
		
			
				|  |  |  |  |   ret = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network, | 
		
	
		
			
				|  |  |  |  | 		     package_id, &subbuf, sizeof subbuf, | 
		
	
		
			
				|  |  |  |  | 		     NULL, &ts, (PVOID *)&profile, &size, | 
		
	
		
			
				|  |  |  |  | 		     &luid, &user_token, "a, &ret2); | 
		
	
		
			
				|  |  |  |  | 		      package_id, &subbuf, sizeof subbuf, | 
		
	
		
			
				|  |  |  |  | 		      NULL, &ts, (PVOID *) &profile, &size, | 
		
	
		
			
				|  |  |  |  | 		      &luid, &user_token, "a, &ret2); | 
		
	
		
			
				|  |  |  |  |   if (ret != STATUS_SUCCESS) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       debug_printf ("LsaLogonUser: %d", ret); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -963,8 +1055,7 @@ subauth (struct passwd *pw) | 
		
	
		
			
				|  |  |  |  |   LsaFreeReturnBuffer (profile); | 
		
	
		
			
				|  |  |  |  |   /* Convert to primary token. */ | 
		
	
		
			
				|  |  |  |  |   if (!DuplicateTokenEx (user_token, TOKEN_ALL_ACCESS, &sa, | 
		
	
		
			
				|  |  |  |  | 			 SecurityImpersonation, TokenPrimary, | 
		
	
		
			
				|  |  |  |  | 			 &primary_token)) | 
		
	
		
			
				|  |  |  |  | 			 SecurityImpersonation, TokenPrimary, &primary_token)) | 
		
	
		
			
				|  |  |  |  |     __seterrno (); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | out: | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1004,7 +1095,7 @@ read_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   DWORD len = 0; | 
		
	
		
			
				|  |  |  |  |   const char *pfile = file; | 
		
	
		
			
				|  |  |  |  |   char fbuf [PATH_MAX]; | 
		
	
		
			
				|  |  |  |  |   char fbuf[PATH_MAX]; | 
		
	
		
			
				|  |  |  |  |   if (current_codepage == oem_cp) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       DWORD fname_len = min (sizeof (fbuf) - 1, strlen (file)); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1015,9 +1106,9 @@ read_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (!GetFileSecurity (pfile, | 
		
	
		
			
				|  |  |  |  | 			OWNER_SECURITY_INFORMATION | 
		
	
		
			
				|  |  |  |  | 			 | GROUP_SECURITY_INFORMATION | 
		
	
		
			
				|  |  |  |  | 			 | DACL_SECURITY_INFORMATION, | 
		
	
		
			
				|  |  |  |  | 			 sd_buf, *sd_size, &len)) | 
		
	
		
			
				|  |  |  |  | 			| GROUP_SECURITY_INFORMATION | 
		
	
		
			
				|  |  |  |  | 			| DACL_SECURITY_INFORMATION, | 
		
	
		
			
				|  |  |  |  | 			sd_buf, *sd_size, &len)) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       __seterrno (); | 
		
	
		
			
				|  |  |  |  |       return -1; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1090,8 +1181,8 @@ write_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size) | 
		
	
		
			
				|  |  |  |  | 		    &bytes_written, FALSE, TRUE, &context)) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       /* Samba returns ERROR_NOT_SUPPORTED. | 
		
	
		
			
				|  |  |  |  | 	 FAT returns ERROR_INVALID_SECURITY_DESCR. | 
		
	
		
			
				|  |  |  |  | 	 This shouldn't return as error, but better be ignored. */ | 
		
	
		
			
				|  |  |  |  |          FAT returns ERROR_INVALID_SECURITY_DESCR. | 
		
	
		
			
				|  |  |  |  |          This shouldn't return as error, but better be ignored. */ | 
		
	
		
			
				|  |  |  |  |       DWORD ret = GetLastError (); | 
		
	
		
			
				|  |  |  |  |       if (ret != ERROR_NOT_SUPPORTED && ret != ERROR_INVALID_SECURITY_DESCR) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1117,7 +1208,7 @@ get_nt_attribute (const char *file, int *attribute, | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   syscall_printf ("file: %s", file); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Yeah, sounds too much, but I've seen SDs of 2100 bytes!*/ | 
		
	
		
			
				|  |  |  |  |   /* Yeah, sounds too much, but I've seen SDs of 2100 bytes! */ | 
		
	
		
			
				|  |  |  |  |   DWORD sd_size = 4096; | 
		
	
		
			
				|  |  |  |  |   char sd_buf[4096]; | 
		
	
		
			
				|  |  |  |  |   PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1282,13 +1373,13 @@ get_file_attribute (int use_ntsec, const char *file, | 
		
	
		
			
				|  |  |  |  |   if (allow_ntea) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       int oatt = *attribute; | 
		
	
		
			
				|  |  |  |  |       res = NTReadEA (file, ".UNIXATTR", (char *) attribute, sizeof (*attribute)); | 
		
	
		
			
				|  |  |  |  |       res = NTReadEA (file, ".UNIXATTR", (char *)attribute, sizeof(*attribute)); | 
		
	
		
			
				|  |  |  |  |       *attribute |= oatt; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   else | 
		
	
		
			
				|  |  |  |  |     res = 0; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* symlinks are everything for everyone!*/ | 
		
	
		
			
				|  |  |  |  |   /* symlinks are everything for everyone! */ | 
		
	
		
			
				|  |  |  |  |   if ((*attribute & S_IFLNK) == S_IFLNK) | 
		
	
		
			
				|  |  |  |  |     *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1296,8 +1387,8 @@ get_file_attribute (int use_ntsec, const char *file, | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static int | 
		
	
		
			
				|  |  |  |  | get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribute, | 
		
	
		
			
				|  |  |  |  | 		  __uid32_t *uidret, __gid32_t *gidret) | 
		
	
		
			
				|  |  |  |  | get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, | 
		
	
		
			
				|  |  |  |  | 			 int *attribute, __uid32_t *uidret, __gid32_t *gidret) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   if (!wincap.has_security ()) | 
		
	
		
			
				|  |  |  |  |     return 0; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1308,18 +1399,15 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu | 
		
	
		
			
				|  |  |  |  |   PACL acl; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (ERROR_SUCCESS != GetSecurityInfo (handle, object_type, | 
		
	
		
			
				|  |  |  |  |                                         DACL_SECURITY_INFORMATION | | 
		
	
		
			
				|  |  |  |  |                                         GROUP_SECURITY_INFORMATION | | 
		
	
		
			
				|  |  |  |  |                                         OWNER_SECURITY_INFORMATION, | 
		
	
		
			
				|  |  |  |  |                                         &owner_sid, | 
		
	
		
			
				|  |  |  |  |                                         &group_sid, | 
		
	
		
			
				|  |  |  |  |                                         &acl, | 
		
	
		
			
				|  |  |  |  |                                         NULL, | 
		
	
		
			
				|  |  |  |  |                                         &psd)) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 	  __seterrno (); | 
		
	
		
			
				|  |  |  |  | 	  debug_printf ("GetSecurityInfo %E"); | 
		
	
		
			
				|  |  |  |  | 	  return -1; | 
		
	
		
			
				|  |  |  |  | 					DACL_SECURITY_INFORMATION | | 
		
	
		
			
				|  |  |  |  | 					GROUP_SECURITY_INFORMATION | | 
		
	
		
			
				|  |  |  |  | 					OWNER_SECURITY_INFORMATION, | 
		
	
		
			
				|  |  |  |  | 					&owner_sid, &group_sid, | 
		
	
		
			
				|  |  |  |  | 					&acl, NULL, &psd)) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       __seterrno (); | 
		
	
		
			
				|  |  |  |  |       debug_printf ("GetSecurityInfo %E"); | 
		
	
		
			
				|  |  |  |  |       return -1; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   __uid32_t uid = cygsid (owner_sid).get_uid (); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1341,8 +1429,7 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu | 
		
	
		
			
				|  |  |  |  |   if (!acl) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; | 
		
	
		
			
				|  |  |  |  |       syscall_printf ("No ACL = %x, uid %d, gid %d", | 
		
	
		
			
				|  |  |  |  | 		      *attribute, uid, gid); | 
		
	
		
			
				|  |  |  |  |       syscall_printf ("No ACL = %x, uid %d, gid %d", *attribute, uid, gid); | 
		
	
		
			
				|  |  |  |  |       LocalFree (psd); | 
		
	
		
			
				|  |  |  |  |       return 0; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1354,7 +1441,7 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   for (DWORD i = 0; i < acl->AceCount; ++i) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       if (!GetAce (acl, i, (PVOID *) &ace)) | 
		
	
		
			
				|  |  |  |  |       if (!GetAce (acl, i, (PVOID *) & ace)) | 
		
	
		
			
				|  |  |  |  | 	continue; | 
		
	
		
			
				|  |  |  |  |       if (ace->Header.AceFlags & INHERIT_ONLY) | 
		
	
		
			
				|  |  |  |  | 	continue; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1372,7 +1459,7 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu | 
		
	
		
			
				|  |  |  |  | 	  continue; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |       cygsid ace_sid ((PSID) &ace->SidStart); | 
		
	
		
			
				|  |  |  |  |       cygsid ace_sid ((PSID) & ace->SidStart); | 
		
	
		
			
				|  |  |  |  |       if (owner_sid && ace_sid == owner_sid) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 	  if (ace->Mask & FILE_READ_DATA) | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1438,11 +1525,12 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | int | 
		
	
		
			
				|  |  |  |  | get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, | 
		
	
		
			
				|  |  |  |  | 		    int *attribute, __uid32_t *uidret, __gid32_t *gidret) | 
		
	
		
			
				|  |  |  |  | 		      int *attribute, __uid32_t *uidret, __gid32_t *gidret) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   if (allow_ntsec) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       int res = get_nt_object_attribute (handle, object_type, attribute, uidret, gidret); | 
		
	
		
			
				|  |  |  |  |       int res = get_nt_object_attribute (handle, object_type, attribute, | 
		
	
		
			
				|  |  |  |  |       					 uidret, gidret); | 
		
	
		
			
				|  |  |  |  |       if (attribute && (*attribute & S_IFLNK) == S_IFLNK) | 
		
	
		
			
				|  |  |  |  | 	*attribute |= S_IRWXU | S_IRWXG | S_IRWXO; | 
		
	
		
			
				|  |  |  |  |       return res; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1456,7 +1544,7 @@ get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, | 
		
	
		
			
				|  |  |  |  |   if (!attribute) | 
		
	
		
			
				|  |  |  |  |     return 0; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* symlinks are everything for everyone!*/ | 
		
	
		
			
				|  |  |  |  |   /* symlinks are everything for everyone! */ | 
		
	
		
			
				|  |  |  |  |   if ((*attribute & S_IFLNK) == S_IFLNK) | 
		
	
		
			
				|  |  |  |  |     *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1475,8 +1563,7 @@ add_access_allowed_ace (PACL acl, int offset, DWORD attributes, | 
		
	
		
			
				|  |  |  |  |   ACCESS_ALLOWED_ACE *ace; | 
		
	
		
			
				|  |  |  |  |   if (GetAce (acl, offset, (PVOID *) &ace)) | 
		
	
		
			
				|  |  |  |  |     ace->Header.AceFlags |= inherit; | 
		
	
		
			
				|  |  |  |  |   len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) | 
		
	
		
			
				|  |  |  |  | 	     + GetLengthSid (sid); | 
		
	
		
			
				|  |  |  |  |   len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) + GetLengthSid (sid); | 
		
	
		
			
				|  |  |  |  |   return TRUE; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1492,8 +1579,7 @@ add_access_denied_ace (PACL acl, int offset, DWORD attributes, | 
		
	
		
			
				|  |  |  |  |   ACCESS_DENIED_ACE *ace; | 
		
	
		
			
				|  |  |  |  |   if (GetAce (acl, offset, (PVOID *) &ace)) | 
		
	
		
			
				|  |  |  |  |     ace->Header.AceFlags |= inherit; | 
		
	
		
			
				|  |  |  |  |   len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) | 
		
	
		
			
				|  |  |  |  | 	     + GetLengthSid (sid); | 
		
	
		
			
				|  |  |  |  |   len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) + GetLengthSid (sid); | 
		
	
		
			
				|  |  |  |  |   return TRUE; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1614,8 +1700,7 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, | 
		
	
		
			
				|  |  |  |  |   if (attribute & S_IXGRP) | 
		
	
		
			
				|  |  |  |  |     group_allow |= FILE_GENERIC_EXECUTE; | 
		
	
		
			
				|  |  |  |  |   if ((attribute & (S_IFDIR | S_IWGRP | S_IXGRP)) | 
		
	
		
			
				|  |  |  |  |       == (S_IFDIR | S_IWGRP | S_IXGRP) | 
		
	
		
			
				|  |  |  |  |       && !(attribute & S_ISVTX)) | 
		
	
		
			
				|  |  |  |  |       == (S_IFDIR | S_IWGRP | S_IXGRP) && !(attribute & S_ISVTX)) | 
		
	
		
			
				|  |  |  |  |     group_allow |= FILE_DELETE_CHILD; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Construct allow attribute for everyone. */ | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1658,30 +1743,30 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Construct appropriate inherit attribute. */ | 
		
	
		
			
				|  |  |  |  |   DWORD inherit = (attribute & S_IFDIR) ? SUB_CONTAINERS_AND_OBJECTS_INHERIT | 
		
	
		
			
				|  |  |  |  |   					: NO_INHERITANCE; | 
		
	
		
			
				|  |  |  |  | 					: NO_INHERITANCE; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Set deny ACE for owner. */ | 
		
	
		
			
				|  |  |  |  |   if (owner_deny | 
		
	
		
			
				|  |  |  |  |       && !add_access_denied_ace (acl, ace_off++, owner_deny, | 
		
	
		
			
				|  |  |  |  | 				  owner_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  | 				 owner_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  |     return NULL; | 
		
	
		
			
				|  |  |  |  |   /* Set allow ACE for owner. */ | 
		
	
		
			
				|  |  |  |  |   if (!add_access_allowed_ace (acl, ace_off++, owner_allow, | 
		
	
		
			
				|  |  |  |  | 				owner_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  | 			       owner_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  |     return NULL; | 
		
	
		
			
				|  |  |  |  |   /* Set deny ACE for group. */ | 
		
	
		
			
				|  |  |  |  |   if (group_deny | 
		
	
		
			
				|  |  |  |  |       && !add_access_denied_ace (acl, ace_off++, group_deny, | 
		
	
		
			
				|  |  |  |  | 				  group_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  | 				 group_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  |     return NULL; | 
		
	
		
			
				|  |  |  |  |   /* Set allow ACE for group. */ | 
		
	
		
			
				|  |  |  |  |   if (!add_access_allowed_ace (acl, ace_off++, group_allow, | 
		
	
		
			
				|  |  |  |  | 				group_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  | 			       group_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  |     return NULL; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Set allow ACE for everyone. */ | 
		
	
		
			
				|  |  |  |  |   if (!add_access_allowed_ace (acl, ace_off++, other_allow, | 
		
	
		
			
				|  |  |  |  | 				well_known_world_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  | 			       well_known_world_sid, acl_len, inherit)) | 
		
	
		
			
				|  |  |  |  |     return NULL; | 
		
	
		
			
				|  |  |  |  |   /* Set null ACE for special bits. */ | 
		
	
		
			
				|  |  |  |  |   if (null_allow | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1764,15 +1849,15 @@ void | 
		
	
		
			
				|  |  |  |  | set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa, | 
		
	
		
			
				|  |  |  |  | 			void *sd_buf, DWORD sd_buf_size) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   /* symlinks are anything for everyone!*/ | 
		
	
		
			
				|  |  |  |  |   /* symlinks are anything for everyone! */ | 
		
	
		
			
				|  |  |  |  |   if ((attribute & S_IFLNK) == S_IFLNK) | 
		
	
		
			
				|  |  |  |  |     attribute |= S_IRWXU | S_IRWXG | S_IRWXO; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   psa->lpSecurityDescriptor = sd_buf; | 
		
	
		
			
				|  |  |  |  |   InitializeSecurityDescriptor ((PSECURITY_DESCRIPTOR)sd_buf, | 
		
	
		
			
				|  |  |  |  |   InitializeSecurityDescriptor ((PSECURITY_DESCRIPTOR) sd_buf, | 
		
	
		
			
				|  |  |  |  | 				SECURITY_DESCRIPTOR_REVISION); | 
		
	
		
			
				|  |  |  |  |   psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (), | 
		
	
		
			
				|  |  |  |  | 					attribute, (PSECURITY_DESCRIPTOR)sd_buf, | 
		
	
		
			
				|  |  |  |  |   psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (), attribute, | 
		
	
		
			
				|  |  |  |  | 					(PSECURITY_DESCRIPTOR) sd_buf, | 
		
	
		
			
				|  |  |  |  | 					&sd_buf_size); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1803,8 +1888,7 @@ set_nt_attribute (const char *file, __uid32_t uid, __gid32_t gid, | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | int | 
		
	
		
			
				|  |  |  |  | set_file_attribute (int use_ntsec, const char *file, | 
		
	
		
			
				|  |  |  |  | 		    __uid32_t uid, __gid32_t gid, | 
		
	
		
			
				|  |  |  |  | 		    int attribute) | 
		
	
		
			
				|  |  |  |  | 		    __uid32_t uid, __gid32_t gid, int attribute) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   int ret = 0; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1825,6 +1909,5 @@ int | 
		
	
		
			
				|  |  |  |  | set_file_attribute (int use_ntsec, const char *file, int attribute) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   return set_file_attribute (use_ntsec, file, | 
		
	
		
			
				|  |  |  |  | 			     myself->uid, myself->gid, | 
		
	
		
			
				|  |  |  |  | 			     attribute); | 
		
	
		
			
				|  |  |  |  | 			     myself->uid, myself->gid, attribute); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					| 
							
							
							
						 |  |  |   |