diff options
-rw-r--r-- | winsup/cygwin/ChangeLog | 15 | ||||
-rw-r--r-- | winsup/cygwin/sec_acl.cc | 4 | ||||
-rw-r--r-- | winsup/cygwin/security.cc | 61 | ||||
-rw-r--r-- | winsup/cygwin/security.h | 61 |
4 files changed, 100 insertions, 41 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1b5da688d..eb15dd325 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,20 @@ 2010-09-10 Corinna Vinschen <corinna@vinschen.de> + * security.cc (get_file_sd): Add bool parameter justcreated. Use + GetSecurityInfo only if justcreated is true, NtQuerySecurityObject + otherwise. Add comment to explain why. Don't waste time to call + NtQuerySecurityObject twice, just allocate big enough area. + (get_file_attribute): Call get_file_sd with justcreated set to false. + (set_file_attribute): Call get_file_sd with justcreated depending on + S_JUSTCREATED pseudo file attribute. + (check_file_access): Call get_file_sd with justcreated set to false. + * sec_acl.cc (setacl): Ditto. + (getacl): Ditto. + * security.h: Convert many functions to regparm functions. + (get_file_sd): Declare with extra bool parameter. + +2010-09-10 Corinna Vinschen <corinna@vinschen.de> + * fhandler_procsys.cc (fhandler_procsys::exists): Rearrange to handle dangling symlinks correctly. Fix comments. (fhandler_procsys::fill_filebuf): Remove useless comment. diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc index 88abac46a..fbf2bffa7 100644 --- a/winsup/cygwin/sec_acl.cc +++ b/winsup/cygwin/sec_acl.cc @@ -41,7 +41,7 @@ setacl (HANDLE handle, path_conv &pc, int nentries, __aclent32_t *aclbufp, { security_descriptor sd_ret; - if (get_file_sd (handle, pc, sd_ret)) + if (get_file_sd (handle, pc, sd_ret, false)) return -1; BOOL dummy; @@ -272,7 +272,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, __aclent32_t *aclbufp) { security_descriptor sd; - if (get_file_sd (handle, pc, sd)) + if (get_file_sd (handle, pc, sd, false)) return -1; cygpsid owner_sid; diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index d101623c7..e88fcf2fc 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -31,7 +31,8 @@ details. */ | OWNER_SECURITY_INFORMATION) LONG -get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd) +get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd, + bool justcreated) { DWORD error = ERROR_SUCCESS; int retry = 0; @@ -41,19 +42,47 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd) { if (fh) { - /* Amazing but true. If you want to know if an ACE is inherited - from the parent object, you can't use the NtQuerySecurityObject - function. In the DACL returned by this functions, the - INHERITED_ACE flag is never set. Only by calling GetSecurityInfo - you get this information. Oh well. */ - PSECURITY_DESCRIPTOR psd; - error = GetSecurityInfo (fh, SE_FILE_OBJECT, ALL_SECURITY_INFORMATION, - NULL, NULL, NULL, NULL, &psd); - if (error == ERROR_SUCCESS) + if (justcreated) { - sd = psd; - res = 0; - break; + /* Amazing but true. If you want to know if an ACE is inherited + from the parent object, you can't use the NtQuerySecurityObject + function. In the DACL returned by this functions, the + INHERITED_ACE flag is never set. Only by calling + GetSecurityInfo you get this information. + + This functionality is slow, and the extra information is only + required when the file has been created and the permissions + are about to be set to POSIX permissions. Therefore we only + use it in case the file just got created. In all other cases + we rather call NtQuerySecurityObject directly. */ + PSECURITY_DESCRIPTOR psd; + error = GetSecurityInfo (fh, SE_FILE_OBJECT, ALL_SECURITY_INFORMATION, + NULL, NULL, NULL, NULL, &psd); + if (error == ERROR_SUCCESS) + { + sd = psd; + res = 0; + break; + } + } + else + { + NTSTATUS status; + ULONG len = 32768; + + if (!sd.malloc (len)) + { + set_errno (ENOMEM); + break; + } + status = NtQuerySecurityObject (fh, ALL_SECURITY_INFORMATION, + sd, len, &len); + if (NT_SUCCESS (status)) + { + res = 0; + break; + } + error = RtlNtStatusToDosError (status); } } if (!retry) @@ -323,7 +352,7 @@ get_file_attribute (HANDLE handle, path_conv &pc, { security_descriptor sd; - if (!get_file_sd (handle, pc, sd)) + if (!get_file_sd (handle, pc, sd, false)) { get_info_from_sd (sd, attribute, uidret, gidret); return 0; @@ -828,7 +857,7 @@ set_file_attribute (HANDLE handle, path_conv &pc, { security_descriptor sd; - if (!get_file_sd (handle, pc, sd) + if (!get_file_sd (handle, pc, sd, attribute & S_JUSTCREATED) && alloc_sd (pc, uid, gid, attribute, sd)) ret = set_file_sd (handle, pc, sd, uid != ILLEGAL_UID || gid != ILLEGAL_GID); @@ -928,7 +957,7 @@ check_file_access (path_conv &pc, int flags, bool effective) desired |= FILE_WRITE_DATA; if (flags & X_OK) desired |= FILE_EXECUTE; - if (!get_file_sd (NULL, pc, sd)) + if (!get_file_sd (NULL, pc, sd, false)) ret = check_access (sd, mapping, desired, flags, effective); debug_printf ("flags %x, ret %d", flags, ret); return ret; diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index dde4d214e..d38edc16d 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -348,24 +348,37 @@ legal_sid_type (SID_NAME_USE type) class path_conv; /* File manipulation */ int __stdcall get_file_attribute (HANDLE, path_conv &, mode_t *, - __uid32_t *, __gid32_t *); + __uid32_t *, __gid32_t *) + __attribute__ ((regparm (3))); int __stdcall set_file_attribute (HANDLE, path_conv &, - __uid32_t, __gid32_t, mode_t); -int __stdcall get_object_sd (HANDLE, security_descriptor &); -int __stdcall get_object_attribute (HANDLE, __uid32_t *, __gid32_t *, mode_t *); -int __stdcall set_object_attribute (HANDLE, __uid32_t, __gid32_t, mode_t); + __uid32_t, __gid32_t, mode_t) + __attribute__ ((regparm (3))); +int __stdcall get_object_sd (HANDLE, security_descriptor &) + __attribute__ ((regparm (2))); +int __stdcall get_object_attribute (HANDLE, __uid32_t *, __gid32_t *, mode_t *) + __attribute__ ((regparm (3))); +int __stdcall set_object_attribute (HANDLE, __uid32_t, __gid32_t, mode_t) + __attribute__ ((regparm (3))); int __stdcall create_object_sd_from_attribute (HANDLE, __uid32_t, __gid32_t, - mode_t, security_descriptor &); -int __stdcall set_object_sd (HANDLE, security_descriptor &, bool); - -int __stdcall get_reg_attribute (HKEY hkey, mode_t *, __uid32_t *, __gid32_t *); -LONG __stdcall get_file_sd (HANDLE fh, path_conv &, security_descriptor &sd); -LONG __stdcall set_file_sd (HANDLE fh, path_conv &, security_descriptor &sd, - bool is_chown); -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 (path_conv &, int, bool); -int __stdcall check_registry_access (HANDLE, int, bool); + mode_t, security_descriptor &) + __attribute__ ((regparm (3))); +int __stdcall set_object_sd (HANDLE, security_descriptor &, bool) + __attribute__ ((regparm (3))); + +int __stdcall get_reg_attribute (HKEY hkey, mode_t *, __uid32_t *, __gid32_t *) + __attribute__ ((regparm (3))); +LONG __stdcall get_file_sd (HANDLE fh, path_conv &, security_descriptor &, bool) + __attribute__ ((regparm (3))); +LONG __stdcall set_file_sd (HANDLE fh, path_conv &, security_descriptor &, bool) + __attribute__ ((regparm (3))); +bool __stdcall add_access_allowed_ace (PACL, int, DWORD, PSID, size_t &, DWORD) + __attribute__ ((regparm (3))); +bool __stdcall add_access_denied_ace (PACL, int, DWORD, PSID, size_t &, DWORD) + __attribute__ ((regparm (3))); +int __stdcall check_file_access (path_conv &, int, bool) + __attribute__ ((regparm (3))); +int __stdcall check_registry_access (HANDLE, int, bool) + __attribute__ ((regparm (3))); void set_security_attribute (path_conv &pc, int attribute, PSECURITY_ATTRIBUTES psa, @@ -437,9 +450,9 @@ void set_cygwin_privileges (HANDLE token); /* Various types of security attributes for use in Create* functions. */ extern SECURITY_ATTRIBUTES sec_none, sec_none_nih, sec_all, sec_all_nih; -extern SECURITY_ATTRIBUTES *__stdcall __sec_user (PVOID sa_buf, PSID sid1, PSID sid2, - DWORD access2, BOOL inherit) - __attribute__ ((regparm (3))); +extern SECURITY_ATTRIBUTES *__stdcall __sec_user (PVOID, PSID, PSID, + DWORD, BOOL) + __attribute__ ((regparm (3))); extern PSECURITY_DESCRIPTOR _everyone_sd (void *buf, ACCESS_MASK access); #define everyone_sd(access) (_everyone_sd (alloca (SD_MIN_SIZE), (access))) @@ -448,10 +461,12 @@ extern PSECURITY_DESCRIPTOR _everyone_sd (void *buf, ACCESS_MASK access); extern bool sec_acl (PACL acl, bool original, bool admins, PSID sid1 = NO_SID, PSID sid2 = NO_SID, DWORD access2 = 0); -ssize_t __stdcall read_ea (HANDLE hdl, path_conv &pc, const char *name, - char *value, size_t size); -int __stdcall write_ea (HANDLE hdl, path_conv &pc, const char *name, - const char *value, size_t size, int flags); +ssize_t __stdcall read_ea (HANDLE, path_conv &, const char *, + char *, size_t) + __attribute__ ((regparm (3))); +int __stdcall write_ea (HANDLE, path_conv &, const char *, const char *, + size_t, int) + __attribute__ ((regparm (3))); /* Note: sid1 is usually (read: currently always) the current user's effective sid (cygheap->user.sid ()). */ |