Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/security.cc')
-rw-r--r--winsup/cygwin/security.cc61
1 files changed, 45 insertions, 16 deletions
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;