diff options
Diffstat (limited to 'winsup/cygwin/security.cc')
-rw-r--r-- | winsup/cygwin/security.cc | 77 |
1 files changed, 66 insertions, 11 deletions
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 3aa658958..33b6876b1 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -1426,21 +1426,76 @@ get_info_from_sd (PSECURITY_DESCRIPTOR psd, mode_t *attribute, (!acl_exists || !acl)?"NO ":"", *attribute, uid, gid); } +static int +get_reg_security (HANDLE handle, security_descriptor &sd_ret) +{ + LONG ret; + DWORD len = 0; + + ret = RegGetKeySecurity ((HKEY) handle, + DACL_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | OWNER_SECURITY_INFORMATION, + sd_ret, &len); + if (ret == ERROR_INSUFFICIENT_BUFFER) + { + if (!sd_ret.malloc (len)) + set_errno (ENOMEM); + else + ret = RegGetKeySecurity ((HKEY) handle, + DACL_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | OWNER_SECURITY_INFORMATION, + sd_ret, &len); + } + if (ret != ERROR_SUCCESS) + { + __seterrno (); + return -1; + } + return 0; +} + int get_nt_object_security (HANDLE handle, SE_OBJECT_TYPE object_type, security_descriptor &sd_ret) { - sd_ret.free (); - /* Don't use NtQuerySecurityObject. It doesn't recognize predefined - registry keys. */ - DWORD ret = GetSecurityInfo (handle, object_type, - DACL_SECURITY_INFORMATION - | GROUP_SECURITY_INFORMATION - | OWNER_SECURITY_INFORMATION, - NULL, NULL, NULL, NULL, sd_ret); - if (ret != ERROR_SUCCESS) - { - __seterrno_from_win_error (ret); + NTSTATUS ret; + ULONG len = 0; + + /* Do not try to use GetSecurityInfo (again), unless we drop NT4 support. + GetSecurityInfo returns the wrong user information when running in + a user session using a token created with NtCreateToken under NT4. + Works fine in 2K and above, but that doesn't help a lot. */ + + /* Unfortunately, NtQuerySecurityObject doesn't work on predefined registry + keys like HKEY_LOCAL_MACHINE. It fails with "Invalid Handle". So we + have to retreat to the Win32 registry functions for registry keys. + What bugs me is that RegGetKeySecurity is obviously just a wrapper + around NtQuerySecurityObject, but there seems to be no function to + convert pseudo HKEY values to real handles. */ + if (object_type == SE_REGISTRY_KEY) + return get_reg_security (handle, sd_ret); + + ret = NtQuerySecurityObject (handle, + DACL_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | OWNER_SECURITY_INFORMATION, + sd_ret, len, &len); + if (ret == STATUS_BUFFER_TOO_SMALL) + { + if (!sd_ret.malloc (len)) + set_errno (ENOMEM); + else + ret = NtQuerySecurityObject (handle, + DACL_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | OWNER_SECURITY_INFORMATION, + sd_ret, len, &len); + } + if (ret != STATUS_SUCCESS) + { + __seterrno_from_nt_status (ret); return -1; } return 0; |