* autoload.cc: Add LoadDLLfunc statements for SetTokenInformation@16.
* cygheap.cc: Include security.h.
        * grp.cc (internal_getgrent): New function.
        (getgroups): Rearranged using `internal_getgrent' and the new
        `cygsid' class.
        * passwd.cc (internal_getpwent): New function.
        * sec_acl.cc: Use new `cygsid' class throughout.
        (acl_access): Use `internal_getgrent' instead of `getgrent'.
        * sec_helper.cc: Use new `cygsid' class throughout.
        (get_id_from_sid): Use `internal_getgrent' instead of `getgrent'.
        Use `internal_getpwent' instead of `getpwent'.
        * security.cc: Use new `cygsid' class throughout.
        * security.h: Move `MAX_SID_LEN' from winsup.h to here.
        Add extern declarations for `internal_getgrent' and `internal_getpwent'.
        (class cygsid): New class.
        * shared.cc (sec_user): Use new `cygsid' class.
        * syscalls.cc (seteuid): Try to set owner to user and primary group to
        current group in impersonation token before performing impersonation.
        (setegid): Try to set primary group in process token to the new group
        if ntsec is on.
        * uinfo.cc (internal_getlogin): Use new `cygsid' class.
        Try to set owner to user and primary group to current group in process
        token if the process has been started from a non cygwin process.
        (uinfo_init): Set primary group only if the process has been started
        from a non cygwin process.
        * winsup.h: Move define for `MAX_SID_LEN' to security.h.
			
			
This commit is contained in:
		| @@ -1,3 +1,32 @@ | ||||
| Tue Apr 25 11:08:00 2001  Corinna Vinschen <corinna@vinschen.de> | ||||
|  | ||||
| 	* autoload.cc: Add LoadDLLfunc statements for SetTokenInformation@16. | ||||
| 	* cygheap.cc: Include security.h. | ||||
| 	* grp.cc (internal_getgrent): New function. | ||||
| 	(getgroups): Rearranged using `internal_getgrent' and the new | ||||
| 	`cygsid' class. | ||||
| 	* passwd.cc (internal_getpwent): New function. | ||||
| 	* sec_acl.cc: Use new `cygsid' class throughout. | ||||
| 	(acl_access): Use `internal_getgrent' instead of `getgrent'. | ||||
| 	* sec_helper.cc: Use new `cygsid' class throughout. | ||||
| 	(get_id_from_sid): Use `internal_getgrent' instead of `getgrent'. | ||||
| 	Use `internal_getpwent' instead of `getpwent'. | ||||
| 	* security.cc: Use new `cygsid' class throughout. | ||||
| 	* security.h: Move `MAX_SID_LEN' from winsup.h to here. | ||||
| 	Add extern declarations for `internal_getgrent' and `internal_getpwent'. | ||||
| 	(class cygsid): New class. | ||||
| 	* shared.cc (sec_user): Use new `cygsid' class. | ||||
| 	* syscalls.cc (seteuid): Try to set owner to user and primary group to | ||||
| 	current group in impersonation token before performing impersonation. | ||||
| 	(setegid): Try to set primary group in process token to the new group | ||||
| 	if ntsec is on. | ||||
| 	* uinfo.cc (internal_getlogin): Use new `cygsid' class. | ||||
| 	Try to set owner to user and primary group to current group in process | ||||
| 	token if the process has been started from a non cygwin process. | ||||
| 	(uinfo_init): Set primary group only if the process has been started | ||||
| 	from a non cygwin process. | ||||
| 	* winsup.h: Move define for `MAX_SID_LEN' to security.h. | ||||
|  | ||||
| Mon Apr 16 23:20:00 2001  Andy Younger <andylyounger@hotmail.com> | ||||
|  | ||||
| 	* fhandler_dsp.cc: Improved handling of 8 bit playback modes. | ||||
|   | ||||
| @@ -318,6 +318,7 @@ LoadDLLfunc (SetSecurityDescriptorControl, 12, advapi32) | ||||
| LoadDLLfunc (SetSecurityDescriptorDacl, 16, advapi32) | ||||
| LoadDLLfunc (SetSecurityDescriptorGroup, 12, advapi32) | ||||
| LoadDLLfunc (SetSecurityDescriptorOwner, 12, advapi32) | ||||
| LoadDLLfunc (SetTokenInformation, 16, advapi32) | ||||
|  | ||||
| LoadDLLinit (netapi32) | ||||
| LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32) | ||||
|   | ||||
| @@ -20,6 +20,7 @@ | ||||
| #include "cygerrno.h" | ||||
| #include "sync.h" | ||||
| #include "shared_info.h" | ||||
| #include "security.h" | ||||
|  | ||||
| init_cygheap NO_COPY *cygheap; | ||||
| void NO_COPY *cygheap_max = NULL; | ||||
|   | ||||
| @@ -258,69 +258,86 @@ setgrent () | ||||
|   grp_pos = 0; | ||||
| } | ||||
|  | ||||
| /* Internal function. ONLY USE THIS INTERNALLY, NEVER `getgrent'!!! */ | ||||
| struct group * | ||||
| internal_getgrent (int pos) | ||||
| { | ||||
|   if (group_state  <= initializing) | ||||
|     read_etc_group(); | ||||
|  | ||||
|   if (pos < curr_lines) | ||||
|     return group_buf + pos; | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| int | ||||
| getgroups (int gidsetsize, gid_t *grouplist, gid_t gid, const char *username) | ||||
| { | ||||
|   HANDLE hToken = NULL; | ||||
|   char buf[4096]; | ||||
|   DWORD size; | ||||
|   int cnt = 0; | ||||
|   struct group *gr; | ||||
|  | ||||
|   if (group_state  <= initializing) | ||||
|     read_etc_group(); | ||||
|  | ||||
|   if (allow_ntsec && | ||||
|       OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken) && | ||||
|       GetTokenInformation (hToken, TokenGroups, buf, 4096, &size)) | ||||
|       OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken)) | ||||
|     { | ||||
|       TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buf; | ||||
|       char ssid[MAX_SID_LEN]; | ||||
|       PSID sid = (PSID) ssid; | ||||
|  | ||||
|       for (DWORD pg = 0; pg < groups->GroupCount; ++pg) | ||||
|       if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size) | ||||
|           || GetLastError () == ERROR_INSUFFICIENT_BUFFER) | ||||
|         { | ||||
| 	  struct group *gr; | ||||
| 	  while ((gr = getgrent ()) != NULL) | ||||
| 	  char buf[size]; | ||||
| 	  TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buf; | ||||
|  | ||||
| 	  if (GetTokenInformation (hToken, TokenGroups, buf, size, &size)) | ||||
| 	    { | ||||
| 	      if (get_gr_sid (sid, gr) && | ||||
| 	          EqualSid (sid, groups->Groups[pg].Sid)) | ||||
| 	        { | ||||
| 		  if (cnt < gidsetsize) | ||||
| 		    grouplist[cnt] = gr->gr_gid; | ||||
| 		  ++cnt; | ||||
| 		  if (gidsetsize && cnt > gidsetsize) | ||||
| 		    goto error; | ||||
| 		  break; | ||||
| 		} | ||||
| 	      cygsid sid; | ||||
|  | ||||
| 	      for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) | ||||
| 		if (get_gr_sid (sid, gr)) | ||||
| 		  for (DWORD pg = 0; pg < groups->GroupCount; ++pg) | ||||
| 		    if (sid == groups->Groups[pg].Sid) | ||||
| 		      { | ||||
| 			if (cnt < gidsetsize) | ||||
| 			  grouplist[cnt] = gr->gr_gid; | ||||
| 			++cnt; | ||||
| 			if (gidsetsize && cnt > gidsetsize) | ||||
| 			  { | ||||
| 			    CloseHandle (hToken); | ||||
| 			    goto error; | ||||
| 			  } | ||||
| 			break; | ||||
| 		      } | ||||
| 	    } | ||||
| 	  endgrent (); | ||||
|         } | ||||
|       else | ||||
|         debug_printf ("%d = GetTokenInformation(NULL) %E", size); | ||||
|       CloseHandle (hToken); | ||||
|       return cnt; | ||||
|       if (cnt) | ||||
|         return cnt; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       for (int i = 0; i < curr_lines; ++i) | ||||
| 	if (gid == group_buf[i].gr_gid) | ||||
|  | ||||
|   for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) | ||||
|     if (gid == gr->gr_gid) | ||||
|       { | ||||
| 	if (cnt < gidsetsize) | ||||
| 	  grouplist[cnt] = gr->gr_gid; | ||||
| 	++cnt; | ||||
| 	if (gidsetsize && cnt > gidsetsize) | ||||
| 	  goto error; | ||||
|       } | ||||
|     else if (gr->gr_mem) | ||||
|       for (int gi = 0; gr->gr_mem[gi]; ++gi) | ||||
| 	if (strcasematch (username, gr->gr_mem[gi])) | ||||
| 	  { | ||||
| 	    if (cnt < gidsetsize) | ||||
| 	      grouplist[cnt] = group_buf[i].gr_gid; | ||||
| 	      grouplist[cnt] = gr->gr_gid; | ||||
| 	    ++cnt; | ||||
| 	    if (gidsetsize && cnt > gidsetsize) | ||||
| 	      goto error; | ||||
| 	  } | ||||
| 	else if (group_buf[i].gr_mem) | ||||
| 	  for (int gi = 0; group_buf[i].gr_mem[gi]; ++gi) | ||||
| 	    if (strcasematch (username, group_buf[i].gr_mem[gi])) | ||||
| 	      { | ||||
| 		if (cnt < gidsetsize) | ||||
| 		  grouplist[cnt] = group_buf[i].gr_gid; | ||||
| 		++cnt; | ||||
| 		if (gidsetsize && cnt > gidsetsize) | ||||
| 		  goto error; | ||||
| 	      } | ||||
|       return cnt; | ||||
|     } | ||||
|   return cnt; | ||||
|  | ||||
| error: | ||||
|   set_errno (EINVAL); | ||||
|   | ||||
| @@ -359,6 +359,18 @@ setpassent () | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| /* Internal function. ONLY USE THIS INTERNALLY, NEVER `getpwent'!!! */ | ||||
| struct passwd * | ||||
| internal_getpwent (int pos) | ||||
| { | ||||
|   if (passwd_state  <= initializing) | ||||
|     read_etc_passwd (); | ||||
|  | ||||
|   if (pos < curr_lines) | ||||
|     return passwd_buf + pos; | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| extern "C" char * | ||||
| getpass (const char * prompt) | ||||
| { | ||||
|   | ||||
| @@ -68,13 +68,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp) | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   char owner_buf[MAX_SID_LEN]; | ||||
|   if (!CopySid (MAX_SID_LEN, (PSID) owner_buf, owner_sid)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   owner_sid = (PSID) owner_buf; | ||||
|   cygsid owner (owner_sid); | ||||
|  | ||||
|   /* Get group SID. */ | ||||
|   PSID group_sid = NULL; | ||||
| @@ -83,13 +77,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp) | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   char group_buf[MAX_SID_LEN]; | ||||
|   if (!CopySid (MAX_SID_LEN, (PSID) group_buf, group_sid)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   group_sid = (PSID) group_buf; | ||||
|   cygsid group (group_sid); | ||||
|  | ||||
|   /* Initialize local security descriptor. */ | ||||
|   SECURITY_DESCRIPTOR sd; | ||||
| @@ -98,13 +86,13 @@ setacl (const char *file, int nentries, aclent_t *aclbufp) | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   if (!SetSecurityDescriptorOwner(&sd, owner_sid, FALSE)) | ||||
|   if (!SetSecurityDescriptorOwner(&sd, owner, FALSE)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   if (group_sid | ||||
|       && !SetSecurityDescriptorGroup(&sd, group_sid, FALSE)) | ||||
|   if (group | ||||
|       && !SetSecurityDescriptorGroup(&sd, group, FALSE)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
| @@ -116,8 +104,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp) | ||||
|   size_t acl_len = sizeof (ACL); | ||||
|   int ace_off = 0; | ||||
|  | ||||
|   char sidbuf[MAX_SID_LEN]; | ||||
|   PSID sid = (PSID) sidbuf; | ||||
|   cygsid sid; | ||||
|   struct passwd *pw; | ||||
|   struct group *gr; | ||||
|   int pos; | ||||
| @@ -164,7 +151,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp) | ||||
| 	case DEF_USER_OBJ: | ||||
| 	  allow |= STANDARD_RIGHTS_ALL & ~DELETE; | ||||
| 	  if (!add_access_allowed_ace (acl, ace_off++, allow, | ||||
| 					owner_sid, acl_len, inheritance)) | ||||
| 					owner, acl_len, inheritance)) | ||||
| 	    return -1; | ||||
| 	  break; | ||||
| 	case USER: | ||||
| @@ -178,7 +165,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp) | ||||
| 	case GROUP_OBJ: | ||||
| 	case DEF_GROUP_OBJ: | ||||
| 	  if (!add_access_allowed_ace (acl, ace_off++, allow, | ||||
| 					group_sid, acl_len, inheritance)) | ||||
| 					group, acl_len, inheritance)) | ||||
| 	    return -1; | ||||
| 	  break; | ||||
| 	case GROUP: | ||||
| @@ -320,21 +307,21 @@ getacl (const char *file, DWORD attr, int nentries, aclent_t *aclbufp) | ||||
|       if (!GetAce (acl, i, (PVOID *) &ace)) | ||||
| 	continue; | ||||
|  | ||||
|       PSID ace_sid = (PSID) &ace->SidStart; | ||||
|       cygsid ace_sid ((PSID) &ace->SidStart); | ||||
|       int id; | ||||
|       int type = 0; | ||||
|  | ||||
|       if (EqualSid (ace_sid, owner_sid)) | ||||
|       if (ace_sid == owner_sid) | ||||
| 	{ | ||||
| 	  type = USER_OBJ; | ||||
| 	  id = uid; | ||||
| 	} | ||||
|       else if (EqualSid (ace_sid, group_sid)) | ||||
|       else if (ace_sid == group_sid) | ||||
| 	{ | ||||
| 	  type = GROUP_OBJ; | ||||
| 	  id = gid; | ||||
| 	} | ||||
|       else if (EqualSid (ace_sid, get_world_sid ())) | ||||
|       else if (ace_sid == get_world_sid ()) | ||||
| 	{ | ||||
| 	  type = OTHER_OBJ; | ||||
| 	  id = 0; | ||||
| @@ -431,23 +418,20 @@ acl_access (const char *path, int flags) | ||||
| 	       * Check if user is a NT group: | ||||
| 	       * Take SID from passwd, search SID in group, check is_grp_member. | ||||
| 	       */ | ||||
| 	      char owner_sidbuf[MAX_SID_LEN]; | ||||
| 	      PSID owner_sid = (PSID) owner_sidbuf; | ||||
| 	      char group_sidbuf[MAX_SID_LEN]; | ||||
| 	      PSID group_sid = (PSID) group_sidbuf; | ||||
| 	      cygsid owner; | ||||
| 	      cygsid group; | ||||
| 	      struct passwd *pw; | ||||
| 	      struct group *gr = NULL; | ||||
|  | ||||
| 	      if ((pw = getpwuid (acls[i].a_id)) != NULL | ||||
| 		  && get_pw_sid (owner_sid, pw)) | ||||
| 		  && get_pw_sid (owner, pw)) | ||||
| 		{ | ||||
| 		  while ((gr = getgrent ())) | ||||
| 		    if (get_gr_sid (group_sid, gr) | ||||
| 			&& EqualSid (owner_sid, group_sid) | ||||
| 		  for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) | ||||
| 		    if (get_gr_sid (group, gr) | ||||
| 			&& owner == group | ||||
| 			&& is_grp_member (myself->uid, gr->gr_gid)) | ||||
| 		      break; | ||||
| 		  endgrent (); | ||||
| 		} | ||||
| 	        } | ||||
| 	      if (!gr) | ||||
| 		continue; | ||||
| 	    } | ||||
|   | ||||
| @@ -120,56 +120,40 @@ get_gr_sid (PSID sid, struct group *gr) | ||||
| PSID | ||||
| get_admin_sid () | ||||
| { | ||||
|   static NO_COPY char admin_sid_buf[MAX_SID_LEN]; | ||||
|   static NO_COPY PSID admin_sid = NULL; | ||||
|   static NO_COPY cygsid admin_sid (NULL); | ||||
|  | ||||
|   if (!admin_sid) | ||||
|     { | ||||
|       admin_sid = (PSID) admin_sid_buf; | ||||
|       convert_string_sid_to_sid (admin_sid, "S-1-5-32-544"); | ||||
|     } | ||||
|     convert_string_sid_to_sid (admin_sid.set (), "S-1-5-32-544"); | ||||
|   return admin_sid; | ||||
| } | ||||
|  | ||||
| PSID | ||||
| get_system_sid () | ||||
| { | ||||
|   static NO_COPY char system_sid_buf[MAX_SID_LEN]; | ||||
|   static NO_COPY PSID system_sid = NULL; | ||||
|   static NO_COPY cygsid system_sid (NULL); | ||||
|  | ||||
|   if (!system_sid) | ||||
|     { | ||||
|       system_sid = (PSID) system_sid_buf; | ||||
|       convert_string_sid_to_sid (system_sid, "S-1-5-18"); | ||||
|     } | ||||
|     convert_string_sid_to_sid (system_sid.set (), "S-1-5-18"); | ||||
|   return system_sid; | ||||
| } | ||||
|  | ||||
| PSID | ||||
| get_creator_owner_sid () | ||||
| { | ||||
|   static NO_COPY char owner_sid_buf[MAX_SID_LEN]; | ||||
|   static NO_COPY PSID owner_sid = NULL; | ||||
|   static NO_COPY cygsid owner_sid (NULL); | ||||
|  | ||||
|   if (!owner_sid) | ||||
|     { | ||||
|       owner_sid = (PSID) owner_sid_buf; | ||||
|       convert_string_sid_to_sid (owner_sid, "S-1-3-0"); | ||||
|     } | ||||
|     convert_string_sid_to_sid (owner_sid.set (), "S-1-3-0"); | ||||
|   return owner_sid; | ||||
| } | ||||
|  | ||||
| PSID | ||||
| get_world_sid () | ||||
| { | ||||
|   static NO_COPY char world_sid_buf[MAX_SID_LEN]; | ||||
|   static NO_COPY PSID world_sid = NULL; | ||||
|   static NO_COPY cygsid world_sid (NULL); | ||||
|  | ||||
|   if (!world_sid) | ||||
|     { | ||||
|       world_sid = (PSID) world_sid_buf; | ||||
|       convert_string_sid_to_sid (world_sid, "S-1-1-0"); | ||||
|     } | ||||
|     convert_string_sid_to_sid (world_sid.set (), "S-1-1-0"); | ||||
|   return world_sid; | ||||
| } | ||||
|  | ||||
| @@ -186,22 +170,20 @@ get_id_from_sid (PSID psid, BOOL search_grp, int *type) | ||||
|   /* First try to get SID from passwd or group entry */ | ||||
|   if (allow_ntsec) | ||||
|     { | ||||
|       char sidbuf[MAX_SID_LEN]; | ||||
|       PSID sid = (PSID) sidbuf; | ||||
|       cygsid sid; | ||||
|       int id = -1; | ||||
|  | ||||
|       if (!search_grp) | ||||
| 	{ | ||||
| 	  struct passwd *pw; | ||||
| 	  while ((pw = getpwent ()) != NULL) | ||||
| 	  for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx) | ||||
| 	    { | ||||
| 	      if (get_pw_sid (sid, pw) && EqualSid (psid, sid)) | ||||
| 	      if (get_pw_sid (sid, pw) && sid == psid) | ||||
| 		{ | ||||
| 		  id = pw->pw_uid; | ||||
| 		  break; | ||||
| 		} | ||||
| 	    } | ||||
| 	  endpwent (); | ||||
| 	  if (id >= 0) | ||||
| 	    { | ||||
| 	      if (type) | ||||
| @@ -212,15 +194,14 @@ get_id_from_sid (PSID psid, BOOL search_grp, int *type) | ||||
|       if (search_grp || type) | ||||
| 	{ | ||||
| 	  struct group *gr; | ||||
| 	  while ((gr = getgrent ()) != NULL) | ||||
| 	  for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) | ||||
| 	    { | ||||
| 	      if (get_gr_sid (sid, gr) && EqualSid (psid, sid)) | ||||
| 	      if (get_gr_sid (sid, gr) && sid == psid) | ||||
| 		{ | ||||
| 		  id = gr->gr_gid; | ||||
| 		  break; | ||||
| 		} | ||||
| 	    } | ||||
| 	  endgrent (); | ||||
| 	  if (id >= 0) | ||||
| 	    { | ||||
| 	      if (type) | ||||
| @@ -321,8 +302,7 @@ is_grp_member (uid_t uid, gid_t gid) | ||||
| BOOL | ||||
| lookup_name (const char *name, const char *logsrv, PSID ret_sid) | ||||
| { | ||||
|   char sidbuf[MAX_SID_LEN]; | ||||
|   PSID sid = (PSID) sidbuf; | ||||
|   cygsid sid; | ||||
|   DWORD sidlen; | ||||
|   char domuser[MAX_COMPUTERNAME_LENGTH+MAX_USER_NAME+1]; | ||||
|   char dom[MAX_COMPUTERNAME_LENGTH+1]; | ||||
|   | ||||
| @@ -333,8 +333,8 @@ get_nt_attribute (const char *file, int *attribute, | ||||
| 	  continue; | ||||
| 	} | ||||
|  | ||||
|       PSID ace_sid = (PSID) &ace->SidStart; | ||||
|       if (owner_sid && EqualSid (ace_sid, owner_sid)) | ||||
|       cygsid ace_sid ((PSID) &ace->SidStart); | ||||
|       if (owner_sid && ace_sid == owner_sid) | ||||
| 	{ | ||||
| 	  if (ace->Mask & FILE_READ_DATA) | ||||
| 	    *flags |= S_IRUSR; | ||||
| @@ -343,7 +343,7 @@ get_nt_attribute (const char *file, int *attribute, | ||||
| 	  if (ace->Mask & FILE_EXECUTE) | ||||
| 	    *flags |= S_IXUSR; | ||||
| 	} | ||||
|       else if (group_sid && EqualSid (ace_sid, group_sid)) | ||||
|       else if (group_sid && ace_sid == group_sid) | ||||
| 	{ | ||||
| 	  if (ace->Mask & FILE_READ_DATA) | ||||
| 	    *flags |= S_IRGRP | ||||
| @@ -355,7 +355,7 @@ get_nt_attribute (const char *file, int *attribute, | ||||
| 	    *flags |= S_IXGRP | ||||
| 		      | ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0); | ||||
| 	} | ||||
|       else if (EqualSid (ace_sid, get_world_sid ())) | ||||
|       else if (ace_sid == get_world_sid ()) | ||||
| 	{ | ||||
| 	  if (ace->Mask & FILE_READ_DATA) | ||||
| 	    *flags |= S_IROTH | ||||
| @@ -469,26 +469,22 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, | ||||
|  | ||||
|   /* Get SID and name of new owner. */ | ||||
|   char owner[MAX_USER_NAME]; | ||||
|   char *owner_sid_buf[MAX_SID_LEN]; | ||||
|   PSID owner_sid = NULL; | ||||
|   cygsid owner_sid; | ||||
|   struct passwd *pw = getpwuid (uid); | ||||
|   strcpy (owner, pw ? pw->pw_name : getlogin ()); | ||||
|   owner_sid = (PSID) owner_sid_buf; | ||||
|   if ((!pw || !get_pw_sid (owner_sid, pw)) | ||||
|       && !lookup_name (owner, logsrv, owner_sid)) | ||||
|     return NULL; | ||||
|   debug_printf ("owner: %s [%d]", owner, | ||||
| 		*GetSidSubAuthority((PSID) owner_sid, | ||||
| 		*GetSidSubAuthorityCount((PSID) owner_sid) - 1)); | ||||
| 		*GetSidSubAuthority(owner_sid, | ||||
| 		*GetSidSubAuthorityCount(owner_sid) - 1)); | ||||
|  | ||||
|   /* Get SID and name of new group. */ | ||||
|   char *group_sid_buf[MAX_SID_LEN]; | ||||
|   PSID group_sid = NULL; | ||||
|   cygsid group_sid (NULL); | ||||
|   struct group *grp = getgrgid (gid); | ||||
|   if (grp) | ||||
|     { | ||||
|       group_sid = (PSID) group_sid_buf; | ||||
|       if ((!grp || !get_gr_sid (group_sid, grp)) | ||||
|       if ((!grp || !get_gr_sid (group_sid.set (), grp)) | ||||
| 	  && !lookup_name (grp->gr_name, logsrv, group_sid)) | ||||
| 	return NULL; | ||||
|     } | ||||
| @@ -643,13 +639,13 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute, | ||||
|     for (DWORD i = 0; i < oacl->AceCount; ++i) | ||||
|       if (GetAce (oacl, i, (PVOID *) &ace)) | ||||
| 	{ | ||||
| 	  PSID ace_sid = (PSID) &ace->SidStart; | ||||
| 	  cygsid ace_sid ((PSID) &ace->SidStart); | ||||
| 	  /* Check for related ACEs. */ | ||||
| 	  if ((cur_owner_sid && EqualSid (ace_sid, cur_owner_sid)) | ||||
| 	      || (owner_sid && EqualSid (ace_sid, owner_sid)) | ||||
| 	      || (cur_group_sid && EqualSid (ace_sid, cur_group_sid)) | ||||
| 	      || (group_sid && EqualSid (ace_sid, group_sid)) | ||||
| 	      || (EqualSid (ace_sid, get_world_sid ()))) | ||||
| 	  if ((cur_owner_sid && ace_sid == cur_owner_sid) | ||||
| 	      || (owner_sid && ace_sid == owner_sid) | ||||
| 	      || (cur_group_sid && ace_sid == cur_group_sid) | ||||
| 	      || (group_sid && ace_sid == group_sid) | ||||
| 	      || (ace_sid == get_world_sid ())) | ||||
| 	    continue; | ||||
| 	  /* | ||||
| 	   * Add unrelated ACCESS_DENIED_ACE to the beginning but | ||||
|   | ||||
| @@ -12,9 +12,46 @@ details. */ | ||||
| #define INHERIT_ALL  (CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE) | ||||
| #define INHERIT_ONLY (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE) | ||||
|  | ||||
| #define MAX_SID_LEN 40 | ||||
|  | ||||
| class cygsid { | ||||
|   PSID psid; | ||||
|   char sbuf[MAX_SID_LEN]; | ||||
| public: | ||||
|   inline cygsid () : psid ((PSID) sbuf) {} | ||||
|   inline cygsid (PSID nsid) { *this = nsid; } | ||||
|  | ||||
|   inline PSID set () { return psid = (PSID) sbuf; } | ||||
|  | ||||
|   inline const PSID operator= (PSID nsid) | ||||
|     { | ||||
|       if (!nsid) | ||||
|         psid = NULL; | ||||
|       else | ||||
|         { | ||||
| 	  psid = (PSID) sbuf; | ||||
| 	  CopySid (MAX_SID_LEN, psid, nsid); | ||||
| 	} | ||||
|       return psid; | ||||
|     } | ||||
|   inline BOOL operator== (PSID nsid) | ||||
|     { | ||||
|       if (!psid || !nsid) | ||||
|         return nsid == psid; | ||||
|       return EqualSid (psid, nsid); | ||||
|     } | ||||
|   inline operator const PSID () { return psid; } | ||||
| }; | ||||
|  | ||||
| extern BOOL allow_ntsec; | ||||
| extern BOOL allow_smbntsec; | ||||
|  | ||||
| /* These both functions are needed to allow walking through the passwd | ||||
|    and group lists so they are somehow security related. Besides that | ||||
|    I didn't find a better place to declare them. */ | ||||
| extern struct passwd *internal_getpwent (int); | ||||
| extern struct group *internal_getgrent (int); | ||||
|  | ||||
| /* File manipulation */ | ||||
| int __stdcall set_process_privileges (); | ||||
| int __stdcall get_file_attribute (int, const char *, int *, | ||||
|   | ||||
| @@ -239,11 +239,10 @@ sec_user (PVOID sa_buf, PSID sid2, BOOL inherit) | ||||
| 			     ((char *) sa_buf + sizeof (*psa)); | ||||
|   PACL acl = (PACL) ((char *) sa_buf + sizeof (*psa) + sizeof (*psd)); | ||||
|  | ||||
|   char sid_buf[MAX_SID_LEN]; | ||||
|   PSID sid = (PSID) sid_buf; | ||||
|   cygsid sid; | ||||
|  | ||||
|   if (cygheap->user.sid ()) | ||||
|     CopySid (MAX_SID_LEN, sid, (void *) cygheap->user.sid ()); | ||||
|     sid = cygheap->user.sid (); | ||||
|   else if (! lookup_name (getlogin (), cygheap->user.logsrv (), sid)) | ||||
|     return inherit ? &sec_none_nih : &sec_none; | ||||
|  | ||||
|   | ||||
| @@ -1977,11 +1977,36 @@ seteuid (uid_t uid) | ||||
| 		debug_printf ("Impersonate (uid == %d)", uid); | ||||
| 		RevertToSelf (); | ||||
| 		if (cygheap->user.token != INVALID_HANDLE_VALUE) | ||||
| 		  if (!ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
| 		    system_printf ("Impersonate (%d) in set (e)uid failed: %E", | ||||
| 				   cygheap->user.token); | ||||
| 		  else | ||||
| 		    cygheap->user.impersonated = TRUE; | ||||
| 		  { | ||||
| 		    struct group *gr; | ||||
| 		    cygsid sid; | ||||
| 		    DWORD siz; | ||||
|  | ||||
| 		    /* Try setting owner to same value as user. */ | ||||
| 		    if (!GetTokenInformation (cygheap->user.token, TokenUser, | ||||
| 					      &sid, sizeof sid, &siz)) | ||||
| 		      debug_printf ("GetTokenInformation(): %E"); | ||||
| 		    else if (!SetTokenInformation (cygheap->user.token, | ||||
| 		    				   TokenOwner, | ||||
| 						   &sid, sizeof sid)) | ||||
| 		      debug_printf ("SetTokenInformation(user.token, " | ||||
| 		      		    "TokenOwner): %E"); | ||||
| 		    /* Try setting primary group in token to current group. */ | ||||
| 	            if ((gr = getgrgid (myself->gid)) && | ||||
| 		        get_gr_sid (sid, gr) && | ||||
| 		        !SetTokenInformation (cygheap->user.token, | ||||
| 		      			      TokenPrimaryGroup, | ||||
| 					      &sid, sizeof sid)) | ||||
| 		      debug_printf ("SetTokenInformation(user.token, " | ||||
| 		    		    "TokenPrimaryGroup): %E"); | ||||
|  | ||||
| 		    /* Now try to impersonate. */ | ||||
| 		    if (!ImpersonateLoggedOnUser (cygheap->user.token)) | ||||
| 		      system_printf ("Impersonate (%d) in set(e)uid failed: %E", | ||||
| 				     cygheap->user.token); | ||||
| 		    else | ||||
| 		      cygheap->user.impersonated = TRUE; | ||||
| 	          } | ||||
| 	      } | ||||
|  | ||||
| 	  cygheap_user user; | ||||
| @@ -2018,12 +2043,35 @@ setegid (gid_t gid) | ||||
|     { | ||||
|       if (gid != (gid_t) -1) | ||||
| 	{ | ||||
| 	  if (!getgrgid (gid)) | ||||
| 	  struct group *gr; | ||||
|  | ||||
| 	  if (!(gr = getgrgid (gid))) | ||||
| 	    { | ||||
| 	      set_errno (EINVAL); | ||||
| 	      return -1; | ||||
| 	    } | ||||
| 	  myself->gid = gid; | ||||
| 	  if (allow_ntsec) | ||||
| 	    { | ||||
| 	      cygsid gsid; | ||||
| 	      HANDLE ptok; | ||||
|  | ||||
| 	      if (get_gr_sid (gsid, gr)) | ||||
| 	        { | ||||
| 		  if (!OpenProcessToken (GetCurrentProcess (), | ||||
| 					 TOKEN_ADJUST_DEFAULT, | ||||
| 					 &ptok)) | ||||
| 		    debug_printf ("OpenProcessToken(): %E\n"); | ||||
| 		  else | ||||
| 		    { | ||||
| 		      if (!SetTokenInformation (ptok, TokenPrimaryGroup, | ||||
| 		      				&gsid, sizeof gsid)) | ||||
| 			debug_printf ("SetTokenInformation(myself, " | ||||
| 				      "TokenPrimaryGroup): %E"); | ||||
| 		      CloseHandle (ptok); | ||||
| 		    } | ||||
| 	        } | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|   else | ||||
|   | ||||
| @@ -115,7 +115,7 @@ internal_getlogin (cygheap_user &user) | ||||
| 	  HANDLE ptok = user.token; /* Which is INVALID_HANDLE_VALUE if no | ||||
| 				       impersonation took place. */ | ||||
| 	  DWORD siz; | ||||
| 	  char tu[1024]; | ||||
| 	  cygsid tu; | ||||
| 	  int ret = 0; | ||||
|  | ||||
| 	  /* Try to get the SID either from already impersonated token | ||||
| @@ -123,18 +123,14 @@ internal_getlogin (cygheap_user &user) | ||||
| 	     important, because you can't rely on the user information | ||||
| 	     in a process token of a currently impersonated process. */ | ||||
| 	  if (ptok == INVALID_HANDLE_VALUE | ||||
| 	      && !OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)) | ||||
| 	      && !OpenProcessToken (GetCurrentProcess (), | ||||
| 	      			    TOKEN_ADJUST_DEFAULT | TOKEN_QUERY, | ||||
| 				    &ptok)) | ||||
| 	    debug_printf ("OpenProcessToken(): %E\n"); | ||||
| 	  else if (!GetTokenInformation (ptok, TokenUser, (LPVOID) &tu, | ||||
| 					 sizeof tu, &siz)) | ||||
| 	  else if (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &siz)) | ||||
| 	    debug_printf ("GetTokenInformation(): %E"); | ||||
| 	  else if (!(ret = user.set_sid (((TOKEN_USER *) &tu)->User.Sid))) | ||||
| 	  else if (!(ret = user.set_sid (tu))) | ||||
| 	    debug_printf ("Couldn't retrieve SID from access token!"); | ||||
| 	  /* Close token only if it's a result from OpenProcessToken(). */ | ||||
| 	  if (ptok != INVALID_HANDLE_VALUE | ||||
| 	      && user.token == INVALID_HANDLE_VALUE) | ||||
| 	    CloseHandle (ptok); | ||||
|  | ||||
| 	  /* If that failes, try to get the SID from localhost. This can only | ||||
| 	     be done if a domain is given because there's a chance that a local | ||||
| 	     and a domain user may have the same name. */ | ||||
| @@ -146,7 +142,7 @@ internal_getlogin (cygheap_user &user) | ||||
| 		debug_printf ("Couldn't retrieve SID locally!"); | ||||
| 	    } | ||||
|  | ||||
| 	  /* If that failes, too, as a last resort try to get the SID from | ||||
| 	  /* If that fails, too, as a last resort try to get the SID from | ||||
| 	     the logon server. */ | ||||
| 	  if (!ret && !(ret = lookup_name (user.name (), user.logsrv (), | ||||
| 					  user.sid ()))) | ||||
| @@ -154,11 +150,11 @@ internal_getlogin (cygheap_user &user) | ||||
|  | ||||
| 	  /* If we have a SID, try to get the corresponding Cygwin user name | ||||
| 	     which can be different from the Windows user name. */ | ||||
| 	  cygsid gsid (NULL); | ||||
| 	  if (ret) | ||||
| 	    { | ||||
| 	      struct passwd *pw; | ||||
| 	      char psidbuf[MAX_SID_LEN]; | ||||
| 	      PSID psid = (PSID) psidbuf; | ||||
| 	      cygsid psid; | ||||
|  | ||||
| 	      if (!strcasematch (user.name (), "SYSTEM") | ||||
| 		  && user.domain () && user.logsrv ()) | ||||
| @@ -166,14 +162,35 @@ internal_getlogin (cygheap_user &user) | ||||
| 		  if (get_registry_hive_path (user.sid (), buf)) | ||||
| 		    setenv ("USERPROFILE", buf, 1); | ||||
| 		} | ||||
| 	      while ((pw = getpwent ()) != NULL) | ||||
| 	      for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx) | ||||
| 		if (get_pw_sid (psid, pw) && EqualSid (user.sid (), psid)) | ||||
| 		  { | ||||
| 		    user.set_name (pw->pw_name); | ||||
| 		    struct group *gr = getgrgid (pw->pw_gid); | ||||
| 		    if (gr) | ||||
| 		      if (!get_gr_sid (gsid.set (), gr)) | ||||
| 			  gsid = NULL; | ||||
| 		    break; | ||||
| 		  } | ||||
| 	      endpwent (); | ||||
| 	    } | ||||
|  | ||||
| 	  /* If this process is started from a non Cygwin process, | ||||
| 	     set token owner to the same value as token user and | ||||
| 	     primary group to the group which is set as primary group | ||||
| 	     in /etc/passwd. */ | ||||
| 	  if (ptok != INVALID_HANDLE_VALUE && myself->ppid == 1) | ||||
| 	    { | ||||
| 	      if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu)) | ||||
| 		debug_printf ("SetTokenInformation(TokenOwner): %E"); | ||||
| 	      if (gsid && !SetTokenInformation (ptok, TokenPrimaryGroup, | ||||
| 		  			        &gsid, sizeof gsid)) | ||||
| 		debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E"); | ||||
| 	    } | ||||
|  | ||||
| 	  /* Close token only if it's a result from OpenProcessToken(). */ | ||||
| 	  if (ptok != INVALID_HANDLE_VALUE | ||||
| 	      && user.token == INVALID_HANDLE_VALUE) | ||||
| 	    CloseHandle (ptok); | ||||
| 	} | ||||
|     } | ||||
|   debug_printf ("Cygwins Username: %s", user.name ()); | ||||
| @@ -198,7 +215,10 @@ uinfo_init () | ||||
|     if ((p = getpwnam (internal_getlogin (cygheap->user))) != NULL) | ||||
|       { | ||||
| 	myself->uid = p->pw_uid; | ||||
| 	myself->gid = p->pw_gid; | ||||
| 	/* Set primary group only if ntsec is off or the process has been | ||||
| 	   started from a non cygwin process. */ | ||||
| 	if (!allow_ntsec || myself->ppid == 1) | ||||
| 	  myself->gid = p->pw_gid; | ||||
|       } | ||||
|     else | ||||
|       { | ||||
|   | ||||
| @@ -101,7 +101,6 @@ extern int dynamically_loaded; | ||||
| #define DEFAULT_UID 500 | ||||
| #define DEFAULT_GID 544 | ||||
|  | ||||
| #define MAX_SID_LEN 40 | ||||
| #define MAX_HOST_NAME 256 | ||||
|  | ||||
| /* status bit manipulation */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user