* dir.cc (mkdir): Use local security_descriptor. Call
set_security_attribute appropriately. * external.cc (cygwin_internal): Ditto. * fhandler.cc (fhandler_base::open): Ditto. * fhandler_socket.cc (fhandler_socket::bind): Ditto. * path.cc (symlink_worker): Ditto. * sec_acl.cc (setacl): Ditto. Call read_sd appropriately. (getace): Ditto. * sec_helper.cc (security_descriptor::malloc): New method. (security_descriptor::realloc): New method. (security_descriptor::free): New method. * security.cc (read_sd): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. Allocate the security_descriptor buffer according to size returned by a call to GetFileSecurity. Return buffer size on success. (write_sd): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (get_nt_attribute): Use local security_descriptor. (get_nt_object_attribute): Ditto in case of type == SE_REGISTRY_KEY. Allocate security_descriptor buffer according to size returned by a call to RegGetKeySecurity. (alloc_sd): Make static. Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. (set_security_attribute): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (set_nt_attribute): Use local security_descriptor. (check_file_access): Ditto. * security.h: Add class security_descriptor. (read_sd): Change declaration to get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (write_sd): Ditto. (set_security_attribute): Ditto. (alloc_sd): Remove declaration. * thread.cc (semaphore::semaphore): Use local security_descriptor. Call set_security_attribute appropriately.
This commit is contained in:
		| @@ -1,3 +1,41 @@ | ||||
