diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2003-11-26 16:23:27 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2003-11-26 16:23:27 +0300 |
commit | 12069cf31bcd401720e1a86b353ac6237b5e29a3 (patch) | |
tree | 1c2de4e70fcc84c84af015ab3fb4349722301d5d /winsup | |
parent | 3db690789f317dc0798bf3dd883a24ebfbb57354 (diff) |
* 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.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 38 | ||||
-rw-r--r-- | winsup/cygwin/dir.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/external.cc | 9 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_socket.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/path.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/sec_acl.cc | 34 | ||||
-rw-r--r-- | winsup/cygwin/sec_helper.cc | 29 | ||||
-rw-r--r-- | winsup/cygwin/security.cc | 165 | ||||
-rw-r--r-- | winsup/cygwin/security.h | 26 | ||||
-rw-r--r-- | winsup/cygwin/thread.cc | 3 |
11 files changed, 200 insertions, 116 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a07903e29..a19126aa1 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,43 @@ 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. * security.cc (get_attribute_from_acl): Ditto. * security.h (FILE_READ_BITS): Define to match also GENERIC bits. diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 247216d3a..90ca1cab4 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -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)) { diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index fcb2b2159..cfe5528e5 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -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: { diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index b27ab678c..12881bd85 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -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); diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 768962870..626818a10 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -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) { diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index e938685be..4fe66ac3f 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -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); diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc index 0988e01e8..a93a6a63a 100644 --- a/winsup/cygwin/sec_acl.cc +++ b/winsup/cygwin/sec_acl.cc @@ -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"); diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc index ccd8d4487..f0b851be8 100644 --- a/winsup/cygwin/sec_helper.cc +++ b/winsup/cygwin/sec_helper.cc @@ -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) diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 448cd6547..71c325ecd 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -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; -} - -LONG -write_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size) -{ - /* Check parameters */ - if (!sd_buf || !sd_size) + if (!GetFileSecurity (pfile, + OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | DACL_SECURITY_INFORMATION, + sd, len, &len)) { - set_errno (EINVAL); + __seterrno (); return -1; } + return sd.size (); +} +LONG +write_sd (const char *file, security_descriptor &sd) +{ 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; - - if (read_sd (file, psd, &sd_size) <= 0) - { - debug_printf ("read_sd %E"); - psd = NULL; - } + security_descriptor sd; - 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) diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index f50599adf..5da8e3d89 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -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) diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index fc2570c6d..eeaa4ba4d 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -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; |