mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-28 12:05:47 +08:00
* 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.
This commit is contained in:
parent
ba1a97a18b
commit
ddf9c4a744
@ -1,3 +1,23 @@
|
|||||||
|
2004-04-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2004-04-14 Corinna Vinschen <corinna@vinschen.de>
|
2004-04-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* autoload.cc (NtSetSecurityObject): Add.
|
* autoload.cc (NtSetSecurityObject): Add.
|
||||||
|
@ -443,7 +443,18 @@ fhandler_base::open (int flags, mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (query_open ())
|
if (query_open ())
|
||||||
access = (query_open () == query_read_control ? READ_CONTROL : 0);
|
switch (query_open ())
|
||||||
|
{
|
||||||
|
case query_null_access:
|
||||||
|
access = 0;
|
||||||
|
break;
|
||||||
|
case query_read_control:
|
||||||
|
access = READ_CONTROL;
|
||||||
|
break;
|
||||||
|
case query_write_control:
|
||||||
|
access = READ_CONTROL | WRITE_OWNER | WRITE_DAC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
else if (get_major () == DEV_TAPE_MAJOR)
|
else if (get_major () == DEV_TAPE_MAJOR)
|
||||||
access = GENERIC_READ | GENERIC_WRITE;
|
access = GENERIC_READ | GENERIC_WRITE;
|
||||||
else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
|
else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
|
||||||
@ -1411,3 +1422,10 @@ fhandler_base::fchmod (mode_t mode)
|
|||||||
/* By default, just succeeds. */
|
/* By default, just succeeds. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_base::fchown (__uid32_t uid, __gid32_t gid)
|
||||||
|
{
|
||||||
|
/* By default, just succeeds. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -62,8 +62,9 @@ enum bg_check_types
|
|||||||
|
|
||||||
enum query_state {
|
enum query_state {
|
||||||
no_query = 0,
|
no_query = 0,
|
||||||
query_read_control = 1,
|
query_null_access = 1,
|
||||||
query_null_access = 2
|
query_read_control = 2,
|
||||||
|
query_write_control = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_base
|
class fhandler_base
|
||||||
@ -243,6 +244,7 @@ class fhandler_base
|
|||||||
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
||||||
|
virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
||||||
virtual int ioctl (unsigned int cmd, void *);
|
virtual int ioctl (unsigned int cmd, void *);
|
||||||
virtual int fcntl (int cmd, void *);
|
virtual int fcntl (int cmd, void *);
|
||||||
virtual char const *ttyname () { return get_name (); }
|
virtual char const *ttyname () { return get_name (); }
|
||||||
@ -568,6 +570,7 @@ class fhandler_disk_file: public fhandler_base
|
|||||||
bool isdevice () { return false; }
|
bool isdevice () { return false; }
|
||||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
||||||
|
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
||||||
|
|
||||||
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, _off64_t off);
|
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, _off64_t off);
|
||||||
int munmap (HANDLE h, caddr_t addr, size_t len);
|
int munmap (HANDLE h, caddr_t addr, size_t len);
|
||||||
@ -1101,6 +1104,7 @@ class fhandler_virtual : public fhandler_base
|
|||||||
int close (void);
|
int close (void);
|
||||||
int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
||||||
|
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
||||||
virtual bool fill_filebuf ();
|
virtual bool fill_filebuf ();
|
||||||
void fixup_after_exec ();
|
void fixup_after_exec ();
|
||||||
};
|
};
|
||||||
|
@ -377,14 +377,18 @@ fhandler_disk_file::fchmod (mode_t mode)
|
|||||||
if (pc.is_fs_special ())
|
if (pc.is_fs_special ())
|
||||||
return chmod_device (pc, mode);
|
return chmod_device (pc, mode);
|
||||||
|
|
||||||
query_open (query_read_control);
|
if (!get_io_handle ())
|
||||||
if (!get_io_handle () && !(oret = open_fs (O_BINARY, 0)))
|
{
|
||||||
return -1;
|
query_open (query_write_control);
|
||||||
|
if (!(oret = open_fs (O_BINARY, 0)))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
SetFileAttributes (get_win32_name (), (DWORD) pc & ~FILE_ATTRIBUTE_READONLY);
|
if (!allow_ntsec && allow_ntea) /* Not necessary when manipulating SD. */
|
||||||
|
SetFileAttributes (pc, (DWORD) pc & ~FILE_ATTRIBUTE_READONLY);
|
||||||
if (pc.isdir ())
|
if (pc.isdir ())
|
||||||
mode |= S_IFDIR;
|
mode |= S_IFDIR;
|
||||||
if (!set_file_attribute (pc.has_acls (), get_io_handle (), get_win32_name (),
|
if (!set_file_attribute (pc.has_acls (), get_io_handle (), pc,
|
||||||
ILLEGAL_UID, ILLEGAL_GID, mode)
|
ILLEGAL_UID, ILLEGAL_GID, mode)
|
||||||
&& allow_ntsec)
|
&& allow_ntsec)
|
||||||
res = 0;
|
res = 0;
|
||||||
@ -410,6 +414,37 @@ fhandler_disk_file::fchmod (mode_t mode)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __stdcall
|
||||||
|
fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
|
||||||
|
{
|
||||||
|
int oret = 0;
|
||||||
|
if (!get_io_handle ())
|
||||||
|
{
|
||||||
|
query_open (query_write_control);
|
||||||
|
if (!(oret = open_fs (O_BINARY, 0)))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode_t attrib = 0;
|
||||||
|
if (pc.isdir ())
|
||||||
|
attrib |= S_IFDIR;
|
||||||
|
int res = get_file_attribute (pc.has_acls (), get_io_handle (), pc, &attrib);
|
||||||
|
if (!res)
|
||||||
|
res = set_file_attribute (pc.has_acls (), get_io_handle (), pc,
|
||||||
|
uid, gid, attrib);
|
||||||
|
if (res && (!pc.has_acls () || !allow_ntsec))
|
||||||
|
{
|
||||||
|
/* fake - if not supported, pretend we're like win95
|
||||||
|
where it just works */
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oret)
|
||||||
|
close_fs ();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
fhandler_disk_file::fhandler_disk_file () :
|
fhandler_disk_file::fhandler_disk_file () :
|
||||||
fhandler_base ()
|
fhandler_base ()
|
||||||
{
|
{
|
||||||
|
@ -234,3 +234,11 @@ fhandler_virtual::fchmod (mode_t mode)
|
|||||||
set_errno (EPERM);
|
set_errno (EPERM);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_virtual::fchown (__uid32_t uid, __gid32_t gid)
|
||||||
|
{
|
||||||
|
/* Same as on Linux. */
|
||||||
|
set_errno (EPERM);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
@ -223,7 +223,7 @@ setacl (const char *file, int nentries, __aclent32_t *aclbufp)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
debug_printf ("Created SD-Size: %d", sd_ret.size ());
|
debug_printf ("Created SD-Size: %d", sd_ret.size ());
|
||||||
return write_sd (file, sd_ret);
|
return write_sd (NULL, file, sd_ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temporary access denied bits */
|
/* Temporary access denied bits */
|
||||||
|
@ -1117,16 +1117,8 @@ read_sd (const char *file, security_descriptor &sd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
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.
|
/* Try turning privilege on, may not have WRITE_OWNER or WRITE_DAC access.
|
||||||
Must have privilege to set different owner, else BackupWrite misbehaves */
|
Must have privilege to set different owner, else BackupWrite misbehaves */
|
||||||
static int NO_COPY saved_res; /* 0: never, 1: failed, 2 & 3: OK */
|
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
|
else
|
||||||
res = saved_res;
|
res = saved_res;
|
||||||
if (res == 1 && owner != cygheap->user.sid ())
|
if (res == 1)
|
||||||
{
|
{
|
||||||
set_errno (EPERM);
|
BOOL dummy;
|
||||||
return -1;
|
cygpsid owner;
|
||||||
|
|
||||||
|
if (!GetSecurityDescriptorOwner (sd, (PSID *) &owner, &dummy))
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (owner != cygheap->user.sid ())
|
||||||
|
{
|
||||||
|
set_errno (EPERM);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
HANDLE fh;
|
NTSTATUS ret;
|
||||||
if ((fh = CreateFile (file,
|
int retry = 0;
|
||||||
WRITE_OWNER | WRITE_DAC,
|
for (; retry < 2; ++retry)
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
&sec_none_nih,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
|
|
||||||
NULL)) == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
{
|
||||||
__seterrno ();
|
if (retry && (fh = CreateFile (file, WRITE_OWNER | WRITE_DAC,
|
||||||
return -1;
|
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;
|
||||||
}
|
}
|
||||||
NTSTATUS ret = NtSetSecurityObject (fh,
|
if (retry && fh != INVALID_HANDLE_VALUE)
|
||||||
DACL_SECURITY_INFORMATION
|
CloseHandle (fh);
|
||||||
| GROUP_SECURITY_INFORMATION
|
|
||||||
| OWNER_SECURITY_INFORMATION,
|
|
||||||
sd);
|
|
||||||
CloseHandle (fh);
|
|
||||||
if (ret != STATUS_SUCCESS)
|
if (ret != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
|
__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))
|
if (!alloc_sd (uid, gid, attribute, sd))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return write_sd (file, sd);
|
return write_sd (handle, file, sd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -256,7 +256,7 @@ int __stdcall set_file_attribute (bool, HANDLE, const char *, __uid32_t, __gid32
|
|||||||
int __stdcall get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, mode_t *,
|
int __stdcall get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, mode_t *,
|
||||||
__uid32_t * = NULL, __gid32_t * = NULL);
|
__uid32_t * = NULL, __gid32_t * = NULL);
|
||||||
LONG __stdcall read_sd (const char *file, security_descriptor &sd);
|
LONG __stdcall read_sd (const char *file, security_descriptor &sd);
|
||||||
LONG __stdcall write_sd (const char *file, security_descriptor &sd);
|
LONG __stdcall write_sd (HANDLE fh, const char *file, security_descriptor &sd);
|
||||||
bool __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
|
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);
|
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 (const char *, int);
|
int __stdcall check_file_access (const char *, int);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user