newlib-cygwin/winsup/cygwin/sec_acl.cc

1185 lines
29 KiB
C++
Raw Normal View History

/* sec_acl.cc: Sun compatible ACL functions.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011, 2012, 2014, 2015 Red Hat, Inc.
Written by Corinna Vinschen <corinna@vinschen.de>
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"
#include <stdlib.h>
#include <sys/acl.h>
#include <ctype.h>
#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"
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
#include "tls_pbuf.h"
static int
2013-04-23 17:44:36 +08:00
searchace (aclent_t *aclp, int nentries, int type, uid_t id = ILLEGAL_UID)
{
int i;
for (i = 0; i < nentries; ++i)
2003-02-06 00:15:22 +08:00
if ((aclp[i].a_type == type && (id == ILLEGAL_UID || aclp[i].a_id == id))
|| !aclp[i].a_type)
return i;
return -1;
}
/* This function *requires* an acl list sorted with aclsort{32}. */
int
2013-04-23 17:44:36 +08:00
setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
bool &writable)
{
* dir.cc (mkdir): Use local security_descriptor. Call set_security_attribute appropriately. * external.cc (cygwin_internal): Ditto. * fhandler.cc (fhandler_base::open): Ditto. * fhandler_socket.cc (fhandler_socket::bind): Ditto. * path.cc (symlink_worker): Ditto. * sec_acl.cc (setacl): Ditto. Call read_sd appropriately. (getace): Ditto. * sec_helper.cc (security_descriptor::malloc): New method. (security_descriptor::realloc): New method. (security_descriptor::free): New method. * security.cc (read_sd): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. Allocate the security_descriptor buffer according to size returned by a call to GetFileSecurity. Return buffer size on success. (write_sd): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (get_nt_attribute): Use local security_descriptor. (get_nt_object_attribute): Ditto in case of type == SE_REGISTRY_KEY. Allocate security_descriptor buffer according to size returned by a call to RegGetKeySecurity. (alloc_sd): Make static. Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. (set_security_attribute): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (set_nt_attribute): Use local security_descriptor. (check_file_access): Ditto. * security.h: Add class security_descriptor. (read_sd): Change declaration to get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (write_sd): Ditto. (set_security_attribute): Ditto. (alloc_sd): Remove declaration. * thread.cc (semaphore::semaphore): Use local security_descriptor. Call set_security_attribute appropriately.
2003-11-26 21:23:27 +08:00
security_descriptor sd_ret;
tmp_pathbuf tp;
if (get_file_sd (handle, pc, sd_ret, false))
return -1;
NTSTATUS status;
PACL acl;
BOOLEAN acl_exists, dummy;
/* Get owner SID. */
2003-02-06 00:15:22 +08:00
PSID owner_sid;
status = RtlGetOwnerSecurityDescriptor (sd_ret, &owner_sid, &dummy);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
}
cygsid owner (owner_sid);
/* Get group SID. */
2003-02-06 00:15:22 +08:00
PSID group_sid;
status = RtlGetGroupSecurityDescriptor (sd_ret, &group_sid, &dummy);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
}
cygsid group (group_sid);
/* Search for NULL ACE and store state of SUID, SGID and VTX bits. */
DWORD null_mask = 0;
if (NT_SUCCESS (RtlGetDaclSecurityDescriptor (sd_ret, &acl_exists, &acl,
&dummy)))
for (USHORT i = 0; i < acl->AceCount; ++i)
{
ACCESS_ALLOWED_ACE *ace;
if (NT_SUCCESS (RtlGetAce (acl, i, (PVOID *) &ace)))
{
cygpsid ace_sid ((PSID) &ace->SidStart);
if (ace_sid == well_known_null_sid)
{
null_mask = ace->Mask;
break;
}
}
}
/* Initialize local security descriptor. */
SECURITY_DESCRIPTOR sd;
RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
/* As in alloc_sd, set SE_DACL_PROTECTED to prevent the DACL from being
modified by inheritable ACEs. */
RtlSetControlSecurityDescriptor (&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
status = RtlSetOwnerSecurityDescriptor (&sd, owner, FALSE);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
}
status = RtlSetGroupSecurityDescriptor (&sd, group, FALSE);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
}
/* Fill access control list. */
acl = (PACL) tp.w_get ();
size_t acl_len = sizeof (ACL);
int ace_off = 0;
cygsid sid;
struct passwd *pw;
2013-04-23 17:44:36 +08:00
struct group *gr;
int pos;
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
cyg_ldap cldap;
RtlCreateAcl (acl, ACL_MAXIMUM_SIZE, ACL_REVISION);
writable = false;
bool *invalid = (bool *) tp.c_get ();
memset (invalid, 0, nentries * sizeof *invalid);
/* Pre-compute owner, group, and other permissions to allow creating
matching deny ACEs as in alloc_sd. */
DWORD owner_allow = 0, group_allow = 0, other_allow = 0;
PDWORD allow;
for (int i = 0; i < nentries; ++i)
{
switch (aclbufp[i].a_type)
{
case USER_OBJ:
allow = &owner_allow;
*allow = STANDARD_RIGHTS_ALL
| (pc.fs_is_samba () ? 0 : FILE_WRITE_ATTRIBUTES);
break;
case GROUP_OBJ:
allow = &group_allow;
break;
case OTHER_OBJ:
allow = &other_allow;
break;
default:
continue;
}
*allow |= STANDARD_RIGHTS_READ | SYNCHRONIZE
| (pc.fs_is_samba () ? 0 : FILE_READ_ATTRIBUTES);
if (aclbufp[i].a_perm & S_IROTH)
*allow |= FILE_GENERIC_READ;
if (aclbufp[i].a_perm & S_IWOTH)
{
*allow |= FILE_GENERIC_WRITE;
writable = true;
}
if (aclbufp[i].a_perm & S_IXOTH)
*allow |= FILE_GENERIC_EXECUTE & ~FILE_READ_ATTRIBUTES;
/* Keep S_ISVTX rule in sync with alloc_sd. */
if (pc.isdir ()
&& (aclbufp[i].a_perm & (S_IWOTH | S_IXOTH)) == (S_IWOTH | S_IXOTH)
&& (aclbufp[i].a_type == USER_OBJ
|| !(null_mask & FILE_READ_DATA)))
*allow |= FILE_DELETE_CHILD;
invalid[i] = true;
}
bool isownergroup = (owner == group);
DWORD owner_deny = ~owner_allow & (group_allow | other_allow);
owner_deny &= ~(STANDARD_RIGHTS_READ
| FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES);
DWORD group_deny = ~group_allow & other_allow;
group_deny &= ~(STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES);
/* Set deny ACE for owner. */
if (owner_deny
&& !add_access_denied_ace (acl, ace_off++, owner_deny,
owner, acl_len, NO_INHERITANCE))
return -1;
/* Set deny ACE for group here to respect the canonical order,
if this does not impact owner */
if (group_deny && !(group_deny & owner_allow) && !isownergroup
&& !add_access_denied_ace (acl, ace_off++, group_deny,
group, acl_len, NO_INHERITANCE))
return -1;
/* Set allow ACE for owner. */
if (!add_access_allowed_ace (acl, ace_off++, owner_allow,
owner, acl_len, NO_INHERITANCE))
return -1;
/* Set deny ACE for group, if still needed. */
if (group_deny & owner_allow && !isownergroup
&& !add_access_denied_ace (acl, ace_off++, group_deny,
group, acl_len, NO_INHERITANCE))
return -1;
/* Set allow ACE for group. */
if (!isownergroup
&& !add_access_allowed_ace (acl, ace_off++, group_allow,
group, acl_len, NO_INHERITANCE))
return -1;
/* Set allow ACE for everyone. */
if (!add_access_allowed_ace (acl, ace_off++, other_allow,
well_known_world_sid, acl_len, NO_INHERITANCE))
return -1;
/* If a NULL ACE exists, copy it verbatim. */
if (null_mask)
if (!add_access_allowed_ace (acl, ace_off++, null_mask, well_known_null_sid,
acl_len, NO_INHERITANCE))
return -1;
for (int i = 0; i < nentries; ++i)
{
DWORD allow;
/* Skip invalidated entries. */
if (invalid[i])
continue;
allow = STANDARD_RIGHTS_READ
| (pc.fs_is_samba () ? 0 : FILE_READ_ATTRIBUTES);
if (aclbufp[i].a_perm & S_IROTH)
allow |= FILE_GENERIC_READ;
if (aclbufp[i].a_perm & S_IWOTH)
{
allow |= FILE_GENERIC_WRITE;
writable = true;
}
if (aclbufp[i].a_perm & S_IXOTH)
allow |= FILE_GENERIC_EXECUTE & ~FILE_READ_ATTRIBUTES;
/* Keep S_ISVTX rule in sync with alloc_sd. */
if (pc.isdir ()
&& (aclbufp[i].a_perm & (S_IWOTH | S_IXOTH)) == (S_IWOTH | S_IXOTH)
&& !(null_mask & FILE_READ_DATA))
allow |= FILE_DELETE_CHILD;
/* Set inherit property. */
DWORD inheritance = (aclbufp[i].a_type & ACL_DEFAULT)
? (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE
| INHERIT_ONLY_ACE)
: NO_INHERITANCE;
/*
* If a specific acl contains a corresponding default entry with
* identical permissions, only one Windows ACE with proper
* inheritance bits is created.
*/
if (!(aclbufp[i].a_type & ACL_DEFAULT)
&& aclbufp[i].a_type & (USER|GROUP)
&& (pos = searchace (aclbufp + i + 1, nentries - i - 1,
aclbufp[i].a_type | ACL_DEFAULT,
(aclbufp[i].a_type & (USER|GROUP))
2003-02-06 00:15:22 +08:00
? aclbufp[i].a_id : ILLEGAL_UID)) >= 0
&& aclbufp[i].a_perm == aclbufp[i + 1 + pos].a_perm)
{
inheritance = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
/* invalidate the corresponding default entry. */
invalid[i + 1 + pos] = true;
}
switch (aclbufp[i].a_type)
{
case DEF_USER_OBJ:
allow |= STANDARD_RIGHTS_ALL
| (pc.fs_is_samba () ? 0 : FILE_WRITE_ATTRIBUTES);
if (!add_access_allowed_ace (acl, ace_off++, allow,
well_known_creator_owner_sid, acl_len, inheritance))
return -1;
break;
case USER:
case DEF_USER:
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
if (!(pw = internal_getpwuid (aclbufp[i].a_id, &cldap))
|| !sid.getfrompw (pw))
{
set_errno (EINVAL);
return -1;
}
if (!add_access_allowed_ace (acl, ace_off++, allow,
sid, acl_len, inheritance))
return -1;
break;
case DEF_GROUP_OBJ:
if (!add_access_allowed_ace (acl, ace_off++, allow,
well_known_creator_group_sid, acl_len, inheritance))
return -1;
break;
case GROUP:
case DEF_GROUP:
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
if (!(gr = internal_getgrgid (aclbufp[i].a_id, &cldap))
|| !sid.getfromgr (gr))
{
set_errno (EINVAL);
return -1;
}
if (!add_access_allowed_ace (acl, ace_off++, allow,
sid, acl_len, inheritance))
return -1;
break;
case DEF_OTHER_OBJ:
if (!add_access_allowed_ace (acl, ace_off++, allow,
well_known_world_sid,
acl_len, inheritance))
return -1;
}
}
/* Set AclSize to computed value. */
acl->AclSize = acl_len;
2013-04-23 17:44:36 +08:00
debug_printf ("ACL-Size: %u", acl_len);
/* Create DACL for local security descriptor. */
status = RtlSetDaclSecurityDescriptor (&sd, TRUE, acl, FALSE);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
}
* dir.cc (mkdir): Use local security_descriptor. Call set_security_attribute appropriately. * external.cc (cygwin_internal): Ditto. * fhandler.cc (fhandler_base::open): Ditto. * fhandler_socket.cc (fhandler_socket::bind): Ditto. * path.cc (symlink_worker): Ditto. * sec_acl.cc (setacl): Ditto. Call read_sd appropriately. (getace): Ditto. * sec_helper.cc (security_descriptor::malloc): New method. (security_descriptor::realloc): New method. (security_descriptor::free): New method. * security.cc (read_sd): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. Allocate the security_descriptor buffer according to size returned by a call to GetFileSecurity. Return buffer size on success. (write_sd): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (get_nt_attribute): Use local security_descriptor. (get_nt_object_attribute): Ditto in case of type == SE_REGISTRY_KEY. Allocate security_descriptor buffer according to size returned by a call to RegGetKeySecurity. (alloc_sd): Make static. Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. (set_security_attribute): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (set_nt_attribute): Use local security_descriptor. (check_file_access): Ditto. * security.h: Add class security_descriptor. (read_sd): Change declaration to get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (write_sd): Ditto. (set_security_attribute): Ditto. (alloc_sd): Remove declaration. * thread.cc (semaphore::semaphore): Use local security_descriptor. Call set_security_attribute appropriately.
2003-11-26 21:23:27 +08:00
/* Make self relative security descriptor in sd_ret. */
DWORD sd_size = 0;
RtlAbsoluteToSelfRelativeSD (&sd, sd_ret, &sd_size);
if (sd_size <= 0)
{
__seterrno ();
return -1;
}
if (!sd_ret.realloc (sd_size))
{
set_errno (ENOMEM);
return -1;
}
status = RtlAbsoluteToSelfRelativeSD (&sd, sd_ret, &sd_size);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
}
2013-04-23 17:44:36 +08:00
debug_printf ("Created SD-Size: %u", sd_ret.size ());
return set_file_sd (handle, pc, sd_ret, false);
}
/* Temporary access denied bits */
#define DENY_R 040000
#define DENY_W 020000
#define DENY_X 010000
static void
2013-04-23 17:44:36 +08:00
getace (aclent_t &acl, int type, int id, DWORD win_ace_mask,
DWORD win_ace_type)
{
acl.a_type = type;
acl.a_id = id;
if ((win_ace_mask & FILE_READ_BITS) && !(acl.a_perm & (S_IROTH | DENY_R)))
* cygheap.cc (creturn): Reorganize to avoid a new compiler warning/error. * dtable.cc (handle_to_fn): Ditto. * fhandler_console.cc (fhandler_console::read): Ditto. (fhandler_console::scroll_screen): Ditto. (dev_console::set_color): Ditto. * fhandler_dsp.cc (fhandler_dev_dsp::write): Ditto. (fhandler_dev_dsp::read): Ditto. * fhandler_tape.cc (mtinfo_drive::get_status): Ditto. * hookapi.cc (find_first_notloaded_dll): Ditto. * mmap.cc (msync): Ditto. * pipe.cc (pipesync::pipesync): Ditto. * sec_acl.cc (getace): Ditto. * sec_auth.cc (create_token): Ditto. (lsaauth): Ditto. * select.cc (peek_pipe): Ditto. * spawn.cc (av::fixup): Ditto. * syscalls.cc (popen): Ditto. * tty.cc (tty::init_session): Ditto. * uinfo.cc (pwdgrp::load): Ditto. * fhandler.cc (fhandler_base::setup_overlapped): Ditto. (fhandler_base::wait_overlapped): Rename second use of res variable to wres or errors are not returned correctly. * dcrt0.cc: Remove obsolete variable. * dll_init.cc (release_upto): Fix typo involving incorrect use of '|'. * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Avoid a compiler warning regarding coercing type-punned variables. (fhandler_base::fstat_by_name): Ditto. fhandler_fifo.cc (fhandler_fifo::open_nonserver): Fix = vs. == typo. (fhandler_fifo::wait): Add all conditions to switch statement to avoid a compiler warning. * fhandler_process.cc: Avoid unneeded initialization of variables to zero. (fhandler_socket::listen): Add braces around initializer. * flock.cc (inode_t::get_all_locks_list): Reorganize to avoid a compiler warning. Fix problem with EWOULDBLOCK error return. * path.cc (GUID_shortcut): Use braces around struct initializer. (cygwin_conv_path): Reorganize to avoid a compiler warning. * random.cc (dummy): Mark variable as volatile to avoid a "used uninitialized" warning. * libc/getopt.c: Mark some variables as dllexport although gcc doesn't seem to do the right thing with them. * libc/minires-os-if.c (get_registry_dns_items): Coerce some function arguments to avoid a compiler warning.
2008-09-11 12:34:24 +08:00
{
if (win_ace_type == ACCESS_ALLOWED_ACE_TYPE)
acl.a_perm |= S_IROTH;
else if (win_ace_type == ACCESS_DENIED_ACE_TYPE)
acl.a_perm |= DENY_R;
}
if ((win_ace_mask & FILE_WRITE_BITS) && !(acl.a_perm & (S_IWOTH | DENY_W)))
* cygheap.cc (creturn): Reorganize to avoid a new compiler warning/error. * dtable.cc (handle_to_fn): Ditto. * fhandler_console.cc (fhandler_console::read): Ditto. (fhandler_console::scroll_screen): Ditto. (dev_console::set_color): Ditto. * fhandler_dsp.cc (fhandler_dev_dsp::write): Ditto. (fhandler_dev_dsp::read): Ditto. * fhandler_tape.cc (mtinfo_drive::get_status): Ditto. * hookapi.cc (find_first_notloaded_dll): Ditto. * mmap.cc (msync): Ditto. * pipe.cc (pipesync::pipesync): Ditto. * sec_acl.cc (getace): Ditto. * sec_auth.cc (create_token): Ditto. (lsaauth): Ditto. * select.cc (peek_pipe): Ditto. * spawn.cc (av::fixup): Ditto. * syscalls.cc (popen): Ditto. * tty.cc (tty::init_session): Ditto. * uinfo.cc (pwdgrp::load): Ditto. * fhandler.cc (fhandler_base::setup_overlapped): Ditto. (fhandler_base::wait_overlapped): Rename second use of res variable to wres or errors are not returned correctly. * dcrt0.cc: Remove obsolete variable. * dll_init.cc (release_upto): Fix typo involving incorrect use of '|'. * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Avoid a compiler warning regarding coercing type-punned variables. (fhandler_base::fstat_by_name): Ditto. fhandler_fifo.cc (fhandler_fifo::open_nonserver): Fix = vs. == typo. (fhandler_fifo::wait): Add all conditions to switch statement to avoid a compiler warning. * fhandler_process.cc: Avoid unneeded initialization of variables to zero. (fhandler_socket::listen): Add braces around initializer. * flock.cc (inode_t::get_all_locks_list): Reorganize to avoid a compiler warning. Fix problem with EWOULDBLOCK error return. * path.cc (GUID_shortcut): Use braces around struct initializer. (cygwin_conv_path): Reorganize to avoid a compiler warning. * random.cc (dummy): Mark variable as volatile to avoid a "used uninitialized" warning. * libc/getopt.c: Mark some variables as dllexport although gcc doesn't seem to do the right thing with them. * libc/minires-os-if.c (get_registry_dns_items): Coerce some function arguments to avoid a compiler warning.
2008-09-11 12:34:24 +08:00
{
if (win_ace_type == ACCESS_ALLOWED_ACE_TYPE)
acl.a_perm |= S_IWOTH;
else if (win_ace_type == ACCESS_DENIED_ACE_TYPE)
acl.a_perm |= DENY_W;
}
if ((win_ace_mask & FILE_EXEC_BITS) && !(acl.a_perm & (S_IXOTH | DENY_X)))
* cygheap.cc (creturn): Reorganize to avoid a new compiler warning/error. * dtable.cc (handle_to_fn): Ditto. * fhandler_console.cc (fhandler_console::read): Ditto. (fhandler_console::scroll_screen): Ditto. (dev_console::set_color): Ditto. * fhandler_dsp.cc (fhandler_dev_dsp::write): Ditto. (fhandler_dev_dsp::read): Ditto. * fhandler_tape.cc (mtinfo_drive::get_status): Ditto. * hookapi.cc (find_first_notloaded_dll): Ditto. * mmap.cc (msync): Ditto. * pipe.cc (pipesync::pipesync): Ditto. * sec_acl.cc (getace): Ditto. * sec_auth.cc (create_token): Ditto. (lsaauth): Ditto. * select.cc (peek_pipe): Ditto. * spawn.cc (av::fixup): Ditto. * syscalls.cc (popen): Ditto. * tty.cc (tty::init_session): Ditto. * uinfo.cc (pwdgrp::load): Ditto. * fhandler.cc (fhandler_base::setup_overlapped): Ditto. (fhandler_base::wait_overlapped): Rename second use of res variable to wres or errors are not returned correctly. * dcrt0.cc: Remove obsolete variable. * dll_init.cc (release_upto): Fix typo involving incorrect use of '|'. * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Avoid a compiler warning regarding coercing type-punned variables. (fhandler_base::fstat_by_name): Ditto. fhandler_fifo.cc (fhandler_fifo::open_nonserver): Fix = vs. == typo. (fhandler_fifo::wait): Add all conditions to switch statement to avoid a compiler warning. * fhandler_process.cc: Avoid unneeded initialization of variables to zero. (fhandler_socket::listen): Add braces around initializer. * flock.cc (inode_t::get_all_locks_list): Reorganize to avoid a compiler warning. Fix problem with EWOULDBLOCK error return. * path.cc (GUID_shortcut): Use braces around struct initializer. (cygwin_conv_path): Reorganize to avoid a compiler warning. * random.cc (dummy): Mark variable as volatile to avoid a "used uninitialized" warning. * libc/getopt.c: Mark some variables as dllexport although gcc doesn't seem to do the right thing with them. * libc/minires-os-if.c (get_registry_dns_items): Coerce some function arguments to avoid a compiler warning.
2008-09-11 12:34:24 +08:00
{
if (win_ace_type == ACCESS_ALLOWED_ACE_TYPE)
acl.a_perm |= S_IXOTH;
else if (win_ace_type == ACCESS_DENIED_ACE_TYPE)
acl.a_perm |= DENY_X;
}
}
int
2013-04-23 17:44:36 +08:00
getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
{
* dir.cc (mkdir): Use local security_descriptor. Call set_security_attribute appropriately. * external.cc (cygwin_internal): Ditto. * fhandler.cc (fhandler_base::open): Ditto. * fhandler_socket.cc (fhandler_socket::bind): Ditto. * path.cc (symlink_worker): Ditto. * sec_acl.cc (setacl): Ditto. Call read_sd appropriately. (getace): Ditto. * sec_helper.cc (security_descriptor::malloc): New method. (security_descriptor::realloc): New method. (security_descriptor::free): New method. * security.cc (read_sd): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. Allocate the security_descriptor buffer according to size returned by a call to GetFileSecurity. Return buffer size on success. (write_sd): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (get_nt_attribute): Use local security_descriptor. (get_nt_object_attribute): Ditto in case of type == SE_REGISTRY_KEY. Allocate security_descriptor buffer according to size returned by a call to RegGetKeySecurity. (alloc_sd): Make static. Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. Drop unnecessary parameter check. (set_security_attribute): Get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (set_nt_attribute): Use local security_descriptor. (check_file_access): Ditto. * security.h: Add class security_descriptor. (read_sd): Change declaration to get security_descriptor as parameter instead of PSECURITY_DESCRIPTOR and a size. (write_sd): Ditto. (set_security_attribute): Ditto. (alloc_sd): Remove declaration. * thread.cc (semaphore::semaphore): Use local security_descriptor. Call set_security_attribute appropriately.
2003-11-26 21:23:27 +08:00
security_descriptor sd;
if (get_file_sd (handle, pc, sd, false))
return -1;
2003-02-06 00:15:22 +08:00
cygpsid owner_sid;
cygpsid group_sid;
NTSTATUS status;
BOOLEAN dummy;
2013-04-23 17:44:36 +08:00
uid_t uid;
gid_t gid;
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
cyg_ldap cldap;
status = RtlGetOwnerSecurityDescriptor (sd, (PSID *) &owner_sid, &dummy);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
}
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
uid = owner_sid.get_uid (&cldap);
status = RtlGetGroupSecurityDescriptor (sd, (PSID *) &group_sid, &dummy);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
}
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
gid = group_sid.get_gid (&cldap);
2013-04-23 17:44:36 +08:00
aclent_t lacl[MAX_ACL_ENTRIES];
memset (&lacl, 0, MAX_ACL_ENTRIES * sizeof (aclent_t));
lacl[0].a_type = USER_OBJ;
lacl[0].a_id = uid;
lacl[1].a_type = GROUP_OBJ;
lacl[1].a_id = gid;
lacl[2].a_type = OTHER_OBJ;
lacl[2].a_id = ILLEGAL_GID;
PACL acl;
BOOLEAN acl_exists;
status = RtlGetDaclSecurityDescriptor (sd, &acl_exists, &acl, &dummy);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
}
int pos, i, types_def = 0;
int pgrp_pos = 1, def_pgrp_pos = -1;
bool has_class_perm = false, has_def_class_perm = false;
mode_t class_perm = 0, def_class_perm = 0;
if (!acl_exists || !acl)
for (pos = 0; pos < 3; ++pos)
lacl[pos].a_perm = S_IROTH | S_IWOTH | S_IXOTH;
else
{
for (i = 0; i < acl->AceCount; ++i)
{
ACCESS_ALLOWED_ACE *ace;
2002-12-12 11:09:38 +08:00
if (!NT_SUCCESS (RtlGetAce (acl, i, (PVOID *) &ace)))
continue;
2003-02-06 00:15:22 +08:00
cygpsid ace_sid ((PSID) &ace->SidStart);
int id;
int type = 0;
if (ace_sid == well_known_null_sid)
{
/* Simply ignore. */
continue;
}
if (ace_sid == well_known_world_sid)
{
type = OTHER_OBJ;
id = ILLEGAL_GID;
}
else if (ace_sid == owner_sid)
{
type = USER_OBJ;
id = uid;
}
else if (ace_sid == group_sid)
{
type = GROUP_OBJ;
id = gid;
}
else if (ace_sid == well_known_creator_group_sid)
{
type = DEF_GROUP_OBJ;
types_def |= type;
id = ILLEGAL_GID;
}
else if (ace_sid == well_known_creator_owner_sid)
{
type = DEF_USER_OBJ;
types_def |= type;
id = ILLEGAL_GID;
}
else
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
id = ace_sid.get_id (TRUE, &type, &cldap);
2003-02-06 00:15:22 +08:00
if (!type)
continue;
if (!(ace->Header.AceFlags & INHERIT_ONLY_ACE || type & ACL_DEFAULT))
{
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
{
getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
/* Fix up CLASS_OBJ value. */
if (type == USER || type == GROUP)
{
has_class_perm = true;
class_perm |= lacl[pos].a_perm;
}
}
}
if ((ace->Header.AceFlags
& (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE))
&& pc.isdir ())
{
if (type == USER_OBJ)
type = USER;
else if (type == GROUP_OBJ)
type = GROUP;
type |= ACL_DEFAULT;
types_def |= type;
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
{
getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
/* Fix up DEF_CLASS_OBJ value. */
if (type == DEF_USER || type == DEF_GROUP)
{
has_def_class_perm = true;
def_class_perm |= lacl[pos].a_perm;
}
/* And note the position of the DEF_GROUP_OBJ entry. */
else if (type == DEF_GROUP_OBJ)
def_pgrp_pos = pos;
}
}
}
/* If secondary user and group entries exist in the ACL, fake a matching
CLASS_OBJ entry. The CLASS_OBJ permissions are the or'ed permissions
of the primary group permissions and all secondary user and group
permissions. */
if (has_class_perm && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
{
lacl[pos].a_type = CLASS_OBJ;
lacl[pos].a_id = ILLEGAL_GID;
lacl[pos].a_perm = class_perm | lacl[pgrp_pos].a_perm;
}
/* Ensure that the default acl contains at least
DEF_(USER|GROUP|OTHER)_OBJ entries. */
if (types_def && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
{
if (!(types_def & USER_OBJ))
{
lacl[pos].a_type = DEF_USER_OBJ;
lacl[pos].a_id = uid;
lacl[pos].a_perm = lacl[0].a_perm;
pos++;
}
if (!(types_def & GROUP_OBJ) && pos < MAX_ACL_ENTRIES)
{
lacl[pos].a_type = DEF_GROUP_OBJ;
lacl[pos].a_id = gid;
lacl[pos].a_perm = lacl[1].a_perm;
/* Note the position of the DEF_GROUP_OBJ entry. */
def_pgrp_pos = pos;
pos++;
}
if (!(types_def & OTHER_OBJ) && pos < MAX_ACL_ENTRIES)
{
lacl[pos].a_type = DEF_OTHER_OBJ;
lacl[pos].a_id = ILLEGAL_GID;
lacl[pos].a_perm = lacl[2].a_perm;
pos++;
}
}
/* If secondary user default and group default entries exist in the ACL,
fake a matching DEF_CLASS_OBJ entry. The DEF_CLASS_OBJ permissions are
the or'ed permissions of the primary group default permissions and all
secondary user and group default permissions. */
if (has_def_class_perm
&& (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
{
lacl[pos].a_type = DEF_CLASS_OBJ;
lacl[pos].a_id = ILLEGAL_GID;
lacl[pos].a_perm = def_class_perm;
if (def_pgrp_pos >= 0)
lacl[pos].a_perm |= lacl[def_pgrp_pos].a_perm;
}
}
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0)
pos = MAX_ACL_ENTRIES;
if (aclbufp)
{
#if 0
/* Disable owner/group permissions equivalence if owner SID == group SID.
It's technically not quite correct, but it helps in case a security
conscious application checks if a file has too open permissions. In
fact, since owner == group, there's no security issue here. */
if (owner_sid == group_sid)
lacl[1].a_perm = lacl[0].a_perm;
#endif
if (pos > nentries)
{
set_errno (ENOSPC);
return -1;
}
memcpy (aclbufp, lacl, pos * sizeof (aclent_t));
for (i = 0; i < pos; ++i)
aclbufp[i].a_perm &= ~(DENY_R | DENY_W | DENY_X);
aclsort32 (pos, 0, aclbufp);
}
syscall_printf ("%R = getacl(%S)", pos, pc.get_nt_native_path ());
return pos;
}
extern "C" int
2013-04-23 17:44:36 +08:00
acl32 (const char *path, int cmd, int nentries, aclent_t *aclbufp)
{
int res = -1;
fhandler_base *fh = build_fh_name (path, PC_SYM_FOLLOW | PC_KEEP_HANDLE,
* dtable.cc (dtable::dup_worker): Reset path_conv handle in duplicated fhandler. * fhandler.cc (fhandler_base::fstatvfs): Keep handle in created path_conv. * fhandler.h (fhandler_base::get_stat_access): New method. (fhandler_base::get_stat_handle): New method. * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Use handle returned by get_stat_handle. Only request inode from system if it isn't already set in the fhandler, and only for filesystems supporting them. (fhandler_base::fstat_fs): Use handle returned by get_stat_handle. Change the way open_fs is called. Explain why. (fhandler_base::fstat_helper): Use handle returned by get_stat_handle. Never use 0 inode number. Simplify executable recognition by re-using get_stat_handle if file could be opened with sufficient rights. (fhandler_disk_file::fstatvfs): Use handle returned by get_stat_handle. (fhandler_disk_file::facl): Use handle returned by get_stat_handle in GETACL and GETACLCNT cases. (fhandler_disk_file::link): Use handle returned by get_stat_handle instead of opening file here again. Add comment. (readdir_get_ino): Keep handle in created path_conv and drop opening file. * ntdll.h (wait_pending): New helper function. * path.cc (symlink_info::check): Drop unused 'opt' parameter from declaration. Add path_conv_handle argument. (path_conv::check): Make sure conv_handle is closed. Keep PC_KEEP_HANDLE flag in pflags_or. Accommodate call to sym.check to new args. (path_conv::~path_conv): Close conv_handle. (symlink_info::check_shortcut): Don't re-open file here, just use incoming handle. Drop goto's and label out. (symlink_info::check_sysfile): Don't re-open file here, just use incoming handle. Keep track of file position to accommodate the fact that file has been opened asynchronously in calling function. (symlink_info::check_nfs_symlink): Don't re-open file here, just use incoming handle. (symlink_info::check): Drop unused 'opt' parameter. Add path_conv_handle argument. Always try to open file with GENERIC_READ rights first to allow reading file content w/o having to re-open the file. Drop back to READ_CONTROL | FILE_READ_ATTRIBUTES otherwise. Call symlink test functions (except for check_reparse_point) only if file could be opened with GENERIC_READ. Keep file handle open if PC_KEEP_HANDLE is set in pflags. * path.h (enum pathconv_arg): Add PC_KEEP_HANDLE flag. (class path_conv_handle): New class. (class path_conv): Add conv_handle member. (path_conv::operator =): Duplicate conv_handle. (path_conv::handle): New method. (path_conv::access): New method. (path_conv::reset_conv_handle): New method. (path_conv::close_conv_handle): New method.
2010-06-15 20:05:15 +08:00
stat_suffixes);
if (!fh || !fh->exists ())
set_errno (ENOENT);
else if (fh->error ())
{
debug_printf ("got %d error from build_fh_name", fh->error ());
set_errno (fh->error ());
}
else
res = fh->facl (cmd, nentries, aclbufp);
delete fh;
syscall_printf ("%R = acl(%s)", res, path);
return res;
}
2013-04-23 17:44:36 +08:00
#ifndef __x86_64__
extern "C" int
2013-04-23 17:44:36 +08:00
lacl32 (const char *path, int cmd, int nentries, aclent_t *aclbufp)
{
/* This call was an accident. Make it absolutely clear. */
set_errno (ENOSYS);
return -1;
}
2013-04-23 17:44:36 +08:00
#endif
extern "C" int
2013-04-23 17:44:36 +08:00
facl32 (int fd, int cmd, int nentries, aclent_t *aclbufp)
{
cygheap_fdget cfd (fd);
if (cfd < 0)
{
syscall_printf ("-1 = facl (%d)", fd);
return -1;
}
int res = cfd->facl (cmd, nentries, aclbufp);
syscall_printf ("%R = facl(%s) )", res, cfd->get_name ());
return res;
}
extern "C" int
2013-04-23 17:44:36 +08:00
aclcheck32 (aclent_t *aclbufp, int nentries, int *which)
{
bool has_user_obj = false;
bool has_group_obj = false;
bool has_other_obj = false;
bool has_class_obj = false;
2013-04-23 17:44:36 +08:00
bool has_ug_objs __attribute__ ((unused)) = false;
bool has_def_objs __attribute__ ((unused)) = false;
2013-04-23 17:44:36 +08:00
bool has_def_user_obj __attribute__ ((unused)) = false;
bool has_def_group_obj = false;
bool has_def_other_obj = false;
bool has_def_class_obj = false;
2013-04-23 17:44:36 +08:00
bool has_def_ug_objs __attribute__ ((unused)) = false;
int pos2;
for (int pos = 0; pos < nentries; ++pos)
switch (aclbufp[pos].a_type)
{
case USER_OBJ:
if (has_user_obj)
{
if (which)
*which = pos;
return USER_ERROR;
}
has_user_obj = true;
break;
case GROUP_OBJ:
if (has_group_obj)
{
if (which)
*which = pos;
return GRP_ERROR;
}
has_group_obj = true;
break;
case OTHER_OBJ:
if (has_other_obj)
{
if (which)
*which = pos;
return OTHER_ERROR;
}
has_other_obj = true;
break;
case CLASS_OBJ:
if (has_class_obj)
{
if (which)
*which = pos;
return CLASS_ERROR;
}
has_class_obj = true;
break;
case USER:
case GROUP:
if ((pos2 = searchace (aclbufp + pos + 1, nentries - pos - 1,
aclbufp[pos].a_type, aclbufp[pos].a_id)) >= 0)
{
if (which)
*which = pos2;
return DUPLICATE_ERROR;
}
has_ug_objs = true;
break;
case DEF_USER_OBJ:
if (has_def_user_obj)
{
if (which)
*which = pos;
return USER_ERROR;
}
has_def_objs = has_def_user_obj = true;
break;
case DEF_GROUP_OBJ:
if (has_def_group_obj)
{
if (which)
*which = pos;
return GRP_ERROR;
}
has_def_objs = has_def_group_obj = true;
break;
case DEF_OTHER_OBJ:
if (has_def_other_obj)
{
if (which)
*which = pos;
return OTHER_ERROR;
}
has_def_objs = has_def_other_obj = true;
break;
case DEF_CLASS_OBJ:
if (has_def_class_obj)
{
if (which)
*which = pos;
return CLASS_ERROR;
}
has_def_objs = has_def_class_obj = true;
break;
case DEF_USER:
case DEF_GROUP:
if ((pos2 = searchace (aclbufp + pos + 1, nentries - pos - 1,
aclbufp[pos].a_type, aclbufp[pos].a_id)) >= 0)
{
if (which)
*which = pos2;
return DUPLICATE_ERROR;
}
has_def_objs = has_def_ug_objs = true;
break;
default:
return ENTRY_ERROR;
}
if (!has_user_obj
|| !has_group_obj
|| !has_other_obj
|| (has_def_objs
&& (!has_def_user_obj || !has_def_group_obj || !has_def_other_obj))
|| (has_ug_objs && !has_class_obj)
|| (has_def_ug_objs && !has_def_class_obj)
)
{
if (which)
*which = -1;
return MISS_ERROR;
}
return 0;
}
static int
acecmp (const void *a1, const void *a2)
{
2013-04-23 17:44:36 +08:00
#define ace(i) ((const aclent_t *) a##i)
int ret = ace (1)->a_type - ace (2)->a_type;
if (!ret)
ret = ace (1)->a_id - ace (2)->a_id;
return ret;
#undef ace
}
extern "C" int
2013-04-23 17:44:36 +08:00
aclsort32 (int nentries, int, aclent_t *aclbufp)
{
2003-02-06 00:15:22 +08:00
if (aclcheck32 (aclbufp, nentries, NULL))
{
set_errno (EINVAL);
return -1;
}
if (!aclbufp || nentries < 1)
{
set_errno (EINVAL);
return -1;
}
2013-04-23 17:44:36 +08:00
qsort ((void *) aclbufp, nentries, sizeof (aclent_t), acecmp);
return 0;
}
extern "C" int
2013-04-23 17:44:36 +08:00
acltomode32 (aclent_t *aclbufp, int nentries, mode_t *modep)
{
int pos;
if (!aclbufp || nentries < 1 || !modep)
{
set_errno (EINVAL);
return -1;
}
*modep = 0;
if ((pos = searchace (aclbufp, nentries, USER_OBJ)) < 0
|| !aclbufp[pos].a_type)
{
set_errno (EINVAL);
return -1;
}
*modep |= (aclbufp[pos].a_perm & S_IRWXO) << 6;
if ((pos = searchace (aclbufp, nentries, GROUP_OBJ)) < 0
|| !aclbufp[pos].a_type)
{
set_errno (EINVAL);
return -1;
}
*modep |= (aclbufp[pos].a_perm & S_IRWXO) << 3;
int cpos;
if ((cpos = searchace (aclbufp, nentries, CLASS_OBJ)) >= 0
&& aclbufp[cpos].a_type == CLASS_OBJ)
*modep |= ((aclbufp[pos].a_perm & S_IRWXO) & aclbufp[cpos].a_perm) << 3;
if ((pos = searchace (aclbufp, nentries, OTHER_OBJ)) < 0
|| !aclbufp[pos].a_type)
{
set_errno (EINVAL);
return -1;
}
*modep |= aclbufp[pos].a_perm & S_IRWXO;
return 0;
}
extern "C" int
2013-04-23 17:44:36 +08:00
aclfrommode32 (aclent_t *aclbufp, int nentries, mode_t *modep)
{
int pos;
if (!aclbufp || nentries < 1 || !modep)
{
set_errno (EINVAL);
return -1;
}
if ((pos = searchace (aclbufp, nentries, USER_OBJ)) < 0
|| !aclbufp[pos].a_type)
{
set_errno (EINVAL);
return -1;
}
aclbufp[pos].a_perm = (*modep & S_IRWXU) >> 6;
if ((pos = searchace (aclbufp, nentries, GROUP_OBJ)) < 0
|| !aclbufp[pos].a_type)
{
set_errno (EINVAL);
return -1;
}
aclbufp[pos].a_perm = (*modep & S_IRWXG) >> 3;
if ((pos = searchace (aclbufp, nentries, CLASS_OBJ)) >= 0
&& aclbufp[pos].a_type == CLASS_OBJ)
aclbufp[pos].a_perm = (*modep & S_IRWXG) >> 3;
if ((pos = searchace (aclbufp, nentries, OTHER_OBJ)) < 0
|| !aclbufp[pos].a_type)
{
set_errno (EINVAL);
return -1;
}
aclbufp[pos].a_perm = (*modep & S_IRWXO);
return 0;
}
extern "C" int
2013-04-23 17:44:36 +08:00
acltopbits32 (aclent_t *aclbufp, int nentries, mode_t *pbitsp)
{
2003-02-06 00:15:22 +08:00
return acltomode32 (aclbufp, nentries, pbitsp);
}
extern "C" int
2013-04-23 17:44:36 +08:00
aclfrompbits32 (aclent_t *aclbufp, int nentries, mode_t *pbitsp)
{
2003-02-06 00:15:22 +08:00
return aclfrommode32 (aclbufp, nentries, pbitsp);
}
static char *
permtostr (mode_t perm)
{
static char pbuf[4];
pbuf[0] = (perm & S_IROTH) ? 'r' : '-';
pbuf[1] = (perm & S_IWOTH) ? 'w' : '-';
pbuf[2] = (perm & S_IXOTH) ? 'x' : '-';
pbuf[3] = '\0';
return pbuf;
}
extern "C" char *
2013-04-23 17:44:36 +08:00
acltotext32 (aclent_t *aclbufp, int aclcnt)
{
if (!aclbufp || aclcnt < 1 || aclcnt > MAX_ACL_ENTRIES
2003-02-06 00:15:22 +08:00
|| aclcheck32 (aclbufp, aclcnt, NULL))
{
set_errno (EINVAL);
return NULL;
}
char buf[32000];
buf[0] = '\0';
bool first = true;
for (int pos = 0; pos < aclcnt; ++pos)
{
if (!first)
strcat (buf, ",");
first = false;
if (aclbufp[pos].a_type & ACL_DEFAULT)
strcat (buf, "default");
switch (aclbufp[pos].a_type & ~ACL_DEFAULT)
{
case USER_OBJ:
__small_sprintf (buf + strlen (buf), "user::%s",
permtostr (aclbufp[pos].a_perm));
break;
case USER:
__small_sprintf (buf + strlen (buf), "user:%d:%s",
aclbufp[pos].a_id, permtostr (aclbufp[pos].a_perm));
break;
case GROUP_OBJ:
__small_sprintf (buf + strlen (buf), "group::%s",
permtostr (aclbufp[pos].a_perm));
break;
case GROUP:
__small_sprintf (buf + strlen (buf), "group:%d:%s",
aclbufp[pos].a_id, permtostr (aclbufp[pos].a_perm));
break;
case CLASS_OBJ:
__small_sprintf (buf + strlen (buf), "mask::%s",
permtostr (aclbufp[pos].a_perm));
break;
case OTHER_OBJ:
__small_sprintf (buf + strlen (buf), "other::%s",
permtostr (aclbufp[pos].a_perm));
break;
default:
set_errno (EINVAL);
return NULL;
}
}
return strdup (buf);
}
static mode_t
permfromstr (char *perm)
{
mode_t mode = 0;
if (strlen (perm) != 3)
return 01000;
if (perm[0] == 'r')
mode |= S_IROTH;
else if (perm[0] != '-')
return 01000;
if (perm[1] == 'w')
mode |= S_IWOTH;
else if (perm[1] != '-')
return 01000;
if (perm[2] == 'x')
mode |= S_IXOTH;
else if (perm[2] != '-')
return 01000;
return mode;
}
2013-04-23 17:44:36 +08:00
extern "C" aclent_t *
2003-02-06 00:15:22 +08:00
aclfromtext32 (char *acltextp, int *)
{
if (!acltextp)
{
set_errno (EINVAL);
return NULL;
}
char buf[strlen (acltextp) + 1];
2013-04-23 17:44:36 +08:00
aclent_t lacl[MAX_ACL_ENTRIES];
memset (lacl, 0, sizeof lacl);
int pos = 0;
strcpy (buf, acltextp);
char *lasts;
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
cyg_ldap cldap;
for (char *c = strtok_r (buf, ",", &lasts);
c;
c = strtok_r (NULL, ",", &lasts))
{
if (!strncmp (c, "default", 7))
{
lacl[pos].a_type |= ACL_DEFAULT;
c += 7;
}
if (!strncmp (c, "user:", 5))
{
if (c[5] == ':')
lacl[pos].a_type |= USER_OBJ;
else
{
lacl[pos].a_type |= USER;
c += 5;
if (isalpha (*c))
{
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
struct passwd *pw = internal_getpwnam (c, &cldap);
if (!pw)
{
set_errno (EINVAL);
return NULL;
}
lacl[pos].a_id = pw->pw_uid;
c = strchrnul (c, ':');
}
else if (isdigit (*c))
lacl[pos].a_id = strtol (c, &c, 10);
2003-02-06 00:15:22 +08:00
if (*c != ':')
{
set_errno (EINVAL);
return NULL;
}
}
}
else if (!strncmp (c, "group:", 6))
{
if (c[5] == ':')
lacl[pos].a_type |= GROUP_OBJ;
else
{
lacl[pos].a_type |= GROUP;
c += 5;
if (isalpha (*c))
{
* autoload.cc (CheckTokenMembership): Import. * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id. * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_group_from_windows. (internal_getgrnam): Ditto. (internal_getgrgid): Ditto. (gr_ent::enumerate_local): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (getgroups32): Rename from internal_getgroups and drop getgroups32 stub. Drop srchsid parameter and code handling it. Add local cyg_ldap instance and forward to internal_getgrXXX. (getgroups): Call getgroups32. (get_groups): Add local cyg_ldap instance and forward to internal_getgrXXX. (getgrouplist): Ditto. (setgroups32): Ditto. * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection is already open. (cyg_ldap::remap_uid): Forward this to internal_getpwsid. (cyg_ldap::remap_gid): Forward this to internal_getgrsid. * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer. Forward to pwdgrp::add_user_from_windows. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to pwdgrp::fetch_account_from_windows. (pg_ent::enumerate_sam): Ditto. (pg_ent::enumerate_ad): Ditto. Forward local cldap instead. * pwdgrp.h (internal_getpwsid): Align declaration to above change. (internal_getpwnam): Ditto. (internal_getpwuid): Ditto. (internal_getgrsid): Ditto. (internal_getgrgid): Ditto. (internal_getgrnam): Ditto. (internal_getgroups): Drop declaration. (pwdgrp::add_account_from_windows): Align declaration to below change. (pwdgrp::add_user_from_windows): Ditto. (pwdgrp::add_group_from_windows): Ditto. * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to internal_getpwuid and internal_getgrgid. (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id. (aclfromtext32): Add local cyg_ldap instance and forward to internal_getpwnam and internal_getgrnam. * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer. Forward to internal_getgrsid and internal_getpwsid. (get_sids_info): Drop ldap_open. Forward local cldap to internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership rather than internal_getgroups. * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default parameter. (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly. (cygpsid::get_gid): Ditto. * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward to internal_getpwXXX and internal_getgrXXX calls. (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer. Forward to pwdgrp::fetch_account_from_windows. (fetch_posix_offset): Drop ldap_open argument and handling. Get cyg_ldap instance as pointer. (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer. Use it if it's not NULL, local instance otherwise. Drop ldap_open. Drop fetching extended group arguments from AD for speed.
2014-02-27 20:57:27 +08:00
struct group *gr = internal_getgrnam (c, &cldap);
if (!gr)
{
set_errno (EINVAL);
return NULL;
}
lacl[pos].a_id = gr->gr_gid;
c = strchrnul (c, ':');
}
else if (isdigit (*c))
lacl[pos].a_id = strtol (c, &c, 10);
2003-02-06 00:15:22 +08:00
if (*c != ':')
{
set_errno (EINVAL);
return NULL;
}
}
}
else if (!strncmp (c, "mask:", 5))
{
if (c[5] == ':')
lacl[pos].a_type |= CLASS_OBJ;
else
{
set_errno (EINVAL);
return NULL;
}
}
else if (!strncmp (c, "other:", 6))
{
if (c[5] == ':')
lacl[pos].a_type |= OTHER_OBJ;
else
{
set_errno (EINVAL);
return NULL;
}
}
if ((lacl[pos].a_perm = permfromstr (c)) == 01000)
{
set_errno (EINVAL);
return NULL;
}
++pos;
}
2013-04-23 17:44:36 +08:00
aclent_t *aclp = (aclent_t *) malloc (pos * sizeof (aclent_t));
if (aclp)
2013-04-23 17:44:36 +08:00
memcpy (aclp, lacl, pos * sizeof (aclent_t));
return aclp;
}
2013-04-23 17:44:36 +08:00
#ifdef __x86_64__
EXPORT_ALIAS (acl32, acl)
EXPORT_ALIAS (facl32, facl)
EXPORT_ALIAS (aclcheck32, aclcheck)
EXPORT_ALIAS (aclsort32, aclsort)
EXPORT_ALIAS (acltomode32, acltomode)
EXPORT_ALIAS (aclfrommode32, aclfrommode)
EXPORT_ALIAS (acltopbits32, acltopbits)
EXPORT_ALIAS (aclfrompbits32, aclfrompbits)
EXPORT_ALIAS (acltotext32, acltotext)
EXPORT_ALIAS (aclfromtext32, aclfromtext)
#else
/* __aclent16_t and aclent_t have same size and same member offsets */
static aclent_t *
2003-02-06 00:15:22 +08:00
acl16to32 (__aclent16_t *aclbufp, int nentries)
{
2013-04-23 17:44:36 +08:00
aclent_t *aclbufp32 = (aclent_t *) aclbufp;
2003-02-06 00:15:22 +08:00
if (aclbufp32)
for (int i = 0; i < nentries; i++)
aclbufp32[i].a_id &= USHRT_MAX;
return aclbufp32;
}
extern "C" int
2003-02-06 00:15:22 +08:00
acl (const char *path, int cmd, int nentries, __aclent16_t *aclbufp)
{
return acl32 (path, cmd, nentries, acl16to32 (aclbufp, nentries));
}
extern "C" int
2003-02-06 00:15:22 +08:00
facl (int fd, int cmd, int nentries, __aclent16_t *aclbufp)
{
return facl32 (fd, cmd, nentries, acl16to32 (aclbufp, nentries));
}
extern "C" int
2003-02-06 00:15:22 +08:00
lacl (const char *path, int cmd, int nentries, __aclent16_t *aclbufp)
{
/* This call was an accident. Make it absolutely clear. */
set_errno (ENOSYS);
return -1;
2003-02-06 00:15:22 +08:00
}
extern "C" int
2003-02-06 00:15:22 +08:00
aclcheck (__aclent16_t *aclbufp, int nentries, int *which)
{
return aclcheck32 (acl16to32 (aclbufp, nentries), nentries, which);
}
extern "C" int
2003-02-06 00:15:22 +08:00
aclsort (int nentries, int i, __aclent16_t *aclbufp)
{
return aclsort32 (nentries, i, acl16to32 (aclbufp, nentries));
}
extern "C" int
2003-02-06 00:15:22 +08:00
acltomode (__aclent16_t *aclbufp, int nentries, mode_t *modep)
{
return acltomode32 (acl16to32 (aclbufp, nentries), nentries, modep);
}
extern "C" int
2003-02-06 00:15:22 +08:00
aclfrommode (__aclent16_t *aclbufp, int nentries, mode_t *modep)
{
2013-04-23 17:44:36 +08:00
return aclfrommode32 ((aclent_t *)aclbufp, nentries, modep);
2003-02-06 00:15:22 +08:00
}
extern "C" int
2003-02-06 00:15:22 +08:00
acltopbits (__aclent16_t *aclbufp, int nentries, mode_t *pbitsp)
{
return acltopbits32 (acl16to32 (aclbufp, nentries), nentries, pbitsp);
}
extern "C" int
2003-02-06 00:15:22 +08:00
aclfrompbits (__aclent16_t *aclbufp, int nentries, mode_t *pbitsp)
{
2013-04-23 17:44:36 +08:00
return aclfrompbits32 ((aclent_t *)aclbufp, nentries, pbitsp);
2003-02-06 00:15:22 +08:00
}
extern "C" char *
2003-02-06 00:15:22 +08:00
acltotext (__aclent16_t *aclbufp, int aclcnt)
{
return acltotext32 (acl16to32 (aclbufp, aclcnt), aclcnt);
}
extern "C" __aclent16_t *
2003-02-06 00:15:22 +08:00
aclfromtext (char *acltextp, int * aclcnt)
{
return (__aclent16_t *) aclfromtext32 (acltextp, aclcnt);
}
2013-04-23 17:44:36 +08:00
#endif /* !__x86_64__ */