2001-11-21 14:47:57 +08:00
|
|
|
/* fhandler_disk_file.cc
|
|
|
|
|
|
|
|
This file is part of Cygwin.
|
|
|
|
|
|
|
|
This software is a copyrighted work licensed under the terms of the
|
|
|
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
|
|
details. */
|
|
|
|
|
|
|
|
#include "winsup.h"
|
2014-02-10 03:44:56 +08:00
|
|
|
#include <winioctl.h>
|
|
|
|
#include <lm.h>
|
2001-11-21 14:47:57 +08:00
|
|
|
#include <stdlib.h>
|
2016-01-07 01:41:36 +08:00
|
|
|
#include <cygwin/acl.h>
|
2007-02-27 20:58:56 +08:00
|
|
|
#include <sys/statvfs.h>
|
2001-11-21 14:47:57 +08:00
|
|
|
#include "cygerrno.h"
|
|
|
|
#include "security.h"
|
|
|
|
#include "path.h"
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
#include "fhandler.h"
|
2001-11-21 14:47:57 +08:00
|
|
|
#include "dtable.h"
|
|
|
|
#include "cygheap.h"
|
|
|
|
#include "shared_info.h"
|
|
|
|
#include "pinfo.h"
|
2004-04-06 18:19:31 +08:00
|
|
|
#include "ntdll.h"
|
2008-04-14 00:47:21 +08:00
|
|
|
#include "tls_pbuf.h"
|
2012-03-30 02:02:54 +08:00
|
|
|
#include "devices.h"
|
2014-02-10 03:44:56 +08:00
|
|
|
#include "ldap.h"
|
2018-07-24 13:31:58 +08:00
|
|
|
#include <aio.h>
|
2023-11-26 19:50:38 +08:00
|
|
|
#include <fcntl.h>
|
2018-12-26 06:38:52 +08:00
|
|
|
#include <cygwin/fs.h>
|
2001-11-21 14:47:57 +08:00
|
|
|
|
2021-11-09 11:22:27 +08:00
|
|
|
#define _LIBC
|
2001-11-21 14:47:57 +08:00
|
|
|
#include <dirent.h>
|
|
|
|
|
2017-06-14 19:22:56 +08:00
|
|
|
enum __DIR_mount_type {
|
|
|
|
__DIR_mount_none = 0,
|
|
|
|
__DIR_mount_target,
|
|
|
|
__DIR_mount_virt_target
|
|
|
|
};
|
|
|
|
|
2006-03-02 06:37:25 +08:00
|
|
|
class __DIR_mounts
|
|
|
|
{
|
2007-07-27 01:30:54 +08:00
|
|
|
int count;
|
|
|
|
const char *parent_dir;
|
2022-08-05 05:48:19 +08:00
|
|
|
size_t parent_dir_len;
|
2007-07-27 01:30:54 +08:00
|
|
|
UNICODE_STRING mounts[MAX_MOUNTS];
|
2012-03-30 02:02:54 +08:00
|
|
|
bool found[MAX_MOUNTS + 3];
|
2007-07-27 01:30:54 +08:00
|
|
|
UNICODE_STRING cygdrive;
|
2006-03-02 06:37:25 +08:00
|
|
|
|
|
|
|
#define __DIR_PROC (MAX_MOUNTS)
|
|
|
|
#define __DIR_CYGDRIVE (MAX_MOUNTS+1)
|
2012-03-30 02:02:54 +08:00
|
|
|
#define __DIR_DEV (MAX_MOUNTS+2)
|
2006-03-02 06:37:25 +08:00
|
|
|
|
|
|
|
public:
|
|
|
|
__DIR_mounts (const char *posix_path)
|
|
|
|
: parent_dir (posix_path)
|
|
|
|
{
|
|
|
|
parent_dir_len = strlen (parent_dir);
|
2007-07-27 01:30:54 +08:00
|
|
|
count = mount_table->get_mounts_here (parent_dir, parent_dir_len, mounts,
|
|
|
|
&cygdrive);
|
2006-03-02 06:37:25 +08:00
|
|
|
rewind ();
|
|
|
|
}
|
2007-07-27 01:30:54 +08:00
|
|
|
~__DIR_mounts ()
|
|
|
|
{
|
2022-08-05 05:48:19 +08:00
|
|
|
mount_table->free_mounts_here (mounts, count, &cygdrive);
|
2007-07-27 01:30:54 +08:00
|
|
|
}
|
2017-06-14 19:22:56 +08:00
|
|
|
/* For an entry within this dir, check if a mount point exists. */
|
|
|
|
bool check_mount (PUNICODE_STRING fname)
|
2006-03-02 06:37:25 +08:00
|
|
|
{
|
|
|
|
if (parent_dir_len == 1) /* root dir */
|
2006-05-28 23:50:14 +08:00
|
|
|
{
|
2009-07-15 01:37:42 +08:00
|
|
|
if (RtlEqualUnicodeString (fname, &ro_u_proc, FALSE))
|
2006-03-02 06:37:25 +08:00
|
|
|
{
|
|
|
|
found[__DIR_PROC] = true;
|
2017-06-14 19:22:56 +08:00
|
|
|
return true;
|
2006-03-02 06:37:25 +08:00
|
|
|
}
|
2012-03-30 02:02:54 +08:00
|
|
|
if (RtlEqualUnicodeString (fname, &ro_u_dev, FALSE))
|
|
|
|
{
|
|
|
|
found[__DIR_DEV] = true;
|
2017-06-14 19:22:56 +08:00
|
|
|
return true;
|
2012-03-30 02:02:54 +08:00
|
|
|
}
|
2007-07-27 01:30:54 +08:00
|
|
|
if (fname->Length / sizeof (WCHAR) == mount_table->cygdrive_len - 2
|
2008-07-17 04:20:45 +08:00
|
|
|
&& RtlEqualUnicodeString (fname, &cygdrive, FALSE))
|
2006-03-02 06:37:25 +08:00
|
|
|
{
|
|
|
|
found[__DIR_CYGDRIVE] = true;
|
2017-06-14 19:22:56 +08:00
|
|
|
return true;
|
2006-03-02 06:37:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < count; ++i)
|
2008-07-17 04:20:45 +08:00
|
|
|
if (RtlEqualUnicodeString (fname, &mounts[i], FALSE))
|
2006-03-02 06:37:25 +08:00
|
|
|
{
|
|
|
|
found[i] = true;
|
2017-06-14 19:22:56 +08:00
|
|
|
return true;
|
2006-03-02 06:37:25 +08:00
|
|
|
}
|
2017-06-14 19:22:56 +08:00
|
|
|
return false;
|
2006-03-02 06:37:25 +08:00
|
|
|
}
|
2017-06-14 19:22:56 +08:00
|
|
|
/* On each call, add another mount point within this directory, which is
|
|
|
|
not backed by a real subdir. */
|
|
|
|
__DIR_mount_type check_missing_mount (PUNICODE_STRING retname = NULL)
|
2006-03-02 06:37:25 +08:00
|
|
|
{
|
|
|
|
for (int i = 0; i < count; ++i)
|
2006-05-28 23:50:14 +08:00
|
|
|
if (!found[i])
|
2006-03-02 06:37:25 +08:00
|
|
|
{
|
|
|
|
found[i] = true;
|
2007-07-27 01:30:54 +08:00
|
|
|
if (retname)
|
2017-06-14 19:22:56 +08:00
|
|
|
*retname = mounts[i];
|
|
|
|
return __DIR_mount_target;
|
2006-03-02 06:37:25 +08:00
|
|
|
}
|
|
|
|
if (parent_dir_len == 1) /* root dir */
|
2006-05-28 23:50:14 +08:00
|
|
|
{
|
2006-03-02 06:37:25 +08:00
|
|
|
if (!found[__DIR_PROC])
|
|
|
|
{
|
|
|
|
found[__DIR_PROC] = true;
|
2007-07-27 01:30:54 +08:00
|
|
|
if (retname)
|
2010-09-06 17:47:01 +08:00
|
|
|
*retname = ro_u_proc;
|
2017-06-14 19:22:56 +08:00
|
|
|
return __DIR_mount_virt_target;
|
2006-03-02 06:37:25 +08:00
|
|
|
}
|
2012-03-30 02:02:54 +08:00
|
|
|
if (!found[__DIR_DEV])
|
|
|
|
{
|
|
|
|
found[__DIR_DEV] = true;
|
|
|
|
if (retname)
|
|
|
|
*retname = ro_u_dev;
|
2017-06-14 19:22:56 +08:00
|
|
|
return __DIR_mount_virt_target;
|
2012-03-30 02:02:54 +08:00
|
|
|
}
|
2006-03-02 06:37:25 +08:00
|
|
|
if (!found[__DIR_CYGDRIVE])
|
|
|
|
{
|
|
|
|
found[__DIR_CYGDRIVE] = true;
|
2007-07-27 01:30:54 +08:00
|
|
|
if (cygdrive.Length > 0)
|
2006-05-28 23:50:14 +08:00
|
|
|
{
|
2007-07-27 01:30:54 +08:00
|
|
|
if (retname)
|
|
|
|
*retname = cygdrive;
|
2017-06-14 19:22:56 +08:00
|
|
|
return __DIR_mount_virt_target;
|
2006-03-02 17:48:42 +08:00
|
|
|
}
|
2006-03-02 06:37:25 +08:00
|
|
|
}
|
|
|
|
}
|
2017-06-14 19:22:56 +08:00
|
|
|
return __DIR_mount_none;
|
2006-03-02 06:37:25 +08:00
|
|
|
}
|
|
|
|
void rewind () { memset (found, 0, sizeof found); }
|
|
|
|
};
|
|
|
|
|
2009-03-13 06:03:28 +08:00
|
|
|
inline bool
|
2013-04-23 17:44:36 +08:00
|
|
|
path_conv::isgood_inode (ino_t ino) const
|
2009-03-13 06:03:28 +08:00
|
|
|
{
|
2012-05-21 20:00:09 +08:00
|
|
|
/* If the FS doesn't support nonambiguous inode numbers anyway, bail out
|
|
|
|
immediately. */
|
|
|
|
if (!hasgood_inode ())
|
|
|
|
return false;
|
|
|
|
/* If the inode numbers are 64 bit numbers or if it's a local FS, they
|
|
|
|
are to be trusted. */
|
|
|
|
if (ino > UINT32_MAX || !isremote ())
|
|
|
|
return true;
|
|
|
|
/* The inode numbers returned from a remote NT4 NTFS are ephemeral
|
|
|
|
32 bit numbers. */
|
|
|
|
if (fs_is_ntfs ())
|
|
|
|
return false;
|
|
|
|
/* Starting with version 3.5.4, Samba returns the real inode numbers, if
|
|
|
|
the file is on the same device as the root of the share (Samba function
|
|
|
|
get_FileIndex). 32 bit inode numbers returned by older versions (likely
|
|
|
|
< 3.0) are ephemeral. */
|
|
|
|
if (fs_is_samba () && fs.samba_version () < 0x03050400)
|
|
|
|
return false;
|
|
|
|
/* Otherwise, trust the inode numbers unless proved otherwise. */
|
|
|
|
return true;
|
2009-03-13 06:03:28 +08:00
|
|
|
}
|
|
|
|
|
2017-07-24 23:33:20 +08:00
|
|
|
/* Check reparse point to determine if it should be treated as a
|
|
|
|
posix symlink or as a normal file/directory. Logic is explained
|
|
|
|
in detail in check_reparse_point_target in path.cc. */
|
2017-06-15 04:01:28 +08:00
|
|
|
static inline bool
|
|
|
|
readdir_check_reparse_point (POBJECT_ATTRIBUTES attr, bool remote)
|
2007-07-27 17:00:12 +08:00
|
|
|
{
|
2017-07-24 23:33:20 +08:00
|
|
|
NTSTATUS status;
|
2007-07-27 17:00:12 +08:00
|
|
|
HANDLE reph;
|
2017-07-24 23:33:20 +08:00
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
tmp_pathbuf tp;
|
|
|
|
UNICODE_STRING symbuf;
|
|
|
|
bool ret = false;
|
2007-07-27 17:00:12 +08:00
|
|
|
|
2017-07-24 23:33:20 +08:00
|
|
|
status = NtOpenFile (&reph, READ_CONTROL, attr, &io, FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
|
|
|
|
if (NT_SUCCESS (status))
|
2007-07-27 17:00:12 +08:00
|
|
|
{
|
2017-07-24 23:33:20 +08:00
|
|
|
PREPARSE_DATA_BUFFER rp = (PREPARSE_DATA_BUFFER) tp.c_get ();
|
|
|
|
ret = (check_reparse_point_target (reph, remote, rp, &symbuf) > 0);
|
2017-07-24 23:26:17 +08:00
|
|
|
NtClose (reph);
|
2007-07-27 17:00:12 +08:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-04-23 17:44:36 +08:00
|
|
|
inline ino_t
|
2010-06-15 16:51:55 +08:00
|
|
|
path_conv::get_ino_by_handle (HANDLE hdl)
|
2008-04-01 02:03:25 +08:00
|
|
|
{
|
|
|
|
IO_STATUS_BLOCK io;
|
2015-12-10 06:51:48 +08:00
|
|
|
FILE_INTERNAL_INFORMATION fii;
|
2008-04-01 02:03:25 +08:00
|
|
|
|
2015-12-10 06:51:48 +08:00
|
|
|
if (NT_SUCCESS (NtQueryInformationFile (hdl, &io, &fii, sizeof fii,
|
2009-03-13 06:03:28 +08:00
|
|
|
FileInternalInformation))
|
2015-12-10 06:51:48 +08:00
|
|
|
&& isgood_inode (fii.IndexNumber.QuadPart))
|
|
|
|
return fii.IndexNumber.QuadPart;
|
2008-04-01 02:03:25 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-05-20 23:11:23 +08:00
|
|
|
/* For files on NFS shares, we request an EA of type NfsV3Attributes.
|
|
|
|
This returns the content of a struct fattr3 as defined in RFC 1813.
|
|
|
|
The content is the NFS equivalent of struct stat. so there's not much
|
|
|
|
to do here except for copying. */
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2013-04-23 17:44:36 +08:00
|
|
|
fhandler_base::fstat_by_nfs_ea (struct stat *buf)
|
2008-05-20 23:11:23 +08:00
|
|
|
{
|
2010-09-30 21:52:34 +08:00
|
|
|
fattr3 *nfs_attr = pc.nfsattr ();
|
2014-02-10 03:44:56 +08:00
|
|
|
PWCHAR domain;
|
|
|
|
cyg_ldap cldap;
|
|
|
|
bool ldap_open = false;
|
2008-05-20 23:11:23 +08:00
|
|
|
|
2023-08-26 21:41:18 +08:00
|
|
|
/* NFS stumbles over its own caching. If you write to the file,
|
|
|
|
a subsequent fstat does not return the actual size of the file,
|
|
|
|
but the size at the time the handle has been opened. Unless
|
|
|
|
access through another handle invalidates the caching within the
|
|
|
|
NFS client. Skip this for Cygwin-created Symlinks playing FIFOs
|
|
|
|
(this sets the filler1 member to NF3FIFO). */
|
|
|
|
if (get_handle () && nfs_attr->filler1 != NF3FIFO)
|
2008-05-20 23:11:23 +08:00
|
|
|
{
|
2010-09-30 21:52:34 +08:00
|
|
|
if (get_access () & GENERIC_WRITE)
|
2019-03-30 15:12:02 +08:00
|
|
|
FlushFileBuffers (get_handle ());
|
|
|
|
pc.get_finfo (get_handle ());
|
2010-09-30 21:52:34 +08:00
|
|
|
}
|
|
|
|
buf->st_dev = nfs_attr->fsid;
|
|
|
|
buf->st_ino = nfs_attr->fileid;
|
|
|
|
buf->st_mode = (nfs_attr->mode & 0xfff)
|
|
|
|
| nfs_type_mapping[nfs_attr->type & 7];
|
|
|
|
buf->st_nlink = nfs_attr->nlink;
|
2015-08-18 02:24:49 +08:00
|
|
|
if (cygheap->pg.nss_pwd_db ())
|
2014-02-10 03:44:56 +08:00
|
|
|
{
|
2015-08-18 02:24:49 +08:00
|
|
|
/* Try to map UNIX uid/gid to Cygwin uid/gid. If there's no mapping in
|
|
|
|
the cache, try to fetch it from the configured RFC 2307 domain (see
|
|
|
|
last comment in cygheap_domain_info::init() for more information) and
|
|
|
|
add it to the mapping cache. */
|
|
|
|
buf->st_uid = cygheap->ugid_cache.get_uid (nfs_attr->uid);
|
|
|
|
if (buf->st_uid == ILLEGAL_UID)
|
|
|
|
{
|
|
|
|
uid_t map_uid = ILLEGAL_UID;
|
2014-02-10 03:44:56 +08:00
|
|
|
|
2015-08-18 02:24:49 +08:00
|
|
|
domain = cygheap->dom.get_rfc2307_domain ();
|
|
|
|
if ((ldap_open = (cldap.open (domain) == NO_ERROR)))
|
|
|
|
map_uid = cldap.remap_uid (nfs_attr->uid);
|
|
|
|
if (map_uid == ILLEGAL_UID)
|
|
|
|
map_uid = MAP_UNIX_TO_CYGWIN_ID (nfs_attr->uid);
|
|
|
|
cygheap->ugid_cache.add_uid (nfs_attr->uid, map_uid);
|
|
|
|
buf->st_uid = map_uid;
|
|
|
|
}
|
2014-02-10 03:44:56 +08:00
|
|
|
}
|
2015-08-18 02:24:49 +08:00
|
|
|
else /* fake files being owned by current user. */
|
|
|
|
buf->st_uid = myself->uid;
|
|
|
|
if (cygheap->pg.nss_grp_db ())
|
2014-02-10 03:44:56 +08:00
|
|
|
{
|
2015-08-18 02:24:49 +08:00
|
|
|
/* See above */
|
|
|
|
buf->st_gid = cygheap->ugid_cache.get_gid (nfs_attr->gid);
|
|
|
|
if (buf->st_gid == ILLEGAL_GID)
|
|
|
|
{
|
|
|
|
gid_t map_gid = ILLEGAL_GID;
|
2014-02-10 03:44:56 +08:00
|
|
|
|
2015-08-18 02:24:49 +08:00
|
|
|
domain = cygheap->dom.get_rfc2307_domain ();
|
|
|
|
if ((ldap_open || cldap.open (domain) == NO_ERROR))
|
|
|
|
map_gid = cldap.remap_gid (nfs_attr->gid);
|
|
|
|
if (map_gid == ILLEGAL_GID)
|
|
|
|
map_gid = MAP_UNIX_TO_CYGWIN_ID (nfs_attr->gid);
|
|
|
|
cygheap->ugid_cache.add_gid (nfs_attr->gid, map_gid);
|
|
|
|
buf->st_gid = map_gid;
|
|
|
|
}
|
2014-02-10 03:44:56 +08:00
|
|
|
}
|
2015-08-18 02:24:49 +08:00
|
|
|
else /* fake files being owned by current group. */
|
|
|
|
buf->st_gid = myself->gid;
|
2010-09-30 21:52:34 +08:00
|
|
|
buf->st_rdev = makedev (nfs_attr->rdev.specdata1,
|
|
|
|
nfs_attr->rdev.specdata2);
|
|
|
|
buf->st_size = nfs_attr->size;
|
|
|
|
buf->st_blksize = PREFERRED_IO_BLKSIZE;
|
2011-01-26 18:55:13 +08:00
|
|
|
buf->st_blocks = (nfs_attr->used + S_BLKSIZE - 1) / S_BLKSIZE;
|
2013-04-23 17:44:36 +08:00
|
|
|
buf->st_atim.tv_sec = nfs_attr->atime.tv_sec;
|
|
|
|
buf->st_atim.tv_nsec = nfs_attr->atime.tv_nsec;
|
|
|
|
buf->st_mtim.tv_sec = nfs_attr->mtime.tv_sec;
|
|
|
|
buf->st_mtim.tv_nsec = nfs_attr->mtime.tv_nsec;
|
|
|
|
buf->st_ctim.tv_sec = nfs_attr->ctime.tv_sec;
|
|
|
|
buf->st_ctim.tv_nsec = nfs_attr->ctime.tv_nsec;
|
2010-09-30 21:52:34 +08:00
|
|
|
return 0;
|
2008-05-20 23:11:23 +08:00
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2013-04-23 17:44:36 +08:00
|
|
|
fhandler_base::fstat_by_handle (struct stat *buf)
|
2002-05-28 09:55:40 +08:00
|
|
|
{
|
2010-06-17 18:25:15 +08:00
|
|
|
HANDLE h = get_stat_handle ();
|
2010-09-13 19:17:36 +08:00
|
|
|
NTSTATUS status = 0;
|
2010-06-17 18:25:15 +08:00
|
|
|
|
2010-09-22 00:07:20 +08:00
|
|
|
/* If the file has been opened for other purposes than stat, we can't rely
|
2015-12-10 07:02:34 +08:00
|
|
|
on the information stored in pc.fai. So we overwrite them here. */
|
2019-03-30 15:12:02 +08:00
|
|
|
if (get_handle ())
|
2010-09-22 00:07:20 +08:00
|
|
|
{
|
2016-06-21 19:28:12 +08:00
|
|
|
status = pc.get_finfo (h);
|
2010-09-22 00:07:20 +08:00
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
2015-12-10 07:02:34 +08:00
|
|
|
debug_printf ("%y = NtQueryInformationFile(%S, FileAllInformation)",
|
2010-09-22 00:07:20 +08:00
|
|
|
status, pc.get_nt_native_path ());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2016-06-21 19:39:35 +08:00
|
|
|
if (pc.isgood_inode (pc.fai ()->InternalInformation.IndexNumber.QuadPart))
|
2015-12-10 07:02:34 +08:00
|
|
|
ino = pc.fai ()->InternalInformation.IndexNumber.QuadPart;
|
|
|
|
return fstat_helper (buf);
|
2002-05-28 09:55:40 +08:00
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2013-04-23 17:44:36 +08:00
|
|
|
fhandler_base::fstat_by_name (struct stat *buf)
|
2002-05-28 09:55:40 +08:00
|
|
|
{
|
2007-07-20 01:22:34 +08:00
|
|
|
NTSTATUS status;
|
|
|
|
OBJECT_ATTRIBUTES attr;
|
2007-07-27 01:30:54 +08:00
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
UNICODE_STRING dirname;
|
|
|
|
UNICODE_STRING basename;
|
|
|
|
HANDLE dir;
|
2008-05-21 18:23:19 +08:00
|
|
|
struct {
|
|
|
|
FILE_ID_BOTH_DIR_INFORMATION fdi;
|
|
|
|
WCHAR buf[NAME_MAX + 1];
|
|
|
|
} fdi_buf;
|
2010-09-13 19:17:36 +08:00
|
|
|
|
Drop NT4 support.
* autoload.cc (DnsQuery_A): Fatal if not available.
(DnsRecordListFree): Ditto.
(DsGetDcNameW): Ditto.
(NetGetAnyDCName): Remove.
(NetGetDCName): Remove.
(EnumProcessModules): Fatal if not available.
(GetModuleFileNameExW): Ditto.
(GetModuleInformation): Ditto.
(GetProcessMemoryInfo): Ditto.
(QueryWorkingSet): Ditto.
(LsaRegisterLogonProcess): Ditto.
* fenv.cc (_feinitialise): Drop supports_sse condition.
* fhandler_disk_file.cc (path_conv::isgood_inode): Fix comment.
(fhandler_base::fstat_by_name): Drop has_fileid_dirinfo condition.
(fhandler_disk_file::opendir): Ditto.
* fhandler_netdrive.cc (fhandler_netdrive::readdir): Fix comment.
* fhandler_proc.cc (format_proc_partitions): Drop NT4-only code.
* fhandler_process.cc (get_process_state): Ditto.
* kernel32.cc (GetWindowsDirectoryW): Remove.
(GetWindowsDirectoryA): Remove.
* miscfuncs.cc (nice_to_winprio): Drop NT4-only code.
* mount.cc (fs_info::update): Fix comments.
* net.cc (get_2k_ifs): Drop NT4-only code.
* sec_auth.cc (get_logon_server): Ditto.
(lsaauth): Drop NT4-specific error handling.
* security.cc (alloc_sd): Set SE_DACL_PROTECTED unconditionally.
* select.cc (select_stuff::wait): Always use MWMO_INPUTAVAILABLE.
(peek_windows): Drop NT4-only condition in call to PeekMessage.
* syscalls.cc (gethostid): Remove NT4-only workaround.
* wincap.cc: Througout, drop has_dacl_protect,
has_broken_if_oper_status, has_process_io_counters,
has_terminal_services, has_extended_priority_class, has_guid_volumes,
has_fileid_dirinfo, has_mwmo_inputavailable and supports_sse from
wincaps.
(wincap_nt4sp4): Remove.
(wincap_minimal): Set to wincap_2000.
(wincapc::init): Rely on availability of OSVERSIONINFOEX structure.
Treat error from GetVersionEx as fatal. Treat NT4 as fatal.
* wincap.h (struct wincaps): Drop has_dacl_protect,
has_broken_if_oper_status, has_process_io_counters,
has_terminal_services, has_extended_priority_class, has_guid_volumes,
has_fileid_dirinfo, has_mwmo_inputavailable and supports_sse flags
and methods.
* winlean.h (GetWindowsDirectoryW) Define as GetSystemWindowsDirectoryW.
(GetWindowsDirectoryA): Define as GetSystemWindowsDirectoryA.
2011-04-04 20:23:36 +08:00
|
|
|
if (!ino && pc.hasgood_inode () && !pc.has_buggy_fileid_dirinfo ())
|
2002-05-28 09:55:40 +08:00
|
|
|
{
|
2010-09-13 19:17:36 +08:00
|
|
|
RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, &basename);
|
|
|
|
InitializeObjectAttributes (&attr, &dirname, pc.objcaseinsensitive (),
|
|
|
|
NULL, NULL);
|
|
|
|
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
|
|
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT
|
|
|
|
| FILE_OPEN_FOR_BACKUP_INTENT
|
|
|
|
| FILE_DIRECTORY_FILE);
|
|
|
|
if (!NT_SUCCESS (status))
|
2013-04-23 17:44:36 +08:00
|
|
|
debug_printf ("%y = NtOpenFile(%S)", status,
|
2010-09-13 19:17:36 +08:00
|
|
|
pc.get_nt_native_path ());
|
|
|
|
else
|
|
|
|
{
|
|
|
|
status = NtQueryDirectoryFile (dir, NULL, NULL, NULL, &io,
|
|
|
|
&fdi_buf.fdi, sizeof fdi_buf,
|
|
|
|
FileIdBothDirectoryInformation,
|
|
|
|
TRUE, &basename, TRUE);
|
|
|
|
NtClose (dir);
|
|
|
|
if (!NT_SUCCESS (status))
|
2013-04-23 17:44:36 +08:00
|
|
|
debug_printf ("%y = NtQueryDirectoryFile(%S)", status,
|
2010-09-13 19:17:36 +08:00
|
|
|
pc.get_nt_native_path ());
|
|
|
|
else
|
2015-12-10 01:11:47 +08:00
|
|
|
ino = fdi_buf.fdi.FileId.QuadPart;
|
2010-09-13 19:17:36 +08:00
|
|
|
}
|
2007-07-27 01:30:54 +08:00
|
|
|
}
|
2015-12-10 07:02:34 +08:00
|
|
|
return fstat_helper (buf);
|
2002-05-28 09:55:40 +08:00
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2013-04-23 17:44:36 +08:00
|
|
|
fhandler_base::fstat_fs (struct stat *buf)
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
|
|
|
int res = -1;
|
|
|
|
int oret;
|
2004-04-08 15:57:28 +08:00
|
|
|
int open_flags = O_RDONLY | O_BINARY;
|
2001-11-21 14:47:57 +08:00
|
|
|
|
2010-06-15 20:05:15 +08:00
|
|
|
if (get_stat_handle ())
|
2002-09-19 11:30:20 +08:00
|
|
|
{
|
2023-08-26 21:41:18 +08:00
|
|
|
if (!nohandle ())
|
|
|
|
{
|
|
|
|
if (pc.fs_is_nfs ())
|
|
|
|
res = fstat_by_nfs_ea (buf);
|
|
|
|
else if (!is_fs_special () || get_flags () & O_PATH)
|
|
|
|
res = fstat_by_handle (buf);
|
|
|
|
}
|
2007-07-27 01:30:54 +08:00
|
|
|
if (res)
|
|
|
|
res = fstat_by_name (buf);
|
|
|
|
return res;
|
2002-09-19 11:30:20 +08:00
|
|
|
}
|
2010-06-15 20:05:15 +08:00
|
|
|
/* First try to open with generic read access. This allows to read the file
|
|
|
|
in fstat_helper (when checking for executability) without having to
|
|
|
|
re-open it. Opening a file can take a lot of time on network drives
|
|
|
|
so we try to avoid that. */
|
2007-07-27 16:38:00 +08:00
|
|
|
oret = open_fs (open_flags, 0);
|
2010-06-15 20:05:15 +08:00
|
|
|
if (!oret)
|
|
|
|
{
|
|
|
|
query_open (query_read_attributes);
|
|
|
|
oret = open_fs (open_flags, 0);
|
|
|
|
}
|
2004-03-23 19:26:54 +08:00
|
|
|
if (oret)
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
2004-03-23 19:26:54 +08:00
|
|
|
/* We now have a valid handle, regardless of the "nohandle" state.
|
2013-10-25 23:33:51 +08:00
|
|
|
Since fhandler_base::close only calls CloseHandle if !nohandle,
|
2007-08-14 01:16:05 +08:00
|
|
|
we have to set it to false before calling close and restore
|
2004-03-23 19:26:54 +08:00
|
|
|
the state afterwards. */
|
2010-09-13 19:17:36 +08:00
|
|
|
res = pc.fs_is_nfs () ? fstat_by_nfs_ea (buf) : fstat_by_handle (buf);
|
2004-04-10 21:45:10 +08:00
|
|
|
bool no_handle = nohandle ();
|
|
|
|
nohandle (false);
|
2007-08-14 03:15:47 +08:00
|
|
|
close_fs ();
|
2004-04-10 21:45:10 +08:00
|
|
|
nohandle (no_handle);
|
2019-03-30 15:12:02 +08:00
|
|
|
set_handle (NULL);
|
2001-11-21 14:47:57 +08:00
|
|
|
}
|
2007-07-27 01:30:54 +08:00
|
|
|
if (res)
|
2004-03-23 19:26:54 +08:00
|
|
|
res = fstat_by_name (buf);
|
2001-11-21 14:47:57 +08:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2015-12-10 07:02:34 +08:00
|
|
|
fhandler_base::fstat_helper (struct stat *buf)
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
2004-04-06 18:19:31 +08:00
|
|
|
IO_STATUS_BLOCK st;
|
|
|
|
FILE_COMPRESSION_INFORMATION fci;
|
2021-02-09 04:00:24 +08:00
|
|
|
HANDLE h = get_stat_handle ();
|
2015-12-10 07:02:34 +08:00
|
|
|
PFILE_ALL_INFORMATION pfai = pc.fai ();
|
2010-09-13 19:17:36 +08:00
|
|
|
ULONG attributes = pc.file_attributes ();
|
|
|
|
|
2015-12-10 07:02:34 +08:00
|
|
|
to_timestruc_t (&pfai->BasicInformation.LastAccessTime, &buf->st_atim);
|
|
|
|
to_timestruc_t (&pfai->BasicInformation.LastWriteTime, &buf->st_mtim);
|
2010-09-13 19:17:36 +08:00
|
|
|
/* If the ChangeTime is 0, the underlying FS doesn't support this timestamp
|
|
|
|
(FAT for instance). If so, it's faked using LastWriteTime. */
|
2015-12-10 07:02:34 +08:00
|
|
|
to_timestruc_t (pfai->BasicInformation.ChangeTime.QuadPart
|
|
|
|
? &pfai->BasicInformation.ChangeTime
|
|
|
|
: &pfai->BasicInformation.LastWriteTime,
|
2010-09-13 19:17:36 +08:00
|
|
|
&buf->st_ctim);
|
2015-12-10 07:02:34 +08:00
|
|
|
to_timestruc_t (&pfai->BasicInformation.CreationTime, &buf->st_birthtim);
|
2012-04-02 19:08:07 +08:00
|
|
|
buf->st_dev = get_dev ();
|
2011-01-13 21:50:02 +08:00
|
|
|
/* CV 2011-01-13: Observations on the Cygwin mailing list point to an
|
|
|
|
interesting behaviour in some Windows versions. Apparently the size of
|
|
|
|
a directory is computed at the time the directory is first scanned. This
|
|
|
|
can result in two subsequent NtQueryInformationFile calls to return size
|
|
|
|
0 in the first call and size > 0 in the second call. This in turn can
|
|
|
|
affect applications like newer tar.
|
|
|
|
FIXME: Is the allocation size affected as well? */
|
2015-12-10 07:02:34 +08:00
|
|
|
buf->st_size = pc.isdir ()
|
|
|
|
? 0
|
|
|
|
: (off_t) pfai->StandardInformation.EndOfFile.QuadPart;
|
2010-06-15 16:51:55 +08:00
|
|
|
/* The number of links to a directory includes the number of subdirectories
|
|
|
|
in the directory, since all those subdirectories point to it. However,
|
|
|
|
this is painfully slow, so we do without it. */
|
2015-12-10 07:02:34 +08:00
|
|
|
buf->st_nlink = pc.fai()->StandardInformation.NumberOfLinks;
|
2001-11-21 14:47:57 +08:00
|
|
|
|
2006-04-27 00:51:09 +08:00
|
|
|
/* Enforce namehash as inode number on untrusted file systems. */
|
2016-06-21 19:39:35 +08:00
|
|
|
buf->st_ino = ino ?: get_ino ();
|
2001-11-21 14:47:57 +08:00
|
|
|
|
2007-01-04 17:17:55 +08:00
|
|
|
buf->st_blksize = PREFERRED_IO_BLKSIZE;
|
2003-02-20 19:12:44 +08:00
|
|
|
|
2017-04-22 20:50:58 +08:00
|
|
|
if (buf->st_size == 0
|
|
|
|
&& pfai->StandardInformation.AllocationSize.QuadPart == 0LL)
|
|
|
|
/* File is empty and no blocks are preallocated. */
|
|
|
|
buf->st_blocks = 0;
|
|
|
|
else if (pfai->StandardInformation.AllocationSize.QuadPart > 0LL)
|
2005-04-12 22:26:31 +08:00
|
|
|
/* A successful NtQueryInformationFile returns the allocation size
|
2017-04-22 20:50:58 +08:00
|
|
|
correctly for compressed and sparse files as well.
|
|
|
|
Allocation size 0 is ignored here because (at least) Windows 10
|
|
|
|
1607 always returns 0 for CompactOS compressed files. */
|
2015-12-10 07:02:34 +08:00
|
|
|
buf->st_blocks = (pfai->StandardInformation.AllocationSize.QuadPart
|
|
|
|
+ S_BLKSIZE - 1) / S_BLKSIZE;
|
2017-04-22 20:50:58 +08:00
|
|
|
else if ((pfai->StandardInformation.AllocationSize.QuadPart == 0LL
|
|
|
|
|| ::has_attribute (attributes, FILE_ATTRIBUTE_COMPRESSED
|
|
|
|
| FILE_ATTRIBUTE_SPARSE_FILE))
|
2010-06-15 20:05:15 +08:00
|
|
|
&& h && !is_fs_special ()
|
|
|
|
&& !NtQueryInformationFile (h, &st, (PVOID) &fci, sizeof fci,
|
|
|
|
FileCompressionInformation))
|
2005-04-12 22:26:31 +08:00
|
|
|
/* Otherwise we request the actual amount of bytes allocated for
|
2017-04-22 20:50:58 +08:00
|
|
|
compressed, sparsed and CompactOS files. */
|
2007-09-27 17:35:06 +08:00
|
|
|
buf->st_blocks = (fci.CompressedFileSize.QuadPart + S_BLKSIZE - 1)
|
|
|
|
/ S_BLKSIZE;
|
2003-02-20 19:12:44 +08:00
|
|
|
else
|
2005-04-12 22:26:31 +08:00
|
|
|
/* Otherwise compute no. of blocks from file size. */
|
2011-01-26 18:55:13 +08:00
|
|
|
buf->st_blocks = (buf->st_size + S_BLKSIZE - 1) / S_BLKSIZE;
|
2001-11-21 14:47:57 +08:00
|
|
|
|
|
|
|
buf->st_mode = 0;
|
2009-11-27 22:27:22 +08:00
|
|
|
/* Using a side effect: get_file_attributes checks for directory.
|
|
|
|
This is used, to set S_ISVTX, if needed. */
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
if (pc.isdir ())
|
2001-11-21 14:47:57 +08:00
|
|
|
buf->st_mode = S_IFDIR;
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
else if (pc.issymlink ())
|
2003-04-11 17:38:07 +08:00
|
|
|
{
|
2004-04-14 11:08:00 +08:00
|
|
|
buf->st_size = pc.get_symlink_length ();
|
2023-02-10 04:55:18 +08:00
|
|
|
get_file_attribute (h, pc, buf->st_mode,
|
|
|
|
&buf->st_uid, &buf->st_gid);
|
2003-04-11 17:38:07 +08:00
|
|
|
/* symlinks are everything for everyone! */
|
|
|
|
buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
|
|
|
|
goto done;
|
|
|
|
}
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
else if (pc.issocket ())
|
2001-11-21 14:47:57 +08:00
|
|
|
buf->st_mode = S_IFSOCK;
|
2002-05-28 09:55:40 +08:00
|
|
|
|
2023-02-10 04:55:18 +08:00
|
|
|
if (!get_file_attribute (h, pc, buf->st_mode, &buf->st_uid, &buf->st_gid))
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
|
|
|
/* If read-only attribute is set, modify ntsec return value */
|
2010-09-13 19:17:36 +08:00
|
|
|
if (::has_attribute (attributes, FILE_ATTRIBUTE_READONLY)
|
2020-01-29 22:14:05 +08:00
|
|
|
&& !pc.isdir () && !pc.issymlink () && !pc.is_fs_special ())
|
2001-11-21 14:47:57 +08:00
|
|
|
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
|
|
|
|
2004-12-26 10:10:30 +08:00
|
|
|
if (buf->st_mode & S_IFMT)
|
|
|
|
/* nothing */;
|
|
|
|
else if (!is_fs_special ())
|
2001-11-21 14:47:57 +08:00
|
|
|
buf->st_mode |= S_IFREG;
|
2004-12-26 10:10:30 +08:00
|
|
|
else
|
|
|
|
{
|
2010-08-18 18:10:14 +08:00
|
|
|
buf->st_dev = buf->st_rdev = dev ();
|
2020-05-29 01:05:32 +08:00
|
|
|
buf->st_mode = dev ().mode ();
|
2005-12-02 01:33:59 +08:00
|
|
|
buf->st_size = 0;
|
2004-12-26 10:10:30 +08:00
|
|
|
}
|
2001-11-21 14:47:57 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
buf->st_mode |= STD_RBITS;
|
|
|
|
|
2010-09-13 19:17:36 +08:00
|
|
|
if (!::has_attribute (attributes, FILE_ATTRIBUTE_READONLY))
|
2001-11-21 14:47:57 +08:00
|
|
|
buf->st_mode |= STD_WBITS;
|
|
|
|
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
|
|
|
|
|
2007-12-12 02:57:44 +08:00
|
|
|
if (pc.isdir ())
|
|
|
|
buf->st_mode |= S_IFDIR | STD_WBITS | STD_XBITS;
|
2001-11-21 14:47:57 +08:00
|
|
|
else if (buf->st_mode & S_IFMT)
|
|
|
|
/* nothing */;
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
else if (is_fs_special ())
|
|
|
|
{
|
2010-08-18 18:10:14 +08:00
|
|
|
buf->st_dev = buf->st_rdev = dev ();
|
2016-06-23 22:56:41 +08:00
|
|
|
buf->st_mode = dev ().mode ();
|
2005-12-02 01:33:59 +08:00
|
|
|
buf->st_size = 0;
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
}
|
2001-11-21 14:47:57 +08:00
|
|
|
else
|
2002-05-28 09:55:40 +08:00
|
|
|
{
|
|
|
|
buf->st_mode |= S_IFREG;
|
2008-10-09 22:23:09 +08:00
|
|
|
/* Check suffix for executable file. */
|
2010-10-07 22:03:26 +08:00
|
|
|
if (pc.exec_state () != is_executable)
|
2008-10-09 22:23:09 +08:00
|
|
|
{
|
|
|
|
PUNICODE_STRING path = pc.get_nt_native_path ();
|
|
|
|
|
2009-07-15 01:37:42 +08:00
|
|
|
if (RtlEqualUnicodePathSuffix (path, &ro_u_exe, TRUE)
|
2022-10-28 18:42:51 +08:00
|
|
|
|| RtlEqualUnicodePathSuffix (path, &ro_u_lnk, TRUE))
|
2008-10-09 22:23:09 +08:00
|
|
|
pc.set_exec ();
|
|
|
|
}
|
2009-11-27 22:27:22 +08:00
|
|
|
/* No known suffix, check file header. This catches binaries and
|
2008-10-09 22:23:09 +08:00
|
|
|
shebang scripts. */
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
if (pc.exec_state () == dont_know_if_executable)
|
2002-10-23 05:35:21 +08:00
|
|
|
{
|
2010-10-07 22:03:26 +08:00
|
|
|
OBJECT_ATTRIBUTES attr;
|
2010-06-15 23:10:42 +08:00
|
|
|
NTSTATUS status = 0;
|
2007-08-21 23:37:10 +08:00
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
|
2010-10-07 22:03:26 +08:00
|
|
|
/* We have to re-open the file. Either the file is not opened
|
2011-06-06 13:02:13 +08:00
|
|
|
for reading, or the read will change the file position of the
|
2010-10-07 22:03:26 +08:00
|
|
|
original handle. */
|
|
|
|
status = NtOpenFile (&h, SYNCHRONIZE | FILE_READ_DATA,
|
2014-08-27 04:47:46 +08:00
|
|
|
pc.init_reopen_attr (attr, h), &io,
|
|
|
|
FILE_SHARE_VALID_FLAGS,
|
2010-10-07 22:03:26 +08:00
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT
|
|
|
|
| FILE_SYNCHRONOUS_IO_NONALERT);
|
|
|
|
if (!NT_SUCCESS (status))
|
2013-04-23 17:44:36 +08:00
|
|
|
debug_printf ("%y = NtOpenFile(%S)", status,
|
2010-10-07 22:03:26 +08:00
|
|
|
pc.get_nt_native_path ());
|
|
|
|
else
|
2008-02-16 01:53:11 +08:00
|
|
|
{
|
2010-10-07 22:03:26 +08:00
|
|
|
LARGE_INTEGER off = { QuadPart:0LL };
|
|
|
|
char magic[3];
|
|
|
|
|
2010-06-15 20:05:15 +08:00
|
|
|
status = NtReadFile (h, NULL, NULL, NULL,
|
|
|
|
&io, magic, 3, &off, NULL);
|
|
|
|
if (!NT_SUCCESS (status))
|
2013-04-23 17:44:36 +08:00
|
|
|
debug_printf ("%y = NtReadFile(%S)", status,
|
2010-02-04 00:05:33 +08:00
|
|
|
pc.get_nt_native_path ());
|
2010-06-15 20:05:15 +08:00
|
|
|
else if (has_exec_chars (magic, io.Information))
|
|
|
|
{
|
|
|
|
/* Heureka, it's an executable */
|
|
|
|
pc.set_exec ();
|
|
|
|
buf->st_mode |= STD_XBITS;
|
|
|
|
}
|
2010-10-07 22:03:26 +08:00
|
|
|
NtClose (h);
|
2002-10-23 10:32:34 +08:00
|
|
|
}
|
2002-10-23 05:35:21 +08:00
|
|
|
}
|
|
|
|
}
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
if (pc.exec_state () == is_executable)
|
2002-10-23 10:32:34 +08:00
|
|
|
buf->st_mode |= STD_XBITS;
|
2003-05-27 15:44:26 +08:00
|
|
|
|
|
|
|
/* This fakes the permissions of all files to match the current umask. */
|
|
|
|
buf->st_mode &= ~(cygheap->umask);
|
2009-11-08 18:22:28 +08:00
|
|
|
/* If the FS supports ACLs, we're here because we couldn't even open
|
|
|
|
the file for READ_CONTROL access. Chances are high that the file's
|
|
|
|
security descriptor has no ACE for "Everyone", so we should not fake
|
|
|
|
any access for "others". */
|
|
|
|
if (has_acls ())
|
|
|
|
buf->st_mode &= ~(S_IROTH | S_IWOTH | S_IXOTH);
|
2002-10-23 05:35:21 +08:00
|
|
|
}
|
2002-10-23 04:41:31 +08:00
|
|
|
|
2003-04-11 17:38:07 +08:00
|
|
|
done:
|
2014-08-27 19:42:17 +08:00
|
|
|
syscall_printf ("0 = fstat (%S, %p) st_size=%D, st_mode=0%o, st_ino=%D"
|
2013-04-23 17:44:36 +08:00
|
|
|
"st_atim=%lx.%lx st_ctim=%lx.%lx "
|
|
|
|
"st_mtim=%lx.%lx st_birthtim=%lx.%lx",
|
2011-07-05 20:02:10 +08:00
|
|
|
pc.get_nt_native_path (), buf,
|
|
|
|
buf->st_size, buf->st_mode, buf->st_ino,
|
|
|
|
buf->st_atim.tv_sec, buf->st_atim.tv_nsec,
|
|
|
|
buf->st_ctim.tv_sec, buf->st_ctim.tv_nsec,
|
|
|
|
buf->st_mtim.tv_sec, buf->st_mtim.tv_nsec,
|
|
|
|
buf->st_birthtim.tv_sec, buf->st_birthtim.tv_nsec);
|
2001-11-21 14:47:57 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2013-04-23 17:44:36 +08:00
|
|
|
fhandler_disk_file::fstat (struct stat *buf)
|
2001-11-22 13:59:07 +08:00
|
|
|
{
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
return fstat_fs (buf);
|
2001-11-22 13:59:07 +08:00
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2007-02-27 20:58:56 +08:00
|
|
|
fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|
|
|
{
|
2007-07-27 18:10:57 +08:00
|
|
|
int ret = -1, opened = 0;
|
2007-02-27 20:58:56 +08:00
|
|
|
IO_STATUS_BLOCK io;
|
2010-08-20 16:52:25 +08:00
|
|
|
/* We must not use the stat handle here, even if it exists. The handle
|
|
|
|
has been opened with FILE_OPEN_REPARSE_POINT, thus, in case of a volume
|
|
|
|
mount point, it points to the FS of the mount point, rather than to the
|
|
|
|
mounted FS. */
|
|
|
|
HANDLE fh = get_handle ();
|
2007-02-27 20:58:56 +08:00
|
|
|
|
2007-07-27 18:10:57 +08:00
|
|
|
if (!fh)
|
2007-02-27 20:58:56 +08:00
|
|
|
{
|
2007-07-27 18:10:57 +08:00
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL,
|
2010-06-15 17:58:56 +08:00
|
|
|
pc.get_object_attr (attr, sec_none_nih),
|
|
|
|
&io, FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT));
|
2007-07-27 18:10:57 +08:00
|
|
|
if (!opened)
|
2007-07-08 00:46:35 +08:00
|
|
|
{
|
2007-07-27 18:10:57 +08:00
|
|
|
/* Can't open file. Try again with parent dir. */
|
|
|
|
UNICODE_STRING dirname;
|
|
|
|
RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, NULL);
|
|
|
|
attr.ObjectName = &dirname;
|
|
|
|
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL, &attr, &io,
|
2010-06-15 17:58:56 +08:00
|
|
|
FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT));
|
2007-07-27 18:10:57 +08:00
|
|
|
if (!opened)
|
2007-02-27 20:58:56 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-25 05:02:57 +08:00
|
|
|
ret = fstatvfs_by_handle (fh, sfs);
|
|
|
|
out:
|
|
|
|
if (opened)
|
|
|
|
NtClose (fh);
|
|
|
|
syscall_printf ("%d = fstatvfs(%s, %p)", ret, get_name (), sfs);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2020-01-25 05:02:57 +08:00
|
|
|
fhandler_base::fstatvfs_by_handle (HANDLE fh, struct statvfs *sfs)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
FILE_FS_FULL_SIZE_INFORMATION full_fsi;
|
|
|
|
|
2007-02-27 20:58:56 +08:00
|
|
|
sfs->f_files = ULONG_MAX;
|
|
|
|
sfs->f_ffree = ULONG_MAX;
|
|
|
|
sfs->f_favail = ULONG_MAX;
|
2008-05-21 18:23:19 +08:00
|
|
|
sfs->f_fsid = pc.fs_serial_number ();
|
|
|
|
sfs->f_flag = pc.fs_flags ();
|
|
|
|
sfs->f_namemax = pc.fs_name_len ();
|
2013-04-23 17:44:36 +08:00
|
|
|
/* Get allocation related information. */
|
2007-07-27 18:10:57 +08:00
|
|
|
status = NtQueryVolumeInformationFile (fh, &io, &full_fsi, sizeof full_fsi,
|
2007-02-27 20:58:56 +08:00
|
|
|
FileFsFullSizeInformation);
|
|
|
|
if (NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
sfs->f_bsize = full_fsi.BytesPerSector * full_fsi.SectorsPerAllocationUnit;
|
|
|
|
sfs->f_frsize = sfs->f_bsize;
|
2013-04-23 17:44:36 +08:00
|
|
|
sfs->f_blocks = (fsblkcnt_t) full_fsi.TotalAllocationUnits.QuadPart;
|
|
|
|
sfs->f_bfree = (fsblkcnt_t)
|
|
|
|
full_fsi.ActualAvailableAllocationUnits.QuadPart;
|
|
|
|
sfs->f_bavail = (fsblkcnt_t)
|
|
|
|
full_fsi.CallerAvailableAllocationUnits.QuadPart;
|
2007-02-27 20:58:56 +08:00
|
|
|
if (sfs->f_bfree > sfs->f_bavail)
|
2007-07-08 00:46:35 +08:00
|
|
|
{
|
2007-02-27 20:58:56 +08:00
|
|
|
/* Quotas active. We can't trust TotalAllocationUnits. */
|
|
|
|
NTFS_VOLUME_DATA_BUFFER nvdb;
|
|
|
|
|
2007-07-27 18:10:57 +08:00
|
|
|
status = NtFsControlFile (fh, NULL, NULL, NULL, &io,
|
|
|
|
FSCTL_GET_NTFS_VOLUME_DATA,
|
|
|
|
NULL, 0, &nvdb, sizeof nvdb);
|
|
|
|
if (!NT_SUCCESS (status))
|
2013-04-23 17:44:36 +08:00
|
|
|
debug_printf ("%y = NtFsControlFile(%S, FSCTL_GET_NTFS_VOLUME_DATA)",
|
2007-08-21 20:09:38 +08:00
|
|
|
status, pc.get_nt_native_path ());
|
2007-02-27 20:58:56 +08:00
|
|
|
else
|
2013-04-23 17:44:36 +08:00
|
|
|
sfs->f_blocks = (fsblkcnt_t) nvdb.TotalClusters.QuadPart;
|
2007-02-27 20:58:56 +08:00
|
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
}
|
2014-08-28 20:29:42 +08:00
|
|
|
else if (status == STATUS_INVALID_PARAMETER /* Netapp */
|
|
|
|
|| status == STATUS_INVALID_INFO_CLASS)
|
|
|
|
{
|
|
|
|
FILE_FS_SIZE_INFORMATION fsi;
|
|
|
|
status = NtQueryVolumeInformationFile (fh, &io, &fsi, sizeof fsi,
|
|
|
|
FileFsSizeInformation);
|
|
|
|
if (NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
sfs->f_bsize = fsi.BytesPerSector * fsi.SectorsPerAllocationUnit;
|
|
|
|
sfs->f_frsize = sfs->f_bsize;
|
|
|
|
sfs->f_blocks = (fsblkcnt_t) fsi.TotalAllocationUnits.QuadPart;
|
|
|
|
sfs->f_bfree = sfs->f_bavail =
|
|
|
|
(fsblkcnt_t) fsi.AvailableAllocationUnits.QuadPart;
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
debug_printf ("%y = NtQueryVolumeInformationFile"
|
2020-03-11 20:36:41 +08:00
|
|
|
"(%S, FileFsSizeInformation)",
|
2014-08-28 20:29:42 +08:00
|
|
|
status, pc.get_nt_native_path ());
|
|
|
|
}
|
2014-07-04 00:48:21 +08:00
|
|
|
else
|
|
|
|
debug_printf ("%y = NtQueryVolumeInformationFile"
|
2020-03-11 20:36:41 +08:00
|
|
|
"(%S, FileFsFullSizeInformation)",
|
2014-07-04 00:48:21 +08:00
|
|
|
status, pc.get_nt_native_path ());
|
2007-02-27 20:58:56 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2004-04-14 04:36:58 +08:00
|
|
|
fhandler_disk_file::fchmod (mode_t mode)
|
|
|
|
{
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
int ret = -1;
|
2004-04-14 04:36:58 +08:00
|
|
|
int oret = 0;
|
2008-05-20 23:11:23 +08:00
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
2004-04-14 04:36:58 +08:00
|
|
|
|
2023-09-09 04:38:53 +08:00
|
|
|
if (pc.is_fs_special ()
|
|
|
|
/* For NFS, only handle Cygwin FIFOs specially. Changing mode of
|
|
|
|
native FIFOs will work with the default code below. */
|
|
|
|
&& (!pc.fs_is_nfs () || pc.nfsattr ()->filler1 == NF3FIFO))
|
2004-04-14 04:36:58 +08:00
|
|
|
return chmod_device (pc, mode);
|
|
|
|
|
2007-07-29 16:23:04 +08:00
|
|
|
if (!get_handle ())
|
2004-04-14 21:40:07 +08:00
|
|
|
{
|
2010-09-25 00:22:53 +08:00
|
|
|
query_open (query_write_dac);
|
2005-04-04 18:26:35 +08:00
|
|
|
if (!(oret = open (O_BINARY, 0)))
|
2005-05-04 03:03:20 +08:00
|
|
|
{
|
2015-12-26 04:40:51 +08:00
|
|
|
/* Need WRITE_DAC to write ACLs. */
|
2008-07-15 04:22:03 +08:00
|
|
|
if (pc.has_acls ())
|
2005-05-04 03:03:20 +08:00
|
|
|
return -1;
|
2007-07-29 16:23:04 +08:00
|
|
|
/* Otherwise FILE_WRITE_ATTRIBUTES is sufficient. */
|
|
|
|
query_open (query_write_attributes);
|
|
|
|
if (!(oret = open (O_BINARY, 0)))
|
|
|
|
return -1;
|
2005-05-04 03:03:20 +08:00
|
|
|
}
|
2005-04-04 18:26:35 +08:00
|
|
|
}
|
2004-04-14 04:36:58 +08:00
|
|
|
|
2008-05-20 23:11:23 +08:00
|
|
|
if (pc.fs_is_nfs ())
|
|
|
|
{
|
|
|
|
/* chmod on NFS shares works by writing an EA of type NfsV3Attributes.
|
2008-11-27 01:21:04 +08:00
|
|
|
Only type and mode have to be set. Apparently type isn't checked
|
2008-05-20 23:11:23 +08:00
|
|
|
for consistency, so it's sufficent to set it to NF3REG all the time. */
|
|
|
|
struct {
|
|
|
|
FILE_FULL_EA_INFORMATION ffei;
|
|
|
|
char buf[sizeof (NFS_V3_ATTR) + sizeof (fattr3)];
|
|
|
|
} ffei_buf;
|
|
|
|
ffei_buf.ffei.NextEntryOffset = 0;
|
|
|
|
ffei_buf.ffei.Flags = 0;
|
|
|
|
ffei_buf.ffei.EaNameLength = sizeof (NFS_V3_ATTR) - 1;
|
|
|
|
ffei_buf.ffei.EaValueLength = sizeof (fattr3);
|
|
|
|
strcpy (ffei_buf.ffei.EaName, NFS_V3_ATTR);
|
|
|
|
fattr3 *nfs_attr = (fattr3 *) (ffei_buf.ffei.EaName
|
|
|
|
+ ffei_buf.ffei.EaNameLength + 1);
|
|
|
|
memset (nfs_attr, 0, sizeof (fattr3));
|
|
|
|
nfs_attr->type = NF3REG;
|
|
|
|
nfs_attr->mode = mode;
|
|
|
|
status = NtSetEaFile (get_handle (), &io,
|
|
|
|
&ffei_buf.ffei, sizeof ffei_buf);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
else
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
ret = 0;
|
2008-05-20 23:11:23 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2008-07-15 04:22:03 +08:00
|
|
|
if (pc.has_acls ())
|
2005-04-04 18:26:35 +08:00
|
|
|
{
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
security_descriptor sd, sd_ret;
|
|
|
|
uid_t uid;
|
|
|
|
gid_t gid;
|
|
|
|
tmp_pathbuf tp;
|
|
|
|
aclent_t *aclp;
|
2016-01-29 05:05:49 +08:00
|
|
|
bool standard_acl = false;
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
int nentries, idx;
|
2023-02-10 04:47:15 +08:00
|
|
|
mode_t attr = pc.isdir () ? S_IFDIR : 0;
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
|
|
|
|
if (!get_file_sd (get_handle (), pc, sd, false))
|
|
|
|
{
|
|
|
|
aclp = (aclent_t *) tp.c_get ();
|
2023-02-10 04:55:18 +08:00
|
|
|
if ((nentries = get_posix_access (sd, attr, &uid, &gid,
|
2016-01-29 05:05:49 +08:00
|
|
|
aclp, MAX_ACL_ENTRIES,
|
|
|
|
&standard_acl)) >= 0)
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
{
|
|
|
|
/* Overwrite ACL permissions as required by POSIX 1003.1e
|
|
|
|
draft 17. */
|
|
|
|
aclp[0].a_perm = (mode >> 6) & S_IRWXO;
|
2016-01-29 05:05:49 +08:00
|
|
|
|
2015-09-02 04:23:59 +08:00
|
|
|
/* POSIXly correct: If CLASS_OBJ is present, chmod only modifies
|
2016-01-29 05:05:49 +08:00
|
|
|
CLASS_OBJ, not GROUP_OBJ.
|
|
|
|
|
|
|
|
Deliberate deviation from POSIX 1003.1e: If the ACL is a
|
|
|
|
"standard" ACL, that is, it only contains POSIX permissions
|
|
|
|
as well as entries for the Administrators group and SYSTEM,
|
|
|
|
then it's kind of a POSIX-only ACL in a twisted, Windowsy
|
|
|
|
way. If so, we change GROUP_OBJ and CLASS_OBJ perms. */
|
|
|
|
if (standard_acl
|
|
|
|
&& (idx = searchace (aclp, nentries, GROUP_OBJ)) >= 0)
|
|
|
|
aclp[idx].a_perm = (mode >> 3) & S_IRWXO;
|
2015-09-02 04:23:59 +08:00
|
|
|
if (nentries > MIN_ACL_ENTRIES
|
|
|
|
&& (idx = searchace (aclp, nentries, CLASS_OBJ)) >= 0)
|
|
|
|
aclp[idx].a_perm = (mode >> 3) & S_IRWXO;
|
2016-01-29 05:05:49 +08:00
|
|
|
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
if ((idx = searchace (aclp, nentries, OTHER_OBJ)) >= 0)
|
|
|
|
aclp[idx].a_perm = mode & S_IRWXO;
|
|
|
|
if (pc.isdir ())
|
|
|
|
mode |= S_IFDIR;
|
|
|
|
if (set_posix_access (mode, uid, gid, aclp, nentries, sd_ret,
|
|
|
|
pc.fs_is_samba ()))
|
|
|
|
ret = set_file_sd (get_handle (), pc, sd_ret, false);
|
|
|
|
}
|
|
|
|
}
|
2004-04-20 23:51:24 +08:00
|
|
|
}
|
2004-04-14 04:36:58 +08:00
|
|
|
|
2008-08-14 22:05:04 +08:00
|
|
|
/* If the mode has any write bits set, the DOS R/O flag is in the way. */
|
2004-04-14 04:36:58 +08:00
|
|
|
if (mode & (S_IWUSR | S_IWGRP | S_IWOTH))
|
2005-03-23 03:00:31 +08:00
|
|
|
pc &= (DWORD) ~FILE_ATTRIBUTE_READONLY;
|
2008-08-14 22:05:04 +08:00
|
|
|
else if (!pc.has_acls ()) /* Never set DOS R/O if security is used. */
|
2005-03-23 03:00:31 +08:00
|
|
|
pc |= (DWORD) FILE_ATTRIBUTE_READONLY;
|
2008-05-21 05:08:39 +08:00
|
|
|
if (S_ISSOCK (mode))
|
2007-08-17 00:59:25 +08:00
|
|
|
pc |= (DWORD) FILE_ATTRIBUTE_SYSTEM;
|
2004-04-14 04:36:58 +08:00
|
|
|
|
2009-07-16 23:28:57 +08:00
|
|
|
status = NtSetAttributesFile (get_handle (), pc.file_attributes ());
|
2009-07-21 16:10:36 +08:00
|
|
|
/* MVFS needs a good amount of kicking to be convinced that it has to write
|
|
|
|
back metadata changes and to invalidate the cached metadata information
|
|
|
|
stored for the given handle. This method to open a second handle to
|
|
|
|
the file and write the same metadata information twice has been found
|
|
|
|
experimentally: http://cygwin.com/ml/cygwin/2009-07/msg00533.html */
|
|
|
|
if (pc.fs_is_mvfs () && NT_SUCCESS (status) && !oret)
|
|
|
|
{
|
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
HANDLE fh;
|
|
|
|
|
2014-08-27 04:47:46 +08:00
|
|
|
if (NT_SUCCESS (NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
|
2020-03-11 20:23:55 +08:00
|
|
|
pc.init_reopen_attr (attr, get_handle ()),
|
2014-08-27 04:47:46 +08:00
|
|
|
&io, FILE_SHARE_VALID_FLAGS,
|
2009-07-21 16:10:36 +08:00
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT)))
|
|
|
|
{
|
|
|
|
NtSetAttributesFile (fh, pc.file_attributes ());
|
|
|
|
NtClose (fh);
|
|
|
|
}
|
|
|
|
}
|
2008-05-20 23:11:23 +08:00
|
|
|
/* Correct NTFS security attributes have higher priority */
|
2008-07-15 04:22:03 +08:00
|
|
|
if (!pc.has_acls ())
|
2008-05-20 23:11:23 +08:00
|
|
|
{
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
else
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
ret = 0;
|
2008-05-20 23:11:23 +08:00
|
|
|
}
|
2004-04-14 04:36:58 +08:00
|
|
|
|
2008-05-20 23:11:23 +08:00
|
|
|
out:
|
2005-01-14 06:56:20 +08:00
|
|
|
if (oret)
|
2008-03-01 00:38:51 +08:00
|
|
|
close_fs ();
|
2005-01-14 06:56:20 +08:00
|
|
|
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
return ret;
|
2004-04-14 04:36:58 +08:00
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2013-04-23 17:44:36 +08:00
|
|
|
fhandler_disk_file::fchown (uid_t uid, gid_t gid)
|
2004-04-14 21:40:07 +08:00
|
|
|
{
|
|
|
|
int oret = 0;
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
int ret = -1;
|
|
|
|
security_descriptor sd, sd_ret;
|
|
|
|
mode_t attr = pc.isdir () ? S_IFDIR : 0;
|
|
|
|
uid_t old_uid;
|
|
|
|
gid_t old_gid;
|
|
|
|
tmp_pathbuf tp;
|
|
|
|
aclent_t *aclp;
|
|
|
|
int nentries;
|
2004-04-17 05:22:13 +08:00
|
|
|
|
2008-07-15 04:22:03 +08:00
|
|
|
if (!pc.has_acls ())
|
2004-04-20 23:51:24 +08:00
|
|
|
{
|
|
|
|
/* fake - if not supported, pretend we're like win95
|
2004-05-29 03:50:07 +08:00
|
|
|
where it just works */
|
2008-05-20 23:11:23 +08:00
|
|
|
/* FIXME: Could be supported on NFS when user->uid mapping is in place. */
|
2004-04-20 23:51:24 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-07-29 16:23:04 +08:00
|
|
|
if (!get_handle ())
|
2004-04-14 21:40:07 +08:00
|
|
|
{
|
2005-02-20 05:53:36 +08:00
|
|
|
query_open (query_write_control);
|
2005-06-02 09:50:23 +08:00
|
|
|
if (!(oret = fhandler_disk_file::open (O_BINARY, 0)))
|
2005-02-20 05:53:36 +08:00
|
|
|
return -1;
|
2004-04-14 21:40:07 +08:00
|
|
|
}
|
|
|
|
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
if (get_file_sd (get_handle (), pc, sd, false))
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
aclp = (aclent_t *) tp.c_get ();
|
2023-02-10 04:55:18 +08:00
|
|
|
if ((nentries = get_posix_access (sd, attr, &old_uid, &old_gid,
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
aclp, MAX_ACL_ENTRIES)) < 0)
|
|
|
|
goto out;
|
|
|
|
|
2021-01-26 10:05:37 +08:00
|
|
|
/* According to POSIX, chown can be a no-op if uid is (uid_t)-1 and
|
|
|
|
gid is (gid_t)-1. Otherwise, even if uid and gid are unchanged,
|
|
|
|
we must ensure that ctime is updated. */
|
|
|
|
if (uid == ILLEGAL_UID && gid == ILLEGAL_GID)
|
2005-12-21 21:01:27 +08:00
|
|
|
{
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
ret = 0;
|
|
|
|
goto out;
|
|
|
|
}
|
2021-01-26 10:05:37 +08:00
|
|
|
if (uid == ILLEGAL_UID)
|
|
|
|
uid = old_uid;
|
|
|
|
else if (gid == ILLEGAL_GID)
|
|
|
|
gid = old_gid;
|
2009-04-09 17:19:03 +08:00
|
|
|
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
/* Windows ACLs can contain permissions for one group, while being owned by
|
|
|
|
another user/group. The permission bits returned above are pretty much
|
|
|
|
useless then. Creating a new ACL with these useless permissions results
|
|
|
|
in a potentially broken symlink. So what we do here is to set the
|
|
|
|
underlying permissions of symlinks to a sensible value which allows the
|
|
|
|
world to read the symlink and only the new owner to change it. */
|
|
|
|
if (pc.issymlink ())
|
|
|
|
for (int idx = 0; idx < nentries; ++idx)
|
|
|
|
{
|
|
|
|
aclp[idx].a_perm |= S_IROTH;
|
|
|
|
if (aclp[idx].a_type & USER_OBJ)
|
|
|
|
aclp[idx].a_perm |= S_IWOTH;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (set_posix_access (attr, uid, gid, aclp, nentries, sd_ret,
|
|
|
|
pc.fs_is_samba ()))
|
|
|
|
ret = set_file_sd (get_handle (), pc, sd_ret, true);
|
|
|
|
|
|
|
|
/* If you're running a Samba server with no winbind, the uid<->SID mapping
|
|
|
|
is disfunctional. Even trying to chown to your own account fails since
|
|
|
|
the account used on the server is the UNIX account which gets used for
|
|
|
|
the standard user mapping. This is a default mechanism which doesn't
|
|
|
|
know your real Windows SID. There are two possible error codes in
|
|
|
|
different Samba releases for this situation, one of them unfortunately
|
|
|
|
the not very significant STATUS_ACCESS_DENIED. Instead of relying on
|
|
|
|
the error codes, we're using the below very simple heuristic.
|
|
|
|
If set_file_sd failed, and the original user account was either already
|
|
|
|
unknown, or one of the standard UNIX accounts, we're faking success. */
|
|
|
|
if (ret == -1 && pc.fs_is_samba ())
|
|
|
|
{
|
|
|
|
PSID sid;
|
|
|
|
|
|
|
|
if (uid == old_uid
|
|
|
|
|| ((sid = sidfromuid (old_uid, NULL)) != NO_SID
|
|
|
|
&& RtlEqualPrefixSid (sid,
|
|
|
|
well_known_samba_unix_user_fake_sid)))
|
|
|
|
{
|
|
|
|
debug_printf ("Faking chown worked on standalone Samba");
|
|
|
|
ret = 0;
|
2009-04-09 17:19:03 +08:00
|
|
|
}
|
2005-12-21 21:01:27 +08:00
|
|
|
}
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
|
|
|
|
out:
|
2004-04-14 21:40:07 +08:00
|
|
|
if (oret)
|
2008-03-01 00:38:51 +08:00
|
|
|
close_fs ();
|
2004-04-14 21:40:07 +08:00
|
|
|
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
return ret;
|
2004-04-14 21:40:07 +08:00
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
int
|
2013-04-23 17:44:36 +08:00
|
|
|
fhandler_disk_file::facl (int cmd, int nentries, aclent_t *aclbufp)
|
2004-04-15 00:36:26 +08:00
|
|
|
{
|
|
|
|
int res = -1;
|
|
|
|
int oret = 0;
|
|
|
|
|
2008-07-15 04:22:03 +08:00
|
|
|
if (!pc.has_acls ())
|
2004-04-15 00:36:26 +08:00
|
|
|
{
|
2007-07-30 18:58:16 +08:00
|
|
|
cant_access_acl:
|
2004-04-15 00:36:26 +08:00
|
|
|
switch (cmd)
|
2004-05-29 03:50:07 +08:00
|
|
|
{
|
2004-04-15 00:36:26 +08:00
|
|
|
|
|
|
|
case SETACL:
|
2005-01-15 06:03:40 +08:00
|
|
|
/* Open for writing required to be able to set ctime
|
|
|
|
(even though setting the ACL is just pretended). */
|
2007-07-29 16:23:04 +08:00
|
|
|
if (!get_handle ())
|
2005-02-11 23:37:26 +08:00
|
|
|
oret = open (O_WRONLY | O_BINARY, 0);
|
2005-01-15 06:03:40 +08:00
|
|
|
res = 0;
|
2004-04-15 00:36:26 +08:00
|
|
|
break;
|
|
|
|
case GETACL:
|
|
|
|
if (!aclbufp)
|
2006-10-23 03:31:33 +08:00
|
|
|
set_errno (EFAULT);
|
2004-04-15 00:36:26 +08:00
|
|
|
else if (nentries < MIN_ACL_ENTRIES)
|
|
|
|
set_errno (ENOSPC);
|
2004-04-17 05:22:13 +08:00
|
|
|
else
|
2004-04-15 00:36:26 +08:00
|
|
|
{
|
2013-04-23 17:44:36 +08:00
|
|
|
struct stat st;
|
2010-02-19 20:37:37 +08:00
|
|
|
if (!fstat (&st))
|
2004-04-17 05:22:13 +08:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
res = MIN_ACL_ENTRIES;
|
|
|
|
}
|
2004-04-15 00:36:26 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GETACLCNT:
|
|
|
|
res = MIN_ACL_ENTRIES;
|
|
|
|
break;
|
2004-04-17 05:22:13 +08:00
|
|
|
default:
|
|
|
|
set_errno (EINVAL);
|
|
|
|
break;
|
2004-04-15 00:36:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-15 20:05:15 +08:00
|
|
|
if ((cmd == SETACL && !get_handle ())
|
|
|
|
|| (cmd != SETACL && !get_stat_handle ()))
|
2004-04-17 05:22:13 +08:00
|
|
|
{
|
2015-12-26 04:40:51 +08:00
|
|
|
query_open (cmd == SETACL ? query_write_dac : query_read_control);
|
2005-02-20 05:53:36 +08:00
|
|
|
if (!(oret = open (O_BINARY, 0)))
|
2007-07-30 18:58:16 +08:00
|
|
|
{
|
|
|
|
if (cmd == GETACL || cmd == GETACLCNT)
|
|
|
|
goto cant_access_acl;
|
|
|
|
return -1;
|
|
|
|
}
|
2004-04-17 05:22:13 +08:00
|
|
|
}
|
2004-04-15 00:36:26 +08:00
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case SETACL:
|
Cygwin: simplify some function names
Remove "32" or "64" from each of the following names: acl32,
aclcheck32, aclfrommode32, aclfrompbits32, aclfromtext32, aclsort32,
acltomode32, acltopbits32, acltotext32, facl32, fchown32, fcntl64,
fstat64, _fstat64, _fstat64_r, ftruncate64, getgid32, getgrent32,
getgrgid32, getgrnam32, getgroups32, getpwuid32, getpwuid_r32,
getuid32, getuid32, initgroups32, lseek64, lstat64, mknod32, mmap64,
setegid32, seteuid32, setgid32, setgroups32, setregid32, setreuid32,
setuid32, stat64, _stat64_r, truncate64.
Remove prototypes and macro definitions of these names.
Remove "#ifndef __INSIDE_CYGWIN__" from some headers so that the new
names will be available when compiling Cygwin.
Remove aliases that are no longer needed.
Include <unistd.h> in fhandler_clipboard.cc for the declarations of
geteuid and getegid.
2022-05-23 03:18:48 +08:00
|
|
|
if (!aclsort (nentries, 0, aclbufp))
|
2007-01-07 20:44:10 +08:00
|
|
|
{
|
|
|
|
bool rw = false;
|
2007-07-29 16:23:04 +08:00
|
|
|
res = setacl (get_handle (), pc, nentries, aclbufp, rw);
|
2007-01-07 20:44:10 +08:00
|
|
|
if (rw)
|
2007-07-29 16:23:04 +08:00
|
|
|
{
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
FILE_BASIC_INFORMATION fbi;
|
|
|
|
fbi.CreationTime.QuadPart
|
|
|
|
= fbi.LastAccessTime.QuadPart
|
|
|
|
= fbi.LastWriteTime.QuadPart
|
|
|
|
= fbi.ChangeTime.QuadPart = 0LL;
|
2007-07-29 23:57:41 +08:00
|
|
|
fbi.FileAttributes = (pc.file_attributes ()
|
|
|
|
& ~FILE_ATTRIBUTE_READONLY)
|
|
|
|
?: FILE_ATTRIBUTE_NORMAL;
|
2007-07-29 16:23:04 +08:00
|
|
|
NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi,
|
|
|
|
FileBasicInformation);
|
|
|
|
}
|
2007-01-07 20:44:10 +08:00
|
|
|
}
|
2004-04-15 00:36:26 +08:00
|
|
|
break;
|
|
|
|
case GETACL:
|
|
|
|
if (!aclbufp)
|
|
|
|
set_errno(EFAULT);
|
2016-03-20 01:45:49 +08:00
|
|
|
else {
|
2010-06-15 20:05:15 +08:00
|
|
|
res = getacl (get_stat_handle (), pc, nentries, aclbufp);
|
2010-09-24 20:41:33 +08:00
|
|
|
/* For this ENOSYS case, see security.cc:get_file_attribute(). */
|
|
|
|
if (res == -1 && get_errno () == ENOSYS)
|
2011-06-06 13:02:13 +08:00
|
|
|
goto cant_access_acl;
|
2016-03-20 01:45:49 +08:00
|
|
|
}
|
2004-04-15 00:36:26 +08:00
|
|
|
break;
|
|
|
|
case GETACLCNT:
|
2010-06-15 20:05:15 +08:00
|
|
|
res = getacl (get_stat_handle (), pc, 0, NULL);
|
2010-09-24 20:41:33 +08:00
|
|
|
/* Ditto. */
|
|
|
|
if (res == -1 && get_errno () == ENOSYS)
|
|
|
|
goto cant_access_acl;
|
2005-06-27 22:18:13 +08:00
|
|
|
break;
|
2004-04-15 00:36:26 +08:00
|
|
|
default:
|
|
|
|
set_errno (EINVAL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (oret)
|
2008-03-01 00:38:51 +08:00
|
|
|
close_fs ();
|
2004-04-15 00:36:26 +08:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
* Makefile.in (DLL_OFILES): Add ntea.o.
* cygwin.din (getxattr, listxattr, removexattr, setxattr, lgetxattr,
llistxattr, lremovexattr, lsetxattr, fgetxattr, flistxattr,
fremovexattr, fsetxattr): Export Linux extended attribute functions.
Sort.
* errno.cc (errmap): Add mappings for ERROR_EAS_DIDNT_FIT,
ERROR_EAS_NOT_SUPPORTED, ERROR_EA_LIST_INCONSISTENT,
ERROR_EA_TABLE_FULL, ERROR_FILE_CORRUPT, ERROR_INVALID_EA_NAME.
* fhandler.h (class fhandler_base): Declare new fgetxattr and
fsetxattr methods.
(class fhandler_disk_file): Ditto.
* fhandler.cc (fhandler_base::fgetxattr): New method.
(fhandler_base::fsetxattr): New method.
* fhandler_disk_file.cc (fhandler_disk_file::fgetxattr): New method.
(fhandler_disk_file::fsetxattr): New method.
* ntdll.h (STATUS_EA_TOO_LARGE): Define.
(STATUS_NONEXISTENT_EA_ENTRY): Define.
(STATUS_NO_EAS_ON_FILE): Define.
* ntea.cc (read_ea): Rewrite for long pathnames and for using with
Linux extended attribute functions.
(write_ea): Ditto.
(getxattr_worker): New static function.
(getxattr): New function.
(lgetxattr): New function.
(fgetxattr): New function.
(listxattr): New function.
(llistxattr): New function.
(flistxattr): New function.
(setxattr_worker): New static function.
(setxattr): New function.
(lsetxattr): New function.
(fsetxattr): New function.
(removexattr): New function.
(lsetxattr): New function.
(fsetxattr): New function.
* security.h (read_ea): Change declaration according to above changes.
(write_ea): Ditto.
* include/cygwin/version.h: Bump API minor version.
2008-02-10 23:43:04 +08:00
|
|
|
ssize_t
|
|
|
|
fhandler_disk_file::fgetxattr (const char *name, void *value, size_t size)
|
|
|
|
{
|
|
|
|
if (pc.is_fs_special ())
|
|
|
|
{
|
|
|
|
set_errno (ENOTSUP);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return read_ea (get_handle (), pc, name, (char *) value, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_disk_file::fsetxattr (const char *name, const void *value, size_t size,
|
|
|
|
int flags)
|
|
|
|
{
|
|
|
|
if (pc.is_fs_special ())
|
|
|
|
{
|
|
|
|
set_errno (ENOTSUP);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return write_ea (get_handle (), pc, name, (const char *) value, size, flags);
|
|
|
|
}
|
|
|
|
|
2005-02-03 06:42:06 +08:00
|
|
|
int
|
2013-04-23 17:44:36 +08:00
|
|
|
fhandler_disk_file::fadvise (off_t offset, off_t length, int advice)
|
2005-02-03 06:42:06 +08:00
|
|
|
{
|
2006-08-08 03:29:14 +08:00
|
|
|
if (advice < POSIX_FADV_NORMAL || advice > POSIX_FADV_NOREUSE)
|
2017-11-02 23:45:34 +08:00
|
|
|
return EINVAL;
|
2006-08-08 03:29:14 +08:00
|
|
|
|
|
|
|
/* Windows only supports advice flags for the whole file. We're using
|
|
|
|
a simplified test here so that we don't have to ask for the actual
|
|
|
|
file size. Length == 0 means all bytes starting at offset anyway.
|
|
|
|
So we only actually follow the advice, if it's given for offset == 0. */
|
|
|
|
if (offset != 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* We only support normal and sequential mode for now. Everything which
|
|
|
|
is not POSIX_FADV_SEQUENTIAL is treated like POSIX_FADV_NORMAL. */
|
|
|
|
if (advice != POSIX_FADV_SEQUENTIAL)
|
|
|
|
advice = POSIX_FADV_NORMAL;
|
|
|
|
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
FILE_MODE_INFORMATION fmi;
|
|
|
|
NTSTATUS status = NtQueryInformationFile (get_handle (), &io,
|
|
|
|
&fmi, sizeof fmi,
|
|
|
|
FileModeInformation);
|
2017-11-02 23:45:34 +08:00
|
|
|
if (NT_SUCCESS (status))
|
2006-08-08 03:29:14 +08:00
|
|
|
{
|
|
|
|
fmi.Mode &= ~FILE_SEQUENTIAL_ONLY;
|
|
|
|
if (advice == POSIX_FADV_SEQUENTIAL)
|
2007-02-20 08:16:18 +08:00
|
|
|
fmi.Mode |= FILE_SEQUENTIAL_ONLY;
|
2006-08-08 03:29:14 +08:00
|
|
|
status = NtSetInformationFile (get_handle (), &io, &fmi, sizeof fmi,
|
|
|
|
FileModeInformation);
|
|
|
|
if (NT_SUCCESS (status))
|
|
|
|
return 0;
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
}
|
|
|
|
|
2017-11-02 23:45:34 +08:00
|
|
|
return geterrno_from_nt_status (status);
|
2006-08-08 03:29:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2023-11-28 17:42:52 +08:00
|
|
|
fhandler_disk_file::falloc_allocate (int mode, off_t offset, off_t length)
|
2006-08-08 03:29:14 +08:00
|
|
|
{
|
2023-11-28 17:42:52 +08:00
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
FILE_STANDARD_INFORMATION fsi;
|
|
|
|
FILE_END_OF_FILE_INFORMATION feofi;
|
|
|
|
FILE_ALLOCATION_INFORMATION fai = { 0 };
|
2023-11-27 04:05:07 +08:00
|
|
|
|
2023-11-28 17:42:52 +08:00
|
|
|
/* Fetch EOF */
|
|
|
|
status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
|
|
|
|
FileStandardInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
return geterrno_from_nt_status (status);
|
2023-11-27 04:05:07 +08:00
|
|
|
|
2023-11-28 17:42:52 +08:00
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
/* For posix_fallocate(3), truncating the file is a no-op. However,
|
|
|
|
for sparse files we still have to allocate the blocks within
|
|
|
|
offset and offset + length which are currently in holes, due to
|
|
|
|
the following POSIX requirement:
|
|
|
|
"If posix_fallocate() returns successfully, subsequent writes to
|
|
|
|
the specified file data shall not fail due to the lack of free
|
|
|
|
space on the file system storage media." */
|
|
|
|
if (offset + length <= fsi.EndOfFile.QuadPart)
|
2023-11-27 04:05:07 +08:00
|
|
|
{
|
2023-11-28 17:42:52 +08:00
|
|
|
if (!has_attribute (FILE_ATTRIBUTE_SPARSE_FILE))
|
2023-11-27 04:05:07 +08:00
|
|
|
return 0;
|
2023-11-28 17:42:52 +08:00
|
|
|
feofi.EndOfFile.QuadPart = fsi.EndOfFile.QuadPart;
|
2023-11-27 04:05:07 +08:00
|
|
|
}
|
2023-11-28 17:42:52 +08:00
|
|
|
else
|
|
|
|
feofi.EndOfFile.QuadPart = offset + length;
|
|
|
|
break;
|
|
|
|
case __FALLOC_FL_TRUNCATE:
|
|
|
|
/* For ftruncate(2), offset is 0. Just use length as is. */
|
|
|
|
feofi.EndOfFile.QuadPart = length;
|
2006-08-08 03:29:14 +08:00
|
|
|
|
2023-11-28 17:42:52 +08:00
|
|
|
/* Make file sparse only when called through ftruncate and the mount
|
|
|
|
mode supports sparse files. Also, make sure that the new region
|
|
|
|
actually spans over at least one sparsifiable chunk. */
|
|
|
|
if (pc.support_sparse ()
|
2012-12-14 18:45:29 +08:00
|
|
|
&& !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE)
|
2023-11-28 17:42:52 +08:00
|
|
|
&& span_sparse_chunk (feofi.EndOfFile.QuadPart,
|
|
|
|
fsi.EndOfFile.QuadPart))
|
2007-02-20 08:16:18 +08:00
|
|
|
{
|
2007-07-27 21:19:41 +08:00
|
|
|
status = NtFsControlFile (get_handle (), NULL, NULL, NULL, &io,
|
|
|
|
FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
|
2012-12-14 18:45:29 +08:00
|
|
|
if (NT_SUCCESS (status))
|
|
|
|
pc.file_attributes (pc.file_attributes ()
|
2023-11-28 17:42:52 +08:00
|
|
|
| FILE_ATTRIBUTE_SPARSE_FILE);
|
|
|
|
debug_printf ("%y = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
|
|
|
status, pc.get_nt_native_path ());
|
2006-08-08 03:29:14 +08:00
|
|
|
}
|
2023-11-28 17:42:52 +08:00
|
|
|
break;
|
|
|
|
case FALLOC_FL_KEEP_SIZE:
|
|
|
|
/* Keep track of the allocation size for overallocation below.
|
|
|
|
Note that overallocation in Windows is only temporary!
|
|
|
|
As soon as the last open handle to the file is closed, the
|
|
|
|
overallocation gets removed by the system. Also, overallocation
|
|
|
|
for sparse files fails silently, so just don't bother. */
|
|
|
|
if (offset + length > fsi.EndOfFile.QuadPart
|
|
|
|
&& !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE))
|
|
|
|
fai.AllocationSize.QuadPart = offset + length;
|
|
|
|
|
|
|
|
feofi.EndOfFile.QuadPart = fsi.EndOfFile.QuadPart;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now set the new EOF */
|
|
|
|
if (feofi.EndOfFile.QuadPart != fsi.EndOfFile.QuadPart)
|
|
|
|
{
|
2007-02-22 18:54:47 +08:00
|
|
|
status = NtSetInformationFile (get_handle (), &io,
|
|
|
|
&feofi, sizeof feofi,
|
|
|
|
FileEndOfFileInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
2023-11-28 17:42:52 +08:00
|
|
|
return geterrno_from_nt_status (status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If called via fallocate(2) or posix_fallocate(3), allocate blocks in
|
|
|
|
sparse file holes. */
|
|
|
|
if (mode != __FALLOC_FL_TRUNCATE
|
|
|
|
&& length
|
|
|
|
&& has_attribute (FILE_ATTRIBUTE_SPARSE_FILE))
|
|
|
|
{
|
|
|
|
int res = falloc_zero_range (mode | __FALLOC_FL_ZERO_HOLES,
|
|
|
|
offset, length);
|
|
|
|
if (res)
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Last but not least, set the new allocation size, if any */
|
|
|
|
if (fai.AllocationSize.QuadPart)
|
|
|
|
{
|
|
|
|
/* This is not fatal. Just note a failure in the debug output. */
|
|
|
|
status = NtSetInformationFile (get_handle (), &io,
|
|
|
|
&fai, sizeof fai,
|
|
|
|
FileAllocationInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
debug_printf ("%y = NtSetInformationFile(%S, "
|
|
|
|
"FileAllocationInformation)",
|
|
|
|
status, pc.get_nt_native_path ());
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_disk_file::falloc_punch_hole (off_t offset, off_t length)
|
|
|
|
{
|
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
FILE_STANDARD_INFORMATION fsi;
|
|
|
|
FILE_ZERO_DATA_INFORMATION fzi;
|
|
|
|
|
|
|
|
/* Fetch EOF */
|
|
|
|
status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
|
|
|
|
FileStandardInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
return geterrno_from_nt_status (status);
|
|
|
|
|
|
|
|
if (offset > fsi.EndOfFile.QuadPart) /* no-op */
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (offset + length > fsi.EndOfFile.QuadPart)
|
|
|
|
length = fsi.EndOfFile.QuadPart - offset;
|
|
|
|
|
|
|
|
/* If the file isn't sparse yet, make it so. */
|
|
|
|
if (!has_attribute (FILE_ATTRIBUTE_SPARSE_FILE))
|
|
|
|
{
|
|
|
|
status = NtFsControlFile (get_handle (), NULL, NULL, NULL, &io,
|
|
|
|
FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
|
|
|
|
debug_printf ("%y = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
|
|
|
status, pc.get_nt_native_path ());
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
return geterrno_from_nt_status (status);
|
|
|
|
pc.file_attributes (pc.file_attributes () | FILE_ATTRIBUTE_SPARSE_FILE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now punch a hole. For once, FSCTL_SET_ZERO_DATA does it exactly as per
|
|
|
|
fallocate(FALLOC_FL_PUNCH_HOLE) specs. */
|
|
|
|
fzi.FileOffset.QuadPart = offset;
|
|
|
|
fzi.BeyondFinalZero.QuadPart = offset + length;
|
|
|
|
status = NtFsControlFile (get_handle (), NULL, NULL, NULL, &io,
|
|
|
|
FSCTL_SET_ZERO_DATA, &fzi, sizeof fzi, NULL, 0);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
return geterrno_from_nt_status (status);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_disk_file::falloc_zero_range (int mode, off_t offset, off_t length)
|
|
|
|
{
|
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
FILE_STANDARD_INFORMATION fsi;
|
|
|
|
FILE_ALLOCATED_RANGE_BUFFER inp, *out = NULL;
|
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
HANDLE zo_handle;
|
|
|
|
tmp_pathbuf tp;
|
|
|
|
size_t data_chunk_count = 0;
|
|
|
|
|
|
|
|
/* Fetch EOF */
|
|
|
|
status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
|
|
|
|
FileStandardInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
return geterrno_from_nt_status (status);
|
|
|
|
|
|
|
|
/* offset and length must not exceed EOF with FALLOC_FL_KEEP_SIZE */
|
|
|
|
if (mode & FALLOC_FL_KEEP_SIZE)
|
|
|
|
{
|
|
|
|
if (offset > fsi.EndOfFile.QuadPart) /* no-op */
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (offset + length > fsi.EndOfFile.QuadPart)
|
|
|
|
length = fsi.EndOfFile.QuadPart - offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the file is sparse, fetch the data ranges within the file
|
|
|
|
to be able to recognize holes. */
|
|
|
|
if (has_attribute (FILE_ATTRIBUTE_SPARSE_FILE))
|
|
|
|
{
|
|
|
|
inp.FileOffset.QuadPart = offset;
|
|
|
|
inp.Length.QuadPart = length;
|
|
|
|
out = (FILE_ALLOCATED_RANGE_BUFFER *) tp.t_get ();
|
|
|
|
status = NtFsControlFile (get_handle (), NULL, NULL, NULL,
|
|
|
|
&io, FSCTL_QUERY_ALLOCATED_RANGES,
|
|
|
|
&inp, sizeof inp, out, 2 * NT_MAX_PATH);
|
2023-12-02 21:38:28 +08:00
|
|
|
if (!NT_ERROR (status))
|
2023-11-28 17:42:52 +08:00
|
|
|
data_chunk_count = io.Information / sizeof *out;
|
2005-02-03 06:42:06 +08:00
|
|
|
}
|
2023-11-28 17:42:52 +08:00
|
|
|
|
|
|
|
/* Re-open the file and use this handle ever after, so as not to
|
|
|
|
move the file pointer of the original file object. */
|
|
|
|
status = NtOpenFile (&zo_handle, SYNCHRONIZE | GENERIC_WRITE,
|
|
|
|
pc.init_reopen_attr (attr, get_handle ()), &io,
|
|
|
|
FILE_SHARE_VALID_FLAGS, get_options ());
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
return geterrno_from_nt_status (status);
|
|
|
|
|
|
|
|
/* FILE_SPARSE_GRANULARITY == 2 * NT_MAX_PATH ==> fits exactly */
|
|
|
|
char *nullbuf = tp.t_get ();
|
|
|
|
memset (nullbuf, 0, FILE_SPARSE_GRANULARITY);
|
|
|
|
int res = 0;
|
|
|
|
|
|
|
|
/* Split range into chunks of size FILE_SPARSE_GRANULARITY and handle
|
|
|
|
them according to being data or hole */
|
|
|
|
LARGE_INTEGER off = { QuadPart:offset };
|
|
|
|
size_t start_idx = 0;
|
|
|
|
while (length > 0)
|
|
|
|
{
|
|
|
|
off_t chunk_len;
|
|
|
|
bool in_data = true;
|
|
|
|
|
|
|
|
if (off.QuadPart % FILE_SPARSE_GRANULARITY) /* First block */
|
|
|
|
chunk_len = roundup2 (off.QuadPart, FILE_SPARSE_GRANULARITY) - off.QuadPart;
|
|
|
|
else
|
|
|
|
chunk_len = FILE_SPARSE_GRANULARITY;
|
|
|
|
if (chunk_len > length) /* First or last block */
|
|
|
|
chunk_len = length;
|
|
|
|
|
|
|
|
/* Check if the current chunk is within data or hole */
|
|
|
|
if (has_attribute (FILE_ATTRIBUTE_SPARSE_FILE)
|
|
|
|
&& off.QuadPart < fsi.EndOfFile.QuadPart)
|
|
|
|
{
|
|
|
|
in_data = false;
|
|
|
|
for (size_t idx = start_idx; idx < data_chunk_count; ++idx)
|
|
|
|
if (off.QuadPart >= out[idx].FileOffset.QuadPart)
|
|
|
|
{
|
|
|
|
/* Skip entries with lower start address next time. */
|
|
|
|
start_idx = idx;
|
|
|
|
if (off.QuadPart < out[idx].FileOffset.QuadPart
|
|
|
|
+ out[idx].Length.QuadPart)
|
|
|
|
{
|
|
|
|
in_data = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Eventually, write zeros into the block. Completely zero out data
|
|
|
|
blocks, just write a single zero to former holes in sparse files.
|
|
|
|
If __FALLOC_FL_ZERO_HOLES has been specified, only write to holes. */
|
|
|
|
if (!(mode & __FALLOC_FL_ZERO_HOLES) || !in_data)
|
|
|
|
{
|
|
|
|
status = NtWriteFile (zo_handle, NULL, NULL, NULL, &io, nullbuf,
|
|
|
|
in_data ? chunk_len : 1, &off, NULL);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
res = geterrno_from_nt_status (status);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
off.QuadPart += chunk_len;
|
|
|
|
length -= chunk_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
NtClose (zo_handle);
|
2005-02-03 06:42:06 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2023-11-28 17:42:52 +08:00
|
|
|
int
|
|
|
|
fhandler_disk_file::fallocate (int mode, off_t offset, off_t length)
|
|
|
|
{
|
|
|
|
if (length < 0 || !get_handle ())
|
|
|
|
return EINVAL;
|
|
|
|
if (pc.isdir ())
|
|
|
|
return EISDIR;
|
|
|
|
if (!(get_access () & GENERIC_WRITE))
|
|
|
|
return EBADF;
|
|
|
|
|
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case __FALLOC_FL_TRUNCATE:
|
|
|
|
case FALLOC_FL_KEEP_SIZE:
|
|
|
|
return falloc_allocate (mode, offset, length);
|
|
|
|
case FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE:
|
|
|
|
/* Only if the filesystem supports it... */
|
|
|
|
if (!(pc.fs_flags () & FILE_SUPPORTS_SPARSE_FILES))
|
|
|
|
return EOPNOTSUPP;
|
|
|
|
return falloc_punch_hole (offset, length);
|
|
|
|
case FALLOC_FL_ZERO_RANGE:
|
|
|
|
case FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE:
|
|
|
|
return falloc_zero_range (mode, offset, length);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return EINVAL;
|
|
|
|
}
|
|
|
|
|
2005-02-20 05:53:36 +08:00
|
|
|
int
|
|
|
|
fhandler_disk_file::link (const char *newpath)
|
|
|
|
{
|
2009-09-26 23:51:53 +08:00
|
|
|
size_t nlen = strlen (newpath);
|
|
|
|
path_conv newpc (newpath, PC_SYM_NOFOLLOW | PC_POSIX | PC_NULLEMPTY, stat_suffixes);
|
2005-02-20 05:53:36 +08:00
|
|
|
if (newpc.error)
|
|
|
|
{
|
2008-07-17 04:20:45 +08:00
|
|
|
set_errno (newpc.error);
|
2005-02-20 19:44:32 +08:00
|
|
|
return -1;
|
2005-02-20 05:53:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (newpc.exists ())
|
|
|
|
{
|
2007-08-14 22:48:52 +08:00
|
|
|
syscall_printf ("file '%S' exists?", newpc.get_nt_native_path ());
|
2005-02-20 05:53:36 +08:00
|
|
|
set_errno (EEXIST);
|
2005-02-20 19:44:32 +08:00
|
|
|
return -1;
|
2005-02-20 05:53:36 +08:00
|
|
|
}
|
|
|
|
|
2009-09-26 23:51:53 +08:00
|
|
|
if (isdirsep (newpath[nlen - 1]) || has_dot_last_component (newpath, false))
|
|
|
|
{
|
|
|
|
set_errno (ENOENT);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char new_buf[nlen + 5];
|
2008-07-17 04:20:45 +08:00
|
|
|
if (!newpc.error)
|
2005-02-20 05:53:36 +08:00
|
|
|
{
|
2019-07-21 05:55:12 +08:00
|
|
|
/* If the original file is a lnk special file,
|
2009-10-12 19:57:29 +08:00
|
|
|
and if the original file has a .lnk suffix, add one to the hardlink
|
|
|
|
as well. */
|
2019-07-21 05:55:12 +08:00
|
|
|
if (pc.is_lnk_special ()
|
2009-10-12 19:57:29 +08:00
|
|
|
&& RtlEqualUnicodePathSuffix (pc.get_nt_native_path (),
|
|
|
|
&ro_u_lnk, TRUE))
|
2006-02-06 02:18:02 +08:00
|
|
|
{
|
|
|
|
/* Shortcut hack. */
|
2007-07-28 00:24:07 +08:00
|
|
|
stpcpy (stpcpy (new_buf, newpath), ".lnk");
|
2006-02-06 02:18:02 +08:00
|
|
|
newpath = new_buf;
|
|
|
|
newpc.check (newpath, PC_SYM_NOFOLLOW);
|
|
|
|
}
|
2007-07-28 00:24:07 +08:00
|
|
|
else if (!pc.isdir ()
|
2007-07-31 23:20:00 +08:00
|
|
|
&& pc.is_binary ()
|
2009-01-07 22:12:40 +08:00
|
|
|
&& RtlEqualUnicodePathSuffix (pc.get_nt_native_path (),
|
2009-07-15 01:37:42 +08:00
|
|
|
&ro_u_exe, TRUE)
|
2007-07-29 00:08:45 +08:00
|
|
|
&& !RtlEqualUnicodePathSuffix (newpc.get_nt_native_path (),
|
2009-07-15 01:37:42 +08:00
|
|
|
&ro_u_exe, TRUE))
|
2006-05-28 23:50:14 +08:00
|
|
|
{
|
|
|
|
/* Executable hack. */
|
2007-07-28 00:24:07 +08:00
|
|
|
stpcpy (stpcpy (new_buf, newpath), ".exe");
|
2006-05-28 23:50:14 +08:00
|
|
|
newpath = new_buf;
|
|
|
|
newpc.check (newpath, PC_SYM_NOFOLLOW);
|
|
|
|
}
|
2005-02-20 05:53:36 +08:00
|
|
|
}
|
|
|
|
|
2010-06-15 20:05:15 +08:00
|
|
|
/* We only need READ_CONTROL access so the handle returned in pc is
|
|
|
|
sufficient. And if the file couldn't be opened with READ_CONTROL
|
|
|
|
access in path_conv, we won't be able to do it here anyway. */
|
|
|
|
HANDLE fh = get_stat_handle ();
|
|
|
|
if (!fh)
|
2007-02-23 02:01:13 +08:00
|
|
|
{
|
2010-06-15 20:05:15 +08:00
|
|
|
set_errno (EACCES);
|
2007-02-23 02:01:13 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2007-07-28 00:24:07 +08:00
|
|
|
PUNICODE_STRING tgt = newpc.get_nt_native_path ();
|
|
|
|
ULONG size = sizeof (FILE_LINK_INFORMATION) + tgt->Length;
|
|
|
|
PFILE_LINK_INFORMATION pfli = (PFILE_LINK_INFORMATION) alloca (size);
|
|
|
|
pfli->ReplaceIfExists = FALSE;
|
|
|
|
pfli->RootDirectory = NULL;
|
|
|
|
memcpy (pfli->FileName, tgt->Buffer, pfli->FileNameLength = tgt->Length);
|
2010-06-15 20:05:15 +08:00
|
|
|
|
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
2007-07-28 00:24:07 +08:00
|
|
|
status = NtSetInformationFile (fh, &io, pfli, size, FileLinkInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
2007-02-23 02:01:13 +08:00
|
|
|
{
|
2012-06-04 16:49:13 +08:00
|
|
|
if (status == STATUS_INVALID_DEVICE_REQUEST
|
|
|
|
|| status == STATUS_NOT_SUPPORTED)
|
2017-11-15 04:29:08 +08:00
|
|
|
/* FS doesn't support hard links. Linux returns EPERM. */
|
|
|
|
set_errno (EPERM);
|
2007-07-28 00:24:07 +08:00
|
|
|
else
|
2017-11-15 04:29:08 +08:00
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
return -1;
|
2005-02-20 05:53:36 +08:00
|
|
|
}
|
2018-02-14 19:55:24 +08:00
|
|
|
else if ((pc.file_attributes () & O_TMPFILE_FILE_ATTRS)
|
|
|
|
== O_TMPFILE_FILE_ATTRS)
|
|
|
|
{
|
|
|
|
/* An O_TMPFILE file has FILE_ATTRIBUTE_TEMPORARY and
|
|
|
|
FILE_ATTRIBUTE_HIDDEN set. After a successful hardlink the file is
|
|
|
|
not temporary anymore in the usual sense. So we remove these
|
2018-03-10 04:13:28 +08:00
|
|
|
attributes here.
|
2018-02-14 19:55:24 +08:00
|
|
|
|
|
|
|
Note that we don't create a reopen attribute for the original
|
|
|
|
link but rather a normal attribute for the just created link.
|
2018-03-10 04:13:28 +08:00
|
|
|
The reason is a curious behaviour of Windows: If we remove the
|
|
|
|
O_TMPFILE attributes on the original link, the new link will not
|
|
|
|
show up in file system listings (not even native ones from , e.g.,
|
|
|
|
`cmd /c dir'), long after the original link has been closed and
|
|
|
|
removed. The file and its metadata will be kept in memory only
|
|
|
|
as long as Windows sees fit. By opening the new link, we request
|
|
|
|
the attribute changes on the new link, so after closing it Windows
|
|
|
|
will have an increased interest to write back the metadata. */
|
2017-11-15 04:28:45 +08:00
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
status = NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
|
2018-02-14 19:55:24 +08:00
|
|
|
newpc.get_object_attr (attr, sec_none_nih), &io,
|
2017-11-15 04:28:45 +08:00
|
|
|
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
debug_printf ("Opening for removing TEMPORARY attrib failed, "
|
|
|
|
"status = %y", status);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FILE_BASIC_INFORMATION fbi;
|
|
|
|
|
|
|
|
fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart
|
|
|
|
= fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL;
|
2018-02-14 19:55:24 +08:00
|
|
|
fbi.FileAttributes = (pc.file_attributes () & ~O_TMPFILE_FILE_ATTRS)
|
2017-11-15 04:28:45 +08:00
|
|
|
?: FILE_ATTRIBUTE_NORMAL;
|
|
|
|
status = NtSetInformationFile (fh, &io, &fbi, sizeof fbi,
|
|
|
|
FileBasicInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
debug_printf ("Removing the TEMPORARY attrib failed, status = %y",
|
|
|
|
status);
|
|
|
|
NtClose (fh);
|
|
|
|
}
|
|
|
|
}
|
2007-02-23 02:01:13 +08:00
|
|
|
return 0;
|
2005-02-20 05:53:36 +08:00
|
|
|
}
|
|
|
|
|
2005-02-20 19:44:32 +08:00
|
|
|
int
|
2008-04-24 17:59:54 +08:00
|
|
|
fhandler_disk_file::utimens (const struct timespec *tvp)
|
2005-04-14 00:17:37 +08:00
|
|
|
{
|
2008-04-24 17:59:54 +08:00
|
|
|
return utimens_fs (tvp);
|
2005-04-14 00:17:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2008-04-24 17:59:54 +08:00
|
|
|
fhandler_base::utimens_fs (const struct timespec *tvp)
|
2005-02-20 19:44:32 +08:00
|
|
|
{
|
2008-04-24 17:59:54 +08:00
|
|
|
struct timespec timeofday;
|
|
|
|
struct timespec tmp[2];
|
2007-07-29 16:23:04 +08:00
|
|
|
bool closeit = false;
|
2005-02-20 19:44:32 +08:00
|
|
|
|
2007-07-29 16:23:04 +08:00
|
|
|
if (!get_handle ())
|
2005-10-20 00:50:43 +08:00
|
|
|
{
|
|
|
|
query_open (query_write_attributes);
|
|
|
|
if (!open_fs (O_BINARY, 0))
|
2005-03-17 05:21:18 +08:00
|
|
|
{
|
2005-10-20 00:50:43 +08:00
|
|
|
/* It's documented in MSDN that FILE_WRITE_ATTRIBUTES is sufficient
|
|
|
|
to change the timestamps. Unfortunately it's not sufficient for a
|
|
|
|
remote HPFS which requires GENERIC_WRITE, so we just retry to open
|
|
|
|
for writing, though this fails for R/O files of course. */
|
|
|
|
query_open (no_query);
|
|
|
|
if (!open_fs (O_WRONLY | O_BINARY, 0))
|
|
|
|
{
|
|
|
|
syscall_printf ("Opening file failed");
|
|
|
|
return -1;
|
|
|
|
}
|
2005-03-17 05:21:18 +08:00
|
|
|
}
|
2005-10-20 00:50:43 +08:00
|
|
|
closeit = true;
|
2005-02-20 19:44:32 +08:00
|
|
|
}
|
|
|
|
|
2009-10-13 10:26:33 +08:00
|
|
|
clock_gettime (CLOCK_REALTIME, &timeofday);
|
2005-02-20 19:44:32 +08:00
|
|
|
if (!tvp)
|
2008-04-24 17:59:54 +08:00
|
|
|
tmp[1] = tmp[0] = timeofday;
|
|
|
|
else
|
2005-02-20 19:44:32 +08:00
|
|
|
{
|
2018-02-07 20:07:44 +08:00
|
|
|
if ((tvp[0].tv_nsec < UTIME_NOW || tvp[0].tv_nsec >= NSPERSEC)
|
|
|
|
|| (tvp[1].tv_nsec < UTIME_NOW || tvp[1].tv_nsec >= NSPERSEC))
|
2008-04-24 17:59:54 +08:00
|
|
|
{
|
2009-10-08 19:13:45 +08:00
|
|
|
if (closeit)
|
|
|
|
close_fs ();
|
2008-04-24 17:59:54 +08:00
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
tmp[0] = (tvp[0].tv_nsec == UTIME_NOW) ? timeofday : tvp[0];
|
|
|
|
tmp[1] = (tvp[1].tv_nsec == UTIME_NOW) ? timeofday : tvp[1];
|
2005-02-20 19:44:32 +08:00
|
|
|
}
|
2013-04-23 17:44:36 +08:00
|
|
|
debug_printf ("incoming lastaccess %ly %ly", tmp[0].tv_sec, tmp[0].tv_nsec);
|
2005-04-14 00:17:37 +08:00
|
|
|
|
2007-07-29 16:23:04 +08:00
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
FILE_BASIC_INFORMATION fbi;
|
2009-07-21 16:10:36 +08:00
|
|
|
|
2007-07-29 16:23:04 +08:00
|
|
|
fbi.CreationTime.QuadPart = 0LL;
|
2009-07-21 16:10:36 +08:00
|
|
|
/* UTIME_OMIT is handled in timespec_to_filetime by setting FILETIME to 0. */
|
2013-06-14 17:09:41 +08:00
|
|
|
timespec_to_filetime (&tmp[0], &fbi.LastAccessTime);
|
|
|
|
timespec_to_filetime (&tmp[1], &fbi.LastWriteTime);
|
2007-07-29 16:23:04 +08:00
|
|
|
fbi.ChangeTime.QuadPart = 0LL;
|
|
|
|
fbi.FileAttributes = 0;
|
|
|
|
NTSTATUS status = NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi,
|
|
|
|
FileBasicInformation);
|
2009-07-21 16:10:36 +08:00
|
|
|
/* For this special case for MVFS see the comment in
|
|
|
|
fhandler_disk_file::fchmod. */
|
|
|
|
if (pc.fs_is_mvfs () && NT_SUCCESS (status) && !closeit)
|
|
|
|
{
|
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
HANDLE fh;
|
|
|
|
|
2014-08-27 04:47:46 +08:00
|
|
|
if (NT_SUCCESS (NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
|
|
|
|
pc.init_reopen_attr (attr, get_handle ()),
|
|
|
|
&io, FILE_SHARE_VALID_FLAGS,
|
2009-07-21 16:10:36 +08:00
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT)))
|
|
|
|
{
|
|
|
|
NtSetInformationFile (fh, &io, &fbi, sizeof fbi,
|
|
|
|
FileBasicInformation);
|
|
|
|
NtClose (fh);
|
|
|
|
}
|
|
|
|
}
|
2007-08-14 22:48:52 +08:00
|
|
|
if (closeit)
|
|
|
|
close_fs ();
|
2005-04-17 01:17:33 +08:00
|
|
|
/* Opening a directory on a 9x share from a NT machine works(!), but
|
2007-07-29 16:23:04 +08:00
|
|
|
then NtSetInformationFile fails with STATUS_NOT_SUPPORTED. Oh well... */
|
|
|
|
if (!NT_SUCCESS (status) && status != STATUS_NOT_SUPPORTED)
|
2005-02-20 19:44:32 +08:00
|
|
|
{
|
2007-07-29 16:23:04 +08:00
|
|
|
__seterrno_from_nt_status (status);
|
2005-02-20 19:44:32 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2005-02-20 05:53:36 +08:00
|
|
|
|
2001-11-21 14:47:57 +08:00
|
|
|
fhandler_disk_file::fhandler_disk_file () :
|
2013-06-04 18:24:43 +08:00
|
|
|
fhandler_base (), prw_handle (NULL)
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2005-02-20 19:44:32 +08:00
|
|
|
fhandler_disk_file::fhandler_disk_file (path_conv &pc) :
|
2013-06-04 18:24:43 +08:00
|
|
|
fhandler_base (), prw_handle (NULL)
|
2005-02-20 19:44:32 +08:00
|
|
|
{
|
|
|
|
set_name (pc);
|
|
|
|
}
|
|
|
|
|
2001-11-21 14:47:57 +08:00
|
|
|
int
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
fhandler_disk_file::open (int flags, mode_t mode)
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
return open_fs (flags, mode);
|
|
|
|
}
|
|
|
|
|
2011-06-17 19:04:44 +08:00
|
|
|
int
|
|
|
|
fhandler_disk_file::close ()
|
|
|
|
{
|
2011-08-28 04:01:29 +08:00
|
|
|
/* Close extra pread/pwrite handle, if it exists. */
|
2011-06-17 19:04:44 +08:00
|
|
|
if (prw_handle)
|
|
|
|
NtClose (prw_handle);
|
|
|
|
return fhandler_base::close ();
|
|
|
|
}
|
|
|
|
|
2013-06-02 18:22:14 +08:00
|
|
|
int
|
|
|
|
fhandler_disk_file::fcntl (int cmd, intptr_t arg)
|
|
|
|
{
|
|
|
|
int res;
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
{
|
2013-10-24 17:41:17 +08:00
|
|
|
case F_LCK_MANDATORY: /* Mandatory locking only works on files. */
|
2013-06-04 18:24:43 +08:00
|
|
|
mandatory_locking (!!arg);
|
|
|
|
need_fork_fixup (true);
|
2013-06-02 18:22:14 +08:00
|
|
|
res = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
res = fhandler_base::fcntl (cmd, arg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2011-06-17 19:04:44 +08:00
|
|
|
int
|
2011-10-16 06:37:30 +08:00
|
|
|
fhandler_disk_file::dup (fhandler_base *child, int flags)
|
2011-06-17 19:04:44 +08:00
|
|
|
{
|
|
|
|
fhandler_disk_file *fhc = (fhandler_disk_file *) child;
|
|
|
|
|
2011-10-16 06:37:30 +08:00
|
|
|
int ret = fhandler_base::dup (child, flags);
|
2011-06-17 19:04:44 +08:00
|
|
|
if (!ret && prw_handle
|
|
|
|
&& !DuplicateHandle (GetCurrentProcess (), prw_handle,
|
|
|
|
GetCurrentProcess (), &fhc->prw_handle,
|
2021-08-31 03:56:33 +08:00
|
|
|
0, FALSE, DUPLICATE_SAME_ACCESS))
|
2013-06-02 18:22:14 +08:00
|
|
|
fhc->prw_handle = NULL;
|
2011-06-17 19:04:44 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
fhandler_disk_file::fixup_after_fork (HANDLE parent)
|
|
|
|
{
|
|
|
|
prw_handle = NULL;
|
2013-06-04 18:24:43 +08:00
|
|
|
mandatory_locking (false);
|
2011-06-17 19:04:44 +08:00
|
|
|
fhandler_base::fixup_after_fork (parent);
|
|
|
|
}
|
|
|
|
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
int
|
|
|
|
fhandler_base::open_fs (int flags, mode_t mode)
|
|
|
|
{
|
2005-01-07 01:43:55 +08:00
|
|
|
/* Unfortunately NT allows to open directories for writing, but that's
|
|
|
|
disallowed according to SUSv3. */
|
2005-12-15 00:38:22 +08:00
|
|
|
if (pc.isdir () && (flags & O_ACCMODE) != O_RDONLY)
|
2005-01-07 01:43:55 +08:00
|
|
|
{
|
|
|
|
set_errno (EISDIR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-21 19:39:04 +08:00
|
|
|
bool new_file = !exists ();
|
|
|
|
|
2020-09-08 04:45:38 +08:00
|
|
|
int res = fhandler_base::open (flags, mode);
|
2015-12-15 20:56:39 +08:00
|
|
|
if (res)
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
2015-12-15 20:56:39 +08:00
|
|
|
/* The file info in pc is wrong at this point for newly created files.
|
|
|
|
Refresh it before fetching any file info. */
|
|
|
|
if (new_file)
|
2019-03-30 15:12:02 +08:00
|
|
|
pc.get_finfo (get_handle ());
|
2016-06-21 19:39:04 +08:00
|
|
|
|
2015-12-15 20:56:39 +08:00
|
|
|
if (pc.isgood_inode (pc.get_ino ()))
|
|
|
|
ino = pc.get_ino ();
|
|
|
|
}
|
2001-11-21 14:47:57 +08:00
|
|
|
|
2013-04-23 17:44:36 +08:00
|
|
|
syscall_printf ("%d = fhandler_disk_file::open(%S, %y)", res,
|
2007-08-14 22:48:52 +08:00
|
|
|
pc.get_nt_native_path (), flags);
|
2001-11-21 14:47:57 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2011-06-17 19:04:44 +08:00
|
|
|
/* POSIX demands that pread/pwrite don't change the current file position.
|
|
|
|
While NtReadFile/NtWriteFile support atomic seek-and-io, both change the
|
|
|
|
file pointer if the file handle has been opened for synchonous I/O.
|
|
|
|
Using this handle for pread/pwrite would break atomicity, because the
|
|
|
|
read/write operation would have to be followed by a seek back to the old
|
|
|
|
file position. What we do is to open another handle to the file on the
|
|
|
|
first call to either pread or pwrite. This is used for any subsequent
|
|
|
|
pread/pwrite. Thus the current file position of the "normal" file
|
|
|
|
handle is not touched.
|
2011-12-18 07:39:47 +08:00
|
|
|
|
2011-06-17 19:04:44 +08:00
|
|
|
FIXME:
|
|
|
|
|
|
|
|
Note that this is just a hack. The problem with this approach is that
|
|
|
|
a change to the file permissions might disallow to open the file with
|
|
|
|
the required permissions to read or write. This appears to be a border case,
|
|
|
|
but that's exactly what git does. It creates the file for reading and
|
|
|
|
writing and after writing it, it chmods the file to read-only. Then it
|
|
|
|
calls pread on the file to examine the content. This works, but if git
|
|
|
|
would use the original handle to pwrite to the file, it would be broken
|
|
|
|
with our approach.
|
|
|
|
|
|
|
|
One way to implement this is to open the pread/pwrite handle right at
|
|
|
|
file open time. We would simply maintain two handles, which wouldn't
|
|
|
|
be much of a problem given how we do that for other fhandler types as
|
|
|
|
well.
|
|
|
|
|
|
|
|
However, ultimately fhandler_disk_file should become a derived class of
|
|
|
|
fhandler_base_overlapped. Each raw_read or raw_write would fetch the
|
|
|
|
actual file position, read/write from there, and then set the file
|
|
|
|
position again. Fortunately, while the file position is not maintained
|
|
|
|
by the I/O manager, it can be fetched and set to a new value by all
|
|
|
|
processes holding a handle to that file object. Pread and pwrite differ
|
|
|
|
from raw_read and raw_write just by not touching the current file pos.
|
|
|
|
Actually they could be merged with raw_read/raw_write if we add a position
|
|
|
|
parameter to the latter. */
|
|
|
|
|
|
|
|
int
|
2018-07-24 13:31:58 +08:00
|
|
|
fhandler_disk_file::prw_open (bool write, void *aio)
|
2011-06-17 19:04:44 +08:00
|
|
|
{
|
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
OBJECT_ATTRIBUTES attr;
|
2018-07-24 13:31:58 +08:00
|
|
|
ULONG options = get_options ();
|
|
|
|
|
|
|
|
/* If async i/o is intended, turn off the default synchronous operation */
|
|
|
|
if (aio)
|
|
|
|
options &= ~FILE_SYNCHRONOUS_IO_NONALERT;
|
2011-06-17 19:04:44 +08:00
|
|
|
|
|
|
|
/* First try to open with the original access mask */
|
|
|
|
ACCESS_MASK access = get_access ();
|
2014-08-27 04:47:46 +08:00
|
|
|
status = NtOpenFile (&prw_handle, access,
|
|
|
|
pc.init_reopen_attr (attr, get_handle ()), &io,
|
2018-07-24 13:31:58 +08:00
|
|
|
FILE_SHARE_VALID_FLAGS, options);
|
2011-06-17 19:04:44 +08:00
|
|
|
if (status == STATUS_ACCESS_DENIED)
|
|
|
|
{
|
|
|
|
/* If we get an access denied, chmod has been called. Try again
|
|
|
|
with just the required rights to perform the called function. */
|
|
|
|
access &= write ? ~GENERIC_READ : ~GENERIC_WRITE;
|
|
|
|
status = NtOpenFile (&prw_handle, access, &attr, &io,
|
2018-07-24 13:31:58 +08:00
|
|
|
FILE_SHARE_VALID_FLAGS, options);
|
2011-06-17 19:04:44 +08:00
|
|
|
}
|
2013-04-23 17:44:36 +08:00
|
|
|
debug_printf ("%y = NtOpenFile (%p, %y, %S, io, %y, %y)",
|
2011-06-17 19:04:44 +08:00
|
|
|
status, prw_handle, access, pc.get_nt_native_path (),
|
2018-07-24 13:31:58 +08:00
|
|
|
FILE_SHARE_VALID_FLAGS, options);
|
2011-06-17 19:04:44 +08:00
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
return -1;
|
|
|
|
}
|
2018-07-24 13:31:58 +08:00
|
|
|
|
|
|
|
/* record prw_handle's asyncness for subsequent pread/pwrite operations */
|
|
|
|
prw_handle_isasync = !!aio;
|
2011-06-17 19:04:44 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
ssize_t
|
2018-07-24 13:31:58 +08:00
|
|
|
fhandler_disk_file::pread (void *buf, size_t count, off_t offset, void *aio)
|
2005-07-30 01:04:46 +08:00
|
|
|
{
|
2018-07-24 13:31:58 +08:00
|
|
|
struct aiocb *aiocb = (struct aiocb *) aio;
|
2013-04-23 17:44:36 +08:00
|
|
|
ssize_t res;
|
|
|
|
|
2011-05-05 21:45:06 +08:00
|
|
|
if ((get_flags () & O_ACCMODE) == O_WRONLY)
|
|
|
|
{
|
|
|
|
set_errno (EBADF);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-06-07 16:28:25 +08:00
|
|
|
/* In binary mode, we can use an atomic NtReadFile call.
|
|
|
|
Windows mandatory locking semantics disallow to use another HANDLE. */
|
|
|
|
if (rbinary () && !mandatory_locking ())
|
2011-05-05 17:05:04 +08:00
|
|
|
{
|
2022-06-07 00:00:45 +08:00
|
|
|
extern int is_at_eof (HANDLE h);
|
2011-05-05 17:05:04 +08:00
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
LARGE_INTEGER off = { QuadPart:offset };
|
2018-07-24 13:31:58 +08:00
|
|
|
HANDLE evt = aio ? (HANDLE) aiocb->aio_wincb.event : NULL;
|
|
|
|
PIO_STATUS_BLOCK pio = aio ? (PIO_STATUS_BLOCK) &aiocb->aio_wincb : &io;
|
2011-05-05 17:05:04 +08:00
|
|
|
|
2018-07-24 13:31:58 +08:00
|
|
|
/* If existing prw_handle asyncness doesn't match this call's, re-open */
|
|
|
|
if (prw_handle && (prw_handle_isasync != !!aio))
|
|
|
|
NtClose (prw_handle), prw_handle = NULL;
|
|
|
|
|
|
|
|
if (!prw_handle && prw_open (false, aio))
|
2011-06-17 19:04:44 +08:00
|
|
|
goto non_atomic;
|
2018-07-24 13:31:58 +08:00
|
|
|
status = NtReadFile (prw_handle, evt, NULL, NULL, pio, buf, count,
|
2011-05-05 17:05:04 +08:00
|
|
|
&off, NULL);
|
2017-11-08 20:21:30 +08:00
|
|
|
if (status == STATUS_END_OF_FILE)
|
|
|
|
res = 0;
|
|
|
|
else if (!NT_SUCCESS (status))
|
2011-05-05 17:05:04 +08:00
|
|
|
{
|
|
|
|
if (pc.isdir ())
|
|
|
|
{
|
|
|
|
set_errno (EISDIR);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (status == (NTSTATUS) STATUS_ACCESS_VIOLATION)
|
|
|
|
{
|
2011-06-17 19:04:44 +08:00
|
|
|
if (is_at_eof (prw_handle))
|
2017-11-08 20:30:42 +08:00
|
|
|
{
|
|
|
|
res = 0;
|
|
|
|
goto out;
|
|
|
|
}
|
2011-05-05 17:05:04 +08:00
|
|
|
switch (mmap_is_attached_or_noreserve (buf, count))
|
|
|
|
{
|
|
|
|
case MMAP_NORESERVE_COMMITED:
|
2018-07-24 13:31:58 +08:00
|
|
|
status = NtReadFile (prw_handle, evt, NULL, NULL, pio,
|
2011-05-05 17:05:04 +08:00
|
|
|
buf, count, &off, NULL);
|
|
|
|
if (NT_SUCCESS (status))
|
2017-11-08 20:30:42 +08:00
|
|
|
{
|
2018-07-24 13:31:58 +08:00
|
|
|
res = aio ? (ssize_t) aiocb->aio_wincb.info
|
|
|
|
: io.Information;
|
2017-11-08 20:30:42 +08:00
|
|
|
goto out;
|
|
|
|
}
|
2011-05-05 17:05:04 +08:00
|
|
|
break;
|
|
|
|
case MMAP_RAISE_SIGBUS:
|
|
|
|
raise (SIGBUS);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
return -1;
|
|
|
|
}
|
2017-11-08 20:21:30 +08:00
|
|
|
else
|
2018-07-24 13:31:58 +08:00
|
|
|
{
|
|
|
|
res = aio ? (ssize_t) aiocb->aio_wincb.info : io.Information;
|
|
|
|
goto out;
|
|
|
|
}
|
2011-05-05 17:05:04 +08:00
|
|
|
}
|
2005-07-30 01:26:10 +08:00
|
|
|
else
|
2005-07-30 01:04:46 +08:00
|
|
|
{
|
2013-04-23 17:44:36 +08:00
|
|
|
non_atomic:
|
|
|
|
/* Text mode stays slow and non-atomic. */
|
|
|
|
off_t curpos = lseek (0, SEEK_CUR);
|
|
|
|
if (curpos < 0 || lseek (offset, SEEK_SET) < 0)
|
2005-07-30 01:26:10 +08:00
|
|
|
res = -1;
|
2013-04-23 17:44:36 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
size_t tmp_count = count;
|
|
|
|
read (buf, tmp_count);
|
|
|
|
if (lseek (curpos, SEEK_SET) >= 0)
|
|
|
|
res = (ssize_t) tmp_count;
|
|
|
|
else
|
|
|
|
res = -1;
|
|
|
|
}
|
2018-07-24 13:31:58 +08:00
|
|
|
|
|
|
|
/* If this was a disallowed async request, simulate its conclusion */
|
|
|
|
if (aio)
|
|
|
|
{
|
|
|
|
aiocb->aio_rbytes = res;
|
|
|
|
aiocb->aio_errno = res == -1 ? get_errno () : 0;
|
|
|
|
SetEvent ((HANDLE) aiocb->aio_wincb.event);
|
|
|
|
}
|
2005-07-30 01:04:46 +08:00
|
|
|
}
|
2017-11-08 20:30:42 +08:00
|
|
|
out:
|
2018-07-24 13:31:58 +08:00
|
|
|
debug_printf ("%d = pread(%p, %ld, %D, %p)\n", res, buf, count, offset, aio);
|
2005-07-30 01:04:46 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
ssize_t
|
2018-07-24 13:31:58 +08:00
|
|
|
fhandler_disk_file::pwrite (void *buf, size_t count, off_t offset, void *aio)
|
2005-07-30 01:04:46 +08:00
|
|
|
{
|
2018-07-24 13:31:58 +08:00
|
|
|
struct aiocb *aiocb = (struct aiocb *) aio;
|
|
|
|
ssize_t res;
|
|
|
|
|
2011-05-05 21:45:06 +08:00
|
|
|
if ((get_flags () & O_ACCMODE) == O_RDONLY)
|
|
|
|
{
|
|
|
|
set_errno (EBADF);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-06-07 16:28:25 +08:00
|
|
|
/* In binary mode, we can use an atomic NtWriteFile call.
|
|
|
|
Windows mandatory locking semantics disallow to use another HANDLE. */
|
|
|
|
if (wbinary () && !mandatory_locking ())
|
2011-05-05 17:05:04 +08:00
|
|
|
{
|
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
2023-11-28 05:48:50 +08:00
|
|
|
FILE_STANDARD_INFORMATION fsi;
|
2011-05-05 17:05:04 +08:00
|
|
|
LARGE_INTEGER off = { QuadPart:offset };
|
2018-07-24 13:31:58 +08:00
|
|
|
HANDLE evt = aio ? (HANDLE) aiocb->aio_wincb.event : NULL;
|
|
|
|
PIO_STATUS_BLOCK pio = aio ? (PIO_STATUS_BLOCK) &aiocb->aio_wincb : &io;
|
|
|
|
|
|
|
|
/* If existing prw_handle asyncness doesn't match this call's, re-open */
|
|
|
|
if (prw_handle && (prw_handle_isasync != !!aio))
|
|
|
|
NtClose (prw_handle), prw_handle = NULL;
|
2011-05-05 17:05:04 +08:00
|
|
|
|
2023-11-28 05:48:50 +08:00
|
|
|
/* If the file system supports sparse files and the application is
|
|
|
|
writing beyond EOF spanning more than one sparsifiable chunk,
|
|
|
|
convert the file to a sparse file. */
|
|
|
|
if (pc.support_sparse ()
|
|
|
|
&& !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE)
|
|
|
|
&& NT_SUCCESS (NtQueryInformationFile (get_handle (),
|
|
|
|
&io, &fsi, sizeof fsi,
|
|
|
|
FileStandardInformation))
|
2023-11-28 17:42:52 +08:00
|
|
|
&& span_sparse_chunk (offset, fsi.EndOfFile.QuadPart))
|
2023-11-28 05:48:50 +08:00
|
|
|
{
|
|
|
|
NTSTATUS status;
|
|
|
|
status = NtFsControlFile (get_handle (), NULL, NULL, NULL,
|
|
|
|
&io, FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
|
|
|
|
if (NT_SUCCESS (status))
|
|
|
|
pc.file_attributes (pc.file_attributes ()
|
|
|
|
| FILE_ATTRIBUTE_SPARSE_FILE);
|
|
|
|
debug_printf ("%y = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
|
|
|
status, pc.get_nt_native_path ());
|
|
|
|
}
|
2018-07-24 13:31:58 +08:00
|
|
|
if (!prw_handle && prw_open (true, aio))
|
2011-06-17 19:04:44 +08:00
|
|
|
goto non_atomic;
|
2018-07-24 13:31:58 +08:00
|
|
|
status = NtWriteFile (prw_handle, evt, NULL, NULL, pio, buf, count,
|
2011-05-05 17:05:04 +08:00
|
|
|
&off, NULL);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
return -1;
|
|
|
|
}
|
2018-07-24 13:31:58 +08:00
|
|
|
res = aio ? (ssize_t) aiocb->aio_wincb.info : io.Information;
|
|
|
|
goto out;
|
2011-05-05 17:05:04 +08:00
|
|
|
}
|
2005-07-30 01:26:10 +08:00
|
|
|
else
|
|
|
|
{
|
2018-07-24 13:31:58 +08:00
|
|
|
non_atomic:
|
|
|
|
/* Text mode stays slow and non-atomic. */
|
|
|
|
off_t curpos = lseek (0, SEEK_CUR);
|
|
|
|
if (curpos < 0 || lseek (offset, SEEK_SET) < 0)
|
|
|
|
res = curpos;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
res = (ssize_t) write (buf, count);
|
|
|
|
if (lseek (curpos, SEEK_SET) < 0)
|
|
|
|
res = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If this was a disallowed async request, simulate its conclusion */
|
|
|
|
if (aio)
|
|
|
|
{
|
|
|
|
aiocb->aio_rbytes = res;
|
|
|
|
aiocb->aio_errno = res == -1 ? get_errno () : 0;
|
|
|
|
SetEvent ((HANDLE) aiocb->aio_wincb.event);
|
|
|
|
}
|
2005-07-30 01:26:10 +08:00
|
|
|
}
|
2018-07-24 13:31:58 +08:00
|
|
|
out:
|
|
|
|
debug_printf ("%d = pwrite(%p, %ld, %D, %p)\n", res, buf, count, offset, aio);
|
2005-07-30 01:04:46 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2005-05-25 12:32:59 +08:00
|
|
|
int
|
|
|
|
fhandler_disk_file::mkdir (mode_t mode)
|
|
|
|
{
|
|
|
|
int res = -1;
|
|
|
|
SECURITY_ATTRIBUTES sa = sec_none_nih;
|
2007-07-29 20:27:22 +08:00
|
|
|
NTSTATUS status;
|
|
|
|
HANDLE dir;
|
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
IO_STATUS_BLOCK io;
|
2008-05-21 00:24:06 +08:00
|
|
|
PFILE_FULL_EA_INFORMATION p = NULL;
|
|
|
|
ULONG plen = 0;
|
2011-03-08 22:26:15 +08:00
|
|
|
ULONG access = FILE_LIST_DIRECTORY | SYNCHRONIZE;
|
2008-05-21 00:24:06 +08:00
|
|
|
|
|
|
|
if (pc.fs_is_nfs ())
|
|
|
|
{
|
|
|
|
/* When creating a dir on an NFS share, we have to set the
|
|
|
|
file mode by writing a NFS fattr3 structure with the
|
|
|
|
correct mode bits set. */
|
|
|
|
plen = sizeof (FILE_FULL_EA_INFORMATION) + sizeof (NFS_V3_ATTR)
|
|
|
|
+ sizeof (fattr3);
|
|
|
|
p = (PFILE_FULL_EA_INFORMATION) alloca (plen);
|
|
|
|
p->NextEntryOffset = 0;
|
|
|
|
p->Flags = 0;
|
|
|
|
p->EaNameLength = sizeof (NFS_V3_ATTR) - 1;
|
|
|
|
p->EaValueLength = sizeof (fattr3);
|
|
|
|
strcpy (p->EaName, NFS_V3_ATTR);
|
|
|
|
fattr3 *nfs_attr = (fattr3 *) (p->EaName + p->EaNameLength + 1);
|
|
|
|
memset (nfs_attr, 0, sizeof (fattr3));
|
|
|
|
nfs_attr->type = NF3DIR;
|
|
|
|
nfs_attr->mode = (mode & 07777) & ~cygheap->umask;
|
|
|
|
}
|
2011-07-05 17:59:34 +08:00
|
|
|
else if (has_acls () && !isremote ())
|
2011-03-08 22:26:15 +08:00
|
|
|
/* If the filesystem supports ACLs, we will overwrite the DACL after the
|
|
|
|
call to NtCreateFile. This requires a handle with READ_CONTROL and
|
|
|
|
WRITE_DAC access, otherwise get_file_sd and set_file_sd both have to
|
2011-07-05 17:59:34 +08:00
|
|
|
open the file again.
|
|
|
|
FIXME: On remote NTFS shares open sometimes fails because even the
|
|
|
|
creator of the file doesn't have the right to change the DACL.
|
2011-08-02 01:01:38 +08:00
|
|
|
I don't know what setting that is or how to recognize such a share,
|
2011-07-05 17:59:34 +08:00
|
|
|
so for now we don't request WRITE_DAC on remote drives. */
|
2011-03-08 22:26:15 +08:00
|
|
|
access |= READ_CONTROL | WRITE_DAC;
|
2018-12-25 08:09:12 +08:00
|
|
|
/* Setting case sensitivity requires FILE_WRITE_ATTRIBUTES. */
|
|
|
|
if (wincap.has_case_sensitive_dirs ()
|
|
|
|
&& !pc.isremote () && pc.fs_is_ntfs ())
|
|
|
|
access |= FILE_WRITE_ATTRIBUTES;
|
2011-03-08 22:26:15 +08:00
|
|
|
status = NtCreateFile (&dir, access, pc.get_object_attr (attr, sa), &io, NULL,
|
2008-08-19 17:46:31 +08:00
|
|
|
FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_CREATE,
|
2007-07-29 20:27:22 +08:00
|
|
|
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
|
|
|
|
| FILE_OPEN_FOR_BACKUP_INTENT,
|
2008-05-21 00:24:06 +08:00
|
|
|
p, plen);
|
2007-07-29 20:27:22 +08:00
|
|
|
if (NT_SUCCESS (status))
|
|
|
|
{
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
/* Set the "directory attribute" so that pc.isdir() returns correct
|
|
|
|
value in subsequent function calls. */
|
|
|
|
pc.file_attributes (FILE_ATTRIBUTE_DIRECTORY);
|
2009-10-31 03:58:53 +08:00
|
|
|
if (has_acls ())
|
Reapply POSIX ACL changes.
- New, unified implementation of POSIX permission and ACL handling. The
new ACLs now store the POSIX ACL MASK/CLASS_OBJ permission mask, and
they allow to inherit the S_ISGID bit. ACL inheritance now really
works as desired, in a limited, but theoretically equivalent fashion
even for non-Cygwin processes.
To accommodate Windows default ACLs, the new code ignores SYSTEM and
Administrators group permissions when computing the MASK/CLASS_OBJ
permission mask on old ACLs, and it doesn't deny access to SYSTEM and
Administrators group based on the value of MASK/CLASS_OBJ when
creating the new ACLs.
The new code now handles the S_ISGID bit on directories as on Linux:
Setting S_ISGID on a directory causes new files and subdirs created
within to inherit its group, rather than the primary group of the user
who created the file. This only works for files and directories
created by Cygwin processes.
2015-05-29 Corinna Vinschen <corinna@vinschen.de>
Reapply POSIX ACL changes.
* utils.xml (setfacl): Show new option output.
(getfacl): Show new option output.
* sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL.
Apply umask, if so. Align comments.
* security.cc (set_created_file_access): Fix permission masking by
incoming requested file mode.
* sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit
for SYSTEM and Admins group.
* sec_acl.cc (set_posix_access): Don't create DENY ACEs for USER and
GROUP entries if they are the same as USER_OBJ or GROUP_OBJ.
* fhandler.h (fhandler_pty_slave::facl): Add prototype.
* fhandler_tty.cc (fhandler_pty_slave::facl): New method.
(fhandler_pty_slave::fchown): Fix uid/gid handling.
* sec_acl.cc (set_posix_access): Drop superfluous class_idx variable.
Simplify and move around code in a few places. To improve ACL
readability, add r/w permissions to Admins ACE appended to pty ACL.
Add comment to explain Windows ACE Mask filtering being in the way of
creating a real CLASS_OBJ.
(get_posix_access): Fake CLASS_OBJ for ptys. Explain why.
* security.cc (get_object_attribute): Add S_IFCHR flag to attributes
when calling get_posix_access.
* sec_acl.cc (set_posix_access): Move merging group perms into owner
perms in case of owner == group after mask has been computed. Take
mask into account when doing so to avoid unnecessary ACCESS_DENIED_ACE.
* sec_acl.cc (get_posix_access): Only set saw_group_obj flag if we saw
the ACCESS_ALLOWED_ACE.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Deliberatly
set GROUP_OBJ and CLASS_OBJ perms to new group perms. Add comment
to explain why.
* security.cc (set_created_file_access): Ditto.
* sec_acl.cc (set_posix_access): Replace previous patch. Return
EINVAL if uid and/or guid is invalid and not backed by an actual
Windows account.
* sec_acl.cc (set_posix_access): Workaround owner/group SIDs being NULL.
* sec_acl.cc (set_posix_access): Handle files with owner == group.
Rephrase switch statement checking against unfiltered a_type value.
(get_posix_access): Handle files with owner == group.
* sec_acl.cc (get_posix_access): Don't use GROUP_OBJ access to fix up
CLASS_OBJ mask on old-style ACLs. Fix a comment.
* sec_acl.cc (set_posix_access): Always make sure Admins have
WRITE_DAC and WRITE_OWNER permissions.
* security.h (create_object_sd_from_attribute): Drop handle parameter
from prototype.
* security.cc (create_object_sd_from_attribute): Drop handle parameter.
Just create the standard POSIXy security descriptor.
(set_object_attribute): Accommodate dropped paramter in call to
create_object_sd_from_attribute.
* fhandler_tty.cc: Ditto, throughout.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Fix typo in
mask computation.
* fhandler.cc (fhandler_base::open_with_arch): Call open with mode
not umasked.
(fhandler_base::open): Explicitely umask mode on NFS here. Call new
set_created_file_access rather than set_file_attribute.
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Reimplement
setting permissions on filesystems supporting ACLs using the new
set_posix_access call.
(fhandler_disk_file::fchown): Ditto.
(fhandler_disk_file::mkdir): Call new set_created_file_access rather
than set_file_attribute.
* fhandler_socket.cc (fhandler_socket::bind): Don't umask here. Add
WRITE_OWNER access to allow writing group in case of SGID bit set.
Call new set_created_file_access rather than set_file_attribute.
* path.cc (symlink_worker): Call new set_created_file_access rather
than set_file_attribute.
* sec_acl.cc (searchace): Un-staticize.
(set_posix_access): New, complementary functionality to
get_posix_access.
(setacl): Implement in terms of get_posix_access/set_posix_access.
(get_posix_access): Add handling for just created files requiring
their first Cygwin ACL. Fix new_style recognition. Handle SGID
bit. For old-style ACLs, ignore SYSTEM and Administrators when
computing the {DEF_}CLASS_OBJ perms.
* security.cc (get_file_sd): Revamp comment. Change and (hopefully)
speed up inheritance processing for just created files.
(alloc_sd): Remove.
(set_security_attribute): Call set_posix_access instead of alloc_sd.
(get_object_attribute): Fix return value.
(create_object_sd_from_attribute): Call set_posix_access instead of
alloc_sd.
(set_file_attribute): Remove.
(set_created_file_access): New function implemented in terms of
get_posix_access/set_posix_access.
* security.h (set_file_attribute): Remove prototype.
(set_created_file_access): Add prototype.
(searchace): Ditto.
(set_posix_access): Ditto.
* syscalls.cc (open): Call open_with_arch with mode not umasked.
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
Describe how to generate deny ACEs in more detail. Accommodate the
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
a special Cygwin ACE. Improve further comments.
(CYG_ACE_NEW_STYLE): Define.
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
NULL deny ACE if the inheritance flags say so.
* sec_helper.cc (well_known_cygwin_sid): Remove.
* security.h (well_known_cygwin_sid): Drop declaration.
* sec_acl.cc (CYG_ACE_ISBITS_TO_WIN): Fix typo.
(get_posix_access): Rename index variable from i to idx. Define only
once at top level.
* security.cc (add_access_allowed_ace): Drop unused parameter "offset".
Accommodate throughout.
(add_access_denied_ace): Ditto.
* sec_acl.cc: Accommodate above change throughout.
* security.h (add_access_allowed_ace): Adjust prototype to above change.
(add_access_denied_ace): Ditto.
* sec_acl.cc (get_posix_access): Handle multiple ACEs for the
owner and primary group of the file. Handle the default primary
group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
set. Add comments. Minor code rearrangements.
Preliminary read side implementation of new permission handling.
* acl.h (MAX_ACL_ENTRIES): Raise to 2730. Add comment to explain.
* sec_acl.cc: Add leading comment to explain new ACL style.
Add definitions and macros to use for bits in new Cygwin ACL.
(DENY_RWX): New mask value for all temporary deny bits.
(getace): Add bool parameter to decide when leaving all bits intact,
rather than filtering them per the already set bits.
(get_posix_access): New function, taking over functionality to read
POSIX ACL from SECURITY_DESCRIPTOR.
(getacl): Just call get_posix_access.
* sec_helper.cc (well_known_cygwin_sid): Define.
* security.cc (get_attribute_from_acl): Remove.
(get_info_from_sd): Remove.
(get_reg_sd): Call get_posix_access instead of get_info_from_sd.
(get_file_attribute): Ditto.
(get_object_attribute): Ditto.
* security.h (well_known_cygwin_sid): Declare.
(get_posix_access): Add prototype.
* Throughout, use simpler ACE macros from Windows' accctrl.h.
* getfacl.c (main): Special-case SYSTEM and Admins group. Add comments.
* setfacl.c: Align more to Linux tool.
(delacl): New function to delete acl entries only.
(modacl): Drop delete functionality. Add handling of recomputing the
mask and default mask values.
(delallacl): Rename from delacl.
(setfacl): Call delacl in Delete case. Call delallacl in DeleteAll
and DeleteDef case.
(usage): Accommodate new options. Rearrange and rephrase slightly.
(longopts): Emit 'x' in --delete case. Add --no-mask and --mask
options.
(opts): Add -x and -n options.
(main): Handle -d and -x the same. Handle -n and --mask options.
Drop handling for -r option.
* getfacl.c (usage): Align more closely to Linux version. Add new
options -c, -e, -E. Change formatting to accommodate longer options.
(longopts): Rename --noname to --numeric. Keep --noname for backward
compatibility. Add --omit-header, --all-effective and --no-effective
options.
(opts): Add -c, -e and -E option.
(main): Handle new -c, -e, and -E options.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-06-24 17:52:29 +08:00
|
|
|
set_created_file_access (dir, pc, mode & 07777);
|
2019-03-01 21:32:08 +08:00
|
|
|
#if 0
|
|
|
|
/* FIXME: This default behaviour badly breaks interoperability.
|
|
|
|
Inspecting the content of case-sensitive directories
|
|
|
|
on remote machines results in lots of errors like
|
|
|
|
disappearing diretories and files, file not found, etc. */
|
|
|
|
|
2018-12-25 08:09:12 +08:00
|
|
|
/* Starting with Windows 10 1803, try to create all dirs below the
|
|
|
|
installation root as case-sensitive. If STATUS_NOT_SUPPORTED
|
|
|
|
is returned, WSL isn't installed (unfortunately a requirement
|
|
|
|
for this functionality. */
|
|
|
|
if (wincap.has_case_sensitive_dirs ()
|
|
|
|
&& !pc.isremote () && pc.fs_is_ntfs ())
|
|
|
|
{
|
|
|
|
PUNICODE_STRING new_dir = pc.get_nt_native_path ();
|
|
|
|
PUNICODE_STRING root_dir = &cygheap->installation_root;
|
|
|
|
|
|
|
|
if (RtlEqualUnicodePathPrefix (new_dir, root_dir, TRUE)
|
|
|
|
&& new_dir->Buffer[root_dir->Length / sizeof (WCHAR)] == L'\\')
|
|
|
|
{
|
|
|
|
FILE_CASE_SENSITIVE_INFORMATION fcsi;
|
|
|
|
|
|
|
|
fcsi.Flags = FILE_CS_FLAG_CASE_SENSITIVE_DIR;
|
|
|
|
status = NtSetInformationFile (dir, &io, &fcsi, sizeof fcsi,
|
|
|
|
FileCaseSensitiveInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
debug_printf ("Setting dir case sensitivity, status %y",
|
|
|
|
status);
|
|
|
|
if (status == STATUS_NOT_SUPPORTED)
|
|
|
|
{
|
|
|
|
debug_printf ("Dir case sensitivity requires WSL");
|
|
|
|
wincap.disable_case_sensitive_dirs ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-03-01 21:32:08 +08:00
|
|
|
#endif
|
2007-07-29 20:27:22 +08:00
|
|
|
NtClose (dir);
|
2005-05-25 12:32:59 +08:00
|
|
|
res = 0;
|
|
|
|
}
|
|
|
|
else
|
2007-07-29 20:27:22 +08:00
|
|
|
__seterrno_from_nt_status (status);
|
2005-05-25 12:32:59 +08:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_disk_file::rmdir ()
|
|
|
|
{
|
2007-01-26 20:25:23 +08:00
|
|
|
if (!pc.isdir ())
|
|
|
|
{
|
|
|
|
set_errno (ENOTDIR);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-07-29 20:27:22 +08:00
|
|
|
if (!pc.exists ())
|
|
|
|
{
|
|
|
|
set_errno (ENOENT);
|
|
|
|
return -1;
|
|
|
|
}
|
2005-05-25 12:32:59 +08:00
|
|
|
|
2023-03-20 19:23:36 +08:00
|
|
|
NTSTATUS status = unlink_nt (pc, false);
|
2005-05-25 12:32:59 +08:00
|
|
|
|
2007-07-29 20:27:22 +08:00
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
2005-05-25 12:32:59 +08:00
|
|
|
}
|
|
|
|
|
2006-01-28 21:41:22 +08:00
|
|
|
/* This is the minimal number of entries which fit into the readdir cache.
|
|
|
|
The number of bytes allocated by the cache is determined by this number,
|
|
|
|
To tune caching, just tweak this number. To get a feeling for the size,
|
2007-07-27 01:30:54 +08:00
|
|
|
the size of the readdir cache is DIR_NUM_ENTRIES * 624 + 4 bytes. */
|
2006-01-28 21:41:22 +08:00
|
|
|
|
2007-07-27 01:30:54 +08:00
|
|
|
#define DIR_NUM_ENTRIES 100 /* Cache size 62404 bytes */
|
2006-01-28 21:41:22 +08:00
|
|
|
|
|
|
|
#define DIR_BUF_SIZE (DIR_NUM_ENTRIES \
|
|
|
|
* (sizeof (FILE_ID_BOTH_DIR_INFORMATION) \
|
2008-03-09 01:28:40 +08:00
|
|
|
+ (NAME_MAX + 1) * sizeof (WCHAR)))
|
2006-01-28 21:41:22 +08:00
|
|
|
|
2006-03-01 21:47:49 +08:00
|
|
|
struct __DIR_cache
|
2006-01-28 21:41:22 +08:00
|
|
|
{
|
2013-04-23 17:44:36 +08:00
|
|
|
char __cache[DIR_BUF_SIZE];
|
2006-01-28 21:41:22 +08:00
|
|
|
ULONG __pos;
|
|
|
|
};
|
|
|
|
|
2006-03-01 21:47:49 +08:00
|
|
|
#define d_cachepos(d) (((__DIR_cache *) (d)->__d_dirname)->__pos)
|
|
|
|
#define d_cache(d) (((__DIR_cache *) (d)->__d_dirname)->__cache)
|
|
|
|
|
|
|
|
#define d_mounts(d) ((__DIR_mounts *) (d)->__d_internal)
|
2006-01-28 21:41:22 +08:00
|
|
|
|
2001-11-21 14:47:57 +08:00
|
|
|
DIR *
|
2007-06-29 23:13:01 +08:00
|
|
|
fhandler_disk_file::opendir (int fd)
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
|
|
|
DIR *dir;
|
|
|
|
DIR *res = NULL;
|
|
|
|
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
if (!pc.isdir ())
|
2001-11-21 14:47:57 +08:00
|
|
|
set_errno (ENOTDIR);
|
|
|
|
else if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)
|
|
|
|
set_errno (ENOMEM);
|
2007-02-22 18:54:47 +08:00
|
|
|
else if ((dir->__d_dirname = (char *) malloc ( sizeof (struct __DIR_cache)))
|
|
|
|
== NULL)
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
|
|
|
set_errno (ENOMEM);
|
2003-11-08 02:21:05 +08:00
|
|
|
goto free_dir;
|
2001-11-21 14:47:57 +08:00
|
|
|
}
|
|
|
|
else if ((dir->__d_dirent =
|
|
|
|
(struct dirent *) malloc (sizeof (struct dirent))) == NULL)
|
|
|
|
{
|
2003-11-06 00:53:55 +08:00
|
|
|
set_errno (ENOMEM);
|
2003-11-08 02:21:05 +08:00
|
|
|
goto free_dirname;
|
2003-11-06 00:53:55 +08:00
|
|
|
}
|
2001-11-21 14:47:57 +08:00
|
|
|
else
|
|
|
|
{
|
2007-06-29 23:13:01 +08:00
|
|
|
cygheap_fdnew cfd;
|
|
|
|
if (cfd < 0 && fd < 0)
|
2003-11-08 02:21:05 +08:00
|
|
|
goto free_dirent;
|
|
|
|
|
2007-07-27 01:30:54 +08:00
|
|
|
dir->__d_dirent->__d_version = __DIRENT_VERSION;
|
2003-11-08 02:21:05 +08:00
|
|
|
dir->__d_cookie = __DIRENT_COOKIE;
|
|
|
|
dir->__handle = INVALID_HANDLE_VALUE;
|
|
|
|
dir->__d_position = 0;
|
2007-07-27 01:30:54 +08:00
|
|
|
dir->__flags = (get_name ()[0] == '/' && get_name ()[1] == '\0')
|
2006-08-20 20:31:07 +08:00
|
|
|
? dirent_isroot : 0;
|
2013-10-30 17:44:47 +08:00
|
|
|
dir->__d_internal = 0;
|
2007-02-22 18:54:47 +08:00
|
|
|
|
2013-10-30 17:44:47 +08:00
|
|
|
if (pc.iscygdrive ())
|
2006-02-28 12:23:17 +08:00
|
|
|
{
|
2013-10-30 17:44:47 +08:00
|
|
|
if (fd < 0 && !open (O_RDONLY, 0))
|
|
|
|
goto free_mounts;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dir->__d_internal = (uintptr_t) new __DIR_mounts (get_name ());
|
|
|
|
d_cachepos (dir) = 0;
|
2007-07-10 01:02:37 +08:00
|
|
|
if (fd < 0)
|
2007-06-29 23:13:01 +08:00
|
|
|
{
|
|
|
|
/* opendir() case. Initialize with given directory name and
|
2007-07-08 00:46:35 +08:00
|
|
|
NULL directory handle. */
|
2007-07-10 01:02:37 +08:00
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
2010-02-19 21:28:49 +08:00
|
|
|
/* Tools like ls(1) call dirfd() to fetch the directory
|
|
|
|
descriptor for calls to facl or fstat. The tight access mask
|
|
|
|
used so far is not sufficient to reuse the handle for these
|
|
|
|
calls, instead the facl/fstat calls find the handle to be
|
|
|
|
unusable and have to re-open the file for reading attributes
|
|
|
|
and control data. So, what we do here is to try to open the
|
|
|
|
directory with more relaxed access mask which enables to use
|
|
|
|
the handle for the aforementioned purpose. This should work
|
|
|
|
in almost all cases. Only if it doesn't work due to
|
|
|
|
permission problems, we drop the additional access bits and
|
|
|
|
try again. */
|
|
|
|
ACCESS_MASK fstat_mask = READ_CONTROL | FILE_READ_ATTRIBUTES;
|
|
|
|
|
|
|
|
do
|
2007-07-10 01:02:37 +08:00
|
|
|
{
|
2010-02-19 21:28:49 +08:00
|
|
|
status = NtOpenFile (&get_handle (),
|
|
|
|
SYNCHRONIZE | FILE_LIST_DIRECTORY
|
|
|
|
| fstat_mask,
|
|
|
|
pc.get_object_attr (attr, sec_none_nih),
|
|
|
|
&io, FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT
|
|
|
|
| FILE_OPEN_FOR_BACKUP_INTENT
|
|
|
|
| FILE_DIRECTORY_FILE);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
if (status == STATUS_ACCESS_DENIED && fstat_mask)
|
|
|
|
fstat_mask = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
goto free_mounts;
|
|
|
|
}
|
|
|
|
}
|
2007-07-10 01:02:37 +08:00
|
|
|
}
|
2010-02-19 21:28:49 +08:00
|
|
|
while (!NT_SUCCESS (status));
|
2007-02-22 18:54:47 +08:00
|
|
|
}
|
2006-02-20 05:18:36 +08:00
|
|
|
|
2015-12-16 00:03:09 +08:00
|
|
|
/* FileIdBothDirectoryInformation was unsupported on XP when
|
|
|
|
accessing UDF. It's not clear if the call isn't also unsupported
|
|
|
|
on other OS/FS combinations. Instead of testing for yet another
|
|
|
|
error code, use FileIdBothDirectoryInformation only on FSes
|
|
|
|
supporting persistent ACLs.
|
2008-05-21 17:02:42 +08:00
|
|
|
|
2008-05-24 01:22:18 +08:00
|
|
|
NFS clients hide dangling symlinks from directory queries,
|
2008-11-27 01:21:04 +08:00
|
|
|
unless you use the FileNamesInformation info class.
|
2015-12-16 04:43:33 +08:00
|
|
|
FileIdBothDirectoryInformation works fine, but only if the NFS
|
|
|
|
share is mounted to a drive letter. TODO: We don't test that
|
|
|
|
here for now, but it might be worth to test if there's a speed
|
|
|
|
gain in using FileIdBothDirectoryInformation, because it doesn't
|
|
|
|
require to open the file to read the inode number. */
|
2007-02-22 18:54:47 +08:00
|
|
|
if (pc.hasgood_inode ())
|
|
|
|
{
|
|
|
|
dir->__flags |= dirent_set_d_ino;
|
2008-05-21 17:02:42 +08:00
|
|
|
if (pc.fs_is_nfs ())
|
2008-11-27 01:21:04 +08:00
|
|
|
dir->__flags |= dirent_nfs_d_ino;
|
Drop NT4 support.
* autoload.cc (DnsQuery_A): Fatal if not available.
(DnsRecordListFree): Ditto.
(DsGetDcNameW): Ditto.
(NetGetAnyDCName): Remove.
(NetGetDCName): Remove.
(EnumProcessModules): Fatal if not available.
(GetModuleFileNameExW): Ditto.
(GetModuleInformation): Ditto.
(GetProcessMemoryInfo): Ditto.
(QueryWorkingSet): Ditto.
(LsaRegisterLogonProcess): Ditto.
* fenv.cc (_feinitialise): Drop supports_sse condition.
* fhandler_disk_file.cc (path_conv::isgood_inode): Fix comment.
(fhandler_base::fstat_by_name): Drop has_fileid_dirinfo condition.
(fhandler_disk_file::opendir): Ditto.
* fhandler_netdrive.cc (fhandler_netdrive::readdir): Fix comment.
* fhandler_proc.cc (format_proc_partitions): Drop NT4-only code.
* fhandler_process.cc (get_process_state): Ditto.
* kernel32.cc (GetWindowsDirectoryW): Remove.
(GetWindowsDirectoryA): Remove.
* miscfuncs.cc (nice_to_winprio): Drop NT4-only code.
* mount.cc (fs_info::update): Fix comments.
* net.cc (get_2k_ifs): Drop NT4-only code.
* sec_auth.cc (get_logon_server): Ditto.
(lsaauth): Drop NT4-specific error handling.
* security.cc (alloc_sd): Set SE_DACL_PROTECTED unconditionally.
* select.cc (select_stuff::wait): Always use MWMO_INPUTAVAILABLE.
(peek_windows): Drop NT4-only condition in call to PeekMessage.
* syscalls.cc (gethostid): Remove NT4-only workaround.
* wincap.cc: Througout, drop has_dacl_protect,
has_broken_if_oper_status, has_process_io_counters,
has_terminal_services, has_extended_priority_class, has_guid_volumes,
has_fileid_dirinfo, has_mwmo_inputavailable and supports_sse from
wincaps.
(wincap_nt4sp4): Remove.
(wincap_minimal): Set to wincap_2000.
(wincapc::init): Rely on availability of OSVERSIONINFOEX structure.
Treat error from GetVersionEx as fatal. Treat NT4 as fatal.
* wincap.h (struct wincaps): Drop has_dacl_protect,
has_broken_if_oper_status, has_process_io_counters,
has_terminal_services, has_extended_priority_class, has_guid_volumes,
has_fileid_dirinfo, has_mwmo_inputavailable and supports_sse flags
and methods.
* winlean.h (GetWindowsDirectoryW) Define as GetSystemWindowsDirectoryW.
(GetWindowsDirectoryA): Define as GetSystemWindowsDirectoryA.
2011-04-04 20:23:36 +08:00
|
|
|
else if (!pc.has_buggy_fileid_dirinfo ())
|
2008-05-24 01:22:18 +08:00
|
|
|
dir->__flags |= dirent_get_d_ino;
|
2006-02-09 22:42:48 +08:00
|
|
|
}
|
2006-01-28 05:50:42 +08:00
|
|
|
}
|
2007-06-29 23:13:01 +08:00
|
|
|
if (fd >= 0)
|
2007-07-10 01:02:37 +08:00
|
|
|
dir->__d_fd = fd;
|
2007-06-29 23:13:01 +08:00
|
|
|
else
|
2007-07-08 00:46:35 +08:00
|
|
|
{
|
2007-06-29 23:13:01 +08:00
|
|
|
/* Filling cfd with `this' (aka storing this in the file
|
|
|
|
descriptor table should only happen after it's clear that
|
|
|
|
opendir doesn't fail, otherwise we end up cfree'ing the
|
|
|
|
fhandler twice, once in opendir() in dir.cc, the second
|
|
|
|
time on exit. Nasty, nasty... */
|
|
|
|
cfd = this;
|
|
|
|
dir->__d_fd = cfd;
|
|
|
|
}
|
2007-07-10 01:02:37 +08:00
|
|
|
set_close_on_exec (true);
|
2006-03-04 04:19:26 +08:00
|
|
|
dir->__fh = this;
|
2006-01-28 05:50:42 +08:00
|
|
|
res = dir;
|
2001-11-21 14:47:57 +08:00
|
|
|
}
|
|
|
|
|
2001-11-22 13:59:07 +08:00
|
|
|
syscall_printf ("%p = opendir (%s)", res, get_name ());
|
2001-11-21 14:47:57 +08:00
|
|
|
return res;
|
2003-11-08 02:21:05 +08:00
|
|
|
|
2006-03-04 04:19:26 +08:00
|
|
|
free_mounts:
|
|
|
|
delete d_mounts (dir);
|
2003-11-08 02:21:05 +08:00
|
|
|
free_dirent:
|
|
|
|
free (dir->__d_dirent);
|
|
|
|
free_dirname:
|
|
|
|
free (dir->__d_dirname);
|
|
|
|
free_dir:
|
|
|
|
free (dir);
|
|
|
|
return res;
|
2001-11-21 14:47:57 +08:00
|
|
|
}
|
|
|
|
|
2022-05-24 03:52:52 +08:00
|
|
|
ino_t
|
2007-07-27 01:30:54 +08:00
|
|
|
readdir_get_ino (const char *path, bool dot_dot)
|
2006-01-28 05:50:42 +08:00
|
|
|
{
|
2007-07-27 01:30:54 +08:00
|
|
|
char *fname;
|
2013-04-23 17:44:36 +08:00
|
|
|
struct stat st;
|
2006-01-28 05:50:42 +08:00
|
|
|
HANDLE hdl;
|
2010-08-20 19:18:58 +08:00
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
IO_STATUS_BLOCK io;
|
2013-04-23 17:44:36 +08:00
|
|
|
ino_t ino = 0;
|
2006-01-28 05:50:42 +08:00
|
|
|
|
2007-07-10 01:02:37 +08:00
|
|
|
if (dot_dot)
|
2007-07-27 01:30:54 +08:00
|
|
|
{
|
|
|
|
fname = (char *) alloca (strlen (path) + 4);
|
|
|
|
char *c = stpcpy (fname, path);
|
|
|
|
if (c[-1] != '/')
|
2008-02-16 01:53:11 +08:00
|
|
|
*c++ = '/';
|
2007-07-27 01:30:54 +08:00
|
|
|
strcpy (c, "..");
|
|
|
|
path = fname;
|
|
|
|
}
|
2020-01-29 04:59:22 +08:00
|
|
|
path_conv pc (path, PC_SYM_NOFOLLOW | PC_POSIX | PC_KEEP_HANDLE);
|
2007-07-10 01:02:37 +08:00
|
|
|
if (pc.isspecial ())
|
2006-01-28 05:50:42 +08:00
|
|
|
{
|
2007-07-27 01:30:54 +08:00
|
|
|
if (!stat_worker (pc, &st))
|
2007-07-10 01:02:37 +08:00
|
|
|
ino = st.st_ino;
|
|
|
|
}
|
|
|
|
else if (!pc.hasgood_inode ())
|
2007-08-16 22:10:06 +08:00
|
|
|
ino = hash_path_name (0, pc.get_nt_native_path ());
|
2010-08-20 19:18:58 +08:00
|
|
|
else if ((hdl = pc.handle ()) != NULL
|
|
|
|
|| NT_SUCCESS (NtOpenFile (&hdl, READ_CONTROL,
|
|
|
|
pc.get_object_attr (attr, sec_none_nih),
|
|
|
|
&io, FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT
|
2018-03-01 23:41:45 +08:00
|
|
|
| (pc.is_known_reparse_point ()
|
2010-08-20 19:18:58 +08:00
|
|
|
? FILE_OPEN_REPARSE_POINT : 0)))
|
|
|
|
)
|
2007-07-10 01:02:37 +08:00
|
|
|
{
|
2010-06-15 16:51:55 +08:00
|
|
|
ino = pc.get_ino_by_handle (hdl);
|
2009-03-13 06:03:28 +08:00
|
|
|
if (!ino)
|
|
|
|
ino = hash_path_name (0, pc.get_nt_native_path ());
|
2006-01-28 05:50:42 +08:00
|
|
|
}
|
|
|
|
return ino;
|
|
|
|
}
|
|
|
|
|
2007-07-27 01:30:54 +08:00
|
|
|
int
|
|
|
|
fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
|
|
|
DWORD attr, PUNICODE_STRING fname)
|
|
|
|
{
|
|
|
|
if (w32_err)
|
|
|
|
{
|
2017-06-14 19:22:56 +08:00
|
|
|
switch (d_mounts (dir)->check_missing_mount (fname))
|
2010-01-29 19:20:06 +08:00
|
|
|
{
|
2017-06-14 19:22:56 +08:00
|
|
|
case __DIR_mount_none:
|
2010-01-29 19:20:06 +08:00
|
|
|
fname->Length = 0;
|
|
|
|
return geterrno_from_win_error (w32_err);
|
2017-06-14 19:22:56 +08:00
|
|
|
case __DIR_mount_virt_target:
|
|
|
|
de->d_type = DT_DIR;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2010-01-29 19:20:06 +08:00
|
|
|
}
|
2007-07-27 01:30:54 +08:00
|
|
|
attr = 0;
|
|
|
|
dir->__flags &= ~dirent_set_d_ino;
|
|
|
|
}
|
|
|
|
|
2010-08-20 19:18:58 +08:00
|
|
|
/* Set d_type if type can be determined from file attributes. For .lnk
|
|
|
|
symlinks, d_type will be reset below. Reparse points can be NTFS
|
|
|
|
symlinks, even if they have the FILE_ATTRIBUTE_DIRECTORY flag set. */
|
2017-06-15 04:01:28 +08:00
|
|
|
if (attr && !(attr & ~FILE_ATTRIBUTE_VALID_FLAGS))
|
2008-11-28 17:04:35 +08:00
|
|
|
{
|
|
|
|
if (attr & FILE_ATTRIBUTE_DIRECTORY)
|
|
|
|
de->d_type = DT_DIR;
|
2010-08-20 19:18:58 +08:00
|
|
|
/* FILE_ATTRIBUTE_SYSTEM might denote system-bit type symlinks. */
|
|
|
|
else if (!(attr & FILE_ATTRIBUTE_SYSTEM))
|
2008-11-28 17:04:35 +08:00
|
|
|
de->d_type = DT_REG;
|
|
|
|
}
|
|
|
|
|
2017-06-15 04:01:28 +08:00
|
|
|
/* Check for reparse points that can be treated as posix symlinks.
|
|
|
|
Mountpoints and unknown or unhandled reparse points will be treated
|
|
|
|
as normal file/directory/unknown. In all cases, returning the INO of
|
|
|
|
the reparse point (not of the target) matches behavior of posix systems.
|
2017-06-14 02:12:50 +08:00
|
|
|
*/
|
2017-06-15 04:01:28 +08:00
|
|
|
if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
|
2007-07-27 01:30:54 +08:00
|
|
|
{
|
2017-06-14 02:12:50 +08:00
|
|
|
OBJECT_ATTRIBUTES oattr;
|
2007-07-27 01:30:54 +08:00
|
|
|
|
2017-06-14 02:12:50 +08:00
|
|
|
InitializeObjectAttributes (&oattr, fname, pc.objcaseinsensitive (),
|
2007-07-27 01:30:54 +08:00
|
|
|
get_handle (), NULL);
|
2017-06-20 16:06:17 +08:00
|
|
|
if (readdir_check_reparse_point (&oattr, isremote ()))
|
2017-06-15 04:01:28 +08:00
|
|
|
de->d_type = DT_LNK;
|
2007-07-27 01:30:54 +08:00
|
|
|
}
|
|
|
|
|
2010-08-20 19:18:58 +08:00
|
|
|
/* Check for Windows shortcut. If it's a Cygwin or U/WIN symlink, drop the
|
|
|
|
.lnk suffix and set d_type accordingly. */
|
|
|
|
if ((attr & (FILE_ATTRIBUTE_DIRECTORY
|
|
|
|
| FILE_ATTRIBUTE_REPARSE_POINT
|
|
|
|
| FILE_ATTRIBUTE_READONLY)) == FILE_ATTRIBUTE_READONLY
|
|
|
|
&& fname->Length > 4 * sizeof (WCHAR))
|
2007-07-27 01:30:54 +08:00
|
|
|
{
|
|
|
|
UNICODE_STRING uname;
|
|
|
|
|
2007-07-29 00:00:35 +08:00
|
|
|
RtlInitCountedUnicodeString (&uname,
|
|
|
|
fname->Buffer
|
|
|
|
+ fname->Length / sizeof (WCHAR) - 4,
|
|
|
|
4 * sizeof (WCHAR));
|
2009-07-15 01:37:42 +08:00
|
|
|
if (RtlEqualUnicodeString (&uname, &ro_u_lnk, TRUE))
|
2007-07-27 01:30:54 +08:00
|
|
|
{
|
2008-04-14 00:47:21 +08:00
|
|
|
tmp_pathbuf tp;
|
2011-02-15 18:31:54 +08:00
|
|
|
char *file = tp.c_get ();
|
2015-02-15 16:59:55 +08:00
|
|
|
char *p = stpcpy (file, pc.get_posix ());
|
2011-02-15 18:47:24 +08:00
|
|
|
if (p[-1] != '/')
|
|
|
|
*p++ = '/';
|
2011-02-15 18:31:54 +08:00
|
|
|
sys_wcstombs (p, NT_MAX_PATH - (p - file),
|
|
|
|
fname->Buffer, fname->Length / sizeof (WCHAR));
|
|
|
|
path_conv fpath (file, PC_SYM_NOFOLLOW);
|
2010-08-20 19:18:58 +08:00
|
|
|
if (fpath.issymlink ())
|
|
|
|
{
|
|
|
|
fname->Length -= 4 * sizeof (WCHAR);
|
|
|
|
de->d_type = DT_LNK;
|
|
|
|
}
|
|
|
|
else if (fpath.isfifo ())
|
2008-11-28 17:04:35 +08:00
|
|
|
{
|
|
|
|
fname->Length -= 4 * sizeof (WCHAR);
|
2010-08-20 19:18:58 +08:00
|
|
|
de->d_type = DT_FIFO;
|
|
|
|
}
|
|
|
|
else if (fpath.is_fs_special ())
|
|
|
|
{
|
|
|
|
fname->Length -= 4 * sizeof (WCHAR);
|
2016-06-23 22:56:41 +08:00
|
|
|
de->d_type = S_ISCHR (fpath.dev.mode ()) ? DT_CHR : DT_BLK;
|
2008-11-28 17:04:35 +08:00
|
|
|
}
|
2007-07-27 01:30:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-17 04:20:45 +08:00
|
|
|
sys_wcstombs (de->d_name, NAME_MAX + 1, fname->Buffer,
|
|
|
|
fname->Length / sizeof (WCHAR));
|
2008-03-12 23:04:06 +08:00
|
|
|
|
2009-08-14 21:39:07 +08:00
|
|
|
/* Don't try to optimize relative to dir->__d_position. On several
|
|
|
|
filesystems it's no safe bet that "." and ".." entries always
|
|
|
|
come first. */
|
|
|
|
if (de->d_name[0] == '.')
|
|
|
|
{
|
|
|
|
if (de->d_name[1] == '\0')
|
|
|
|
dir->__flags |= dirent_saw_dot;
|
|
|
|
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
|
|
|
|
dir->__flags |= dirent_saw_dot_dot;
|
|
|
|
}
|
2007-07-27 01:30:54 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-01-28 05:50:42 +08:00
|
|
|
int
|
|
|
|
fhandler_disk_file::readdir (DIR *dir, dirent *de)
|
|
|
|
{
|
|
|
|
int res = 0;
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
2006-01-28 21:41:22 +08:00
|
|
|
PFILE_ID_BOTH_DIR_INFORMATION buf = NULL;
|
2007-07-27 01:30:54 +08:00
|
|
|
PWCHAR FileName;
|
2008-05-21 17:02:42 +08:00
|
|
|
ULONG FileNameLength;
|
2017-11-15 04:28:45 +08:00
|
|
|
ULONG FileAttributes;
|
2006-01-28 21:41:22 +08:00
|
|
|
IO_STATUS_BLOCK io;
|
2007-07-27 01:30:54 +08:00
|
|
|
UNICODE_STRING fname;
|
2006-01-28 05:50:42 +08:00
|
|
|
|
2006-01-30 18:30:58 +08:00
|
|
|
/* d_cachepos always refers to the next cache entry to use. If it's 0
|
2006-01-28 21:41:22 +08:00
|
|
|
we must reload the cache. */
|
2017-11-15 04:28:45 +08:00
|
|
|
FileAttributes = 0;
|
2006-01-30 18:30:58 +08:00
|
|
|
if (d_cachepos (dir) == 0)
|
2006-01-28 21:41:22 +08:00
|
|
|
{
|
|
|
|
if ((dir->__flags & dirent_get_d_ino))
|
|
|
|
{
|
2008-12-19 02:54:25 +08:00
|
|
|
status = NtQueryDirectoryFile (get_handle (), NULL, NULL, NULL, &io,
|
2006-01-28 21:41:22 +08:00
|
|
|
d_cache (dir), DIR_BUF_SIZE,
|
|
|
|
FileIdBothDirectoryInformation,
|
|
|
|
FALSE, NULL, dir->__d_position == 0);
|
|
|
|
/* FileIdBothDirectoryInformation isn't supported for remote drives
|
2013-04-23 17:44:36 +08:00
|
|
|
on NT4 and 2K systems. There are also hacked versions of
|
|
|
|
Samba 3.0.x out there (Debian-based it seems), which return
|
|
|
|
STATUS_NOT_SUPPORTED rather than handling this info class.
|
|
|
|
We just fall back to using a standard directory query in
|
2009-10-20 18:12:05 +08:00
|
|
|
this case and note this case using the dirent_get_d_ino flag. */
|
2010-01-29 19:20:06 +08:00
|
|
|
if (!NT_SUCCESS (status) && status != STATUS_NO_MORE_FILES
|
|
|
|
&& (status == STATUS_INVALID_LEVEL
|
|
|
|
|| status == STATUS_NOT_SUPPORTED
|
|
|
|
|| status == STATUS_INVALID_PARAMETER
|
|
|
|
|| status == STATUS_INVALID_NETWORK_RESPONSE
|
|
|
|
|| status == STATUS_INVALID_INFO_CLASS))
|
2006-01-28 21:41:22 +08:00
|
|
|
dir->__flags &= ~dirent_get_d_ino;
|
2006-08-20 20:18:12 +08:00
|
|
|
/* Something weird happens on Samba up to version 3.0.21c, which is
|
|
|
|
fixed in 3.0.22. FileIdBothDirectoryInformation seems to work
|
|
|
|
nicely, but only up to the 128th entry in the directory. After
|
|
|
|
reaching this entry, the next call to NtQueryDirectoryFile
|
|
|
|
(FileIdBothDirectoryInformation) returns STATUS_INVALID_LEVEL.
|
2010-01-29 19:20:06 +08:00
|
|
|
Why should we care, we can just switch to
|
|
|
|
FileBothDirectoryInformation, isn't it? Nope! The next call to
|
|
|
|
NtQueryDirectoryFile(FileBothDirectoryInformation) actually
|
|
|
|
returns STATUS_NO_MORE_FILES, regardless how many files are left
|
|
|
|
unread in the directory. This does not happen when using
|
|
|
|
FileBothDirectoryInformation right from the start, but since
|
2006-08-20 20:18:12 +08:00
|
|
|
we can't decide whether the server we're talking with has this
|
|
|
|
bug or not, we end up serving Samba shares always in the slow
|
2010-01-29 19:20:06 +08:00
|
|
|
mode using FileBothDirectoryInformation. So, what we do here is
|
2006-08-20 20:18:12 +08:00
|
|
|
to implement the solution suggested by Andrew Tridgell, we just
|
|
|
|
reread all entries up to dir->d_position using
|
2010-01-29 19:20:06 +08:00
|
|
|
FileBothDirectoryInformation.
|
2006-08-20 20:18:12 +08:00
|
|
|
However, We do *not* mark this server as broken and fall back to
|
2010-01-29 19:20:06 +08:00
|
|
|
using FileBothDirectoryInformation further on. This would slow
|
2006-08-20 20:18:12 +08:00
|
|
|
down every access to such a server, even for directories under
|
|
|
|
128 entries. Also, bigger dirs only suffer from one additional
|
|
|
|
call per full directory scan, which shouldn't be too big a hit.
|
|
|
|
This can easily be changed if necessary. */
|
|
|
|
if (status == STATUS_INVALID_LEVEL && dir->__d_position)
|
|
|
|
{
|
|
|
|
d_cachepos (dir) = 0;
|
|
|
|
for (int cnt = 0; cnt < dir->__d_position; ++cnt)
|
2007-02-20 08:16:18 +08:00
|
|
|
{
|
2006-08-20 20:18:12 +08:00
|
|
|
if (d_cachepos (dir) == 0)
|
|
|
|
{
|
2007-07-10 01:02:37 +08:00
|
|
|
status = NtQueryDirectoryFile (get_handle (), NULL, NULL,
|
2008-12-19 02:54:25 +08:00
|
|
|
NULL, &io, d_cache (dir),
|
|
|
|
DIR_BUF_SIZE,
|
2010-01-29 19:20:06 +08:00
|
|
|
FileBothDirectoryInformation,
|
2006-08-20 20:18:12 +08:00
|
|
|
FALSE, NULL, cnt == 0);
|
|
|
|
if (!NT_SUCCESS (status))
|
2007-02-20 08:16:18 +08:00
|
|
|
goto go_ahead;
|
2006-08-20 20:18:12 +08:00
|
|
|
}
|
|
|
|
buf = (PFILE_ID_BOTH_DIR_INFORMATION) (d_cache (dir)
|
2007-02-20 08:16:18 +08:00
|
|
|
+ d_cachepos (dir));
|
2006-08-20 20:18:12 +08:00
|
|
|
if (buf->NextEntryOffset == 0)
|
|
|
|
d_cachepos (dir) = 0;
|
|
|
|
else
|
|
|
|
d_cachepos (dir) += buf->NextEntryOffset;
|
|
|
|
}
|
|
|
|
goto go_ahead;
|
|
|
|
}
|
2006-01-28 21:41:22 +08:00
|
|
|
}
|
2023-09-10 05:05:29 +08:00
|
|
|
/* NFS must use FileNamesInformation! Any other information class
|
|
|
|
skips all symlinks. */
|
2006-01-28 21:41:22 +08:00
|
|
|
if (!(dir->__flags & dirent_get_d_ino))
|
2008-12-19 02:54:25 +08:00
|
|
|
status = NtQueryDirectoryFile (get_handle (), NULL, NULL, NULL, &io,
|
2006-01-28 21:41:22 +08:00
|
|
|
d_cache (dir), DIR_BUF_SIZE,
|
2008-05-21 17:02:42 +08:00
|
|
|
(dir->__flags & dirent_nfs_d_ino)
|
|
|
|
? FileNamesInformation
|
2010-01-29 19:20:06 +08:00
|
|
|
: FileBothDirectoryInformation,
|
2006-01-28 21:41:22 +08:00
|
|
|
FALSE, NULL, dir->__d_position == 0);
|
|
|
|
}
|
2006-01-28 05:50:42 +08:00
|
|
|
|
2006-08-20 20:18:12 +08:00
|
|
|
go_ahead:
|
|
|
|
|
2008-12-19 02:54:25 +08:00
|
|
|
if (status == STATUS_NO_MORE_FILES)
|
|
|
|
/*nothing*/;
|
|
|
|
else if (!NT_SUCCESS (status))
|
2013-04-23 17:44:36 +08:00
|
|
|
debug_printf ("NtQueryDirectoryFile failed, status %y, win32 error %u",
|
2006-12-21 18:59:47 +08:00
|
|
|
status, RtlNtStatusToDosError (status));
|
|
|
|
else
|
2006-01-28 21:41:22 +08:00
|
|
|
{
|
2006-01-30 18:30:58 +08:00
|
|
|
buf = (PFILE_ID_BOTH_DIR_INFORMATION) (d_cache (dir) + d_cachepos (dir));
|
2006-01-28 21:41:22 +08:00
|
|
|
if (buf->NextEntryOffset == 0)
|
2006-05-28 23:50:14 +08:00
|
|
|
d_cachepos (dir) = 0;
|
2006-01-28 21:41:22 +08:00
|
|
|
else
|
2006-01-30 18:30:58 +08:00
|
|
|
d_cachepos (dir) += buf->NextEntryOffset;
|
2006-01-28 21:41:22 +08:00
|
|
|
if ((dir->__flags & dirent_get_d_ino))
|
|
|
|
{
|
|
|
|
FileName = buf->FileName;
|
2008-05-21 17:02:42 +08:00
|
|
|
FileNameLength = buf->FileNameLength;
|
|
|
|
FileAttributes = buf->FileAttributes;
|
2006-01-28 05:50:42 +08:00
|
|
|
if ((dir->__flags & dirent_set_d_ino))
|
2015-12-10 01:11:47 +08:00
|
|
|
de->d_ino = buf->FileId.QuadPart;
|
2006-05-28 23:50:14 +08:00
|
|
|
}
|
2008-05-21 17:02:42 +08:00
|
|
|
else if ((dir->__flags & dirent_nfs_d_ino))
|
|
|
|
{
|
|
|
|
FileName = ((PFILE_NAMES_INFORMATION) buf)->FileName;
|
|
|
|
FileNameLength = ((PFILE_NAMES_INFORMATION) buf)->FileNameLength;
|
2008-11-27 01:21:04 +08:00
|
|
|
}
|
2006-01-28 05:50:42 +08:00
|
|
|
else
|
2008-05-21 17:02:42 +08:00
|
|
|
{
|
2013-04-23 17:44:36 +08:00
|
|
|
FileName = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileName;
|
2010-01-29 19:20:06 +08:00
|
|
|
FileNameLength =
|
2013-04-23 17:44:36 +08:00
|
|
|
((PFILE_BOTH_DIR_INFORMATION) buf)->FileNameLength;
|
2010-01-29 19:20:06 +08:00
|
|
|
FileAttributes =
|
2013-04-23 17:44:36 +08:00
|
|
|
((PFILE_BOTH_DIR_INFORMATION) buf)->FileAttributes;
|
2008-05-21 17:02:42 +08:00
|
|
|
}
|
|
|
|
RtlInitCountedUnicodeString (&fname, FileName, FileNameLength);
|
2017-06-14 19:22:56 +08:00
|
|
|
d_mounts (dir)->check_mount (&fname);
|
2006-01-28 21:41:22 +08:00
|
|
|
if (de->d_ino == 0 && (dir->__flags & dirent_set_d_ino))
|
2006-01-28 05:50:42 +08:00
|
|
|
{
|
2009-08-14 21:39:07 +08:00
|
|
|
/* Don't try to optimize relative to dir->__d_position. On several
|
|
|
|
filesystems it's no safe bet that "." and ".." entries always
|
|
|
|
come first. */
|
|
|
|
if (FileNameLength == sizeof (WCHAR) && FileName[0] == '.')
|
2010-06-15 16:51:55 +08:00
|
|
|
de->d_ino = pc.get_ino_by_handle (get_handle ());
|
2009-08-15 02:27:18 +08:00
|
|
|
else if (FileNameLength == 2 * sizeof (WCHAR)
|
2007-07-27 01:30:54 +08:00
|
|
|
&& FileName[0] == L'.' && FileName[1] == L'.')
|
2009-08-14 21:39:07 +08:00
|
|
|
{
|
|
|
|
if (!(dir->__flags & dirent_isroot))
|
|
|
|
de->d_ino = readdir_get_ino (get_name (), true);
|
|
|
|
else
|
2010-06-15 16:51:55 +08:00
|
|
|
de->d_ino = pc.get_ino_by_handle (get_handle ());
|
2009-08-14 21:39:07 +08:00
|
|
|
}
|
2006-01-28 21:41:22 +08:00
|
|
|
else
|
2006-01-28 05:50:42 +08:00
|
|
|
{
|
2009-08-14 21:39:07 +08:00
|
|
|
OBJECT_ATTRIBUTES attr;
|
2006-01-28 21:41:22 +08:00
|
|
|
HANDLE hdl;
|
2009-08-14 21:39:07 +08:00
|
|
|
NTSTATUS f_status;
|
2007-07-27 01:30:54 +08:00
|
|
|
|
2008-07-17 04:20:45 +08:00
|
|
|
InitializeObjectAttributes (&attr, &fname,
|
|
|
|
pc.objcaseinsensitive (),
|
2007-07-27 01:30:54 +08:00
|
|
|
get_handle (), NULL);
|
2009-08-14 21:39:07 +08:00
|
|
|
/* FILE_OPEN_REPARSE_POINT on NFS is a no-op, so the normal
|
2011-06-06 13:02:13 +08:00
|
|
|
NtOpenFile here returns the inode number of the symlink target,
|
2009-08-14 21:39:07 +08:00
|
|
|
rather than the inode number of the symlink itself.
|
2011-06-06 13:02:13 +08:00
|
|
|
|
2009-08-14 21:39:07 +08:00
|
|
|
Worse, trying to open a symlink without setting the special
|
|
|
|
"ActOnSymlink" EA triggers a bug in Windows 7 which results
|
2009-08-14 22:10:31 +08:00
|
|
|
in a timeout of up to 20 seconds, followed by two exceptions
|
2009-08-14 21:39:07 +08:00
|
|
|
in the NT kernel.
|
|
|
|
|
|
|
|
Since both results are far from desirable, we open symlinks
|
|
|
|
on NFS so that we get the right inode and a happy W7.
|
|
|
|
And, since some filesystems choke on the EAs, we don't
|
|
|
|
use them unconditionally. */
|
|
|
|
f_status = (dir->__flags & dirent_nfs_d_ino)
|
2023-09-10 05:23:52 +08:00
|
|
|
? NtCreateFile (&hdl,
|
|
|
|
READ_CONTROL | FILE_READ_ATTRIBUTES,
|
|
|
|
&attr, &io, NULL, 0,
|
|
|
|
FILE_SHARE_VALID_FLAGS, FILE_OPEN,
|
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT,
|
2009-08-14 21:39:07 +08:00
|
|
|
&nfs_aol_ffei, sizeof nfs_aol_ffei)
|
|
|
|
: NtOpenFile (&hdl, READ_CONTROL, &attr, &io,
|
|
|
|
FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT
|
|
|
|
| FILE_OPEN_REPARSE_POINT);
|
|
|
|
if (NT_SUCCESS (f_status))
|
2006-01-28 21:41:22 +08:00
|
|
|
{
|
2010-08-20 19:18:58 +08:00
|
|
|
/* We call NtQueryInformationFile here, rather than
|
|
|
|
pc.get_ino_by_handle(), otherwise we can't short-circuit
|
|
|
|
dirent_set_d_ino correctly. */
|
2015-12-10 06:51:48 +08:00
|
|
|
FILE_INTERNAL_INFORMATION fii;
|
|
|
|
f_status = NtQueryInformationFile (hdl, &io, &fii, sizeof fii,
|
2010-08-20 19:18:58 +08:00
|
|
|
FileInternalInformation);
|
2023-09-10 05:23:52 +08:00
|
|
|
/* On NFS fetch the (faked, but useful) DOS attribute.
|
|
|
|
We need it to recognize shortcut FIFOs. */
|
|
|
|
if ((dir->__flags & dirent_nfs_d_ino))
|
|
|
|
{
|
|
|
|
FILE_BASIC_INFORMATION fbi;
|
|
|
|
|
|
|
|
if (NT_SUCCESS (NtQueryInformationFile (hdl, &io, &fbi,
|
|
|
|
sizeof fbi, FileBasicInformation)))
|
|
|
|
FileAttributes = fbi.FileAttributes;
|
|
|
|
}
|
2007-07-27 01:30:54 +08:00
|
|
|
NtClose (hdl);
|
2010-08-20 19:18:58 +08:00
|
|
|
if (NT_SUCCESS (f_status))
|
|
|
|
{
|
2015-12-10 06:51:48 +08:00
|
|
|
if (pc.isgood_inode (fii.IndexNumber.QuadPart))
|
|
|
|
de->d_ino = fii.IndexNumber.QuadPart;
|
2010-08-20 19:18:58 +08:00
|
|
|
else
|
|
|
|
/* Untrusted file system. Don't try to fetch inode
|
|
|
|
number again. */
|
|
|
|
dir->__flags &= ~dirent_set_d_ino;
|
|
|
|
}
|
2006-01-28 21:41:22 +08:00
|
|
|
}
|
2006-01-28 05:50:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(res = readdir_helper (dir, de, RtlNtStatusToDosError (status),
|
2010-08-20 19:18:58 +08:00
|
|
|
FileAttributes, &fname)))
|
2006-01-28 05:50:42 +08:00
|
|
|
dir->__d_position++;
|
|
|
|
else if (!(dir->__flags & dirent_saw_dot))
|
|
|
|
{
|
|
|
|
strcpy (de->d_name , ".");
|
2010-06-15 16:51:55 +08:00
|
|
|
de->d_ino = pc.get_ino_by_handle (get_handle ());
|
2010-08-20 19:18:58 +08:00
|
|
|
de->d_type = DT_DIR;
|
2006-01-28 05:50:42 +08:00
|
|
|
dir->__d_position++;
|
|
|
|
dir->__flags |= dirent_saw_dot;
|
|
|
|
res = 0;
|
|
|
|
}
|
2006-05-08 23:20:04 +08:00
|
|
|
else if (!(dir->__flags & dirent_saw_dot_dot))
|
2006-01-28 05:50:42 +08:00
|
|
|
{
|
|
|
|
strcpy (de->d_name , "..");
|
2007-07-10 01:02:37 +08:00
|
|
|
if (!(dir->__flags & dirent_isroot))
|
2007-07-27 01:30:54 +08:00
|
|
|
de->d_ino = readdir_get_ino (get_name (), true);
|
2007-07-10 01:02:37 +08:00
|
|
|
else
|
2010-06-15 16:51:55 +08:00
|
|
|
de->d_ino = pc.get_ino_by_handle (get_handle ());
|
2010-08-20 19:18:58 +08:00
|
|
|
de->d_type = DT_DIR;
|
2006-01-28 05:50:42 +08:00
|
|
|
dir->__d_position++;
|
|
|
|
dir->__flags |= dirent_saw_dot_dot;
|
|
|
|
res = 0;
|
|
|
|
}
|
|
|
|
|
2013-04-23 17:44:36 +08:00
|
|
|
syscall_printf ("%d = readdir(%p, %p) (L\"%lS\" > \"%ls\") (attr %y > type %d)",
|
2010-08-20 19:18:58 +08:00
|
|
|
res, dir, &de, res ? NULL : &fname, res ? "***" : de->d_name,
|
|
|
|
FileAttributes, de->d_type);
|
2006-01-28 05:50:42 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2010-07-06 00:59:56 +08:00
|
|
|
long
|
2001-11-21 14:47:57 +08:00
|
|
|
fhandler_disk_file::telldir (DIR *dir)
|
|
|
|
{
|
|
|
|
return dir->__d_position;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-07-06 00:59:56 +08:00
|
|
|
fhandler_disk_file::seekdir (DIR *dir, long loc)
|
2001-11-21 14:47:57 +08:00
|
|
|
{
|
2005-03-17 05:21:18 +08:00
|
|
|
rewinddir (dir);
|
|
|
|
while (loc > dir->__d_position)
|
|
|
|
if (!::readdir (dir))
|
|
|
|
break;
|
2001-11-21 14:47:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
fhandler_disk_file::rewinddir (DIR *dir)
|
|
|
|
{
|
2007-02-22 18:54:47 +08:00
|
|
|
d_cachepos (dir) = 0;
|
2001-11-21 14:47:57 +08:00
|
|
|
dir->__d_position = 0;
|
2006-03-01 21:47:49 +08:00
|
|
|
d_mounts (dir)->rewind ();
|
2001-11-21 14:47:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_disk_file::closedir (DIR *dir)
|
|
|
|
{
|
|
|
|
int res = 0;
|
2007-02-22 23:07:21 +08:00
|
|
|
|
2006-03-01 21:47:49 +08:00
|
|
|
delete d_mounts (dir);
|
2011-12-04 05:43:27 +08:00
|
|
|
syscall_printf ("%d = closedir(%p, %s)", res, dir, get_name ());
|
2006-02-05 15:03:24 +08:00
|
|
|
return res;
|
2001-11-21 14:47:57 +08:00
|
|
|
}
|
2001-11-22 13:59:07 +08:00
|
|
|
|
2018-12-26 06:38:52 +08:00
|
|
|
uint64_t
|
|
|
|
fhandler_disk_file::fs_ioc_getflags ()
|
|
|
|
{
|
|
|
|
NTSTATUS status;
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
FILE_BASIC_INFORMATION fbi;
|
|
|
|
FILE_CASE_SENSITIVE_INFORMATION fcsi;
|
|
|
|
uint64_t flags = 0;
|
|
|
|
|
|
|
|
status = NtQueryInformationFile (get_handle (), &io, &fbi, sizeof fbi,
|
|
|
|
FileBasicInformation);
|
|
|
|
if (NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
flags = (uint64_t) fbi.FileAttributes & FS_FL_USER_VISIBLE;
|
|
|
|
pc.file_attributes (fbi.FileAttributes);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
flags = (uint64_t) pc.file_attributes () & FS_FL_USER_VISIBLE;
|
|
|
|
if (pc.isdir () && wincap.has_case_sensitive_dirs ()
|
|
|
|
&& !pc.isremote () && pc.fs_is_ntfs ())
|
|
|
|
{
|
|
|
|
fcsi.Flags = 0;
|
|
|
|
status = NtQueryInformationFile (get_handle (), &io,
|
|
|
|
&fcsi, sizeof fcsi,
|
|
|
|
FileCaseSensitiveInformation);
|
|
|
|
if (NT_SUCCESS (status)
|
|
|
|
&& (fcsi.Flags & FILE_CS_FLAG_CASE_SENSITIVE_DIR))
|
|
|
|
flags |= FS_CASESENS_FL;
|
|
|
|
}
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Settable DOS attributes */
|
|
|
|
#define FS_FL_SETATTRIBS (FS_READONLY_FL \
|
|
|
|
| FS_HIDDEN_FL \
|
|
|
|
| FS_SYSTEM_FL \
|
|
|
|
| FS_ARCHIVE_FL \
|
|
|
|
| FS_TEMP_FL \
|
|
|
|
| FS_NOTINDEXED_FL)
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_disk_file::fs_ioc_setflags (uint64_t flags)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
uint64_t old_flags;
|
|
|
|
HANDLE fh;
|
|
|
|
NTSTATUS status;
|
|
|
|
OBJECT_ATTRIBUTES attr;
|
|
|
|
IO_STATUS_BLOCK io;
|
|
|
|
FILE_BASIC_INFORMATION fbi;
|
|
|
|
FILE_SET_SPARSE_BUFFER fssb;
|
|
|
|
USHORT comp;
|
|
|
|
FILE_CASE_SENSITIVE_INFORMATION fcsi;
|
|
|
|
|
|
|
|
if ((get_access () & (GENERIC_WRITE | FILE_WRITE_ATTRIBUTES)) != 0)
|
|
|
|
fh = get_handle ();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
status = NtOpenFile (&fh, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
|
|
|
|
pc.init_reopen_attr (attr, get_handle ()), &io,
|
|
|
|
FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_OPEN_FOR_BACKUP_INTENT);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
fh = get_handle ();
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
old_flags = fs_ioc_getflags ();
|
|
|
|
if ((old_flags & FS_FL_SETATTRIBS) != (flags & FS_FL_SETATTRIBS))
|
|
|
|
{
|
|
|
|
fbi.CreationTime.QuadPart
|
|
|
|
= fbi.LastAccessTime.QuadPart
|
|
|
|
= fbi.LastWriteTime.QuadPart
|
|
|
|
= fbi.ChangeTime.QuadPart = 0LL;
|
|
|
|
fbi.FileAttributes = (ULONG) old_flags;
|
|
|
|
fbi.FileAttributes &= ~FS_FL_SETATTRIBS;
|
|
|
|
fbi.FileAttributes |= (flags & FS_FL_SETATTRIBS);
|
|
|
|
if (fbi.FileAttributes == 0)
|
|
|
|
fbi.FileAttributes = FILE_ATTRIBUTE_NORMAL;
|
|
|
|
status = NtSetInformationFile (fh, &io, &fbi, sizeof fbi,
|
|
|
|
FileBasicInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!pc.isdir() && (flags & FS_SPARSE_FL) != (old_flags & FS_SPARSE_FL))
|
|
|
|
{
|
|
|
|
fssb.SetSparse = (flags & FS_SPARSE_FL) ? TRUE : FALSE;
|
|
|
|
status = NtFsControlFile (fh, NULL, NULL, NULL, &io,
|
|
|
|
FSCTL_SET_SPARSE, &fssb, sizeof fssb, NULL, 0);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pc.isdir () && (flags & FS_CASESENS_FL) != (old_flags & FS_CASESENS_FL))
|
|
|
|
{
|
|
|
|
if (wincap.has_case_sensitive_dirs ()
|
|
|
|
&& !pc.isremote () && pc.fs_is_ntfs ())
|
|
|
|
{
|
|
|
|
fcsi.Flags = (flags & FS_CASESENS_FL)
|
|
|
|
? FILE_CS_FLAG_CASE_SENSITIVE_DIR : 0;
|
|
|
|
status = NtSetInformationFile (fh, &io, &fcsi, sizeof fcsi,
|
|
|
|
FileCaseSensitiveInformation);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
2021-12-02 21:13:43 +08:00
|
|
|
__seterrno_from_nt_status (status);
|
2018-12-26 06:38:52 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
set_errno (ENOTSUP);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((flags & FS_COMPRESSED_FL) != (old_flags & FS_COMPRESSED_FL))
|
|
|
|
{
|
|
|
|
if (fh != get_handle ())
|
|
|
|
NtClose (fh);
|
|
|
|
fh = NULL;
|
|
|
|
if ((get_access () & (GENERIC_WRITE | GENERIC_READ))
|
|
|
|
!= (GENERIC_WRITE | GENERIC_READ))
|
|
|
|
{
|
|
|
|
status = NtOpenFile (&fh, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
|
|
|
|
pc.init_reopen_attr (attr, get_handle ()), &io,
|
|
|
|
FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT
|
|
|
|
| FILE_OPEN_FOR_BACKUP_INTENT);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
fh = get_handle ();
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
comp = (flags & FS_COMPRESSED_FL)
|
|
|
|
? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;
|
|
|
|
status = NtFsControlFile (fh, NULL, NULL, NULL, &io,
|
|
|
|
FSCTL_SET_COMPRESSION, &comp, sizeof comp,
|
|
|
|
NULL, 0);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!pc.isdir() && (flags & FS_ENCRYPT_FL) != (old_flags & FS_ENCRYPT_FL))
|
|
|
|
{
|
|
|
|
tmp_pathbuf tp;
|
|
|
|
PWCHAR path = tp.w_get ();
|
|
|
|
BOOL cret;
|
|
|
|
|
|
|
|
/* EncryptFileW/DecryptFileW needs exclusive access. */
|
|
|
|
if (fh != get_handle ())
|
|
|
|
NtClose (fh);
|
|
|
|
NtClose (get_handle ());
|
2019-03-30 15:12:02 +08:00
|
|
|
set_handle (NULL);
|
2018-12-26 06:38:52 +08:00
|
|
|
|
|
|
|
pc.get_wide_win32_path (path);
|
|
|
|
cret = (flags & FS_ENCRYPT_FL)
|
|
|
|
? EncryptFileW (path) : DecryptFileW (path, 0);
|
|
|
|
status = NtOpenFile (&fh, get_access (),
|
|
|
|
pc.get_object_attr (attr, sec_none_nih), &io,
|
|
|
|
FILE_SHARE_VALID_FLAGS,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT
|
|
|
|
| FILE_OPEN_FOR_BACKUP_INTENT);
|
|
|
|
if (!NT_SUCCESS (status))
|
|
|
|
{
|
|
|
|
__seterrno_from_nt_status (status);
|
|
|
|
return -1;
|
|
|
|
}
|
2019-03-30 15:12:02 +08:00
|
|
|
set_handle (fh);
|
2018-12-26 06:38:52 +08:00
|
|
|
if (!cret)
|
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
out:
|
|
|
|
status = NtQueryInformationFile (fh, &io, &fbi, sizeof fbi,
|
|
|
|
FileBasicInformation);
|
|
|
|
if (NT_SUCCESS (status))
|
|
|
|
pc.file_attributes (fbi.FileAttributes);
|
|
|
|
if (fh != get_handle ())
|
|
|
|
NtClose (fh);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_disk_file::ioctl (unsigned int cmd, void *p)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
uint64_t flags = 0;
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case FS_IOC_GETFLAGS:
|
|
|
|
__try
|
|
|
|
{
|
|
|
|
uint64_t *fp = (uint64_t *) p;
|
|
|
|
*fp = fs_ioc_getflags ();
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
__except (EFAULT) {}
|
|
|
|
__endtry
|
|
|
|
break;
|
|
|
|
case FS_IOC_SETFLAGS:
|
|
|
|
__try
|
|
|
|
{
|
|
|
|
flags = *(__uint64_t *) p;
|
|
|
|
}
|
|
|
|
__except (EFAULT)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
__endtry
|
|
|
|
if (flags & ~FS_FL_USER_MODIFIABLE)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ret = fs_ioc_setflags (flags);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = fhandler_base::ioctl (cmd, p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
syscall_printf ("%d = ioctl_file(%x, %p)", ret, cmd, p);
|
|
|
|
return ret;
|
|
|
|
}
|