Implement POSIX.1e ACL functions
* Makefile.in (DLL_OFILES): Add sec_posixacl.o. (SUBLIBS): Add libacl.a (libacl.a): New rule to create libacl.a. * common.din: Export POSIX ACL functions as well as most libacl.a extensions. * fhandler.h (fhander_base::acl_get): New prototype. (fhander_base::acl_set): Ditto. (fhandler_disk_file::acl_get): Ditto. (fhandler_disk_file::acl_set): Ditto. * include/acl/libacl.h: New file. * include/cygwin/version.h: Bump API minor version. * include/sys/acl.h: Drop including cygwin/acl.h. Accommodate throughout Cygwin. Add POSIX ACL definitions. * sec_acl.cc: Include sec_posixacl.h. Replace ILLEGAL_UID and ILLEGAL_GID with ACL_UNDEFINED_ID where sensible. (__aclcheck): New internal acl check function to be used for Solaris and POSIX ACLs. (aclcheck32): Call __aclcheck. (__aclcalcmask): New function to compute ACL_MASK value. (__aclsort): New internal acl sort function to be used for Solaris and POSIX ACLs. (aclsort32): Call __aclsort. (permtostr): Work directly on provided buffer. (__acltotext): New internal acltotext function to be used for Solaris and POSIX ACLs. (acltotext32): Call __acltotext. (__aclfromtext): New internal aclfromtext function to be used for Solaris and POSIX ACLs. (aclfromtext32): Call __aclfromtext. * sec_posixacl.cc: New file implemeting POSIX ACL functions. * sec_posixacl.h: New internal header. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
edd7d93484
commit
9ddf063921
|
@ -267,6 +267,7 @@ DLL_OFILES:= \
|
|||
sec_acl.o \
|
||||
sec_auth.o \
|
||||
sec_helper.o \
|
||||
sec_posixacl.o \
|
||||
security.o \
|
||||
select.o \
|
||||
sem.o \
|
||||
|
@ -443,7 +444,7 @@ endif
|
|||
API_VER:=$(srcdir)/include/cygwin/version.h
|
||||
|
||||
LIB_NAME:=libcygwin.a
|
||||
SUBLIBS:=libpthread.a libutil.a ${CURDIR}/libm.a ${CURDIR}/libc.a libdl.a libresolv.a librt.a
|
||||
SUBLIBS:=libpthread.a libutil.a ${CURDIR}/libm.a ${CURDIR}/libc.a libdl.a libresolv.a librt.a libacl.a
|
||||
EXTRALIBS:=libautomode.a libbinmode.a libtextmode.a libtextreadmode.a
|
||||
INSTOBJS:=automode.o binmode.o textmode.o textreadmode.o
|
||||
TARGET_LIBS:=$(LIB_NAME) $(CYGWIN_START) $(GMON_START) $(LIBGMON_A) $(SUBLIBS) $(INSTOBJS) $(EXTRALIBS)
|
||||
|
@ -643,6 +644,9 @@ libresolv.a: ${LIB_NAME} minires.o
|
|||
librt.a: ${LIB_NAME} posix_ipc.o
|
||||
${speclib} ${@F}
|
||||
|
||||
libacl.a: ${LIB_NAME} sec_posixacl.o
|
||||
${speclib} ${@F}
|
||||
|
||||
${EXTRALIBS}: lib%.a: %.o
|
||||
$(AR) cru $@ $?
|
||||
|
||||
|
|
|
@ -117,6 +117,45 @@ accept = cygwin_accept SIGFE
|
|||
accept4 SIGFE
|
||||
access SIGFE
|
||||
acl SIGFE
|
||||
acl_add_perm NOSIGFE
|
||||
acl_calc_mask SIGFE
|
||||
acl_check NOSIGFE
|
||||
acl_clear_perms NOSIGFE
|
||||
acl_cmp SIGFE
|
||||
acl_copy_entry NOSIGFE
|
||||
acl_copy_ext NOSIGFE
|
||||
acl_copy_int NOSIGFE
|
||||
acl_create_entry SIGFE
|
||||
acl_delete_def_file SIGFE
|
||||
acl_delete_entry NOSIGFE
|
||||
acl_delete_perm NOSIGFE
|
||||
acl_dup SIGFE
|
||||
acl_entries NOSIGFE
|
||||
acl_equiv_mode SIGFE
|
||||
acl_error NOSIGFE
|
||||
acl_extended_fd SIGFE
|
||||
acl_extended_file SIGFE
|
||||
acl_extended_file_nofollow SIGFE
|
||||
acl_free SIGFE
|
||||
acl_from_mode NOSIGFE
|
||||
acl_from_text SIGFE
|
||||
acl_get_entry NOSIGFE
|
||||
acl_get_fd SIGFE
|
||||
acl_get_file SIGFE
|
||||
acl_get_perm NOSIGFE
|
||||
acl_get_permset NOSIGFE
|
||||
acl_get_qualifier SIGFE
|
||||
acl_get_tag_type NOSIGFE
|
||||
acl_init SIGFE
|
||||
acl_set_fd SIGFE
|
||||
acl_set_file SIGFE
|
||||
acl_set_permset NOSIGFE
|
||||
acl_set_qualifier NOSIGFE
|
||||
acl_set_tag_type NOSIGFE
|
||||
acl_size NOSIGFE
|
||||
acl_to_any_text SIGFE
|
||||
acl_to_text SIGFE
|
||||
acl_valid NOSIGFE
|
||||
aclcheck NOSIGFE
|
||||
aclfrommode SIGFE
|
||||
aclfrompbits SIGFE
|
||||
|
|
|
@ -13,7 +13,7 @@ details. */
|
|||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/acl.h>
|
||||
#include <cygwin/acl.h>
|
||||
#include <sys/param.h>
|
||||
#include "cygerrno.h"
|
||||
#include "perprocess.h"
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct __DIR DIR;
|
|||
struct dirent;
|
||||
struct iovec;
|
||||
struct acl;
|
||||
struct __acl_t;
|
||||
|
||||
enum dirent_states
|
||||
{
|
||||
|
@ -355,6 +356,8 @@ public:
|
|||
virtual int __reg1 fchmod (mode_t mode);
|
||||
virtual int __reg2 fchown (uid_t uid, gid_t gid);
|
||||
virtual int __reg3 facl (int, int, struct acl *);
|
||||
virtual struct __acl_t * __reg2 acl_get (uint32_t);
|
||||
virtual int __reg3 acl_set (struct __acl_t *, uint32_t);
|
||||
virtual ssize_t __reg3 fgetxattr (const char *, void *, size_t);
|
||||
virtual int __reg3 fsetxattr (const char *, const void *, size_t, int);
|
||||
virtual int __reg3 fadvise (off_t, off_t, int);
|
||||
|
@ -1011,6 +1014,8 @@ class fhandler_disk_file: public fhandler_base
|
|||
int __reg1 fchmod (mode_t mode);
|
||||
int __reg2 fchown (uid_t uid, gid_t gid);
|
||||
int __reg3 facl (int, int, struct acl *);
|
||||
struct __acl_t * __reg2 acl_get (uint32_t);
|
||||
int __reg3 acl_set (struct __acl_t *, uint32_t);
|
||||
ssize_t __reg3 fgetxattr (const char *, void *, size_t);
|
||||
int __reg3 fsetxattr (const char *, const void *, size_t, int);
|
||||
int __reg3 fadvise (off_t, off_t, int);
|
||||
|
|
|
@ -13,7 +13,7 @@ details. */
|
|||
#include <winioctl.h>
|
||||
#include <lm.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/acl.h>
|
||||
#include <cygwin/acl.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include "cygerrno.h"
|
||||
#include "security.h"
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "wininfo.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/acl.h>
|
||||
#include <cygwin/acl.h>
|
||||
#include "cygtls.h"
|
||||
#include <sys/un.h>
|
||||
#include "ntdll.h"
|
||||
|
|
|
@ -12,7 +12,7 @@ details. */
|
|||
#include "winsup.h"
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/acl.h>
|
||||
#include <cygwin/acl.h>
|
||||
#include <cygwin/kd.h>
|
||||
#include "cygerrno.h"
|
||||
#include "security.h"
|
||||
|
|
|
@ -10,7 +10,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|||
details. */
|
||||
|
||||
#include "winsup.h"
|
||||
#include <sys/acl.h>
|
||||
#include <cygwin/acl.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include "cygerrno.h"
|
||||
#include "path.h"
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/* acl/libacl.h: Non-POSIX extensions of libacl
|
||||
|
||||
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. */
|
||||
|
||||
#ifndef _ACL_LIBACL_H
|
||||
#define _ACL_LIBACL_H
|
||||
|
||||
#include <sys/acl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Sync'd with cygwin/acl.h values. */
|
||||
#define ACL_MULTI_ERROR (0x4)
|
||||
#define ACL_DUPLICATE_ERROR (0x5)
|
||||
#define ACL_ENTRY_ERROR (0x6)
|
||||
#define ACL_MISS_ERROR (0x7)
|
||||
|
||||
/* acl_to_any_text options. */
|
||||
#define TEXT_ABBREVIATE (0x01)
|
||||
#define TEXT_NUMERIC_IDS (0x02)
|
||||
#define TEXT_SOME_EFFECTIVE (0x04)
|
||||
#define TEXT_ALL_EFFECTIVE (0x08)
|
||||
#define TEXT_SMART_INDENT (0x10)
|
||||
|
||||
extern int acl_check (acl_t __acl, int *__last);
|
||||
extern int acl_cmp (acl_t __acl1, acl_t __acl2);
|
||||
extern int acl_entries (acl_t __acl);
|
||||
extern int acl_equiv_mode (acl_t __acl, mode_t *__mode_p);
|
||||
extern const char *acl_error (int __code);
|
||||
extern int acl_extended_fd (int __fd);
|
||||
extern int acl_extended_file (const char *__path_p);
|
||||
extern int acl_extended_file_nofollow (const char *__path_p);
|
||||
extern acl_t acl_from_mode (mode_t __mode);
|
||||
extern int acl_get_perm (acl_permset_t __permset_d, acl_perm_t __perm);
|
||||
extern char *acl_to_any_text (acl_t __acl, const char *__prefix,
|
||||
char __separator, int __options);
|
||||
|
||||
#if 0
|
||||
/* TODO */
|
||||
struct error_context;
|
||||
extern int perm_copy_file (const char *, const char *, struct error_context *);
|
||||
extern int perm_copy_fd (const char *, int, const char *, int,
|
||||
struct error_context *);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _ACL_LIBACL_H */
|
|
@ -476,13 +476,14 @@ details. */
|
|||
292: Export rpmatch.
|
||||
293: Convert utmpname/utmpxname to int.
|
||||
294: Export clog10, clog10f.
|
||||
295: Export POSIX ACL functions.
|
||||
*/
|
||||
|
||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull,
|
||||
sigaltstack, sethostname. */
|
||||
|
||||
#define CYGWIN_VERSION_API_MAJOR 0
|
||||
#define CYGWIN_VERSION_API_MINOR 294
|
||||
#define CYGWIN_VERSION_API_MINOR 295
|
||||
|
||||
/* There is also a compatibity version number associated with the
|
||||
shared memory regions. It is incremented when incompatible
|
||||
|
|
|
@ -12,6 +12,89 @@ details. */
|
|||
#ifndef _SYS_ACL_H
|
||||
#define _SYS_ACL_H
|
||||
|
||||
#include <cygwin/acl.h>
|
||||
#include <_ansi.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* POSIX ACL types and functions. The implementation is based on the
|
||||
internal original Solaris implementation as defined in cygwin/acl.h.
|
||||
However, we don't include cygwin/acl.h from here to avoid poisoning
|
||||
the namespace. */
|
||||
|
||||
/* acl_perm_t constants */
|
||||
#define ACL_READ (0x4)
|
||||
#define ACL_WRITE (0x2)
|
||||
#define ACL_EXECUTE (0x1)
|
||||
|
||||
/* acl_tag_t constants, in sync with values from cygwin/acl.h */
|
||||
#define ACL_UNDEFINED_TAG (0x0000)
|
||||
#define ACL_USER_OBJ (0x0001)
|
||||
#define ACL_USER (0x0002)
|
||||
#define ACL_GROUP_OBJ (0x0004)
|
||||
#define ACL_GROUP (0x0008)
|
||||
#define ACL_MASK (0x0010)
|
||||
#define ACL_OTHER (0x0020)
|
||||
|
||||
/* acl_type_t constants */
|
||||
#define ACL_TYPE_ACCESS (0x0)
|
||||
#define ACL_TYPE_DEFAULT (0x1)
|
||||
|
||||
/* qualifier constant */
|
||||
#define ACL_UNDEFINED_ID ((id_t) -1)
|
||||
|
||||
/* entry_id constants */
|
||||
#define ACL_FIRST_ENTRY (0x0)
|
||||
#define ACL_NEXT_ENTRY (0x1)
|
||||
|
||||
/* types */
|
||||
typedef uint32_t acl_perm_t, acl_type_t, acl_tag_t;
|
||||
typedef uint64_t acl_permset_t;
|
||||
typedef uint64_t acl_entry_t;
|
||||
|
||||
struct __acl_t;
|
||||
typedef struct __acl_t *acl_t;
|
||||
|
||||
extern int acl_add_perm (acl_permset_t __permset_d, acl_perm_t __perm);
|
||||
extern int acl_calc_mask (acl_t *__acl_p);
|
||||
extern int acl_clear_perms (acl_permset_t __permset_d);
|
||||
extern int acl_copy_entry (acl_entry_t __dest_d, acl_entry_t __src_d);
|
||||
extern ssize_t acl_copy_ext (void *__buf_p, acl_t __acl, ssize_t __size);
|
||||
extern acl_t acl_copy_int (const void *__buf_p);
|
||||
extern int acl_create_entry (acl_t *__acl_p, acl_entry_t *__entry_p);
|
||||
extern int acl_delete_def_file (const char *__path_p);
|
||||
extern int acl_delete_entry (acl_t __acl, acl_entry_t __entry_d);
|
||||
extern int acl_delete_perm (acl_permset_t __permset_d, acl_perm_t __perm);
|
||||
extern acl_t acl_dup (acl_t __acl);
|
||||
extern int acl_free (void *__obj_p);
|
||||
extern acl_t acl_from_text (const char *__buf_p);
|
||||
extern int acl_get_entry (acl_t __acl, int __entry_id,
|
||||
acl_entry_t *__entry_p);
|
||||
extern acl_t acl_get_fd (int __fd);
|
||||
extern acl_t acl_get_file (const char *__path_p, acl_type_t __type);
|
||||
extern int acl_get_permset (acl_entry_t __entry_d,
|
||||
acl_permset_t *__permset_p);
|
||||
extern void *acl_get_qualifier (acl_entry_t __entry_d);
|
||||
extern int acl_get_tag_type (acl_entry_t __entry_d,
|
||||
acl_tag_t *__tag_type_p);
|
||||
extern acl_t acl_init (int __count);
|
||||
extern int acl_set_fd (int __fd, acl_t __acl);
|
||||
extern int acl_set_file (const char *__path_p, acl_type_t __type,
|
||||
acl_t __acl);
|
||||
extern int acl_set_permset (acl_entry_t __entry_d,
|
||||
acl_permset_t __permset_d);
|
||||
extern int acl_set_qualifier (acl_entry_t __entry_d,
|
||||
const void *__tag_qualifier_p);
|
||||
extern int acl_set_tag_type (acl_entry_t __entry_d, acl_tag_t __tag_type);
|
||||
extern ssize_t acl_size (acl_t __acl);
|
||||
extern char *acl_to_text (acl_t __acl, ssize_t *__len_p);
|
||||
extern int acl_valid (acl_t __acl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _SYS_ACL_H */
|
||||
|
|
|
@ -13,7 +13,6 @@ details. */
|
|||
|
||||
#include "winsup.h"
|
||||
#include <stdlib.h>
|
||||
#include <sys/acl.h>
|
||||
#include <ctype.h>
|
||||
#include "cygerrno.h"
|
||||
#include "security.h"
|
||||
|
@ -23,6 +22,7 @@ details. */
|
|||
#include "cygheap.h"
|
||||
#include "ntdll.h"
|
||||
#include "tls_pbuf.h"
|
||||
#include "sec_posixacl.h"
|
||||
|
||||
/* How does a correctly constructed new-style Windows ACL claiming to be a
|
||||
POSIX ACL look like?
|
||||
|
@ -118,7 +118,8 @@ searchace (aclent_t *aclp, int nentries, int type, uid_t id)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < nentries; ++i)
|
||||
if ((aclp[i].a_type == type && (id == ILLEGAL_UID || aclp[i].a_id == id))
|
||||
if ((aclp[i].a_type == type
|
||||
&& (id == ACL_UNDEFINED_ID || aclp[i].a_id == id))
|
||||
|| !aclp[i].a_type)
|
||||
return i;
|
||||
return -1;
|
||||
|
@ -186,25 +187,25 @@ set_posix_access (mode_t attr, uid_t uid, gid_t gid,
|
|||
{
|
||||
aclbufp = (aclent_t *) tp.c_get ();
|
||||
aclbufp[0].a_type = USER_OBJ;
|
||||
aclbufp[0].a_id = ILLEGAL_UID;
|
||||
aclbufp[0].a_id = ACL_UNDEFINED_ID;
|
||||
aclbufp[0].a_perm = (attr >> 6) & S_IRWXO;
|
||||
aclbufp[1].a_type = GROUP_OBJ;
|
||||
aclbufp[1].a_id = ILLEGAL_GID;
|
||||
aclbufp[1].a_id = ACL_UNDEFINED_ID;
|
||||
aclbufp[1].a_perm = (attr >> 3) & S_IRWXO;
|
||||
aclbufp[2].a_type = OTHER_OBJ;
|
||||
aclbufp[2].a_id = ILLEGAL_GID;
|
||||
aclbufp[2].a_id = ACL_UNDEFINED_ID;
|
||||
aclbufp[2].a_perm = attr & S_IRWXO;
|
||||
nentries = MIN_ACL_ENTRIES;
|
||||
if (S_ISDIR (attr))
|
||||
{
|
||||
aclbufp[3].a_type = DEF_USER_OBJ;
|
||||
aclbufp[3].a_id = ILLEGAL_UID;
|
||||
aclbufp[3].a_id = ACL_UNDEFINED_ID;
|
||||
aclbufp[3].a_perm = (attr >> 6) & S_IRWXO;
|
||||
aclbufp[4].a_type = GROUP_OBJ;
|
||||
aclbufp[4].a_id = ILLEGAL_GID;
|
||||
aclbufp[4].a_id = ACL_UNDEFINED_ID;
|
||||
aclbufp[4].a_perm = (attr >> 3) & S_IRWXO;
|
||||
aclbufp[5].a_type = OTHER_OBJ;
|
||||
aclbufp[5].a_id = ILLEGAL_GID;
|
||||
aclbufp[5].a_id = ACL_UNDEFINED_ID;
|
||||
aclbufp[5].a_perm = attr & S_IRWXO;
|
||||
nentries += MIN_ACL_ENTRIES;
|
||||
}
|
||||
|
@ -618,19 +619,19 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
if (attr_ret)
|
||||
*attr_ret &= S_IFMT;
|
||||
if (uid_ret)
|
||||
*uid_ret = ILLEGAL_UID;
|
||||
*uid_ret = ACL_UNDEFINED_ID;
|
||||
if (gid_ret)
|
||||
*gid_ret = ILLEGAL_GID;
|
||||
*gid_ret = ACL_UNDEFINED_ID;
|
||||
if (aclbufp)
|
||||
{
|
||||
aclbufp[0].a_type = USER_OBJ;
|
||||
aclbufp[0].a_id = ILLEGAL_UID;
|
||||
aclbufp[0].a_id = ACL_UNDEFINED_ID;
|
||||
aclbufp[0].a_perm = 0;
|
||||
aclbufp[1].a_type = GROUP_OBJ;
|
||||
aclbufp[1].a_id = ILLEGAL_GID;
|
||||
aclbufp[1].a_id = ACL_UNDEFINED_ID;
|
||||
aclbufp[1].a_perm = 0;
|
||||
aclbufp[2].a_type = OTHER_OBJ;
|
||||
aclbufp[2].a_id = ILLEGAL_GID;
|
||||
aclbufp[2].a_id = ACL_UNDEFINED_ID;
|
||||
aclbufp[2].a_perm = 0;
|
||||
return MIN_ACL_ENTRIES;
|
||||
}
|
||||
|
@ -674,7 +675,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
lacl[1].a_type = GROUP_OBJ;
|
||||
lacl[1].a_id = gid;
|
||||
lacl[2].a_type = OTHER_OBJ;
|
||||
lacl[2].a_id = ILLEGAL_GID;
|
||||
lacl[2].a_id = ACL_UNDEFINED_ID;
|
||||
/* Create array to collect SIDs of all entries in lacl. */
|
||||
aclsid = (cygpsid *) tp.w_get ();
|
||||
aclsid[0] = owner_sid;
|
||||
|
@ -730,7 +731,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
>= 0)
|
||||
{
|
||||
lacl[pos].a_type = CLASS_OBJ;
|
||||
lacl[pos].a_id = ILLEGAL_GID;
|
||||
lacl[pos].a_id = ACL_UNDEFINED_ID;
|
||||
lacl[pos].a_perm = CYG_ACE_MASK_TO_POSIX (ace->Mask);
|
||||
aclsid[pos] = well_known_null_sid;
|
||||
}
|
||||
|
@ -743,7 +744,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
DEF_CLASS_OBJ)) >= 0)
|
||||
{
|
||||
lacl[pos].a_type = DEF_CLASS_OBJ;
|
||||
lacl[pos].a_id = ILLEGAL_GID;
|
||||
lacl[pos].a_id = ACL_UNDEFINED_ID;
|
||||
lacl[pos].a_perm = CYG_ACE_MASK_TO_POSIX (ace->Mask);
|
||||
aclsid[pos] = well_known_null_sid;
|
||||
}
|
||||
|
@ -767,7 +768,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
else if (ace_sid == well_known_world_sid)
|
||||
{
|
||||
type = OTHER_OBJ;
|
||||
id = ILLEGAL_GID;
|
||||
id = ACL_UNDEFINED_ID;
|
||||
if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE
|
||||
&& !(ace->Header.AceFlags & INHERIT_ONLY))
|
||||
saw_other_obj = true;
|
||||
|
@ -776,14 +777,14 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
{
|
||||
type = DEF_USER_OBJ;
|
||||
types_def |= type;
|
||||
id = ILLEGAL_GID;
|
||||
id = ACL_UNDEFINED_ID;
|
||||
saw_def_user_obj = true;
|
||||
}
|
||||
else if (ace_sid == well_known_creator_group_sid)
|
||||
{
|
||||
type = DEF_GROUP_OBJ;
|
||||
types_def |= type;
|
||||
id = ILLEGAL_GID;
|
||||
id = ACL_UNDEFINED_ID;
|
||||
saw_def_group_obj = true;
|
||||
}
|
||||
else
|
||||
|
@ -888,10 +889,10 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
{
|
||||
if (owner_eq_group && !saw_def_group_obj && attr & S_ISGID)
|
||||
{
|
||||
/* This needs post-processing in the following GROUP_OBJ
|
||||
handling... Set id to ILLEGAL_GID to play it safe. */
|
||||
/* Needs post-processing in the following GROUP_OBJ block.
|
||||
Set id to ACL_UNDEFINED_ID to play it safe. */
|
||||
type = GROUP_OBJ;
|
||||
id = ILLEGAL_GID;
|
||||
id = ACL_UNDEFINED_ID;
|
||||
}
|
||||
else
|
||||
type = USER;
|
||||
|
@ -944,7 +945,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
&& (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
|
||||
{
|
||||
lacl[pos].a_type = CLASS_OBJ;
|
||||
lacl[pos].a_id = ILLEGAL_GID;
|
||||
lacl[pos].a_id = ACL_UNDEFINED_ID;
|
||||
class_perm |= lacl[1].a_perm;
|
||||
lacl[pos].a_perm = class_perm;
|
||||
aclsid[pos] = well_known_null_sid;
|
||||
|
@ -960,7 +961,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
&& (pos = searchace (lacl, MAX_ACL_ENTRIES, CLASS_OBJ)) >= 0)
|
||||
{
|
||||
lacl[pos].a_type = CLASS_OBJ;
|
||||
lacl[pos].a_id = ILLEGAL_GID;
|
||||
lacl[pos].a_id = ACL_UNDEFINED_ID;
|
||||
lacl[pos].a_perm = lacl[1].a_perm; /* == group perms */
|
||||
aclsid[pos] = well_known_null_sid;
|
||||
}
|
||||
|
@ -1004,7 +1005,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
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_id = ACL_UNDEFINED_ID;
|
||||
lacl[pos].a_perm = lacl[2].a_perm;
|
||||
aclsid[pos] = well_known_world_sid;
|
||||
pos++;
|
||||
|
@ -1019,7 +1020,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||
&& (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
|
||||
{
|
||||
lacl[pos].a_type = DEF_CLASS_OBJ;
|
||||
lacl[pos].a_id = ILLEGAL_GID;
|
||||
lacl[pos].a_id = ACL_UNDEFINED_ID;
|
||||
lacl[pos].a_perm = def_class_perm;
|
||||
if (def_pgrp_pos >= 0)
|
||||
lacl[pos].a_perm |= lacl[def_pgrp_pos].a_perm;
|
||||
|
@ -1175,23 +1176,35 @@ facl32 (int fd, int cmd, int nentries, aclent_t *aclbufp)
|
|||
return res;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
aclcheck32 (aclent_t *aclbufp, int nentries, int *which)
|
||||
int
|
||||
__aclcheck (aclent_t *aclbufp, int nentries, int *which, bool posix)
|
||||
{
|
||||
bool has_user_obj = false;
|
||||
bool has_group_obj = false;
|
||||
bool has_other_obj = false;
|
||||
bool has_class_obj = false;
|
||||
bool has_ug_objs __attribute__ ((unused)) = false;
|
||||
bool has_def_objs __attribute__ ((unused)) = false;
|
||||
bool has_def_user_obj __attribute__ ((unused)) = false;
|
||||
bool has_ug_objs = false;
|
||||
bool has_def_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 __attribute__ ((unused)) = false;
|
||||
bool has_def_ug_objs = false;
|
||||
int pos2;
|
||||
|
||||
for (int pos = 0; pos < nentries; ++pos)
|
||||
{
|
||||
/* POSIX ACLs may contain deleted entries. Just ignore them. */
|
||||
if (posix && aclbufp[pos].a_type == ACL_DELETED_TAG)
|
||||
continue;
|
||||
/* POSIX defines two sorts of ACLs, access and default, none of which
|
||||
is supposed to have the ACL_DEFAULT flag set. */
|
||||
if (posix && (aclbufp[pos].a_type & ACL_DEFAULT))
|
||||
{
|
||||
if (which)
|
||||
*which = pos;
|
||||
return ENTRY_ERROR;
|
||||
}
|
||||
switch (aclbufp[pos].a_type)
|
||||
{
|
||||
case USER_OBJ:
|
||||
|
@ -1289,16 +1302,25 @@ aclcheck32 (aclent_t *aclbufp, int nentries, int *which)
|
|||
has_def_objs = has_def_ug_objs = true;
|
||||
break;
|
||||
default:
|
||||
if (which)
|
||||
*which = pos;
|
||||
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)
|
||||
)
|
||||
|| (has_ug_objs && !has_class_obj))
|
||||
{
|
||||
if (which)
|
||||
*which = -1;
|
||||
return MISS_ERROR;
|
||||
}
|
||||
/* Check for missing default entries only on Solaris ACLs. */
|
||||
if (!posix &&
|
||||
((has_def_objs
|
||||
&& !(has_def_user_obj && has_def_group_obj && has_def_other_obj))
|
||||
|| (has_def_ug_objs && !has_def_class_obj)))
|
||||
{
|
||||
if (which)
|
||||
*which = -1;
|
||||
|
@ -1307,22 +1329,44 @@ aclcheck32 (aclent_t *aclbufp, int nentries, int *which)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
extern "C" int
|
||||
aclcheck32 (aclent_t *aclbufp, int nentries, int *which)
|
||||
{
|
||||
return __aclcheck (aclbufp, nentries, which, false);
|
||||
}
|
||||
|
||||
/* For the sake of acl_calc_mask, return -1 if the ACL doesn't need a mask
|
||||
or if a mask entry already exists (__aclcalcmask sets the mask by itself).
|
||||
Otherwise return the mask value so acl_calc_mask can create a mask entry.
|
||||
This doesn't matter when called from aclsort. */
|
||||
mode_t
|
||||
__aclcalcmask (aclent_t *aclbufp, int nentries)
|
||||
{
|
||||
mode_t mask = 0;
|
||||
bool need_mask = false;
|
||||
int mask_idx = -1;
|
||||
|
||||
for (int idx = 0; idx < nentries; ++idx)
|
||||
switch (aclbufp[idx].a_type)
|
||||
{
|
||||
if (aclbufp[idx].a_type == CLASS_OBJ)
|
||||
mask_idx = idx;
|
||||
else if (aclbufp[idx].a_type
|
||||
& (USER | GROUP_OBJ | GROUP))
|
||||
case USER:
|
||||
case GROUP:
|
||||
need_mask = true;
|
||||
/*FALLTHRU*/
|
||||
case GROUP_OBJ:
|
||||
mask |= aclbufp[idx].a_perm;
|
||||
break;
|
||||
case CLASS_OBJ:
|
||||
mask_idx = idx;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (mask_idx != -1)
|
||||
aclbufp[mask_idx].a_perm = mask;
|
||||
if (need_mask && mask_idx == -1)
|
||||
return mask;
|
||||
return (acl_perm_t) -1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1336,15 +1380,25 @@ acecmp (const void *a1, const void *a2)
|
|||
#undef ace
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
aclsort32 (int nentries, int calclass, aclent_t *aclbufp)
|
||||
/* Sorts any acl. Called from sec_posixacl.cc. */
|
||||
int
|
||||
__aclsort (int nentries, aclent_t *aclbufp)
|
||||
{
|
||||
if (aclcheck32 (aclbufp, nentries, NULL))
|
||||
if (!aclbufp || nentries < 0)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (!aclbufp || nentries < 1)
|
||||
if (nentries > 0)
|
||||
qsort ((void *) aclbufp, nentries, sizeof (aclent_t), acecmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
aclsort32 (int nentries, int calclass, aclent_t *aclbufp)
|
||||
{
|
||||
if (!aclbufp || nentries < MIN_ACL_ENTRIES
|
||||
|| aclcheck32 (aclbufp, nentries, NULL))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
|
@ -1444,79 +1498,224 @@ aclfrompbits32 (aclent_t *aclbufp, int nentries, mode_t *pbitsp)
|
|||
}
|
||||
|
||||
static char *
|
||||
permtostr (mode_t perm)
|
||||
permtostr (char *bufp, mode_t perm)
|
||||
{
|
||||
static char pbuf[4];
|
||||
*bufp++ = (perm & S_IROTH) ? 'r' : '-';
|
||||
*bufp++ = (perm & S_IWOTH) ? 'w' : '-';
|
||||
*bufp++ = (perm & S_IXOTH) ? 'x' : '-';
|
||||
return bufp;
|
||||
}
|
||||
|
||||
pbuf[0] = (perm & S_IROTH) ? 'r' : '-';
|
||||
pbuf[1] = (perm & S_IWOTH) ? 'w' : '-';
|
||||
pbuf[2] = (perm & S_IXOTH) ? 'x' : '-';
|
||||
pbuf[3] = '\0';
|
||||
return pbuf;
|
||||
#define _OPT(o) (options & (o))
|
||||
|
||||
#define _CHK(l) \
|
||||
if (bufp + (l) >= buf + 2 * NT_MAX_PATH - 1) \
|
||||
{ \
|
||||
set_errno (ENOMEM); \
|
||||
return NULL; \
|
||||
}
|
||||
#define _CPY(s) ({ \
|
||||
const char *_s = (s); \
|
||||
_CHK (strlen (_s)); \
|
||||
bufp = stpcpy (bufp, _s); \
|
||||
})
|
||||
#define _PTS(p) { \
|
||||
_CHK (3); \
|
||||
bufp = permtostr (bufp, p); \
|
||||
}
|
||||
|
||||
#define _CMP(s) (!strncmp (bufp, acl_part[s].str, acl_part[s].len))
|
||||
|
||||
struct _acl_part
|
||||
{
|
||||
const char *str;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static _acl_part acl_part_l[] =
|
||||
{
|
||||
{ "default:", 8 },
|
||||
{ "user:", 5 },
|
||||
{ "group:", 6 },
|
||||
{ "mask:", 5 },
|
||||
{ "other:", 6 }
|
||||
};
|
||||
|
||||
static _acl_part acl_part_s[] =
|
||||
{
|
||||
{ "d:", 2 },
|
||||
{ "u:", 2 },
|
||||
{ "g:", 2 },
|
||||
{ "m:", 2 },
|
||||
{ "o:", 2 }
|
||||
};
|
||||
|
||||
enum _acl_type {
|
||||
default_s,
|
||||
user_s,
|
||||
group_s,
|
||||
mask_s,
|
||||
other_s,
|
||||
none_s
|
||||
};
|
||||
|
||||
char *
|
||||
__acltotext (aclent_t *aclbufp, int aclcnt, const char *prefix, char separator,
|
||||
int options)
|
||||
{
|
||||
if (!aclbufp || aclcnt < 1 || aclcnt > MAX_ACL_ENTRIES
|
||||
|| aclsort32 (aclcnt, 0, aclbufp))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
cyg_ldap cldap;
|
||||
tmp_pathbuf tp;
|
||||
char *buf = tp.t_get ();
|
||||
char *bufp = buf;
|
||||
char *entry_start;
|
||||
bool first = true;
|
||||
struct passwd *pw;
|
||||
struct group *gr;
|
||||
mode_t mask = S_IRWXO;
|
||||
mode_t def_mask = S_IRWXO;
|
||||
mode_t effective;
|
||||
int pos;
|
||||
_acl_part *acl_part = _OPT (TEXT_ABBREVIATE) ? acl_part_s : acl_part_l;
|
||||
|
||||
*bufp = '\0';
|
||||
/* If effective rights are requested, fetch mask values. */
|
||||
if (_OPT (TEXT_SOME_EFFECTIVE | TEXT_ALL_EFFECTIVE))
|
||||
{
|
||||
if ((pos = searchace (aclbufp, aclcnt, CLASS_OBJ)) >= 0)
|
||||
mask = aclbufp[pos].a_perm;
|
||||
if ((pos = searchace (aclbufp, aclcnt, DEF_CLASS_OBJ)) >= 0)
|
||||
def_mask = aclbufp[pos].a_perm;
|
||||
}
|
||||
for (pos = 0; pos < aclcnt; ++pos)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
_CHK (1);
|
||||
*bufp++ = separator;
|
||||
}
|
||||
first = false;
|
||||
/* Rememeber start position of entry to compute TEXT_SMART_INDENT tabs. */
|
||||
entry_start = bufp;
|
||||
/* prefix */
|
||||
if (prefix)
|
||||
_CPY (prefix);
|
||||
/* Solaris default acl? */
|
||||
if (!_OPT (TEXT_IS_POSIX) && aclbufp[pos].a_type & ACL_DEFAULT)
|
||||
_CPY (acl_part[default_s].str);
|
||||
/* acl type */
|
||||
switch (aclbufp[pos].a_type & ~ACL_DEFAULT)
|
||||
{
|
||||
case USER_OBJ:
|
||||
case USER:
|
||||
_CPY (acl_part[user_s].str);
|
||||
break;
|
||||
case GROUP_OBJ:
|
||||
case GROUP:
|
||||
_CPY (acl_part[group_s].str);
|
||||
break;
|
||||
case CLASS_OBJ:
|
||||
_CPY (acl_part[mask_s].str);
|
||||
break;
|
||||
case OTHER_OBJ:
|
||||
_CPY (acl_part[other_s].str);
|
||||
break;
|
||||
}
|
||||
/* id, if any */
|
||||
switch (aclbufp[pos].a_type & ~ACL_DEFAULT)
|
||||
{
|
||||
case USER:
|
||||
if (_OPT (TEXT_NUMERIC_IDS)
|
||||
|| !(pw = internal_getpwuid (aclbufp[pos].a_id, &cldap)))
|
||||
{
|
||||
_CHK (11);
|
||||
bufp += __small_sprintf (bufp, "%u:", aclbufp[pos].a_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
_CHK (strlen (pw->pw_name + 1));
|
||||
bufp += __small_sprintf (bufp, "%s:", pw->pw_name);
|
||||
}
|
||||
break;
|
||||
case GROUP:
|
||||
if (_OPT (TEXT_NUMERIC_IDS)
|
||||
|| !(gr = internal_getgrgid (aclbufp[pos].a_id, &cldap)))
|
||||
{
|
||||
_CHK (11);
|
||||
bufp += __small_sprintf (bufp, "%u:", aclbufp[pos].a_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
_CHK (strlen (gr->gr_name));
|
||||
bufp += __small_sprintf (bufp, "%s:", gr->gr_name);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_CPY (":");
|
||||
break;
|
||||
}
|
||||
/* real permissions */
|
||||
_PTS (aclbufp[pos].a_perm);
|
||||
if (!_OPT (TEXT_SOME_EFFECTIVE | TEXT_ALL_EFFECTIVE))
|
||||
continue;
|
||||
/* effective permissions */
|
||||
switch (aclbufp[pos].a_type)
|
||||
{
|
||||
case USER:
|
||||
case GROUP_OBJ:
|
||||
case GROUP:
|
||||
effective = aclbufp[pos].a_perm & mask;
|
||||
break;
|
||||
case DEF_USER:
|
||||
case DEF_GROUP_OBJ:
|
||||
case DEF_GROUP:
|
||||
effective = aclbufp[pos].a_perm & def_mask;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if (_OPT (TEXT_ALL_EFFECTIVE) || effective != aclbufp[pos].a_perm)
|
||||
{
|
||||
if (_OPT (TEXT_SMART_INDENT))
|
||||
{
|
||||
int tabs = 3 - (bufp - entry_start) / 8;
|
||||
if (tabs-- > 0)
|
||||
{
|
||||
_CHK (tabs);
|
||||
while (tabs-- > 0)
|
||||
*bufp++ = '\t';
|
||||
}
|
||||
}
|
||||
_CPY ("\t#effective:");
|
||||
_PTS (effective);
|
||||
}
|
||||
}
|
||||
if (_OPT (TEXT_END_SEPARATOR))
|
||||
{
|
||||
_CHK (1);
|
||||
*bufp++ = separator;
|
||||
*bufp++ = '\0';
|
||||
}
|
||||
return strdup (buf);
|
||||
}
|
||||
|
||||
extern "C" char *
|
||||
acltotext32 (aclent_t *aclbufp, int aclcnt)
|
||||
{
|
||||
if (!aclbufp || aclcnt < 1 || aclcnt > MAX_ACL_ENTRIES
|
||||
|| aclcheck32 (aclbufp, aclcnt, NULL))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
tmp_pathbuf tp;
|
||||
char *buf = tp.c_get ();
|
||||
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);
|
||||
return __acltotext (aclbufp, aclcnt, NULL, ',', 0);
|
||||
}
|
||||
|
||||
static mode_t
|
||||
permfromstr (char *perm)
|
||||
permfromstr (char *perm, bool posix_long)
|
||||
{
|
||||
mode_t mode = 0;
|
||||
int idx;
|
||||
|
||||
if (strlen (perm) != 3)
|
||||
return 01000;
|
||||
if (perm[0] == 'r')
|
||||
mode |= S_IROTH;
|
||||
else if (perm[0] != '-')
|
||||
|
@ -1529,117 +1728,155 @@ permfromstr (char *perm)
|
|||
mode |= S_IXOTH;
|
||||
else if (perm[2] != '-')
|
||||
return 01000;
|
||||
idx = 3;
|
||||
/* In posix long mode, only tabs up to a hash sign allowed. */
|
||||
if (posix_long)
|
||||
while (perm[idx] == '\t')
|
||||
++idx;
|
||||
if (perm[idx] == '\0' || (posix_long && perm[idx] == '#'))
|
||||
return mode;
|
||||
return 01000;
|
||||
}
|
||||
|
||||
extern "C" aclent_t *
|
||||
aclfromtext32 (const char *acltextp, int *aclcnt)
|
||||
void *
|
||||
__aclfromtext (const char *acltextp, int *aclcnt, bool posix)
|
||||
{
|
||||
if (!acltextp || strlen (acltextp) > NT_MAX_PATH)
|
||||
if (!acltextp || strlen (acltextp) >= 2 * NT_MAX_PATH)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
cyg_ldap cldap;
|
||||
tmp_pathbuf tp;
|
||||
aclent_t lacl[MAX_ACL_ENTRIES];
|
||||
memset (lacl, 0, sizeof lacl);
|
||||
const char *delim;
|
||||
_acl_part *acl_part;
|
||||
char *bufp, *lasts, *qualifier;
|
||||
int pos = 0;
|
||||
int acl_type;
|
||||
|
||||
aclent_t *lacl = (aclent_t *) tp.c_get ();
|
||||
memset (lacl, 0, MAX_ACL_ENTRIES * sizeof (aclent_t *));
|
||||
char *buf = tp.t_get ();
|
||||
stpcpy (buf, acltextp);
|
||||
char *lasts;
|
||||
cyg_ldap cldap;
|
||||
for (char *c = strtok_r (buf, ",", &lasts);
|
||||
c;
|
||||
c = strtok_r (NULL, ",", &lasts))
|
||||
|
||||
if (posix)
|
||||
{
|
||||
if (!strncmp (c, "default", 7))
|
||||
/* Posix long or short form. Any \n in the string means long form. */
|
||||
if (strchr (buf, '\n'))
|
||||
{
|
||||
delim = "\n";
|
||||
acl_part = acl_part_l;
|
||||
}
|
||||
else
|
||||
{
|
||||
delim = ",";
|
||||
acl_part = acl_part_s;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Solaris aclfromtext format. */
|
||||
delim = ",";
|
||||
acl_part = acl_part_l;
|
||||
}
|
||||
|
||||
for (bufp = strtok_r (buf, delim, &lasts);
|
||||
bufp;
|
||||
bufp = strtok_r (NULL, delim, &lasts))
|
||||
{
|
||||
/* Handle default acl entries only for Solaris ACLs. */
|
||||
if (!posix && _CMP (default_s))
|
||||
{
|
||||
lacl[pos].a_type |= ACL_DEFAULT;
|
||||
c += 7;
|
||||
bufp += acl_part[default_s].len;
|
||||
}
|
||||
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))
|
||||
{
|
||||
struct passwd *pw = internal_getpwnam (c, &cldap);
|
||||
if (!pw)
|
||||
lacl[pos].a_id = ACL_UNDEFINED_ID;
|
||||
for (acl_type = user_s; acl_type < none_s; ++acl_type)
|
||||
if (_CMP (acl_type))
|
||||
break;
|
||||
if (acl_type == none_s)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
bufp += acl_part[acl_type].len;
|
||||
switch (acl_type)
|
||||
{
|
||||
case user_s:
|
||||
case group_s:
|
||||
qualifier = bufp;
|
||||
bufp = strchrnul (bufp, ':');
|
||||
*bufp++ = '\0';
|
||||
/* No qualifier? USER_OBJ or GROUP_OBJ */
|
||||
if (!*qualifier)
|
||||
{
|
||||
lacl[pos].a_type |= (acl_type == user_s) ? USER_OBJ : GROUP_OBJ;
|
||||
break;
|
||||
}
|
||||
/* Some qualifier, USER or GROUP */
|
||||
lacl[pos].a_type |= (acl_type == user_s) ? USER : GROUP;
|
||||
if (isdigit (*qualifier))
|
||||
{
|
||||
char *ep;
|
||||
|
||||
id_t id = strtol (qualifier, &ep, 10);
|
||||
if (*ep == '\0')
|
||||
{
|
||||
lacl[pos].a_id = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (acl_type == user_s)
|
||||
{
|
||||
struct passwd *pw = internal_getpwnam (qualifier, &cldap);
|
||||
if (pw)
|
||||
lacl[pos].a_id = pw->pw_uid;
|
||||
c = strchrnul (c, ':');
|
||||
}
|
||||
else if (isdigit (*c))
|
||||
lacl[pos].a_id = strtol (c, &c, 10);
|
||||
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))
|
||||
{
|
||||
struct group *gr = internal_getgrnam (c, &cldap);
|
||||
if (!gr)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
struct group *gr = internal_getgrnam (qualifier, &cldap);
|
||||
if (gr)
|
||||
lacl[pos].a_id = gr->gr_gid;
|
||||
c = strchrnul (c, ':');
|
||||
}
|
||||
else if (isdigit (*c))
|
||||
lacl[pos].a_id = strtol (c, &c, 10);
|
||||
if (*c != ':')
|
||||
if (lacl[pos].a_id == ACL_UNDEFINED_ID)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strncmp (c, "mask:", 5))
|
||||
{
|
||||
if (c[5] == ':')
|
||||
lacl[pos].a_type |= CLASS_OBJ;
|
||||
else
|
||||
break;
|
||||
case mask_s:
|
||||
case other_s:
|
||||
if (*bufp++ != ':')
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
lacl[pos].a_type |= (acl_type == mask_s) ? CLASS_OBJ : OTHER_OBJ;
|
||||
break;
|
||||
}
|
||||
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)
|
||||
/* In posix long mode, the next char after the permissions may be a tab
|
||||
followed by effective permissions we can ignore here. */
|
||||
if ((lacl[pos].a_perm = permfromstr (bufp, *delim == '\n')) == 01000)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
if (posix)
|
||||
{
|
||||
acl_t acl = (acl_t) acl_init (pos);
|
||||
if (acl)
|
||||
{
|
||||
memcpy (acl->entry, lacl, pos * sizeof (aclent_t));
|
||||
acl->count = pos;
|
||||
if (aclcnt)
|
||||
*aclcnt = pos;
|
||||
}
|
||||
return (void *) acl;
|
||||
}
|
||||
else
|
||||
{
|
||||
aclent_t *aclp = (aclent_t *) malloc (pos * sizeof (aclent_t));
|
||||
if (aclp)
|
||||
{
|
||||
|
@ -1647,7 +1884,14 @@ aclfromtext32 (const char *acltextp, int *aclcnt)
|
|||
if (aclcnt)
|
||||
*aclcnt = pos;
|
||||
}
|
||||
return aclp;
|
||||
return (void *) aclp;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" aclent_t *
|
||||
aclfromtext32 (char *acltextp, int *aclcnt)
|
||||
{
|
||||
return (aclent_t *) __aclfromtext (acltextp, aclcnt, false);
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
|
|
@ -13,7 +13,7 @@ details. */
|
|||
|
||||
#include "winsup.h"
|
||||
#include <stdlib.h>
|
||||
#include <sys/acl.h>
|
||||
#include <cygwin/acl.h>
|
||||
#include <sys/queue.h>
|
||||
#include <authz.h>
|
||||
#include <wchar.h>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,68 @@
|
|||
/* sec_posixacl.h: Internal definitions for POSIX ACLs.
|
||||
|
||||
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 <cygwin/acl.h>
|
||||
#include <sys/acl.h>
|
||||
#include <acl/libacl.h>
|
||||
|
||||
/* Magic marker for acl_t. */
|
||||
#define ACL_MAGIC (0xacdccdcadcaccacdULL)
|
||||
|
||||
/* Only used internally as a_type for deleted entries. */
|
||||
#define ACL_DELETED_TAG (0xffff)
|
||||
|
||||
/* Only used internally from acl_to_text/acl_to_any_text. */
|
||||
#define TEXT_END_SEPARATOR (0x1000)
|
||||
#define TEXT_IS_POSIX (0x2000)
|
||||
|
||||
/* Internal ACL representation. */
|
||||
struct __acl_t
|
||||
{
|
||||
uint64_t magic; /* Must be ACL_MAGIC. */
|
||||
uint16_t max_count; /* Max. number of entries. */
|
||||
uint16_t count; /* Number of used entries. */
|
||||
uint16_t deleted; /* Number of used but deleted entries. */
|
||||
uint16_t next; /* Next entry to be returned by acl_get_entry. */
|
||||
aclent_t *entry; /* Pointer to variable array of ACL entries. */
|
||||
};
|
||||
|
||||
inline acl_entry_t
|
||||
__to_entry (acl_t acl, uint16_t idx)
|
||||
{
|
||||
return ((uint64_t) idx << 48) | (uint64_t) acl;
|
||||
}
|
||||
#define __to_permset(a,i) ((acl_permset_t)__to_entry((a),(i)))
|
||||
|
||||
inline acl_t
|
||||
__from_entry (acl_entry_t entry_d, uint16_t &idx)
|
||||
{
|
||||
idx = entry_d >> 48;
|
||||
acl_t acl = (acl_t) (entry_d & ~((uint64_t) 0xffff << 48));
|
||||
if (acl->magic != ACL_MAGIC)
|
||||
return NULL;
|
||||
if (idx >= acl->count)
|
||||
return NULL;
|
||||
if (acl->entry[idx].a_type == ACL_DELETED_TAG)
|
||||
return NULL;
|
||||
return acl;
|
||||
}
|
||||
#define __from_permset(p,i) __from_entry((acl_permset_t)(p),(i))
|
||||
|
||||
/* External (but opaque) ACL representation. */
|
||||
struct __acl_ext_t
|
||||
{
|
||||
uint16_t count; /* Number of used entries. */
|
||||
aclent_t entry[0]; /* Variable array of ACL entries. */
|
||||
};
|
||||
|
||||
/* Shared functions defined in sec_acl.cc. */
|
||||
mode_t __aclcalcmask (aclent_t *, int);
|
||||
int __aclsort (int, aclent_t *);
|
||||
int __aclcheck (aclent_t *, int, int *, bool);
|
||||
char *__acltotext (aclent_t *, int, const char *, char, int);
|
||||
void *__aclfromtext (const char *, int *, bool);
|
|
@ -15,7 +15,7 @@ details. */
|
|||
#include "winsup.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/acl.h>
|
||||
#include <cygwin/acl.h>
|
||||
#include "cygerrno.h"
|
||||
#include "security.h"
|
||||
#include "path.h"
|
||||
|
|
|
@ -15,8 +15,7 @@ details. */
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/acl.h>
|
||||
#include <cygwin/acl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cygwin/version.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -20,8 +20,7 @@ details. */
|
|||
#include <getopt.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/acl.h>
|
||||
#include <cygwin/acl.h>
|
||||
#include <cygwin/version.h>
|
||||
|
||||
#ifndef BOOL
|
||||
|
|
Loading…
Reference in New Issue