summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/security.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2004-04-14 13:40:07 +0000
committerCorinna Vinschen <corinna@vinschen.de>2004-04-14 13:40:07 +0000
commitddf9c4a7444970b5ad4c0ed4a82bdc7bd4964c15 (patch)
tree0f0c9b57900da5163c44f21cc1b3e7288e677d1f /winsup/cygwin/security.cc
parentba1a97a18b5d629f62c691d62c69fe97da903b05 (diff)
downloadcygnal-ddf9c4a7444970b5ad4c0ed4a82bdc7bd4964c15.tar.gz
cygnal-ddf9c4a7444970b5ad4c0ed4a82bdc7bd4964c15.tar.bz2
cygnal-ddf9c4a7444970b5ad4c0ed4a82bdc7bd4964c15.zip
* fhandler.cc (fhandler_base::open): Accomodate query_write_control
query_state. (fhandler_base::fchown): New method. * fhandler.h: Declare fchown method in fhandler_base, fhandler_disk_file and fhandler_virtual. (enum query_state): Add query_write_control. * fhandler_disk_file.cc (fhandler_disk_file::fchmod): Set query_state to query_write_control. Only remove FILE_ATTRIBUTE_READONLY if not setting security descriptor. (fhandler_disk_file::fchown): New method. * fhandler_virtual.cc (fhandler_virtual::fchown): New method. * sec_acl.cc (setacl): Call write_sd with additional handle attribute. * security.cc (write_sd): Take handle argument. Only request owner if getting SE_RESTORE_NAME privilege failed. Only open file if NtSetSecurityObject failed or handle is NULL. (set_nt_attribute): Call write_sd with additional handle attribute. * security.h (write_sd): Declare with additional handle argument.
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