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.cc67
1 files changed, 36 insertions, 31 deletions
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
index c932c2441..0915a77e6 100644
--- a/winsup/cygwin/security.cc
+++ b/winsup/cygwin/security.cc
@@ -1117,16 +1117,8 @@ read_sd (const char *file, security_descriptor &sd)
}
LONG
-write_sd (const char *file, security_descriptor &sd)
+write_sd (HANDLE fh, const char *file, security_descriptor &sd)
{
- BOOL dummy;
- cygpsid owner;
-
- if (!GetSecurityDescriptorOwner (sd, (PSID *) &owner, &dummy))
- {
- __seterrno ();
- return -1;
- }
/* Try turning privilege on, may not have WRITE_OWNER or WRITE_DAC access.
Must have privilege to set different owner, else BackupWrite misbehaves */
static int NO_COPY saved_res; /* 0: never, 1: failed, 2 & 3: OK */
@@ -1140,29 +1132,42 @@ write_sd (const char *file, security_descriptor &sd)
}
else
res = saved_res;
- if (res == 1 && owner != cygheap->user.sid ())
- {
- set_errno (EPERM);
- return -1;
- }
- HANDLE fh;
- if ((fh = CreateFile (file,
- WRITE_OWNER | WRITE_DAC,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sec_none_nih,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
- NULL)) == INVALID_HANDLE_VALUE)
+ if (res == 1)
{
- __seterrno ();
- return -1;
+ BOOL dummy;
+ cygpsid owner;
+
+ if (!GetSecurityDescriptorOwner (sd, (PSID *) &owner, &dummy))
+ {
+ __seterrno ();
+ return -1;
+ }
+ if (owner != cygheap->user.sid ())
+ {
+ set_errno (EPERM);
+ return -1;
+ }
}
- NTSTATUS ret = NtSetSecurityObject (fh,
- DACL_SECURITY_INFORMATION
- | GROUP_SECURITY_INFORMATION
- | OWNER_SECURITY_INFORMATION,
- sd);
- CloseHandle (fh);
+ NTSTATUS ret;
+ int retry = 0;
+ for (; retry < 2; ++retry)
+ {
+ if (retry && (fh = CreateFile (file, WRITE_OWNER | WRITE_DAC,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sec_none_nih, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL
+ | FILE_FLAG_BACKUP_SEMANTICS,
+ NULL)) == INVALID_HANDLE_VALUE)
+ break;
+ if (fh && (ret = NtSetSecurityObject (fh,
+ DACL_SECURITY_INFORMATION
+ | GROUP_SECURITY_INFORMATION
+ | OWNER_SECURITY_INFORMATION,
+ sd)) == STATUS_SUCCESS)
+ break;
+ }
+ if (retry && fh != INVALID_HANDLE_VALUE)
+ CloseHandle (fh);
if (ret != STATUS_SUCCESS)
{
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
@@ -1802,7 +1807,7 @@ set_nt_attribute (HANDLE handle, const char *file,
if (!alloc_sd (uid, gid, attribute, sd))
return -1;
- return write_sd (file, sd);
+ return write_sd (handle, file, sd);
}
int