2003-01-12 12:38:51 +01:00
|
|
|
/* sec_acl.cc: Sun compatible ACL functions.
|
2001-04-20 15:02:32 +02:00
|
|
|
|
2003-01-12 12:38:51 +01:00
|
|
|
Copyright 2000, 2001, 2002, 2003 Red Hat, Inc.
|
2001-04-20 15:02:32 +02:00
|
|
|
|
|
|
|
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 <grp.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/acl.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <wingdi.h>
|
|
|
|
#include <winuser.h>
|
|
|
|
#include "cygerrno.h"
|
2001-07-26 21:22:24 +02:00
|
|
|
#include "security.h"
|
2001-04-20 15:02:32 +02:00
|
|
|
#include "fhandler.h"
|
|
|
|
#include "path.h"
|
|
|
|
#include "dtable.h"
|
|
|
|
#include "pinfo.h"
|
|
|
|
#include "cygheap.h"
|
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* pwdgrp.h (pwdgrp_check::pwdgrp_state): Replace by
pwdgrp_check::isinitializing ().
(pwdgrp_check::isinitializing): Create.
* passwd.cc (grab_int): Change type to unsigned, use strtoul and
set the pointer content to 0 if the field is invalid.
(parse_pwd): Move validity test after getting pw_gid.
(read_etc_passwd): Replace "passwd_state <= " by
passwd_state::isinitializing ().
(internal_getpwuid): Ditto.
(internal_getpwnam): Ditto.
(getpwent): Ditto.
(getpass): Ditto.
* grp.cc (parse_grp): Use strtoul for gr_gid and verify the validity.
(read_etc_group): Replace "group_state <= " by
group_state::isinitializing ().
(internal_getgrgid): Ditto.
(getgrent32): Ditto.
(internal_getgrent): Ditto.
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* security.h: Move declarations of internal_getgrent,
internal_getpwsid and internal_getgrsid to pwdgrp.h.
* pwdgrp.h: Declare internal_getpwsid, internal_getpwnam,
internal_getpwuid, internal_getgrsid, internal_getgrgid,
internal_getgrnam, internal_getgrent and internal_getgroups.
Delete "emulated" from enum pwdgrp_state.
(pwdgrp_check::isuninitialized): Create.
(pwdgrp_check::pwdgrp_state): Change state to initializing
rather than to uninitialized.
(pwdgrp_read::gets): Remove trailing CRs.
* passwd.cc (grab_string): Don't look for NLs.
(grab_int): Ditto.
(parse_pwd): Don't look for CRs. Return 0 if entry is too short.
(search_for): Delete.
(read_etc_passwd): Simplify tests to actually read the file.
Set state to loaded before making internal_getpwXX calls.
Replace search_for calls by equivalent internal_pwgetXX calls.
(internal_getpwsid): Use passwd_state.isuninitialized to decide
to call read_etc_passwd.
(internal_getpwuid): Create.
(internal_getpwnam): Create.
(getpwuid32): Simply call internal_getpwuid.
(getpwuid_r32): Call internal_getpwuid.
(getpwnam): Simply call internal_getpwnam.
(getpwnam_r): Call internal_getpwnam.
* grp.cc (parse_grp): Don't look for CRs. Adjust blank space.
(add_grp_line): Adjust blank space.
(class group_lock): Ditto.
(read_etc_group): Simplify tests to actually read the file.
Set state to loaded before making internal_getgrXX calls.
Replace getgrXX calls by equivalent internal calls.
(internal_getgrsid): Use group_state.isuninitialized to decide
to call read_etc_group.
(internal_getgrgid): Create.
(internal_getgrnam): Create.
(getgroups32): Simply call internal_getgrgid.
(getgrnam32): Simply call internal_getgrnam.
(internal_getgrent): Call group_state.isuninitialized.
(internal_getgroups): Create from the former getgroups32, using
two of the four arguments. Set gid to myself->gid and username
to cygheap->user.name ().
(getgroups32): Simply call internal_getgroup.
(getgroups): Call internal_getgroup instead of getgroups32.
(setgroups32): Call internal versions of get{pw,gr}XX.
* sec_helper.cc: Include pwdgrp.h.
(is_grp_member): Call internal versions of get{pw,gr}XX.
* security.cc: Include pwdgrp.h.
(alloc_sd): Call internal versions of get{pw,gr}XX.
* syscalls.cc: Include pwdgrp.h.
(seteuid32): Call internal versions of get{pw,gr}XX.
(setegid32): Ditto.
* uinfo.cc: Include pwdgrp.h.
(internal_getlogin): Call internal versions of get{pw,gr}XX.
(cygheap_user::ontherange): Ditto.
* sec_acl.cc: Include pwdgrp.h.
(setacl): Call internal versions of get{pw,gr}XX.
(acl_access): Ditto and simplify logic.
(aclfromtext): Ditto.
2002-12-10 13:43:49 +01:00
|
|
|
#include "pwdgrp.h"
|
2001-04-20 15:02:32 +02:00
|
|
|
|
2003-02-05 17:15:22 +01:00
|
|
|
extern "C" int aclsort32 (int nentries, int, __aclent32_t *aclbufp);
|
|
|
|
extern "C" int acl32 (const char *path, int cmd, int nentries, __aclent32_t *aclbufp);
|
* (child_info.h, cygheap.h, dcrt0.cc, dir.cc, fhandler.cc, fhandler.h,
fhandler_clipboard.cc, fhandler_disk_file.cc, fhandler_dsp.cc,
fhandler_floppy.cc, fhandler_mem.cc, fhandler_random.cc,
fhandler_tape.cc, fhandler_zero.cc, grp.cc, mmap.cc, passwd.cc,
pinfo.cc, pinfo.h, pipe.cc, sec_acl.cc, sec_helper.cc, security.cc,
security.h, spawn.cc, syscalls.cc, thread.h, uinfo.cc, winsup.h):
Change usage of uid_t to __uid16_t, gid_t to __gid16_t and
off_t to __off32_t throughout. Use INVALID_UID, INVALID_GID and
INVALID_SEEK instead casting -1 to the appropriate type.
* winsup.h: Define INVALID_UID, INVALID_GID and INVALID_SEEK.
* include/cygwin/acl.h: Define internal __aclent16_t and __aclent32_t
types. Don't declare acl functions when compiling Cygwin.
* include/cygwin/grp.h: Declare getgrgid() and getgrnam() with
correct types for internal usage.
2002-02-10 14:38:51 +01:00
|
|
|
|
2001-04-20 15:02:32 +02:00
|
|
|
static int
|
2003-02-05 17:15:22 +01:00
|
|
|
searchace (__aclent32_t *aclp, int nentries, int type, __uid32_t id = ILLEGAL_UID)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < nentries; ++i)
|
2003-02-05 17:15:22 +01:00
|
|
|
if ((aclp[i].a_type == type && (id == ILLEGAL_UID || aclp[i].a_id == id))
|
2001-04-20 15:02:32 +02:00
|
|
|
|| !aclp[i].a_type)
|
|
|
|
return i;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2003-02-05 17:15:22 +01:00
|
|
|
setacl (const char *file, int nentries, __aclent32_t *aclbufp)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
DWORD sd_size = 4096;
|
|
|
|
char sd_buf[4096];
|
|
|
|
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
|
|
|
|
|
|
|
if (read_sd (file, psd, &sd_size) <= 0)
|
|
|
|
{
|
|
|
|
debug_printf ("read_sd %E");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL dummy;
|
|
|
|
|
|
|
|
/* Get owner SID. */
|
2003-02-05 17:15:22 +01:00
|
|
|
PSID owner_sid;
|
2001-04-20 15:02:32 +02:00
|
|
|
if (!GetSecurityDescriptorOwner (psd, &owner_sid, &dummy))
|
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
2001-04-25 11:43:25 +02:00
|
|
|
cygsid owner (owner_sid);
|
2001-04-20 15:02:32 +02:00
|
|
|
|
|
|
|
/* Get group SID. */
|
2003-02-05 17:15:22 +01:00
|
|
|
PSID group_sid;
|
2001-04-20 15:02:32 +02:00
|
|
|
if (!GetSecurityDescriptorGroup (psd, &group_sid, &dummy))
|
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
2001-04-25 11:43:25 +02:00
|
|
|
cygsid group (group_sid);
|
2001-04-20 15:02:32 +02:00
|
|
|
|
|
|
|
/* Initialize local security descriptor. */
|
|
|
|
SECURITY_DESCRIPTOR sd;
|
|
|
|
if (!InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION))
|
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
2002-09-22 05:38:57 +02:00
|
|
|
if (!SetSecurityDescriptorOwner (&sd, owner, FALSE))
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
2003-02-05 17:15:22 +01:00
|
|
|
if (!SetSecurityDescriptorGroup (&sd, group, FALSE))
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill access control list. */
|
|
|
|
char acl_buf[3072];
|
|
|
|
PACL acl = (PACL) acl_buf;
|
|
|
|
size_t acl_len = sizeof (ACL);
|
|
|
|
int ace_off = 0;
|
|
|
|
|
2001-04-25 11:43:25 +02:00
|
|
|
cygsid sid;
|
2001-04-20 15:02:32 +02:00
|
|
|
struct passwd *pw;
|
Change internal gid datatype from __gid16_t to __gid32_t
throughout.
* cygwin.din: Export new symbols chown32, fchown32, getegid32,
getgid32, getgrgid32, getgrnam32, getgroups32, initgroups32, lchown32,
setgid32, setegid32, getgrent32.
* grp.cc (grp32togrp16): New static function.
(getgrgid32): New function.
(getgrnam32): Ditto.
(getgrent32): Ditto.
(getgroups32): Change name of internal function from getgroups.
(getgroups32): New function.
(initgroups32): Ditto.
* syscalls.cc (chown32): Ditto.
(lchown32): Ditto.
(fchown32): Ditto.
(setegid32): Ditto.
(setgid32): Ditto.
* uinfo.cc (getgid32): Ditto.
(getegid32): Ditto.
* include/cygwin/grp.h: Remove declaration of getgrgid() and getgrnam().
Declare getgrgid32() and getgrnam32() instead. Declare getgid32().
2002-05-28 16:10:55 +02:00
|
|
|
struct __group32 *gr;
|
2001-04-20 15:02:32 +02:00
|
|
|
int pos;
|
|
|
|
|
|
|
|
if (!InitializeAcl (acl, 3072, ACL_REVISION))
|
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
for (int i = 0; i < nentries; ++i)
|
|
|
|
{
|
2003-02-05 17:15:22 +01:00
|
|
|
DWORD allow;
|
|
|
|
/* Owner has more standard rights set. */
|
|
|
|
if ((aclbufp[i].a_type & ~ACL_DEFAULT) == USER_OBJ)
|
|
|
|
allow = (STANDARD_RIGHTS_ALL & ~DELETE)
|
|
|
|
| FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA;
|
|
|
|
else
|
|
|
|
allow = STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | FILE_READ_EA;
|
2001-04-20 15:02:32 +02:00
|
|
|
if (aclbufp[i].a_perm & S_IROTH)
|
|
|
|
allow |= FILE_GENERIC_READ;
|
|
|
|
if (aclbufp[i].a_perm & S_IWOTH)
|
2003-02-05 17:15:22 +01:00
|
|
|
{
|
|
|
|
allow |= STANDARD_RIGHTS_WRITE | FILE_GENERIC_WRITE;
|
|
|
|
/* Owner gets DELETE right, too. */
|
|
|
|
if ((aclbufp[i].a_type & ~ACL_DEFAULT) == USER_OBJ)
|
|
|
|
allow |= DELETE;
|
|
|
|
}
|
2001-04-20 15:02:32 +02:00
|
|
|
if (aclbufp[i].a_perm & S_IXOTH)
|
|
|
|
allow |= FILE_GENERIC_EXECUTE;
|
2001-07-16 00:40:07 +02:00
|
|
|
if ((aclbufp[i].a_perm & (S_IWOTH | S_IXOTH)) == (S_IWOTH | S_IXOTH))
|
2001-09-07 23:32:07 +02:00
|
|
|
allow |= FILE_DELETE_CHILD;
|
2001-04-20 15:02:32 +02:00
|
|
|
/* Set inherit property. */
|
|
|
|
DWORD inheritance = (aclbufp[i].a_type & ACL_DEFAULT)
|
2002-07-02 10:11:15 +02:00
|
|
|
? (SUB_CONTAINERS_AND_OBJECTS_INHERIT | INHERIT_ONLY)
|
|
|
|
: NO_INHERITANCE;
|
2001-04-20 15:02:32 +02:00
|
|
|
/*
|
|
|
|
* 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)
|
2003-01-12 12:38:51 +01:00
|
|
|
&& aclbufp[i].a_type & (USER|GROUP|OTHER_OBJ)
|
2003-01-26 07:42:40 +01:00
|
|
|
&& (pos = searchace (aclbufp + i + 1, nentries - i - 1,
|
2001-04-20 15:02:32 +02:00
|
|
|
aclbufp[i].a_type | ACL_DEFAULT,
|
|
|
|
(aclbufp[i].a_type & (USER|GROUP))
|
2003-02-05 17:15:22 +01:00
|
|
|
? aclbufp[i].a_id : ILLEGAL_UID)) >= 0
|
2001-04-20 15:02:32 +02:00
|
|
|
&& aclbufp[i].a_perm == aclbufp[pos].a_perm)
|
|
|
|
{
|
2002-07-02 10:11:15 +02:00
|
|
|
inheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
2003-01-26 07:42:40 +01:00
|
|
|
/* This invalidates the corresponding default entry. */
|
|
|
|
aclbufp[pos].a_type = USER|GROUP|ACL_DEFAULT;
|
2001-04-20 15:02:32 +02:00
|
|
|
}
|
|
|
|
switch (aclbufp[i].a_type)
|
|
|
|
{
|
|
|
|
case USER_OBJ:
|
|
|
|
if (!add_access_allowed_ace (acl, ace_off++, allow,
|
2001-04-25 11:43:25 +02:00
|
|
|
owner, acl_len, inheritance))
|
2001-04-20 15:02:32 +02:00
|
|
|
return -1;
|
|
|
|
break;
|
2003-01-12 12:38:51 +01:00
|
|
|
case DEF_USER_OBJ:
|
|
|
|
if (!add_access_allowed_ace (acl, ace_off++, allow,
|
|
|
|
well_known_creator_owner_sid, acl_len, inheritance))
|
|
|
|
return -1;
|
|
|
|
break;
|
2001-04-20 15:02:32 +02:00
|
|
|
case USER:
|
|
|
|
case DEF_USER:
|
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* pwdgrp.h (pwdgrp_check::pwdgrp_state): Replace by
pwdgrp_check::isinitializing ().
(pwdgrp_check::isinitializing): Create.
* passwd.cc (grab_int): Change type to unsigned, use strtoul and
set the pointer content to 0 if the field is invalid.
(parse_pwd): Move validity test after getting pw_gid.
(read_etc_passwd): Replace "passwd_state <= " by
passwd_state::isinitializing ().
(internal_getpwuid): Ditto.
(internal_getpwnam): Ditto.
(getpwent): Ditto.
(getpass): Ditto.
* grp.cc (parse_grp): Use strtoul for gr_gid and verify the validity.
(read_etc_group): Replace "group_state <= " by
group_state::isinitializing ().
(internal_getgrgid): Ditto.
(getgrent32): Ditto.
(internal_getgrent): Ditto.
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* security.h: Move declarations of internal_getgrent,
internal_getpwsid and internal_getgrsid to pwdgrp.h.
* pwdgrp.h: Declare internal_getpwsid, internal_getpwnam,
internal_getpwuid, internal_getgrsid, internal_getgrgid,
internal_getgrnam, internal_getgrent and internal_getgroups.
Delete "emulated" from enum pwdgrp_state.
(pwdgrp_check::isuninitialized): Create.
(pwdgrp_check::pwdgrp_state): Change state to initializing
rather than to uninitialized.
(pwdgrp_read::gets): Remove trailing CRs.
* passwd.cc (grab_string): Don't look for NLs.
(grab_int): Ditto.
(parse_pwd): Don't look for CRs. Return 0 if entry is too short.
(search_for): Delete.
(read_etc_passwd): Simplify tests to actually read the file.
Set state to loaded before making internal_getpwXX calls.
Replace search_for calls by equivalent internal_pwgetXX calls.
(internal_getpwsid): Use passwd_state.isuninitialized to decide
to call read_etc_passwd.
(internal_getpwuid): Create.
(internal_getpwnam): Create.
(getpwuid32): Simply call internal_getpwuid.
(getpwuid_r32): Call internal_getpwuid.
(getpwnam): Simply call internal_getpwnam.
(getpwnam_r): Call internal_getpwnam.
* grp.cc (parse_grp): Don't look for CRs. Adjust blank space.
(add_grp_line): Adjust blank space.
(class group_lock): Ditto.
(read_etc_group): Simplify tests to actually read the file.
Set state to loaded before making internal_getgrXX calls.
Replace getgrXX calls by equivalent internal calls.
(internal_getgrsid): Use group_state.isuninitialized to decide
to call read_etc_group.
(internal_getgrgid): Create.
(internal_getgrnam): Create.
(getgroups32): Simply call internal_getgrgid.
(getgrnam32): Simply call internal_getgrnam.
(internal_getgrent): Call group_state.isuninitialized.
(internal_getgroups): Create from the former getgroups32, using
two of the four arguments. Set gid to myself->gid and username
to cygheap->user.name ().
(getgroups32): Simply call internal_getgroup.
(getgroups): Call internal_getgroup instead of getgroups32.
(setgroups32): Call internal versions of get{pw,gr}XX.
* sec_helper.cc: Include pwdgrp.h.
(is_grp_member): Call internal versions of get{pw,gr}XX.
* security.cc: Include pwdgrp.h.
(alloc_sd): Call internal versions of get{pw,gr}XX.
* syscalls.cc: Include pwdgrp.h.
(seteuid32): Call internal versions of get{pw,gr}XX.
(setegid32): Ditto.
* uinfo.cc: Include pwdgrp.h.
(internal_getlogin): Call internal versions of get{pw,gr}XX.
(cygheap_user::ontherange): Ditto.
* sec_acl.cc: Include pwdgrp.h.
(setacl): Call internal versions of get{pw,gr}XX.
(acl_access): Ditto and simplify logic.
(aclfromtext): Ditto.
2002-12-10 13:43:49 +01:00
|
|
|
if (!(pw = internal_getpwuid (aclbufp[i].a_id))
|
* fork.cc (fork): Eliminate superfluous call to getuid().
* security.h: New define `NO_SID'. Remove declarations of functions
moved to methods into class cygsid.
(class cygsid): Declare new methods `getfromstr', `get_sid',
`getfrompw', `getfromgr', `get_rid', `get_uid', `get_gid', `string'
and new constructors and operators =, == and !=.
Declare new global cygsids `well_known_XXX_sid' substituting the
corresponding `get_XXX_sid' functions. Remove declarations of
these functions.
* sec_helper.cc (well_known_admin_sid): New global variable.
(well_known_system_sid): Ditto
(well_known_creator_owner_sid): Ditto
(well_known_world_sid): Ditto
(cygsid::string): New method, substituting `convert_sid_to_string_sid'.
(cygsid::get_sid): New method, substituting `get_sid'.
(cygsid::getfromstr): New method, substituting
`convert_string_sid_to_sid'.
(cygsid::getfrompw): New method, substituting `get_pw_sid'.
(cygsid::getfromgr): New method, substituting `get_gr_sid'.
(cygsid::get_id): New method, substituting `get_id_from_sid'.
(get_admin_sid): Eliminated.
(get_system_sid): Ditto.
(get_creator_owner_sid): Ditto.
(get_world_sid): Ditto.
* grp.cc: Use new cygsid methods and well known sids throughout.
* registry.cc: Ditto.
* sec_acl.cc: Ditto.
* security.cc: Ditto.
* shared.cc: Ditto.
* syscalls.cc (seteuid): Ditto. Eliminate redundant conditional.
* uinfo.cc (internal_getlogin): Ditto.
* spawn.cc (spawn_guts) Revert previous patch.
2001-05-15 21:23:31 +02:00
|
|
|
|| !sid.getfrompw (pw)
|
2001-04-20 15:02:32 +02:00
|
|
|
|| !add_access_allowed_ace (acl, ace_off++, allow,
|
2003-02-05 17:15:22 +01:00
|
|
|
sid, acl_len, inheritance))
|
2001-04-20 15:02:32 +02:00
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
case GROUP_OBJ:
|
|
|
|
if (!add_access_allowed_ace (acl, ace_off++, allow,
|
2003-02-05 17:15:22 +01:00
|
|
|
group, acl_len, inheritance))
|
2001-04-20 15:02:32 +02:00
|
|
|
return -1;
|
|
|
|
break;
|
2003-01-12 12:38:51 +01:00
|
|
|
case DEF_GROUP_OBJ:
|
|
|
|
if (!add_access_allowed_ace (acl, ace_off++, allow,
|
|
|
|
well_known_creator_group_sid, acl_len, inheritance))
|
|
|
|
return -1;
|
|
|
|
break;
|
2001-04-20 15:02:32 +02:00
|
|
|
case GROUP:
|
|
|
|
case DEF_GROUP:
|
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* pwdgrp.h (pwdgrp_check::pwdgrp_state): Replace by
pwdgrp_check::isinitializing ().
(pwdgrp_check::isinitializing): Create.
* passwd.cc (grab_int): Change type to unsigned, use strtoul and
set the pointer content to 0 if the field is invalid.
(parse_pwd): Move validity test after getting pw_gid.
(read_etc_passwd): Replace "passwd_state <= " by
passwd_state::isinitializing ().
(internal_getpwuid): Ditto.
(internal_getpwnam): Ditto.
(getpwent): Ditto.
(getpass): Ditto.
* grp.cc (parse_grp): Use strtoul for gr_gid and verify the validity.
(read_etc_group): Replace "group_state <= " by
group_state::isinitializing ().
(internal_getgrgid): Ditto.
(getgrent32): Ditto.
(internal_getgrent): Ditto.
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* security.h: Move declarations of internal_getgrent,
internal_getpwsid and internal_getgrsid to pwdgrp.h.
* pwdgrp.h: Declare internal_getpwsid, internal_getpwnam,
internal_getpwuid, internal_getgrsid, internal_getgrgid,
internal_getgrnam, internal_getgrent and internal_getgroups.
Delete "emulated" from enum pwdgrp_state.
(pwdgrp_check::isuninitialized): Create.
(pwdgrp_check::pwdgrp_state): Change state to initializing
rather than to uninitialized.
(pwdgrp_read::gets): Remove trailing CRs.
* passwd.cc (grab_string): Don't look for NLs.
(grab_int): Ditto.
(parse_pwd): Don't look for CRs. Return 0 if entry is too short.
(search_for): Delete.
(read_etc_passwd): Simplify tests to actually read the file.
Set state to loaded before making internal_getpwXX calls.
Replace search_for calls by equivalent internal_pwgetXX calls.
(internal_getpwsid): Use passwd_state.isuninitialized to decide
to call read_etc_passwd.
(internal_getpwuid): Create.
(internal_getpwnam): Create.
(getpwuid32): Simply call internal_getpwuid.
(getpwuid_r32): Call internal_getpwuid.
(getpwnam): Simply call internal_getpwnam.
(getpwnam_r): Call internal_getpwnam.
* grp.cc (parse_grp): Don't look for CRs. Adjust blank space.
(add_grp_line): Adjust blank space.
(class group_lock): Ditto.
(read_etc_group): Simplify tests to actually read the file.
Set state to loaded before making internal_getgrXX calls.
Replace getgrXX calls by equivalent internal calls.
(internal_getgrsid): Use group_state.isuninitialized to decide
to call read_etc_group.
(internal_getgrgid): Create.
(internal_getgrnam): Create.
(getgroups32): Simply call internal_getgrgid.
(getgrnam32): Simply call internal_getgrnam.
(internal_getgrent): Call group_state.isuninitialized.
(internal_getgroups): Create from the former getgroups32, using
two of the four arguments. Set gid to myself->gid and username
to cygheap->user.name ().
(getgroups32): Simply call internal_getgroup.
(getgroups): Call internal_getgroup instead of getgroups32.
(setgroups32): Call internal versions of get{pw,gr}XX.
* sec_helper.cc: Include pwdgrp.h.
(is_grp_member): Call internal versions of get{pw,gr}XX.
* security.cc: Include pwdgrp.h.
(alloc_sd): Call internal versions of get{pw,gr}XX.
* syscalls.cc: Include pwdgrp.h.
(seteuid32): Call internal versions of get{pw,gr}XX.
(setegid32): Ditto.
* uinfo.cc: Include pwdgrp.h.
(internal_getlogin): Call internal versions of get{pw,gr}XX.
(cygheap_user::ontherange): Ditto.
* sec_acl.cc: Include pwdgrp.h.
(setacl): Call internal versions of get{pw,gr}XX.
(acl_access): Ditto and simplify logic.
(aclfromtext): Ditto.
2002-12-10 13:43:49 +01:00
|
|
|
if (!(gr = internal_getgrgid (aclbufp[i].a_id))
|
* fork.cc (fork): Eliminate superfluous call to getuid().
* security.h: New define `NO_SID'. Remove declarations of functions
moved to methods into class cygsid.
(class cygsid): Declare new methods `getfromstr', `get_sid',
`getfrompw', `getfromgr', `get_rid', `get_uid', `get_gid', `string'
and new constructors and operators =, == and !=.
Declare new global cygsids `well_known_XXX_sid' substituting the
corresponding `get_XXX_sid' functions. Remove declarations of
these functions.
* sec_helper.cc (well_known_admin_sid): New global variable.
(well_known_system_sid): Ditto
(well_known_creator_owner_sid): Ditto
(well_known_world_sid): Ditto
(cygsid::string): New method, substituting `convert_sid_to_string_sid'.
(cygsid::get_sid): New method, substituting `get_sid'.
(cygsid::getfromstr): New method, substituting
`convert_string_sid_to_sid'.
(cygsid::getfrompw): New method, substituting `get_pw_sid'.
(cygsid::getfromgr): New method, substituting `get_gr_sid'.
(cygsid::get_id): New method, substituting `get_id_from_sid'.
(get_admin_sid): Eliminated.
(get_system_sid): Ditto.
(get_creator_owner_sid): Ditto.
(get_world_sid): Ditto.
* grp.cc: Use new cygsid methods and well known sids throughout.
* registry.cc: Ditto.
* sec_acl.cc: Ditto.
* security.cc: Ditto.
* shared.cc: Ditto.
* syscalls.cc (seteuid): Ditto. Eliminate redundant conditional.
* uinfo.cc (internal_getlogin): Ditto.
* spawn.cc (spawn_guts) Revert previous patch.
2001-05-15 21:23:31 +02:00
|
|
|
|| !sid.getfromgr (gr)
|
2001-04-20 15:02:32 +02:00
|
|
|
|| !add_access_allowed_ace (acl, ace_off++, allow,
|
2003-02-05 17:15:22 +01:00
|
|
|
sid, acl_len, inheritance))
|
2001-04-20 15:02:32 +02:00
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
case OTHER_OBJ:
|
|
|
|
case DEF_OTHER_OBJ:
|
|
|
|
if (!add_access_allowed_ace (acl, ace_off++, allow,
|
* fork.cc (fork): Eliminate superfluous call to getuid().
* security.h: New define `NO_SID'. Remove declarations of functions
moved to methods into class cygsid.
(class cygsid): Declare new methods `getfromstr', `get_sid',
`getfrompw', `getfromgr', `get_rid', `get_uid', `get_gid', `string'
and new constructors and operators =, == and !=.
Declare new global cygsids `well_known_XXX_sid' substituting the
corresponding `get_XXX_sid' functions. Remove declarations of
these functions.
* sec_helper.cc (well_known_admin_sid): New global variable.
(well_known_system_sid): Ditto
(well_known_creator_owner_sid): Ditto
(well_known_world_sid): Ditto
(cygsid::string): New method, substituting `convert_sid_to_string_sid'.
(cygsid::get_sid): New method, substituting `get_sid'.
(cygsid::getfromstr): New method, substituting
`convert_string_sid_to_sid'.
(cygsid::getfrompw): New method, substituting `get_pw_sid'.
(cygsid::getfromgr): New method, substituting `get_gr_sid'.
(cygsid::get_id): New method, substituting `get_id_from_sid'.
(get_admin_sid): Eliminated.
(get_system_sid): Ditto.
(get_creator_owner_sid): Ditto.
(get_world_sid): Ditto.
* grp.cc: Use new cygsid methods and well known sids throughout.
* registry.cc: Ditto.
* sec_acl.cc: Ditto.
* security.cc: Ditto.
* shared.cc: Ditto.
* syscalls.cc (seteuid): Ditto. Eliminate redundant conditional.
* uinfo.cc (internal_getlogin): Ditto.
* spawn.cc (spawn_guts) Revert previous patch.
2001-05-15 21:23:31 +02:00
|
|
|
well_known_world_sid,
|
|
|
|
acl_len, inheritance))
|
2001-04-20 15:02:32 +02:00
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Set AclSize to computed value. */
|
|
|
|
acl->AclSize = acl_len;
|
|
|
|
debug_printf ("ACL-Size: %d", acl_len);
|
|
|
|
/* Create DACL for local security descriptor. */
|
|
|
|
if (!SetSecurityDescriptorDacl (&sd, TRUE, acl, FALSE))
|
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* Make self relative security descriptor in psd. */
|
|
|
|
sd_size = 0;
|
|
|
|
MakeSelfRelativeSD (&sd, psd, &sd_size);
|
|
|
|
if (sd_size <= 0)
|
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!MakeSelfRelativeSD (&sd, psd, &sd_size))
|
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
debug_printf ("Created SD-Size: %d", sd_size);
|
|
|
|
return write_sd (file, psd, sd_size);
|
|
|
|
}
|
|
|
|
|
2002-11-24 19:58:47 +01:00
|
|
|
/* Temporary access denied bits */
|
|
|
|
#define DENY_R 040000
|
|
|
|
#define DENY_W 020000
|
|
|
|
#define DENY_X 010000
|
|
|
|
|
2001-04-20 15:02:32 +02:00
|
|
|
static void
|
2003-02-05 17:15:22 +01:00
|
|
|
getace (__aclent32_t &acl, int type, int id, DWORD win_ace_mask,
|
2003-01-26 07:42:40 +01:00
|
|
|
DWORD win_ace_type)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
acl.a_type = type;
|
|
|
|
acl.a_id = id;
|
|
|
|
|
2002-11-24 19:58:47 +01:00
|
|
|
if ((win_ace_mask & FILE_READ_DATA) && !(acl.a_perm & (S_IROTH | DENY_R)))
|
2001-04-20 15:02:32 +02:00
|
|
|
if (win_ace_type == ACCESS_ALLOWED_ACE_TYPE)
|
2002-11-24 19:58:47 +01:00
|
|
|
acl.a_perm |= S_IROTH;
|
2001-04-20 15:02:32 +02:00
|
|
|
else if (win_ace_type == ACCESS_DENIED_ACE_TYPE)
|
2002-11-24 19:58:47 +01:00
|
|
|
acl.a_perm |= DENY_R;
|
2001-04-20 15:02:32 +02:00
|
|
|
|
2002-11-24 19:58:47 +01:00
|
|
|
if ((win_ace_mask & FILE_WRITE_DATA) && !(acl.a_perm & (S_IWOTH | DENY_W)))
|
2001-04-20 15:02:32 +02:00
|
|
|
if (win_ace_type == ACCESS_ALLOWED_ACE_TYPE)
|
2002-11-24 19:58:47 +01:00
|
|
|
acl.a_perm |= S_IWOTH;
|
2001-04-20 15:02:32 +02:00
|
|
|
else if (win_ace_type == ACCESS_DENIED_ACE_TYPE)
|
2002-11-24 19:58:47 +01:00
|
|
|
acl.a_perm |= DENY_W;
|
2001-04-20 15:02:32 +02:00
|
|
|
|
2002-11-24 19:58:47 +01:00
|
|
|
if ((win_ace_mask & FILE_EXECUTE) && !(acl.a_perm & (S_IXOTH | DENY_X)))
|
2001-04-20 15:02:32 +02:00
|
|
|
if (win_ace_type == ACCESS_ALLOWED_ACE_TYPE)
|
2002-11-24 19:58:47 +01:00
|
|
|
acl.a_perm |= S_IXOTH;
|
2001-04-20 15:02:32 +02:00
|
|
|
else if (win_ace_type == ACCESS_DENIED_ACE_TYPE)
|
2002-11-24 19:58:47 +01:00
|
|
|
acl.a_perm |= DENY_X;
|
2001-04-20 15:02:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2003-02-05 17:15:22 +01:00
|
|
|
getacl (const char *file, DWORD attr, int nentries, __aclent32_t *aclbufp)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
DWORD sd_size = 4096;
|
|
|
|
char sd_buf[4096];
|
|
|
|
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
|
|
|
|
|
|
|
int ret;
|
|
|
|
if ((ret = read_sd (file, psd, &sd_size)) <= 0)
|
|
|
|
{
|
|
|
|
debug_printf ("read_sd %E");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2003-02-05 17:15:22 +01:00
|
|
|
cygpsid owner_sid;
|
|
|
|
cygpsid group_sid;
|
2001-04-20 15:02:32 +02:00
|
|
|
BOOL dummy;
|
2002-05-29 17:04:29 +02:00
|
|
|
__uid32_t uid;
|
Change internal gid datatype from __gid16_t to __gid32_t
throughout.
* cygwin.din: Export new symbols chown32, fchown32, getegid32,
getgid32, getgrgid32, getgrnam32, getgroups32, initgroups32, lchown32,
setgid32, setegid32, getgrent32.
* grp.cc (grp32togrp16): New static function.
(getgrgid32): New function.
(getgrnam32): Ditto.
(getgrent32): Ditto.
(getgroups32): Change name of internal function from getgroups.
(getgroups32): New function.
(initgroups32): Ditto.
* syscalls.cc (chown32): Ditto.
(lchown32): Ditto.
(fchown32): Ditto.
(setegid32): Ditto.
(setgid32): Ditto.
* uinfo.cc (getgid32): Ditto.
(getegid32): Ditto.
* include/cygwin/grp.h: Remove declaration of getgrgid() and getgrnam().
Declare getgrgid32() and getgrnam32() instead. Declare getgid32().
2002-05-28 16:10:55 +02:00
|
|
|
__gid32_t gid;
|
2001-04-20 15:02:32 +02:00
|
|
|
|
2003-02-05 17:15:22 +01:00
|
|
|
if (!GetSecurityDescriptorOwner (psd, (PSID *) &owner_sid, &dummy))
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
debug_printf ("GetSecurityDescriptorOwner %E");
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
2003-02-05 17:15:22 +01:00
|
|
|
uid = owner_sid.get_uid ();
|
2001-04-20 15:02:32 +02:00
|
|
|
|
2003-02-05 17:15:22 +01:00
|
|
|
if (!GetSecurityDescriptorGroup (psd, (PSID *) &group_sid, &dummy))
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
debug_printf ("GetSecurityDescriptorGroup %E");
|
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
2003-02-05 17:15:22 +01:00
|
|
|
gid = group_sid.get_gid ();
|
2001-04-20 15:02:32 +02:00
|
|
|
|
2003-02-05 17:15:22 +01:00
|
|
|
__aclent32_t lacl[MAX_ACL_ENTRIES];
|
|
|
|
memset (&lacl, 0, MAX_ACL_ENTRIES * sizeof (__aclent32_t));
|
2001-04-20 15:02:32 +02:00
|
|
|
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;
|
2002-11-24 19:58:47 +01:00
|
|
|
lacl[2].a_id = ILLEGAL_GID;
|
|
|
|
lacl[3].a_type = CLASS_OBJ;
|
|
|
|
lacl[3].a_id = ILLEGAL_GID;
|
|
|
|
lacl[3].a_perm = S_IROTH | S_IWOTH | S_IXOTH;
|
2001-04-20 15:02:32 +02:00
|
|
|
|
|
|
|
PACL acl;
|
|
|
|
BOOL acl_exists;
|
|
|
|
|
|
|
|
if (!GetSecurityDescriptorDacl (psd, &acl_exists, &acl, &dummy))
|
|
|
|
{
|
|
|
|
__seterrno ();
|
|
|
|
debug_printf ("GetSecurityDescriptorDacl %E");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-11-24 19:58:47 +01:00
|
|
|
int pos, i, types_def = 0;
|
2001-04-20 15:02:32 +02:00
|
|
|
|
|
|
|
if (!acl_exists || !acl)
|
2002-11-24 19:58:47 +01:00
|
|
|
for (pos = 0; pos < 3; ++pos) /* Don't change CLASS_OBJ entry */
|
|
|
|
lacl[pos].a_perm = S_IROTH | S_IWOTH | S_IXOTH;
|
|
|
|
else
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
2002-11-24 19:58:47 +01:00
|
|
|
for (i = 0; i < acl->AceCount; ++i)
|
|
|
|
{
|
|
|
|
ACCESS_ALLOWED_ACE *ace;
|
2002-12-12 04:09:38 +01:00
|
|
|
|
2002-11-24 19:58:47 +01:00
|
|
|
if (!GetAce (acl, i, (PVOID *) &ace))
|
|
|
|
continue;
|
2001-04-20 15:02:32 +02:00
|
|
|
|
2003-02-05 17:15:22 +01:00
|
|
|
cygpsid ace_sid ((PSID) &ace->SidStart);
|
2002-11-24 19:58:47 +01:00
|
|
|
int id;
|
|
|
|
int type = 0;
|
2001-04-20 15:02:32 +02:00
|
|
|
|
2002-11-24 19:58:47 +01:00
|
|
|
if (ace_sid == well_known_world_sid)
|
|
|
|
{
|
|
|
|
type = OTHER_OBJ;
|
|
|
|
id = ILLEGAL_GID;
|
|
|
|
}
|
|
|
|
else if (ace_sid == group_sid)
|
|
|
|
{
|
|
|
|
type = GROUP_OBJ;
|
|
|
|
id = gid;
|
|
|
|
}
|
|
|
|
else if (ace_sid == owner_sid)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
2002-11-24 19:58:47 +01:00
|
|
|
type = USER_OBJ;
|
|
|
|
id = uid;
|
|
|
|
}
|
2003-01-12 12:38:51 +01:00
|
|
|
else if (ace_sid == well_known_creator_group_sid)
|
|
|
|
{
|
|
|
|
type = GROUP_OBJ | ACL_DEFAULT;
|
|
|
|
id = ILLEGAL_GID;
|
|
|
|
}
|
|
|
|
else if (ace_sid == well_known_creator_owner_sid)
|
|
|
|
{
|
|
|
|
type = USER_OBJ | ACL_DEFAULT;
|
|
|
|
id = ILLEGAL_GID;
|
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
else
|
2003-02-05 17:15:22 +01:00
|
|
|
id = ace_sid.get_id (TRUE, &type);
|
|
|
|
|
2002-11-24 19:58:47 +01:00
|
|
|
if (!type)
|
|
|
|
continue;
|
2003-01-12 12:38:51 +01:00
|
|
|
if (!(ace->Header.AceFlags & INHERIT_ONLY || type & ACL_DEFAULT))
|
2002-11-24 19:58:47 +01:00
|
|
|
{
|
|
|
|
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
|
|
|
|
getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
|
|
|
|
}
|
|
|
|
if ((ace->Header.AceFlags & SUB_CONTAINERS_AND_OBJECTS_INHERIT)
|
|
|
|
&& (attr & FILE_ATTRIBUTE_DIRECTORY))
|
|
|
|
{
|
2003-01-12 12:38:51 +01:00
|
|
|
if (type == USER_OBJ)
|
|
|
|
type = USER;
|
|
|
|
else if (type == GROUP_OBJ)
|
|
|
|
type = GROUP;
|
2002-11-24 19:58:47 +01:00
|
|
|
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);
|
|
|
|
}
|
2001-04-20 15:02:32 +02:00
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
/* Include DEF_CLASS_OBJ if any default ace exists */
|
2002-12-12 04:09:38 +01:00
|
|
|
if ((types_def & (USER|GROUP))
|
2002-11-24 19:58:47 +01:00
|
|
|
&& ((pos = searchace (lacl, MAX_ACL_ENTRIES, DEF_CLASS_OBJ)) >= 0))
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
2002-11-24 19:58:47 +01:00
|
|
|
lacl[pos].a_type = DEF_CLASS_OBJ;
|
|
|
|
lacl[pos].a_id = ILLEGAL_GID;
|
|
|
|
lacl[pos].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
|
2001-04-20 15:02:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0)
|
|
|
|
pos = MAX_ACL_ENTRIES;
|
2002-11-24 19:58:47 +01:00
|
|
|
if (aclbufp) {
|
2003-02-05 17:15:22 +01:00
|
|
|
if (owner_sid == group_sid)
|
2002-11-24 19:58:47 +01:00
|
|
|
lacl[0].a_perm = lacl[1].a_perm;
|
|
|
|
if (pos > nentries)
|
2002-11-25 12:23:21 +01:00
|
|
|
{
|
2003-01-26 07:42:40 +01:00
|
|
|
set_errno (ENOSPC);
|
2002-11-25 12:23:21 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2003-02-05 17:15:22 +01:00
|
|
|
memcpy (aclbufp, lacl, pos * sizeof (__aclent32_t));
|
2002-11-24 19:58:47 +01:00
|
|
|
for (i = 0; i < pos; ++i)
|
|
|
|
aclbufp[i].a_perm &= ~(DENY_R | DENY_W | DENY_X);
|
2003-02-05 17:15:22 +01:00
|
|
|
aclsort32 (pos, 0, aclbufp);
|
2002-11-24 19:58:47 +01:00
|
|
|
}
|
2001-04-20 15:02:32 +02:00
|
|
|
syscall_printf ("%d = getacl (%s)", pos, file);
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
acl_worker (const char *path, int cmd, int nentries, __aclent32_t *aclbufp,
|
2001-04-20 15:02:32 +02:00
|
|
|
int nofollow)
|
|
|
|
{
|
|
|
|
extern suffix_info stat_suffixes[];
|
|
|
|
path_conv real_path (path, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) | PC_FULL, stat_suffixes);
|
|
|
|
if (real_path.error)
|
|
|
|
{
|
|
|
|
set_errno (real_path.error);
|
|
|
|
syscall_printf ("-1 = acl (%s)", path);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
if (!real_path.has_acls () || !allow_ntsec)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
2002-02-25 18:47:51 +01:00
|
|
|
struct __stat64 st;
|
2001-04-20 15:02:32 +02:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case SETACL:
|
|
|
|
set_errno (ENOSYS);
|
|
|
|
break;
|
|
|
|
case GETACL:
|
2003-01-12 12:38:51 +01:00
|
|
|
if (!aclbufp)
|
|
|
|
set_errno(EFAULT);
|
|
|
|
else if (nentries < MIN_ACL_ENTRIES)
|
|
|
|
set_errno (ENOSPC);
|
2002-02-25 18:47:51 +01:00
|
|
|
else if ((nofollow && !lstat64 (path, &st))
|
|
|
|
|| (!nofollow && !stat64 (path, &st)))
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
2003-01-12 12:38:51 +01: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;
|
|
|
|
aclbufp[3].a_type = CLASS_OBJ;
|
|
|
|
aclbufp[3].a_id = ILLEGAL_GID;
|
|
|
|
aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
|
|
|
|
ret = MIN_ACL_ENTRIES;
|
2001-04-20 15:02:32 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GETACLCNT:
|
2003-01-12 12:38:51 +01:00
|
|
|
ret = MIN_ACL_ENTRIES;
|
2001-04-20 15:02:32 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
syscall_printf ("%d = acl (%s)", ret, path);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case SETACL:
|
2003-02-05 17:15:22 +01:00
|
|
|
if (!aclsort32 (nentries, 0, aclbufp))
|
2001-04-20 15:02:32 +02:00
|
|
|
return setacl (real_path.get_win32 (),
|
|
|
|
nentries, aclbufp);
|
|
|
|
break;
|
|
|
|
case GETACL:
|
2003-01-12 12:38:51 +01:00
|
|
|
if (!aclbufp)
|
|
|
|
set_errno(EFAULT);
|
|
|
|
else
|
|
|
|
return getacl (real_path.get_win32 (),
|
|
|
|
real_path.file_attributes (),
|
|
|
|
nentries, aclbufp);
|
|
|
|
break;
|
2001-04-20 15:02:32 +02:00
|
|
|
case GETACLCNT:
|
|
|
|
return getacl (real_path.get_win32 (),
|
|
|
|
real_path.file_attributes (),
|
|
|
|
0, NULL);
|
|
|
|
default:
|
2003-01-12 12:38:51 +01:00
|
|
|
set_errno (EINVAL);
|
2001-04-20 15:02:32 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
syscall_printf ("-1 = acl (%s)", path);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
acl32 (const char *path, int cmd, int nentries, __aclent32_t *aclbufp)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
return acl_worker (path, cmd, nentries, aclbufp, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
lacl32 (const char *path, int cmd, int nentries, __aclent32_t *aclbufp)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
return acl_worker (path, cmd, nentries, aclbufp, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
facl32 (int fd, int cmd, int nentries, __aclent32_t *aclbufp)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
2001-10-16 01:39:33 +02:00
|
|
|
cygheap_fdget cfd (fd);
|
|
|
|
if (cfd < 0)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
syscall_printf ("-1 = facl (%d)", fd);
|
|
|
|
return -1;
|
|
|
|
}
|
2001-10-16 01:39:33 +02:00
|
|
|
const char *path = cfd->get_name ();
|
2001-04-20 15:02:32 +02:00
|
|
|
if (path == NULL)
|
|
|
|
{
|
|
|
|
syscall_printf ("-1 = facl (%d) (no name)", fd);
|
|
|
|
set_errno (ENOSYS);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
syscall_printf ("facl (%d): calling acl (%s)", fd, path);
|
|
|
|
return acl_worker (path, cmd, nentries, aclbufp, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
aclcheck32 (__aclent32_t *aclbufp, int nentries, int *which)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
BOOL has_user_obj = FALSE;
|
|
|
|
BOOL has_group_obj = FALSE;
|
|
|
|
BOOL has_other_obj = FALSE;
|
|
|
|
BOOL has_class_obj = FALSE;
|
|
|
|
BOOL has_ug_objs = FALSE;
|
|
|
|
BOOL has_def_user_obj = FALSE;
|
|
|
|
BOOL has_def_group_obj = FALSE;
|
|
|
|
BOOL has_def_other_obj = FALSE;
|
|
|
|
BOOL has_def_class_obj = FALSE;
|
|
|
|
BOOL has_def_ug_objs = 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_user_obj = TRUE;
|
|
|
|
break;
|
|
|
|
case DEF_GROUP_OBJ:
|
|
|
|
if (has_def_group_obj)
|
|
|
|
{
|
|
|
|
if (which)
|
|
|
|
*which = pos;
|
|
|
|
return GRP_ERROR;
|
|
|
|
}
|
|
|
|
has_def_group_obj = TRUE;
|
|
|
|
break;
|
|
|
|
case DEF_OTHER_OBJ:
|
|
|
|
if (has_def_other_obj)
|
|
|
|
{
|
|
|
|
if (which)
|
|
|
|
*which = pos;
|
|
|
|
return OTHER_ERROR;
|
|
|
|
}
|
|
|
|
has_def_other_obj = TRUE;
|
|
|
|
break;
|
|
|
|
case DEF_CLASS_OBJ:
|
|
|
|
if (has_def_class_obj)
|
|
|
|
{
|
|
|
|
if (which)
|
|
|
|
*which = pos;
|
|
|
|
return CLASS_ERROR;
|
|
|
|
}
|
|
|
|
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_ug_objs = TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return ENTRY_ERROR;
|
|
|
|
}
|
|
|
|
if (!has_user_obj
|
|
|
|
|| !has_group_obj
|
|
|
|
|| !has_other_obj
|
|
|
|
#if 0
|
|
|
|
/* These checks are not ok yet since CLASS_OBJ isn't fully implemented. */
|
|
|
|
|| (has_ug_objs && !has_class_obj)
|
|
|
|
|| (has_def_ug_objs && !has_def_class_obj)
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (which)
|
|
|
|
*which = -1;
|
|
|
|
return MISS_ERROR;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-02-05 17:15:22 +01:00
|
|
|
static
|
2001-04-20 15:02:32 +02:00
|
|
|
int acecmp (const void *a1, const void *a2)
|
|
|
|
{
|
2003-02-05 17:15:22 +01:00
|
|
|
#define ace(i) ((const __aclent32_t *) a##i)
|
2002-09-22 05:38:57 +02:00
|
|
|
int ret = ace (1)->a_type - ace (2)->a_type;
|
2001-04-20 15:02:32 +02:00
|
|
|
if (!ret)
|
2002-09-22 05:38:57 +02:00
|
|
|
ret = ace (1)->a_id - ace (2)->a_id;
|
2001-04-20 15:02:32 +02:00
|
|
|
return ret;
|
|
|
|
#undef ace
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
aclsort32 (int nentries, int, __aclent32_t *aclbufp)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
2003-02-05 17:15:22 +01:00
|
|
|
if (aclcheck32 (aclbufp, nentries, NULL))
|
2001-04-20 15:02:32 +02:00
|
|
|
return -1;
|
|
|
|
if (!aclbufp || nentries < 1)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
2003-02-05 17:15:22 +01:00
|
|
|
qsort ((void *) aclbufp, nentries, sizeof (__aclent32_t), acecmp);
|
2001-04-20 15:02:32 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
acltomode32 (__aclent32_t *aclbufp, int nentries, mode_t *modep)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
int pos;
|
|
|
|
|
|
|
|
if (!aclbufp || nentries < 1 || !modep)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*modep = 0;
|
2002-11-24 19:58:47 +01:00
|
|
|
if ((pos = searchace (aclbufp, nentries, USER_OBJ)) < 0
|
|
|
|
|| !aclbufp[pos].a_type)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
*modep |= (aclbufp[pos].a_perm & S_IRWXO) << 6;
|
|
|
|
if ((pos = searchace (aclbufp, nentries, GROUP_OBJ)) < 0
|
|
|
|
|| !aclbufp[pos].a_type)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
*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)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
*modep |= aclbufp[pos].a_perm & S_IRWXO;
|
2001-04-20 15:02:32 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
aclfrommode32 (__aclent32_t *aclbufp, int nentries, mode_t *modep)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
int pos;
|
|
|
|
|
|
|
|
if (!aclbufp || nentries < 1 || !modep)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
if ((pos = searchace (aclbufp, nentries, USER_OBJ)) < 0
|
|
|
|
|| !aclbufp[pos].a_type)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
aclbufp[pos].a_perm = (*modep & S_IRWXU) >> 6;
|
|
|
|
if ((pos = searchace (aclbufp, nentries, GROUP_OBJ)) < 0
|
|
|
|
|| !aclbufp[pos].a_type)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
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)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-11-24 19:58:47 +01:00
|
|
|
aclbufp[pos].a_perm = (*modep & S_IRWXO);
|
2001-04-20 15:02:32 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
acltopbits32 (__aclent32_t *aclbufp, int nentries, mode_t *pbitsp)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
2003-02-05 17:15:22 +01:00
|
|
|
return acltomode32 (aclbufp, nentries, pbitsp);
|
2001-04-20 15:02:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
2003-02-05 17:15:22 +01:00
|
|
|
aclfrompbits32 (__aclent32_t *aclbufp, int nentries, mode_t *pbitsp)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
2003-02-05 17:15:22 +01:00
|
|
|
return aclfrommode32 (aclbufp, nentries, pbitsp);
|
2001-04-20 15:02:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
permtostr (mode_t perm)
|
|
|
|
{
|
|
|
|
static char pbuf[4];
|
|
|
|
|
2002-11-24 19:58:47 +01:00
|
|
|
pbuf[0] = (perm & S_IROTH) ? 'r' : '-';
|
|
|
|
pbuf[1] = (perm & S_IWOTH) ? 'w' : '-';
|
|
|
|
pbuf[2] = (perm & S_IXOTH) ? 'x' : '-';
|
2001-04-20 15:02:32 +02:00
|
|
|
pbuf[3] = '\0';
|
|
|
|
return pbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
char *
|
2003-02-05 17:15:22 +01:00
|
|
|
acltotext32 (__aclent32_t *aclbufp, int aclcnt)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
if (!aclbufp || aclcnt < 1 || aclcnt > MAX_ACL_ENTRIES
|
2003-02-05 17:15:22 +01:00
|
|
|
|| aclcheck32 (aclbufp, aclcnt, NULL))
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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')
|
2002-11-24 19:58:47 +01:00
|
|
|
mode |= S_IROTH;
|
2001-04-20 15:02:32 +02:00
|
|
|
else if (perm[0] != '-')
|
|
|
|
return 01000;
|
|
|
|
if (perm[1] == 'w')
|
2002-11-24 19:58:47 +01:00
|
|
|
mode |= S_IWOTH;
|
2001-04-20 15:02:32 +02:00
|
|
|
else if (perm[1] != '-')
|
|
|
|
return 01000;
|
|
|
|
if (perm[2] == 'x')
|
2002-11-24 19:58:47 +01:00
|
|
|
mode |= S_IXOTH;
|
2001-04-20 15:02:32 +02:00
|
|
|
else if (perm[2] != '-')
|
|
|
|
return 01000;
|
|
|
|
return mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
2003-02-05 17:15:22 +01:00
|
|
|
__aclent32_t *
|
|
|
|
aclfromtext32 (char *acltextp, int *)
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
if (!acltextp)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
char buf[strlen (acltextp) + 1];
|
2003-02-05 17:15:22 +01:00
|
|
|
__aclent32_t lacl[MAX_ACL_ENTRIES];
|
2001-04-20 15:02:32 +02:00
|
|
|
memset (lacl, 0, sizeof lacl);
|
|
|
|
int pos = 0;
|
|
|
|
strcpy (buf, acltextp);
|
|
|
|
char *lasts;
|
|
|
|
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))
|
|
|
|
{
|
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* pwdgrp.h (pwdgrp_check::pwdgrp_state): Replace by
pwdgrp_check::isinitializing ().
(pwdgrp_check::isinitializing): Create.
* passwd.cc (grab_int): Change type to unsigned, use strtoul and
set the pointer content to 0 if the field is invalid.
(parse_pwd): Move validity test after getting pw_gid.
(read_etc_passwd): Replace "passwd_state <= " by
passwd_state::isinitializing ().
(internal_getpwuid): Ditto.
(internal_getpwnam): Ditto.
(getpwent): Ditto.
(getpass): Ditto.
* grp.cc (parse_grp): Use strtoul for gr_gid and verify the validity.
(read_etc_group): Replace "group_state <= " by
group_state::isinitializing ().
(internal_getgrgid): Ditto.
(getgrent32): Ditto.
(internal_getgrent): Ditto.
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* security.h: Move declarations of internal_getgrent,
internal_getpwsid and internal_getgrsid to pwdgrp.h.
* pwdgrp.h: Declare internal_getpwsid, internal_getpwnam,
internal_getpwuid, internal_getgrsid, internal_getgrgid,
internal_getgrnam, internal_getgrent and internal_getgroups.
Delete "emulated" from enum pwdgrp_state.
(pwdgrp_check::isuninitialized): Create.
(pwdgrp_check::pwdgrp_state): Change state to initializing
rather than to uninitialized.
(pwdgrp_read::gets): Remove trailing CRs.
* passwd.cc (grab_string): Don't look for NLs.
(grab_int): Ditto.
(parse_pwd): Don't look for CRs. Return 0 if entry is too short.
(search_for): Delete.
(read_etc_passwd): Simplify tests to actually read the file.
Set state to loaded before making internal_getpwXX calls.
Replace search_for calls by equivalent internal_pwgetXX calls.
(internal_getpwsid): Use passwd_state.isuninitialized to decide
to call read_etc_passwd.
(internal_getpwuid): Create.
(internal_getpwnam): Create.
(getpwuid32): Simply call internal_getpwuid.
(getpwuid_r32): Call internal_getpwuid.
(getpwnam): Simply call internal_getpwnam.
(getpwnam_r): Call internal_getpwnam.
* grp.cc (parse_grp): Don't look for CRs. Adjust blank space.
(add_grp_line): Adjust blank space.
(class group_lock): Ditto.
(read_etc_group): Simplify tests to actually read the file.
Set state to loaded before making internal_getgrXX calls.
Replace getgrXX calls by equivalent internal calls.
(internal_getgrsid): Use group_state.isuninitialized to decide
to call read_etc_group.
(internal_getgrgid): Create.
(internal_getgrnam): Create.
(getgroups32): Simply call internal_getgrgid.
(getgrnam32): Simply call internal_getgrnam.
(internal_getgrent): Call group_state.isuninitialized.
(internal_getgroups): Create from the former getgroups32, using
two of the four arguments. Set gid to myself->gid and username
to cygheap->user.name ().
(getgroups32): Simply call internal_getgroup.
(getgroups): Call internal_getgroup instead of getgroups32.
(setgroups32): Call internal versions of get{pw,gr}XX.
* sec_helper.cc: Include pwdgrp.h.
(is_grp_member): Call internal versions of get{pw,gr}XX.
* security.cc: Include pwdgrp.h.
(alloc_sd): Call internal versions of get{pw,gr}XX.
* syscalls.cc: Include pwdgrp.h.
(seteuid32): Call internal versions of get{pw,gr}XX.
(setegid32): Ditto.
* uinfo.cc: Include pwdgrp.h.
(internal_getlogin): Call internal versions of get{pw,gr}XX.
(cygheap_user::ontherange): Ditto.
* sec_acl.cc: Include pwdgrp.h.
(setacl): Call internal versions of get{pw,gr}XX.
(acl_access): Ditto and simplify logic.
(aclfromtext): Ditto.
2002-12-10 13:43:49 +01:00
|
|
|
struct passwd *pw = internal_getpwnam (c);
|
2001-04-20 15:02:32 +02:00
|
|
|
if (!pw)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
lacl[pos].a_id = pw->pw_uid;
|
2003-02-05 17:15:22 +01:00
|
|
|
c = strechr (c, ':');
|
2001-04-20 15:02:32 +02:00
|
|
|
}
|
|
|
|
else if (isdigit (*c))
|
|
|
|
lacl[pos].a_id = strtol (c, &c, 10);
|
2003-02-05 17:15:22 +01:00
|
|
|
if (*c != ':')
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
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))
|
|
|
|
{
|
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* pwdgrp.h (pwdgrp_check::pwdgrp_state): Replace by
pwdgrp_check::isinitializing ().
(pwdgrp_check::isinitializing): Create.
* passwd.cc (grab_int): Change type to unsigned, use strtoul and
set the pointer content to 0 if the field is invalid.
(parse_pwd): Move validity test after getting pw_gid.
(read_etc_passwd): Replace "passwd_state <= " by
passwd_state::isinitializing ().
(internal_getpwuid): Ditto.
(internal_getpwnam): Ditto.
(getpwent): Ditto.
(getpass): Ditto.
* grp.cc (parse_grp): Use strtoul for gr_gid and verify the validity.
(read_etc_group): Replace "group_state <= " by
group_state::isinitializing ().
(internal_getgrgid): Ditto.
(getgrent32): Ditto.
(internal_getgrent): Ditto.
2002-12-10 Pierre Humblet <pierre.humblet@ieee.org>
* security.h: Move declarations of internal_getgrent,
internal_getpwsid and internal_getgrsid to pwdgrp.h.
* pwdgrp.h: Declare internal_getpwsid, internal_getpwnam,
internal_getpwuid, internal_getgrsid, internal_getgrgid,
internal_getgrnam, internal_getgrent and internal_getgroups.
Delete "emulated" from enum pwdgrp_state.
(pwdgrp_check::isuninitialized): Create.
(pwdgrp_check::pwdgrp_state): Change state to initializing
rather than to uninitialized.
(pwdgrp_read::gets): Remove trailing CRs.
* passwd.cc (grab_string): Don't look for NLs.
(grab_int): Ditto.
(parse_pwd): Don't look for CRs. Return 0 if entry is too short.
(search_for): Delete.
(read_etc_passwd): Simplify tests to actually read the file.
Set state to loaded before making internal_getpwXX calls.
Replace search_for calls by equivalent internal_pwgetXX calls.
(internal_getpwsid): Use passwd_state.isuninitialized to decide
to call read_etc_passwd.
(internal_getpwuid): Create.
(internal_getpwnam): Create.
(getpwuid32): Simply call internal_getpwuid.
(getpwuid_r32): Call internal_getpwuid.
(getpwnam): Simply call internal_getpwnam.
(getpwnam_r): Call internal_getpwnam.
* grp.cc (parse_grp): Don't look for CRs. Adjust blank space.
(add_grp_line): Adjust blank space.
(class group_lock): Ditto.
(read_etc_group): Simplify tests to actually read the file.
Set state to loaded before making internal_getgrXX calls.
Replace getgrXX calls by equivalent internal calls.
(internal_getgrsid): Use group_state.isuninitialized to decide
to call read_etc_group.
(internal_getgrgid): Create.
(internal_getgrnam): Create.
(getgroups32): Simply call internal_getgrgid.
(getgrnam32): Simply call internal_getgrnam.
(internal_getgrent): Call group_state.isuninitialized.
(internal_getgroups): Create from the former getgroups32, using
two of the four arguments. Set gid to myself->gid and username
to cygheap->user.name ().
(getgroups32): Simply call internal_getgroup.
(getgroups): Call internal_getgroup instead of getgroups32.
(setgroups32): Call internal versions of get{pw,gr}XX.
* sec_helper.cc: Include pwdgrp.h.
(is_grp_member): Call internal versions of get{pw,gr}XX.
* security.cc: Include pwdgrp.h.
(alloc_sd): Call internal versions of get{pw,gr}XX.
* syscalls.cc: Include pwdgrp.h.
(seteuid32): Call internal versions of get{pw,gr}XX.
(setegid32): Ditto.
* uinfo.cc: Include pwdgrp.h.
(internal_getlogin): Call internal versions of get{pw,gr}XX.
(cygheap_user::ontherange): Ditto.
* sec_acl.cc: Include pwdgrp.h.
(setacl): Call internal versions of get{pw,gr}XX.
(acl_access): Ditto and simplify logic.
(aclfromtext): Ditto.
2002-12-10 13:43:49 +01:00
|
|
|
struct __group32 *gr = internal_getgrnam (c);
|
2001-04-20 15:02:32 +02:00
|
|
|
if (!gr)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
lacl[pos].a_id = gr->gr_gid;
|
2003-02-05 17:15:22 +01:00
|
|
|
c = strechr (c, ':');
|
2001-04-20 15:02:32 +02:00
|
|
|
}
|
|
|
|
else if (isdigit (*c))
|
|
|
|
lacl[pos].a_id = strtol (c, &c, 10);
|
2003-02-05 17:15:22 +01:00
|
|
|
if (*c != ':')
|
2001-04-20 15:02:32 +02:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2003-02-05 17:15:22 +01:00
|
|
|
__aclent32_t *aclp = (__aclent32_t *) malloc (pos * sizeof (__aclent32_t));
|
2001-04-20 15:02:32 +02:00
|
|
|
if (aclp)
|
2003-02-05 17:15:22 +01:00
|
|
|
memcpy (aclp, lacl, pos * sizeof (__aclent32_t));
|
2001-04-20 15:02:32 +02:00
|
|
|
return aclp;
|
|
|
|
}
|
|
|
|
|
2003-02-05 17:15:22 +01:00
|
|
|
/* __aclent16_t and __aclent32_t have same size and same member offsets */
|
|
|
|
static __aclent32_t *
|
|
|
|
acl16to32 (__aclent16_t *aclbufp, int nentries)
|
|
|
|
{
|
|
|
|
__aclent32_t *aclbufp32 = (__aclent32_t *) aclbufp;
|
|
|
|
if (aclbufp32)
|
|
|
|
for (int i = 0; i < nentries; i++)
|
|
|
|
aclbufp32[i].a_id &= USHRT_MAX;
|
|
|
|
return aclbufp32;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
acl (const char *path, int cmd, int nentries, __aclent16_t *aclbufp)
|
|
|
|
{
|
|
|
|
return acl32 (path, cmd, nentries, acl16to32 (aclbufp, nentries));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
facl (int fd, int cmd, int nentries, __aclent16_t *aclbufp)
|
|
|
|
{
|
|
|
|
return facl32 (fd, cmd, nentries, acl16to32 (aclbufp, nentries));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
lacl (const char *path, int cmd, int nentries, __aclent16_t *aclbufp)
|
|
|
|
{
|
|
|
|
return lacl32 (path, cmd, nentries, acl16to32 (aclbufp, nentries));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
aclcheck (__aclent16_t *aclbufp, int nentries, int *which)
|
|
|
|
{
|
|
|
|
return aclcheck32 (acl16to32 (aclbufp, nentries), nentries, which);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
aclsort (int nentries, int i, __aclent16_t *aclbufp)
|
|
|
|
{
|
|
|
|
return aclsort32 (nentries, i, acl16to32 (aclbufp, nentries));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
acltomode (__aclent16_t *aclbufp, int nentries, mode_t *modep)
|
|
|
|
{
|
|
|
|
return acltomode32 (acl16to32 (aclbufp, nentries), nentries, modep);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
aclfrommode (__aclent16_t *aclbufp, int nentries, mode_t *modep)
|
|
|
|
{
|
|
|
|
return aclfrommode32 ((__aclent32_t *)aclbufp, nentries, modep);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
acltopbits (__aclent16_t *aclbufp, int nentries, mode_t *pbitsp)
|
|
|
|
{
|
|
|
|
return acltopbits32 (acl16to32 (aclbufp, nentries), nentries, pbitsp);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
aclfrompbits (__aclent16_t *aclbufp, int nentries, mode_t *pbitsp)
|
|
|
|
{
|
|
|
|
return aclfrompbits32 ((__aclent32_t *)aclbufp, nentries, pbitsp);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
char *
|
|
|
|
acltotext (__aclent16_t *aclbufp, int aclcnt)
|
|
|
|
{
|
|
|
|
return acltotext32 (acl16to32 (aclbufp, aclcnt), aclcnt);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
__aclent16_t *
|
|
|
|
aclfromtext (char *acltextp, int * aclcnt)
|
|
|
|
{
|
|
|
|
return (__aclent16_t *) aclfromtext32 (acltextp, aclcnt);
|
|
|
|
}
|