| 2003-11-26  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* dir.cc (mkdir): Use local security_descriptor. Call | ||||
| 	set_security_attribute appropriately. | ||||
| 	* external.cc (cygwin_internal): Ditto. | ||||
| 	* fhandler.cc (fhandler_base::open): Ditto. | ||||
| 	* fhandler_socket.cc (fhandler_socket::bind): Ditto. | ||||
| 	* path.cc (symlink_worker): Ditto. | ||||
| 	* sec_acl.cc (setacl): Ditto. Call read_sd appropriately. | ||||
| 	(getace): Ditto. | ||||
| 	* sec_helper.cc (security_descriptor::malloc): New method. | ||||
| 	(security_descriptor::realloc): New method. | ||||
| 	(security_descriptor::free): New method. | ||||
| 	* security.cc (read_sd): Get security_descriptor as parameter instead | ||||
| 	of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. | ||||
| 	Allocate the security_descriptor buffer according to size returned by | ||||
| 	a call to GetFileSecurity. Return buffer size on success. | ||||
| 	(write_sd): Get security_descriptor as parameter instead of | ||||
| 	PSECURITY_DESCRIPTOR and a size. | ||||
| 	(get_nt_attribute): Use local security_descriptor. | ||||
| 	(get_nt_object_attribute): Ditto in case of type == SE_REGISTRY_KEY. | ||||
| 	Allocate security_descriptor buffer according to size returned by | ||||
| 	a call to RegGetKeySecurity. | ||||
| 	(alloc_sd): Make static. Get security_descriptor as parameter instead | ||||
| 	of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. | ||||
| 	(set_security_attribute): Get security_descriptor as parameter instead | ||||
| 	of PSECURITY_DESCRIPTOR and a size. | ||||
| 	(set_nt_attribute): Use local security_descriptor. | ||||
| 	(check_file_access): Ditto. | ||||
| 	* security.h: Add class security_descriptor. | ||||
| 	(read_sd): Change declaration to get security_descriptor as parameter | ||||
| 	instead of PSECURITY_DESCRIPTOR and a size. | ||||
| 	(write_sd): Ditto. | ||||
| 	(set_security_attribute): Ditto. | ||||
| 	(alloc_sd): Remove declaration. | ||||
| 	* thread.cc (semaphore::semaphore): Use local security_descriptor. Call | ||||
| 	set_security_attribute appropriately. | ||||
|  | ||||
| 2003-11-26  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* sec_acl.h (getace): Use FILE_*_BITS as permission mask. | ||||
|   | ||||
| @@ -263,6 +263,7 @@ mkdir (const char *dir, mode_t mode) | ||||
| { | ||||
|   int res = -1; | ||||
|   SECURITY_ATTRIBUTES sa = sec_none_nih; | ||||
|   security_descriptor sd; | ||||
|  | ||||
|   path_conv real_dir (dir, PC_SYM_NOFOLLOW); | ||||
|  | ||||
| @@ -278,7 +279,7 @@ mkdir (const char *dir, mode_t mode) | ||||
|  | ||||
|   if (allow_ntsec && real_dir.has_acls ()) | ||||
|     set_security_attribute (S_IFDIR | ((mode & 07777) & ~cygheap->umask), | ||||
| 			    &sa, alloca (4096), 4096); | ||||
| 			    &sa, sd); | ||||
|  | ||||
|   if (CreateDirectoryA (real_dir.get_win32 (), &sa)) | ||||
|     { | ||||
|   | ||||
| @@ -268,12 +268,17 @@ cygwin_internal (cygwin_getinfo_types t, ...) | ||||
| 	} | ||||
|       case CW_GET_POSIX_SECURITY_ATTRIBUTE: | ||||
| 	{ | ||||
| 	  security_descriptor sd; | ||||
| 	  int attribute = va_arg (arg, int); | ||||
| 	  PSECURITY_ATTRIBUTES psa = va_arg (arg, PSECURITY_ATTRIBUTES); | ||||
| 	  void *sd_buf = va_arg (arg, void *); | ||||
| 	  DWORD sd_buf_size = va_arg (arg, DWORD); | ||||
| 	  set_security_attribute (attribute, psa, sd_buf, sd_buf_size); | ||||
| 	  return psa->lpSecurityDescriptor ? 0 : -1; | ||||
| 	  set_security_attribute (attribute, psa, sd); | ||||
| 	  if (!psa->lpSecurityDescriptor || sd.size () > sd_buf_size) | ||||
| 	    return sd.size (); | ||||
| 	  memcpy (sd_buf, sd, sd.size ()); | ||||
| 	  psa->lpSecurityDescriptor = sd_buf; | ||||
| 	  return 0; | ||||
|         } | ||||
|       case CW_GET_SHMLBA: | ||||
|         { | ||||
|   | ||||
| @@ -342,6 +342,7 @@ fhandler_base::open (int flags, mode_t mode) | ||||
|   int shared; | ||||
|   int creation_distribution; | ||||
|   SECURITY_ATTRIBUTES sa = sec_none; | ||||
|   security_descriptor sd; | ||||
|  | ||||
|   syscall_printf ("(%s, %p) query_open %d", get_win32_name (), flags, get_query_open ()); | ||||
|  | ||||
| @@ -421,7 +422,7 @@ fhandler_base::open (int flags, mode_t mode) | ||||
|   /* If the file should actually be created and ntsec is on, | ||||
|      set files attributes. */ | ||||
|   if (flags & O_CREAT && get_device () == FH_FS && allow_ntsec && has_acls ()) | ||||
|     set_security_attribute (mode, &sa, alloca (4096), 4096); | ||||
|     set_security_attribute (mode, &sa, sd); | ||||
|  | ||||
|   x = CreateFile (get_win32_name (), access, shared, &sa, creation_distribution, | ||||
| 		  file_attributes, 0); | ||||
|   | ||||
| @@ -442,8 +442,9 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen) | ||||
|       if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH))) | ||||
| 	attr |= FILE_ATTRIBUTE_READONLY; | ||||
|       SECURITY_ATTRIBUTES sa = sec_none; | ||||
|       security_descriptor sd; | ||||
|       if (allow_ntsec && pc.has_acls ()) | ||||
| 	set_security_attribute (mode, &sa, alloca (4096), 4096); | ||||
| 	set_security_attribute (mode, &sa, sd); | ||||
|       HANDLE fh = CreateFile (pc, GENERIC_WRITE, 0, &sa, CREATE_NEW, attr, 0); | ||||
|       if (fh == INVALID_HANDLE_VALUE) | ||||
| 	{ | ||||
|   | ||||
| @@ -2491,6 +2491,7 @@ symlink_worker (const char *topath, const char *frompath, bool use_winsym, | ||||
|   char w32topath[CYG_MAX_PATH + 1]; | ||||
|   DWORD written; | ||||
|   SECURITY_ATTRIBUTES sa = sec_none_nih; | ||||
|   security_descriptor sd; | ||||
|  | ||||
|   /* POSIX says that empty 'frompath' is invalid input whlie empty | ||||
|      'topath' is valid -- it's symlink resolver job to verify if | ||||
| @@ -2565,7 +2566,7 @@ symlink_worker (const char *topath, const char *frompath, bool use_winsym, | ||||
|  | ||||
|   if (allow_ntsec && win32_path.has_acls ()) | ||||
|     set_security_attribute (S_IFLNK | STD_RBITS | STD_WBITS, | ||||
| 			    &sa, alloca (4096), 4096); | ||||
| 			    &sa, sd); | ||||
|  | ||||
|   h = CreateFile (win32_path, GENERIC_WRITE, 0, &sa, create_how, | ||||
| 		  FILE_ATTRIBUTE_NORMAL, 0); | ||||
|   | ||||
| @@ -49,11 +49,9 @@ searchace (__aclent32_t *aclp, int nentries, int type, __uid32_t id = ILLEGAL_UI | ||||
| static int | ||||
| setacl (const char *file, int nentries, __aclent32_t *aclbufp) | ||||
| { | ||||
|   DWORD sd_size = 4096; | ||||
|   char sd_buf[4096]; | ||||
|   PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; | ||||
|   security_descriptor sd_ret; | ||||
|  | ||||
|   if (read_sd (file, psd, &sd_size) <= 0) | ||||
|   if (read_sd (file, sd_ret) <= 0) | ||||
|     { | ||||
|       debug_printf ("read_sd %E"); | ||||
|       return -1; | ||||
| @@ -63,7 +61,7 @@ setacl (const char *file, int nentries, __aclent32_t *aclbufp) | ||||
|  | ||||
|   /* Get owner SID. */ | ||||
|   PSID owner_sid; | ||||
|   if (!GetSecurityDescriptorOwner (psd, &owner_sid, &dummy)) | ||||
|   if (!GetSecurityDescriptorOwner (sd_ret, &owner_sid, &dummy)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
| @@ -72,7 +70,7 @@ setacl (const char *file, int nentries, __aclent32_t *aclbufp) | ||||
|  | ||||
|   /* Get group SID. */ | ||||
|   PSID group_sid; | ||||
|   if (!GetSecurityDescriptorGroup (psd, &group_sid, &dummy)) | ||||
|   if (!GetSecurityDescriptorGroup (sd_ret, &group_sid, &dummy)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
| @@ -206,21 +204,21 @@ setacl (const char *file, int nentries, __aclent32_t *aclbufp) | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   /* Make self relative security descriptor in psd. */ | ||||
|   sd_size = 0; | ||||
|   MakeSelfRelativeSD (&sd, psd, &sd_size); | ||||
|   /* Make self relative security descriptor in sd_ret. */ | ||||
|   DWORD sd_size = 0; | ||||
|   MakeSelfRelativeSD (&sd, sd_ret, &sd_size); | ||||
|   if (sd_size <= 0) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   if (!MakeSelfRelativeSD (&sd, psd, &sd_size)) | ||||
|   if (!MakeSelfRelativeSD (&sd, sd_ret, &sd_size)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   debug_printf ("Created SD-Size: %d", sd_size); | ||||
|   return write_sd (file, psd, sd_size); | ||||
|   debug_printf ("Created SD-Size: %d", sd_ret.size ()); | ||||
|   return write_sd (file, sd_ret); | ||||
| } | ||||
|  | ||||
| /* Temporary access denied bits */ | ||||
| @@ -257,12 +255,10 @@ getace (__aclent32_t &acl, int type, int id, DWORD win_ace_mask, | ||||
| static int | ||||
| getacl (const char *file, DWORD attr, int nentries, __aclent32_t *aclbufp) | ||||
| { | ||||
|   DWORD sd_size = 4096; | ||||
|   char sd_buf[4096]; | ||||
|   PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; | ||||
|   security_descriptor sd; | ||||
|  | ||||
|   int ret; | ||||
|   if ((ret = read_sd (file, psd, &sd_size)) <= 0) | ||||
|   if ((ret = read_sd (file, sd)) <= 0) | ||||
|     { | ||||
|       debug_printf ("read_sd %E"); | ||||
|       return ret; | ||||
| @@ -274,7 +270,7 @@ getacl (const char *file, DWORD attr, int nentries, __aclent32_t *aclbufp) | ||||
|   __uid32_t uid; | ||||
|   __gid32_t gid; | ||||
|  | ||||
|   if (!GetSecurityDescriptorOwner (psd, (PSID *) &owner_sid, &dummy)) | ||||
|   if (!GetSecurityDescriptorOwner (sd, (PSID *) &owner_sid, &dummy)) | ||||
|     { | ||||
|       debug_printf ("GetSecurityDescriptorOwner %E"); | ||||
|       __seterrno (); | ||||
| @@ -282,7 +278,7 @@ getacl (const char *file, DWORD attr, int nentries, __aclent32_t *aclbufp) | ||||
|     } | ||||
|   uid = owner_sid.get_uid (); | ||||
|  | ||||
|   if (!GetSecurityDescriptorGroup (psd, (PSID *) &group_sid, &dummy)) | ||||
|   if (!GetSecurityDescriptorGroup (sd, (PSID *) &group_sid, &dummy)) | ||||
|     { | ||||
|       debug_printf ("GetSecurityDescriptorGroup %E"); | ||||
|       __seterrno (); | ||||
| @@ -305,7 +301,7 @@ getacl (const char *file, DWORD attr, int nentries, __aclent32_t *aclbufp) | ||||
|   PACL acl; | ||||
|   BOOL acl_exists; | ||||
|  | ||||
|   if (!GetSecurityDescriptorDacl (psd, &acl_exists, &acl, &dummy)) | ||||
|   if (!GetSecurityDescriptorDacl (sd, &acl_exists, &acl, &dummy)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       debug_printf ("GetSecurityDescriptorDacl %E"); | ||||
|   | ||||
| @@ -225,6 +225,35 @@ get_sids_info (cygpsid owner_sid, cygpsid group_sid, __uid32_t * uidret, __gid32 | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| PSECURITY_DESCRIPTOR | ||||
| security_descriptor::malloc (size_t nsize) | ||||
| { | ||||
|   if (psd) | ||||
|     ::free (psd); | ||||
|   psd = (PSECURITY_DESCRIPTOR) ::malloc (nsize); | ||||
|   sd_size = psd ? nsize : 0; | ||||
|   return psd; | ||||
| } | ||||
|  | ||||
| PSECURITY_DESCRIPTOR | ||||
| security_descriptor::realloc (size_t nsize) | ||||
| { | ||||
|   PSECURITY_DESCRIPTOR tmp = (PSECURITY_DESCRIPTOR) ::realloc (psd, nsize); | ||||
|   if (!tmp) | ||||
|     return NULL; | ||||
|   sd_size = nsize; | ||||
|   return psd = tmp; | ||||
| } | ||||
|  | ||||
| void | ||||
| security_descriptor::free (void) | ||||
| { | ||||
|   if (psd) | ||||
|     ::free (psd); | ||||
|   psd = NULL; | ||||
|   sd_size = 0; | ||||
| } | ||||
|  | ||||
| #if 0 // unused | ||||
| #define SIDLEN	(sidlen = MAX_SID_LEN, &sidlen) | ||||
| #define DOMLEN	(domlen = INTERNET_MAX_HOST_NAME_LENGTH, &domlen) | ||||
|   | ||||
| @@ -1067,23 +1067,18 @@ out: | ||||
|    of the SD on success. Unfortunately NT returns | ||||
|    0 in `len' on success, while W2K returns the | ||||
|    correct size! | ||||
|     | ||||
|    2003-11-26: Now the function allocates the space needed by itself so | ||||
|    it knows the real size and returns it in the security_descriptor object. | ||||
| */ | ||||
|  | ||||
| LONG | ||||
| read_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size) | ||||
| read_sd (const char *file, security_descriptor &sd) | ||||
| { | ||||
|   /* Check parameters */ | ||||
|   if (!sd_size) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   debug_printf ("file = %s", file); | ||||
|  | ||||
|   DWORD len = 0; | ||||
|   const char *pfile = file; | ||||
|   char fbuf[PATH_MAX]; | ||||
|   char fbuf[CYG_MAX_PATH]; | ||||
|   if (current_codepage == oem_cp) | ||||
|     { | ||||
|       DWORD fname_len = min (sizeof (fbuf) - 1, strlen (file)); | ||||
| @@ -1096,34 +1091,38 @@ read_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size) | ||||
| 			OWNER_SECURITY_INFORMATION | ||||
| 			| GROUP_SECURITY_INFORMATION | ||||
| 			| DACL_SECURITY_INFORMATION, | ||||
| 			sd_buf, *sd_size, &len)) | ||||
| 			NULL, 0, &len) | ||||
|       && GetLastError () != ERROR_INSUFFICIENT_BUFFER) | ||||
|     { | ||||
|       debug_printf ("file = %s", file); | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   debug_printf ("file = %s: len=%d", file, len); | ||||
|   if (len > *sd_size) | ||||
|   if (!sd.malloc (len)) | ||||
|     { | ||||
|       *sd_size = len; | ||||
|       return 0; | ||||
|       set_errno (ENOMEM); | ||||
|       return -1; | ||||
|     } | ||||
|   return 1; | ||||
|   if (!GetFileSecurity (pfile, | ||||
| 			OWNER_SECURITY_INFORMATION | ||||
| 			| GROUP_SECURITY_INFORMATION | ||||
| 			| DACL_SECURITY_INFORMATION, | ||||
| 			sd, len, &len)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|     } | ||||
|   return sd.size (); | ||||
| } | ||||
|  | ||||
| LONG | ||||
| write_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size) | ||||
| write_sd (const char *file, security_descriptor &sd) | ||||
| { | ||||
|   /* Check parameters */ | ||||
|   if (!sd_buf || !sd_size) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   BOOL dummy; | ||||
|   cygpsid owner; | ||||
|  | ||||
|   if (!GetSecurityDescriptorOwner (sd_buf, (PSID *) &owner, &dummy)) | ||||
|   if (!GetSecurityDescriptorOwner (sd, (PSID *) &owner, &dummy)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
| @@ -1168,7 +1167,7 @@ write_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size) | ||||
|   header.dwStreamId = BACKUP_SECURITY_DATA; | ||||
|   header.dwStreamAttributes = STREAM_CONTAINS_SECURITY; | ||||
|   header.Size.HighPart = 0; | ||||
|   header.Size.LowPart = sd_size; | ||||
|   header.Size.LowPart = sd.size (); | ||||
|   header.dwStreamNameSize = 0; | ||||
|   if (!BackupWrite (fh, (LPBYTE) &header, | ||||
| 		    3 * sizeof (DWORD) + sizeof (LARGE_INTEGER), | ||||
| @@ -1180,7 +1179,7 @@ write_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size) | ||||
|     } | ||||
|  | ||||
|   /* write new security descriptor */ | ||||
|   if (!BackupWrite (fh, (LPBYTE) sd_buf, | ||||
|   if (!BackupWrite (fh, (LPBYTE) (PSECURITY_DESCRIPTOR) sd, | ||||
| 		    header.Size.LowPart + header.dwStreamNameSize, | ||||
| 		    &bytes_written, FALSE, TRUE, &context)) | ||||
|     { | ||||
| @@ -1361,19 +1360,11 @@ static void | ||||
| get_nt_attribute (const char *file, mode_t *attribute, | ||||
| 		  __uid32_t *uidret, __gid32_t *gidret) | ||||
| { | ||||
|   /* 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; | ||||
|   security_descriptor sd; | ||||
|  | ||||
|   if (read_sd (file, psd, &sd_size) <= 0) | ||||
|     { | ||||
|       debug_printf ("read_sd %E"); | ||||
|       psd = NULL; | ||||
|     } | ||||
|  | ||||
|   get_info_from_sd (psd, attribute, uidret, gidret); | ||||
|   return; | ||||
|   if (read_sd (file, sd) <= 0) | ||||
|     debug_printf ("read_sd %E"); | ||||
|   get_info_from_sd (sd, attribute, uidret, gidret); | ||||
| } | ||||
|  | ||||
| int | ||||
| @@ -1411,26 +1402,37 @@ get_file_attribute (int use_ntsec, const char *file, | ||||
|  | ||||
| static void | ||||
| get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, | ||||
| 			 mode_t *attribute, __uid32_t *uidret, __gid32_t *gidret) | ||||
| 			 mode_t *attribute, __uid32_t *uidret, | ||||
| 			 __gid32_t *gidret) | ||||
| { | ||||
|   PSECURITY_DESCRIPTOR psd; | ||||
|   char sd_buf[4096]; | ||||
|   security_descriptor sd; | ||||
|   PSECURITY_DESCRIPTOR psd = NULL; | ||||
|  | ||||
|   if (object_type == SE_REGISTRY_KEY) | ||||
|     { | ||||
|       /* use different code for registry handles, for performance reasons */ | ||||
|       psd = (PSECURITY_DESCRIPTOR) & sd_buf[0]; | ||||
|       DWORD len = sizeof (sd_buf); | ||||
|       if (ERROR_SUCCESS != RegGetKeySecurity ((HKEY) handle, | ||||
| 					      DACL_SECURITY_INFORMATION | | ||||
| 					      GROUP_SECURITY_INFORMATION | | ||||
| 					      OWNER_SECURITY_INFORMATION, | ||||
| 					      psd, &len)) | ||||
|       DWORD len = 0; | ||||
|       if (RegGetKeySecurity ((HKEY) handle, | ||||
| 			     DACL_SECURITY_INFORMATION | ||||
| 			     | GROUP_SECURITY_INFORMATION | ||||
| 			     | OWNER_SECURITY_INFORMATION, | ||||
| 			     sd, &len) != ERROR_INSUFFICIENT_BUFFER) | ||||
| 	{ | ||||
| 	  __seterrno (); | ||||
| 	  debug_printf ("RegGetKeySecurity %E"); | ||||
| 	  psd = NULL; | ||||
| 	} | ||||
|       if (!sd.malloc (len)) | ||||
| 	set_errno (ENOMEM); | ||||
|       else if (RegGetKeySecurity ((HKEY) handle, | ||||
| 				  DACL_SECURITY_INFORMATION | ||||
| 				  | GROUP_SECURITY_INFORMATION | ||||
| 				  | OWNER_SECURITY_INFORMATION, | ||||
| 				  sd, &len) != ERROR_SUCCESS) | ||||
| 	{ | ||||
| 	  __seterrno (); | ||||
| 	  debug_printf ("RegGetKeySecurity %E"); | ||||
| 	} | ||||
| 	get_info_from_sd (sd, attribute, uidret, gidret); | ||||
|       } | ||||
|   else | ||||
|     { | ||||
| @@ -1444,13 +1446,10 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, | ||||
| 	  debug_printf ("GetSecurityInfo %E"); | ||||
| 	  psd = NULL; | ||||
| 	} | ||||
|       get_info_from_sd (psd, attribute, uidret, gidret); | ||||
|       if (psd) | ||||
| 	LocalFree (psd); | ||||
|     } | ||||
|  | ||||
|   get_info_from_sd (psd, attribute, uidret, gidret); | ||||
|   if (psd != (PSECURITY_DESCRIPTOR) & sd_buf[0]) | ||||
|     LocalFree (psd); | ||||
|  | ||||
|   return; | ||||
| } | ||||
|  | ||||
| int | ||||
| @@ -1498,18 +1497,13 @@ add_access_denied_ace (PACL acl, int offset, DWORD attributes, | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| PSECURITY_DESCRIPTOR | ||||
| static PSECURITY_DESCRIPTOR | ||||
| alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, | ||||
| 	  PSECURITY_DESCRIPTOR sd_ret, DWORD *sd_size_ret) | ||||
| 	  security_descriptor &sd_ret) | ||||
| { | ||||
|   BOOL dummy; | ||||
|  | ||||
|   debug_printf("uid %d, gid %d, attribute %x", uid, gid, attribute); | ||||
|   if (!sd_ret || !sd_size_ret) | ||||
|     { | ||||
|       set_errno (EINVAL); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
|   /* Get owner and group from current security descriptor. */ | ||||
|   PSID cur_owner_sid = NULL; | ||||
| @@ -1788,33 +1782,37 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, | ||||
|     } | ||||
|  | ||||
|   /* Make self relative security descriptor. */ | ||||
|   *sd_size_ret = 0; | ||||
|   MakeSelfRelativeSD (&sd, sd_ret, sd_size_ret); | ||||
|   if (*sd_size_ret <= 0) | ||||
|   DWORD sd_size = 0; | ||||
|   MakeSelfRelativeSD (&sd, sd_ret, &sd_size); | ||||
|   if (sd_size <= 0) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return NULL; | ||||
|     } | ||||
|   if (!MakeSelfRelativeSD (&sd, sd_ret, sd_size_ret)) | ||||
|   if (!sd_ret.malloc (sd_size)) | ||||
|     { | ||||
|       set_errno (ENOMEM); | ||||
|       return NULL; | ||||
|     } | ||||
|   if (!MakeSelfRelativeSD (&sd, sd_ret, &sd_size)) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return NULL; | ||||
|     } | ||||
|   debug_printf ("Created SD-Size: %d", *sd_size_ret); | ||||
|   debug_printf ("Created SD-Size: %u", sd_ret.size ()); | ||||
|  | ||||
|   return sd_ret; | ||||
| } | ||||
|  | ||||
| void | ||||
| set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa, | ||||
| 			void *sd_buf, DWORD sd_buf_size) | ||||
| 			security_descriptor &sd) | ||||
| { | ||||
|   psa->lpSecurityDescriptor = sd_buf; | ||||
|   InitializeSecurityDescriptor ((PSECURITY_DESCRIPTOR) sd_buf, | ||||
|   psa->lpSecurityDescriptor = sd.malloc (SECURITY_DESCRIPTOR_MIN_LENGTH); | ||||
|   InitializeSecurityDescriptor ((PSECURITY_DESCRIPTOR)psa->lpSecurityDescriptor, | ||||
| 				SECURITY_DESCRIPTOR_REVISION); | ||||
|   psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (), attribute, | ||||
| 					(PSECURITY_DESCRIPTOR) sd_buf, | ||||
| 					&sd_buf_size); | ||||
|   psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (), | ||||
|   					attribute, sd); | ||||
| } | ||||
|  | ||||
| static int | ||||
| @@ -1824,22 +1822,19 @@ set_nt_attribute (const char *file, __uid32_t uid, __gid32_t gid, | ||||
|   if (!wincap.has_security ()) | ||||
|     return 0; | ||||
|  | ||||
|   DWORD sd_size = 4096; | ||||
|   char sd_buf[4096]; | ||||
|   PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; | ||||
|   security_descriptor sd; | ||||
|  | ||||
|   int ret; | ||||
|   if ((ret = read_sd (file, psd, &sd_size)) <= 0) | ||||
|   if ((ret = read_sd (file, sd)) <= 0) | ||||
|     { | ||||
|       debug_printf ("read_sd %E"); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   sd_size = 4096; | ||||
|   if (!(psd = alloc_sd (uid, gid, attribute, psd, &sd_size))) | ||||
|   if (!alloc_sd (uid, gid, attribute, sd)) | ||||
|     return -1; | ||||
|  | ||||
|   return write_sd (file, psd, sd_size); | ||||
|   return write_sd (file, sd); | ||||
| } | ||||
|  | ||||
| int | ||||
| @@ -1872,9 +1867,9 @@ int | ||||
| check_file_access (const char *fn, int flags) | ||||
| { | ||||
|   int ret = -1; | ||||
|   char sd_buf[4096]; | ||||
|   DWORD sd_size = sizeof sd_buf; | ||||
|   PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; | ||||
|  | ||||
|   security_descriptor sd; | ||||
|  | ||||
|   HANDLE hToken, hIToken; | ||||
|   BOOL status; | ||||
|   char pbuf[sizeof (PRIVILEGE_SET) + 3 * sizeof (LUID_AND_ATTRIBUTES)]; | ||||
| @@ -1883,7 +1878,7 @@ check_file_access (const char *fn, int flags) | ||||
| 					     FILE_GENERIC_WRITE, | ||||
| 					     FILE_GENERIC_EXECUTE, | ||||
| 					     FILE_ALL_ACCESS }; | ||||
|   if (read_sd (fn, psd, &sd_size) <= 0) | ||||
|   if (read_sd (fn, sd) <= 0) | ||||
|     goto done; | ||||
|  | ||||
|   if (cygheap->user.issetuid ()) | ||||
| @@ -1906,7 +1901,7 @@ check_file_access (const char *fn, int flags) | ||||
|     desired |= FILE_WRITE_DATA; | ||||
|   if (flags & X_OK) | ||||
|     desired |= FILE_EXECUTE; | ||||
|   if (!AccessCheck (psd, hIToken, desired, &mapping, | ||||
|   if (!AccessCheck (sd, hIToken, desired, &mapping, | ||||
| 		    (PPRIVILEGE_SET) pbuf, &plength, &granted, &status)) | ||||
|     __seterrno (); | ||||
|   else if (!status) | ||||
|   | ||||
| @@ -167,6 +167,24 @@ public: | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /* Wrapper class to allow simple deleting of buffer space allocated | ||||
|    by read_sd() */ | ||||
| class security_descriptor { | ||||
| protected: | ||||
|   PSECURITY_DESCRIPTOR psd; | ||||
|   DWORD sd_size; | ||||
| public: | ||||
|   security_descriptor () : psd (NULL), sd_size (0) {} | ||||
|   ~security_descriptor () { free (); } | ||||
|  | ||||
|   PSECURITY_DESCRIPTOR malloc (size_t nsize); | ||||
|   PSECURITY_DESCRIPTOR realloc (size_t nsize); | ||||
|   void free (void); | ||||
|  | ||||
|   inline DWORD size (void) const { return sd_size; } | ||||
|   inline operator const PSECURITY_DESCRIPTOR () { return psd; } | ||||
| }; | ||||
|  | ||||
| class user_groups { | ||||
| public: | ||||
|   cygsid pgsid; | ||||
| @@ -228,14 +246,14 @@ int __stdcall set_file_attribute (int, const char *, int); | ||||
| int __stdcall set_file_attribute (int, const char *, __uid32_t, __gid32_t, int); | ||||
| int __stdcall get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, mode_t *, | ||||
| 				  __uid32_t * = NULL, __gid32_t * = NULL); | ||||
| LONG __stdcall read_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size); | ||||
| LONG __stdcall write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size); | ||||
| LONG __stdcall read_sd (const char *file, security_descriptor &sd); | ||||
| LONG __stdcall write_sd (const char *file, security_descriptor &sd); | ||||
| BOOL __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit); | ||||
| BOOL __stdcall add_access_denied_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit); | ||||
| int __stdcall check_file_access (const char *, int); | ||||
|  | ||||
| void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa, | ||||
| 			     void *sd_buf, DWORD sd_buf_size); | ||||
| 			     security_descriptor &sd_buf); | ||||
|  | ||||
| bool get_sids_info (cygpsid, cygpsid, __uid32_t * , __gid32_t *); | ||||
|  | ||||
| @@ -268,8 +286,6 @@ extern BOOL sec_acl (PACL acl, bool original, bool admins, PSID sid1 = NO_SID, | ||||
|  | ||||
| int __stdcall NTReadEA (const char *file, const char *attrname, char *buf, int len); | ||||
| BOOL __stdcall NTWriteEA (const char *file, const char *attrname, const char *buf, int len); | ||||
| PSECURITY_DESCRIPTOR alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, | ||||
| 	  PSECURITY_DESCRIPTOR sd_ret, DWORD *sd_size_ret); | ||||
|  | ||||
| extern inline SECURITY_ATTRIBUTES * | ||||
| sec_user_nih (char sa_buf[], PSID sid1 = NULL, PSID sid2 = NULL, DWORD access2 = 0) | ||||
|   | ||||
| @@ -1676,8 +1676,9 @@ semaphore::semaphore (const char *sem_name, int oflag, mode_t mode, | ||||
|   if (oflag & O_CREAT) | ||||
|     { | ||||
|       SECURITY_ATTRIBUTES sa = sec_all; | ||||
|       security_descriptor sd; | ||||
|       if (allow_ntsec) | ||||
| 	set_security_attribute (mode, &sa, alloca (4096), 4096); | ||||
| 	set_security_attribute (mode, &sa, sd); | ||||
|       this->win32_obj_id = ::CreateSemaphore (&sa, value, LONG_MAX, sem_name); | ||||
|       if (!this->win32_obj_id) | ||||
| 	magic = 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user