* autoload.cc (NtCreateFile): Add.
* dir.cc (mkdir): Change set_file_attribute call to indicate that NT security isn't used. * fhandler.cc (fhandler_base::open_9x): New method, created from fhandler_base::open. (fhandler_base::open): Rearrange to use NtCreateFile instead of CreateFile. * fhandler.h (enum query_state): Redefine query_null_access to query_stat_control. query_null_access isn't allowed in NtCreateFile. (fhandler_base::open_9x): Declare. * fhandler_disk_file.cc (fhandler_base::fstat_fs): Use query_stat_control first, query_read_control if that fails. (fhandler_disk_file::fchmod): Call enable_restore_privilege before trying to open for query_write_control. Don't fall back to opening for query_read_control. (fhandler_disk_file::fchown): Ditto. (fhandler_disk_file::facl): Only request restore privilege and query access necessary for given cmd. * fhandler_raw.cc (fhandler_dev_raw::open): Call fhandler_base::open instead of opening device here. * ntdll.h (NtCreateFile): Declare. * path.cc (symlink_worker): Change set_file_attribute call to indicate that NT security isn't used. * sec_acl.cc (getacl): Fix bracketing. * sec_helper.cc (enable_restore_privilege): New function. * security.cc (str2buf2uni_cat): New function. (write_sd): Don't request restore permission here. * security.h (set_process_privileges): Drop stale declaration. (str2buf2uni): Declare. (str2buf2uni_cat): Declare. (enable_restore_privilege): Declare. * syscalls.cc (fchown32): Return immediate success on 9x.
This commit is contained in:
parent
e2c248c18b
commit
e859706578
|
@ -1,3 +1,38 @@
|
|||
2004-04-16 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* autoload.cc (NtCreateFile): Add.
|
||||
* dir.cc (mkdir): Change set_file_attribute call to indicate that
|
||||
NT security isn't used.
|
||||
* fhandler.cc (fhandler_base::open_9x): New method, created from
|
||||
fhandler_base::open.
|
||||
(fhandler_base::open): Rearrange to use NtCreateFile instead of
|
||||
CreateFile.
|
||||
* fhandler.h (enum query_state): Redefine query_null_access to
|
||||
query_stat_control. query_null_access isn't allowed in NtCreateFile.
|
||||
(fhandler_base::open_9x): Declare.
|
||||
* fhandler_disk_file.cc (fhandler_base::fstat_fs): Use
|
||||
query_stat_control first, query_read_control if that fails.
|
||||
(fhandler_disk_file::fchmod): Call enable_restore_privilege before
|
||||
trying to open for query_write_control. Don't fall back to
|
||||
opening for query_read_control.
|
||||
(fhandler_disk_file::fchown): Ditto.
|
||||
(fhandler_disk_file::facl): Only request restore privilege and query
|
||||
access necessary for given cmd.
|
||||
* fhandler_raw.cc (fhandler_dev_raw::open): Call fhandler_base::open
|
||||
instead of opening device here.
|
||||
* ntdll.h (NtCreateFile): Declare.
|
||||
* path.cc (symlink_worker): Change set_file_attribute call to indicate
|
||||
that NT security isn't used.
|
||||
* sec_acl.cc (getacl): Fix bracketing.
|
||||
* sec_helper.cc (enable_restore_privilege): New function.
|
||||
* security.cc (str2buf2uni_cat): New function.
|
||||
(write_sd): Don't request restore permission here.
|
||||
* security.h (set_process_privileges): Drop stale declaration.
|
||||
(str2buf2uni): Declare.
|
||||
(str2buf2uni_cat): Declare.
|
||||
(enable_restore_privilege): Declare.
|
||||
* syscalls.cc (fchown32): Return immediate success on 9x.
|
||||
|
||||
2004-04-15 Christopher Faylor <cgf@alum.bu.edu>
|
||||
|
||||
* autoload.cc (dll_chain1): Rename to dll_chain. Remove old dll_chain
|
||||
|
|
|
@ -375,6 +375,7 @@ LoadDLLfunc (NetUserGetGroups, 28, netapi32)
|
|||
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
|
||||
LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32)
|
||||
|
||||
LoadDLLfuncEx (NtCreateFile, 44, ntdll, 1)
|
||||
LoadDLLfuncEx (NtCreateToken, 52, ntdll, 1)
|
||||
LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
|
||||
LoadDLLfuncEx (NtOpenFile, 24, ntdll, 1)
|
||||
|
|
|
@ -284,7 +284,7 @@ mkdir (const char *dir, mode_t mode)
|
|||
if (CreateDirectoryA (real_dir.get_win32 (), &sa))
|
||||
{
|
||||
if (!allow_ntsec && allow_ntea)
|
||||
set_file_attribute (real_dir.has_acls (), NULL, real_dir.get_win32 (),
|
||||
set_file_attribute (false, NULL, real_dir.get_win32 (),
|
||||
S_IFDIR | ((mode & 07777) & ~cygheap->umask));
|
||||
#ifdef HIDDEN_DOT_FILES
|
||||
char *c = strrchr (real_dir.get_win32 (), '\\');
|
||||
|
|
|
@ -28,6 +28,8 @@ details. */
|
|||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <winioctl.h>
|
||||
#include <ntdef.h>
|
||||
#include "ntdll.h"
|
||||
|
||||
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
||||
|
||||
|
@ -425,7 +427,7 @@ done:
|
|||
|
||||
/* Open system call handler function. */
|
||||
int
|
||||
fhandler_base::open (int flags, mode_t mode)
|
||||
fhandler_base::open_9x (int flags, mode_t mode)
|
||||
{
|
||||
int res = 0;
|
||||
HANDLE x;
|
||||
|
@ -435,7 +437,7 @@ fhandler_base::open (int flags, mode_t mode)
|
|||
SECURITY_ATTRIBUTES sa = sec_none;
|
||||
security_descriptor sd;
|
||||
|
||||
syscall_printf ("(%s, %p) query_open %d", get_win32_name (), flags, query_open ());
|
||||
syscall_printf ("(%s, %p)", get_win32_name (), flags);
|
||||
|
||||
if (get_win32_name () == NULL)
|
||||
{
|
||||
|
@ -443,34 +445,12 @@ fhandler_base::open (int flags, mode_t mode)
|
|||
goto done;
|
||||
}
|
||||
|
||||
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;
|
||||
default:
|
||||
if (get_major () == DEV_TAPE_MAJOR)
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
|
||||
access = GENERIC_READ;
|
||||
else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY)
|
||||
access = GENERIC_WRITE;
|
||||
else
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Allow reliable lseek on disk devices. */
|
||||
if (get_major () == DEV_FLOPPY_MAJOR)
|
||||
access |= GENERIC_READ;
|
||||
|
||||
/* FIXME: O_EXCL handling? */
|
||||
if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
|
||||
access = GENERIC_READ;
|
||||
else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY)
|
||||
access = GENERIC_WRITE;
|
||||
else
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
|
||||
if ((flags & O_TRUNC) && ((flags & O_ACCMODE) != O_RDONLY))
|
||||
{
|
||||
|
@ -508,16 +488,6 @@ fhandler_base::open (int flags, mode_t mode)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* CreateFile() with dwDesiredAccess == 0 when called on remote
|
||||
share returns some handle, even if file doesn't exist. This code
|
||||
works around this bug. */
|
||||
if (query_open () && isremote () &&
|
||||
creation_distribution == OPEN_EXISTING && !pc.exists ())
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If mode has no write bits set, we set the R/O attribute. */
|
||||
if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
|
||||
file_attributes |= FILE_ATTRIBUTE_READONLY;
|
||||
|
@ -564,6 +534,162 @@ done:
|
|||
return res;
|
||||
}
|
||||
|
||||
/* Open system call handler function. */
|
||||
int
|
||||
fhandler_base::open (int flags, mode_t mode)
|
||||
{
|
||||
if (!wincap.is_winnt ())
|
||||
return fhandler_base::open_9x (flags, mode);
|
||||
|
||||
int res = 0;
|
||||
HANDLE x;
|
||||
ULONG file_attributes = 0;
|
||||
ULONG shared = wincap.shared ();
|
||||
ULONG create_disposition;
|
||||
ULONG create_options;
|
||||
SECURITY_ATTRIBUTES sa = sec_none;
|
||||
security_descriptor sd;
|
||||
UNICODE_STRING upath;
|
||||
WCHAR wpath[CYG_MAX_PATH + 10];
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
|
||||
syscall_printf ("(%s, %p)", get_win32_name (), flags);
|
||||
if (get_win32_name () == NULL)
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
goto done;
|
||||
}
|
||||
if (get_win32_name ()[0] == '\\')
|
||||
{
|
||||
if (get_win32_name ()[1] == '\\')
|
||||
{
|
||||
str2buf2uni (upath, wpath, "\\??\\UNC");
|
||||
str2buf2uni_cat (upath, get_win32_name () + 1);
|
||||
}
|
||||
else
|
||||
str2buf2uni (upath, wpath, get_win32_name ());
|
||||
}
|
||||
else
|
||||
{
|
||||
str2buf2uni (upath, wpath, "\\??\\");
|
||||
str2buf2uni_cat (upath, get_win32_name ());
|
||||
}
|
||||
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
|
||||
sa.lpSecurityDescriptor, NULL);
|
||||
|
||||
switch (query_open ())
|
||||
{
|
||||
case query_read_control:
|
||||
access = READ_CONTROL;
|
||||
create_options = FILE_OPEN_FOR_BACKUP_INTENT;
|
||||
break;
|
||||
case query_stat_control:
|
||||
access = READ_CONTROL | FILE_READ_ATTRIBUTES;
|
||||
create_options = FILE_OPEN_FOR_BACKUP_INTENT;
|
||||
break;
|
||||
case query_write_control:
|
||||
access = READ_CONTROL | WRITE_OWNER | WRITE_DAC;
|
||||
create_options = FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_FOR_RECOVERY;
|
||||
break;
|
||||
default:
|
||||
create_options = 0;
|
||||
if (get_major () == DEV_TAPE_MAJOR && (flags & O_TEXT))
|
||||
{
|
||||
/* O_TEXT is used to indicate write-through on tape devices */
|
||||
create_options |= FILE_WRITE_THROUGH;
|
||||
flags &= ~O_TEXT;
|
||||
}
|
||||
if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
|
||||
access = GENERIC_READ;
|
||||
else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY)
|
||||
access = GENERIC_WRITE;
|
||||
else
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
/* Allow reliable lseek on disk devices. */
|
||||
if (get_major () == DEV_FLOPPY_MAJOR)
|
||||
access |= GENERIC_READ;
|
||||
else if (get_major () != DEV_SERIAL_MAJOR)
|
||||
{
|
||||
create_options |= FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
access |= SYNCHRONIZE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ((flags & O_TRUNC) && ((flags & O_ACCMODE) != O_RDONLY))
|
||||
{
|
||||
if (flags & O_CREAT)
|
||||
create_disposition = FILE_SUPERSEDE;
|
||||
else
|
||||
create_disposition = FILE_OVERWRITE;
|
||||
}
|
||||
else if (flags & O_CREAT)
|
||||
create_disposition = FILE_OPEN_IF;
|
||||
else
|
||||
create_disposition = FILE_OPEN;
|
||||
|
||||
if ((flags & O_EXCL) && (flags & O_CREAT))
|
||||
create_disposition = FILE_CREATE;
|
||||
|
||||
if (flags & O_APPEND)
|
||||
append_mode (true);
|
||||
|
||||
if (flags & O_CREAT && get_device () == FH_FS)
|
||||
{
|
||||
file_attributes = FILE_ATTRIBUTE_NORMAL;
|
||||
/* If mode has no write bits set, we set the R/O attribute. */
|
||||
if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
|
||||
file_attributes |= FILE_ATTRIBUTE_READONLY;
|
||||
#ifdef HIDDEN_DOT_FILES
|
||||
char *c = strrchr (get_win32_name (), '\\');
|
||||
if ((c && c[1] == '.') || *get_win32_name () == '.')
|
||||
file_attributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||
#endif
|
||||
/* If the file should actually be created and ntsec is on,
|
||||
set files attributes. */
|
||||
if (allow_ntsec && has_acls ())
|
||||
{
|
||||
set_security_attribute (mode, &sa, sd);
|
||||
attr.SecurityDescriptor = sa.lpSecurityDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
status = NtCreateFile (&x, access, &attr, &io, NULL, file_attributes, shared,
|
||||
create_disposition, create_options, NULL, 0);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
if (!wincap.can_open_directories () && pc.isdir ())
|
||||
{
|
||||
if (flags & (O_CREAT | O_EXCL) == (O_CREAT | O_EXCL))
|
||||
set_errno (EEXIST);
|
||||
else if (flags & (O_WRONLY | O_RDWR))
|
||||
set_errno (EISDIR);
|
||||
else
|
||||
nohandle (true);
|
||||
}
|
||||
__seterrno_from_win_error (RtlNtStatusToDosError (status));
|
||||
if (!nohandle ())
|
||||
goto done;
|
||||
}
|
||||
|
||||
syscall_printf ("%x = NtCreateFile "
|
||||
"(%p, %x, %s, io, NULL, %x, %x, %x, %x, NULL, 0)",
|
||||
status, x, access, get_win32_name (), file_attributes, shared,
|
||||
create_disposition, create_options);
|
||||
|
||||
set_io_handle (x);
|
||||
set_flags (flags, pc.binmode ());
|
||||
|
||||
res = 1;
|
||||
set_open_status ();
|
||||
done:
|
||||
syscall_printf ("%d = fhandler_base::open (%s, %p)", res, get_win32_name (),
|
||||
flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* states:
|
||||
open buffer in binary mode? Just do the read.
|
||||
|
||||
|
|
|
@ -63,8 +63,8 @@ enum bg_check_types
|
|||
|
||||
enum query_state {
|
||||
no_query = 0,
|
||||
query_null_access = 1,
|
||||
query_read_control = 2,
|
||||
query_read_control = 1,
|
||||
query_stat_control = 2,
|
||||
query_write_control = 3
|
||||
};
|
||||
|
||||
|
@ -226,6 +226,7 @@ class fhandler_base
|
|||
void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
|
||||
virtual bool need_fixup_before () const {return false;}
|
||||
|
||||
int open_9x (int flags, mode_t mode = 0);
|
||||
virtual int open (int flags, mode_t mode = 0);
|
||||
int open_fs (int flags, mode_t mode = 0);
|
||||
virtual int close ();
|
||||
|
|
|
@ -174,16 +174,16 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
|
|||
then just do a "query open" as it is apparently much faster. */
|
||||
if (pc.exec_state () != dont_know_if_executable)
|
||||
{
|
||||
query_open (query_read_control);
|
||||
if (pc.fs_is_fat () && !strpbrk (get_win32_name (), "?*|<>"))
|
||||
return fstat_by_name (buf);
|
||||
query_open (query_stat_control);
|
||||
}
|
||||
if (!(oret = open_fs (open_flags, 0)) && get_errno () == EACCES)
|
||||
{
|
||||
/* If we couldn't open the file, try a query open with no permissions.
|
||||
This allows us to determine *some* things about the file, at least. */
|
||||
pc.set_exec (0);
|
||||
query_open (query_null_access);
|
||||
query_open (query_read_control);
|
||||
oret = open_fs (open_flags, 0);
|
||||
}
|
||||
|
||||
|
@ -378,15 +378,15 @@ fhandler_disk_file::fchmod (mode_t mode)
|
|||
if (pc.is_fs_special ())
|
||||
return chmod_device (pc, mode);
|
||||
|
||||
if (!get_io_handle ())
|
||||
if (wincap.has_security ())
|
||||
{
|
||||
query_open (query_write_control);
|
||||
if (!(oret = open_fs (O_BINARY, 0)))
|
||||
{
|
||||
query_open (query_read_control);
|
||||
enable_restore_privilege ();
|
||||
if (!get_io_handle ())
|
||||
{
|
||||
query_open (query_write_control);
|
||||
if (!(oret = open_fs (O_BINARY, 0)))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!allow_ntsec && allow_ntea) /* Not necessary when manipulating SD. */
|
||||
|
@ -423,15 +423,13 @@ int __stdcall
|
|||
fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
|
||||
{
|
||||
int oret = 0;
|
||||
|
||||
enable_restore_privilege ();
|
||||
if (!get_io_handle ())
|
||||
{
|
||||
query_open (query_write_control);
|
||||
if (!(oret = open_fs (O_BINARY, 0)))
|
||||
{
|
||||
query_open (query_read_control);
|
||||
if (!(oret = open_fs (O_BINARY, 0)))
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
mode_t attrib = 0;
|
||||
|
@ -460,17 +458,6 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
|||
int res = -1;
|
||||
int oret = 0;
|
||||
|
||||
if (!get_io_handle ())
|
||||
{
|
||||
query_open (query_write_control);
|
||||
if (!(oret = open_fs (O_BINARY, 0)))
|
||||
{
|
||||
query_open (query_read_control);
|
||||
if (!(oret = open_fs (O_BINARY, 0)))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pc.has_acls () || !allow_ntsec)
|
||||
{
|
||||
switch (cmd)
|
||||
|
@ -485,30 +472,50 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
|||
set_errno(EFAULT);
|
||||
else if (nentries < MIN_ACL_ENTRIES)
|
||||
set_errno (ENOSPC);
|
||||
else if (!fstat_by_handle (&st))
|
||||
else
|
||||
{
|
||||
aclbufp[0].a_type = USER_OBJ;
|
||||
aclbufp[0].a_id = st.st_uid;
|
||||
aclbufp[0].a_perm = (st.st_mode & S_IRWXU) >> 6;
|
||||
aclbufp[1].a_type = GROUP_OBJ;
|
||||
aclbufp[1].a_id = st.st_gid;
|
||||
aclbufp[1].a_perm = (st.st_mode & S_IRWXG) >> 3;
|
||||
aclbufp[2].a_type = OTHER_OBJ;
|
||||
aclbufp[2].a_id = ILLEGAL_GID;
|
||||
aclbufp[2].a_perm = st.st_mode & S_IRWXO;
|
||||
aclbufp[3].a_type = CLASS_OBJ;
|
||||
aclbufp[3].a_id = ILLEGAL_GID;
|
||||
aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
res = MIN_ACL_ENTRIES;
|
||||
if (!get_io_handle ())
|
||||
{
|
||||
query_open (query_read_control);
|
||||
if (!(oret = open_fs (O_BINARY, 0)))
|
||||
return -1;
|
||||
}
|
||||
if (!fstat_by_handle (&st))
|
||||
{
|
||||
aclbufp[0].a_type = USER_OBJ;
|
||||
aclbufp[0].a_id = st.st_uid;
|
||||
aclbufp[0].a_perm = (st.st_mode & S_IRWXU) >> 6;
|
||||
aclbufp[1].a_type = GROUP_OBJ;
|
||||
aclbufp[1].a_id = st.st_gid;
|
||||
aclbufp[1].a_perm = (st.st_mode & S_IRWXG) >> 3;
|
||||
aclbufp[2].a_type = OTHER_OBJ;
|
||||
aclbufp[2].a_id = ILLEGAL_GID;
|
||||
aclbufp[2].a_perm = st.st_mode & S_IRWXO;
|
||||
aclbufp[3].a_type = CLASS_OBJ;
|
||||
aclbufp[3].a_id = ILLEGAL_GID;
|
||||
aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
res = MIN_ACL_ENTRIES;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GETACLCNT:
|
||||
res = MIN_ACL_ENTRIES;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cmd == SETACL)
|
||||
enable_restore_privilege ();
|
||||
if (!get_io_handle ())
|
||||
{
|
||||
query_open (cmd == SETACL ? query_write_control : query_read_control);
|
||||
if (!(oret = open_fs (O_BINARY, 0)))
|
||||
return -1;
|
||||
}
|
||||
switch (cmd)
|
||||
{
|
||||
case SETACL:
|
||||
|
|
|
@ -144,41 +144,16 @@ fhandler_dev_raw::open (int flags, mode_t)
|
|||
flags &= ~(O_CREAT | O_TRUNC);
|
||||
flags |= O_BINARY;
|
||||
|
||||
DWORD access = GENERIC_READ | SYNCHRONIZE;
|
||||
if (get_major () == DEV_TAPE_MAJOR
|
||||
|| (flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY
|
||||
|| (flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDWR)
|
||||
access |= GENERIC_WRITE;
|
||||
flags = ((flags & ~(O_WRONLY | O_RDWR)) | O_RDWR);
|
||||
|
||||
extern void str2buf2uni (UNICODE_STRING &, WCHAR *, const char *);
|
||||
UNICODE_STRING dev;
|
||||
WCHAR devname[CYG_MAX_PATH + 1];
|
||||
str2buf2uni (dev, devname, get_win32_name ());
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
ULONG options = FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
/* The O_TEXT flag is used to indicate write-through on tape devices */
|
||||
if (get_major () == DEV_TAPE_MAJOR && (flags & O_TEXT))
|
||||
options |= FILE_WRITE_THROUGH;
|
||||
flags &= ~O_TEXT;
|
||||
InitializeObjectAttributes (&attr, &dev, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
HANDLE h;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status = NtOpenFile (&h, access, &attr, &io, 0 /* excl. access */,
|
||||
options);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_win_error (RtlNtStatusToDosError (status));
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_io_handle (h);
|
||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||
|
||||
if (devbufsiz > 1L)
|
||||
int res = fhandler_base::open (flags, 0);
|
||||
if (res && devbufsiz > 1L)
|
||||
devbuf = new char [devbufsiz];
|
||||
|
||||
return 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -389,6 +389,9 @@ typedef struct _OBJECT_NAME_INFORMATION
|
|||
standard Win32 header. */
|
||||
extern "C"
|
||||
{
|
||||
NTSTATUS NTAPI NtCreateFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||
PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG,
|
||||
ULONG, ULONG, PVOID, ULONG);
|
||||
NTSTATUS NTAPI NtCreateToken (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||
TOKEN_TYPE, PLUID, PLARGE_INTEGER, PTOKEN_USER,
|
||||
PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER,
|
||||
|
|
|
@ -2648,8 +2648,7 @@ symlink_worker (const char *topath, const char *frompath, bool use_winsym,
|
|||
{
|
||||
CloseHandle (h);
|
||||
if (!allow_ntsec && allow_ntea)
|
||||
set_file_attribute (win32_path.has_acls (), NULL,
|
||||
win32_path.get_win32 (),
|
||||
set_file_attribute (false, NULL, win32_path.get_win32 (),
|
||||
S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
|
||||
DWORD attr = use_winsym ? FILE_ATTRIBUTE_READONLY
|
||||
|
|
|
@ -261,7 +261,7 @@ getacl (HANDLE handle, const char *file, DWORD attr, int nentries,
|
|||
{
|
||||
security_descriptor sd;
|
||||
|
||||
if (!handle || get_nt_object_security (handle, SE_FILE_OBJECT, sd)
|
||||
if ((!handle || get_nt_object_security (handle, SE_FILE_OBJECT, sd))
|
||||
&& read_sd (file, sd) <= 0)
|
||||
{
|
||||
debug_printf ("read_sd %E");
|
||||
|
|
|
@ -375,6 +375,20 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Helper function to set the SE_RESTORE_NAME privilege once. */
|
||||
void
|
||||
enable_restore_privilege ()
|
||||
{
|
||||
static int NO_COPY saved_res;
|
||||
bool issetuid = cygheap->user.issetuid ();
|
||||
if (!saved_res || issetuid)
|
||||
{
|
||||
int res = 2 + set_process_privilege (SE_RESTORE_NAME, true, issetuid);
|
||||
if (!issetuid)
|
||||
saved_res = res;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to return a common SECURITY_DESCRIPTOR * that
|
||||
* allows all access.
|
||||
|
|
|
@ -165,6 +165,16 @@ str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr)
|
|||
sys_mbstowcs (buf, srcstr, tgt.MaximumLength);
|
||||
}
|
||||
|
||||
void
|
||||
str2buf2uni_cat (UNICODE_STRING &tgt, const char *srcstr)
|
||||
{
|
||||
DWORD len = strlen (srcstr) * sizeof (WCHAR);
|
||||
sys_mbstowcs (tgt.Buffer + tgt.Length / sizeof (WCHAR), srcstr,
|
||||
len + tgt.MaximumLength);
|
||||
tgt.Length += len;
|
||||
tgt.MaximumLength += len;
|
||||
}
|
||||
|
||||
#if 0 /* unused */
|
||||
static void
|
||||
lsa2wchar (WCHAR *tgt, LSA_UNICODE_STRING &src, int size)
|
||||
|
@ -1119,38 +1129,9 @@ read_sd (const char *file, security_descriptor &sd)
|
|||
LONG
|
||||
write_sd (HANDLE fh, const char *file, security_descriptor &sd)
|
||||
{
|
||||
/* 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 */
|
||||
int res;
|
||||
if (!saved_res || cygheap->user.issetuid ())
|
||||
{
|
||||
res = 2 + set_process_privilege (SE_RESTORE_NAME, true,
|
||||
cygheap->user.issetuid ());
|
||||
if (!cygheap->user.issetuid ())
|
||||
saved_res = res;
|
||||
}
|
||||
else
|
||||
res = saved_res;
|
||||
if (res == 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 = STATUS_SUCCESS;
|
||||
int retry = 0;
|
||||
res = -1;
|
||||
int res = -1;
|
||||
for (; retry < 2; ++retry)
|
||||
{
|
||||
if (retry && (fh = CreateFile (file, WRITE_OWNER | WRITE_DAC,
|
||||
|
|
|
@ -248,7 +248,6 @@ extern bool allow_ntsec;
|
|||
extern bool allow_smbntsec;
|
||||
|
||||
/* File manipulation */
|
||||
int __stdcall set_process_privileges ();
|
||||
int __stdcall get_file_attribute (int, HANDLE, const char *, mode_t *,
|
||||
__uid32_t * = NULL, __gid32_t * = NULL);
|
||||
int __stdcall set_file_attribute (bool, HANDLE, const char *, int);
|
||||
|
@ -275,6 +274,10 @@ extern "C" int acl32 (const char *, int, int, __acl32 *);
|
|||
int getacl (HANDLE, const char *, DWORD, int, __acl32 *);
|
||||
int setacl (HANDLE, const char *, int, __acl32 *);
|
||||
|
||||
struct _UNICODE_STRING;
|
||||
void __stdcall str2buf2uni (_UNICODE_STRING &, WCHAR *, const char *) __attribute__ ((regparm (3)));
|
||||
void __stdcall str2buf2uni_cat (_UNICODE_STRING &, const char *) __attribute__ ((regparm (2)));
|
||||
|
||||
/* Try a subauthentication. */
|
||||
HANDLE subauth (struct passwd *pw);
|
||||
/* Try creating a token directly. */
|
||||
|
@ -289,6 +292,7 @@ bool get_logon_server (const char * domain, char * server, WCHAR *wserver = NULL
|
|||
|
||||
/* sec_helper.cc: Security helper functions. */
|
||||
int set_process_privilege (const char *privilege, bool enable = true, bool use_thread = false);
|
||||
void enable_restore_privilege (void);
|
||||
|
||||
/* shared.cc: */
|
||||
/* Retrieve a security descriptor that allows all access */
|
||||
|
|
|
@ -872,6 +872,9 @@ lchown (const char * name, __uid16_t uid, __gid16_t gid)
|
|||
extern "C" int
|
||||
fchown32 (int fd, __uid32_t uid, __gid32_t gid)
|
||||
{
|
||||
if (!wincap.has_security ()) // real chown only works on NT
|
||||
return 0; // return zero (and do nothing) under Windows 9x
|
||||
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue