X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/1b897d50a93b82b4393778a2a8bcda62f85e17d5..25082d1ef6712a15c52a1dacb36b7f0642c23ac8:/lib/sysacls.c diff --git a/lib/sysacls.c b/lib/sysacls.c index 725d277e..19d4d7ad 100644 --- a/lib/sysacls.c +++ b/lib/sysacls.c @@ -1,29 +1,31 @@ -/* - Unix SMB/CIFS implementation. - Samba system utilities for ACL support. - Copyright (C) Jeremy Allison 2000. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ +/* + * Unix SMB/CIFS implementation. + * Based on the Samba ACL support code. + * Copyright (C) Jeremy Allison 2000. + * Copyright (C) 2007-2008 Wayne Davison + * + * The permission functions have been changed to get/set all bits via + * one call. Some functions that rsync doesn't need were also removed. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * with this program; if not, visit the http://fsf.org website. + */ #include "rsync.h" -#include "sysacls.h" /****** ADDED ******/ +#include "sysacls.h" #ifdef SUPPORT_ACLS -/****** EXTRAS -- THESE ITEMS ARE NOT FROM THE SAMBA SOURCE ******/ #ifdef DEBUG #undef DEBUG #endif @@ -35,19 +37,6 @@ void SAFE_FREE(void *mem) free(mem); } -char *uidtoname(uid_t uid) -{ - static char idbuf[12]; - struct passwd *pw; - - if ((pw = getpwuid(uid)) == NULL) { - slprintf(idbuf, sizeof(idbuf)-1, "%ld", (long)uid); - return idbuf; - } - return pw->pw_name; -} -/****** EXTRAS -- END ******/ - /* This file wraps all differing system ACL interfaces into a consistent one based on the POSIX interface. It also returns the correct errors @@ -57,43 +46,22 @@ char *uidtoname(uid_t uid) int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) - int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p - void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d) + int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p) SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type) SMB_ACL_T sys_acl_get_fd(int fd) - int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset); - int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); - char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen) SMB_ACL_T sys_acl_init( int count) int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) - int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) - int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual) - int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) + int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id) + int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits) int sys_acl_valid( SMB_ACL_T theacl ) int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) int sys_acl_set_fd( int fd, SMB_ACL_T theacl) int sys_acl_delete_def_file(const char *path) - - This next one is not POSIX complient - but we *have* to have it ! - More POSIX braindamage. - - int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) - - The generic POSIX free is the following call. We split this into - several different free functions as we may need to add tag info - to structures when emulating the POSIX interface. - - int sys_acl_free( void *obj_p) - - The calls we actually use are : - - int sys_acl_free_text(char *text) - free acl_to_text int sys_acl_free_acl(SMB_ACL_T posix_acl) - int sys_acl_free_qualifier(void *qualifier, SMB_ACL_TAG_T tagtype) */ -#if defined(HAVE_POSIX_ACLS) +#if defined(HAVE_POSIX_ACLS) /*--------------------------------------------*/ /* Identity mapping - easy. */ @@ -107,53 +75,43 @@ int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) return acl_get_tag_type( entry_d, tag_type_p); } -int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - return acl_get_permset( entry_d, permset_p); -} - -void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d) -{ - return acl_get_qualifier( entry_d); -} - SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type) { return acl_get_file( path_p, type); } +#if 0 SMB_ACL_T sys_acl_get_fd(int fd) { return acl_get_fd(fd); } +#endif -int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset) -{ - return acl_clear_perms(permset); -} - -int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return acl_add_perm(permset, perm); -} - -int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ #if defined(HAVE_ACL_GET_PERM_NP) - /* - * Required for TrustedBSD-based ACL implementations where - * non-POSIX.1e functions are denoted by a _np (non-portable) - * suffix. - */ - return acl_get_perm_np(permset, perm); -#else - return acl_get_perm(permset, perm); +#define acl_get_perm(p, b) acl_get_perm_np(p, b) #endif -} -char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen) +int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p) { - return acl_to_text( the_acl, plen); + acl_permset_t permset; + + if (acl_get_tag_type(entry, tag_type_p) != 0 + || acl_get_permset(entry, &permset) != 0) + return -1; + + *bits_p = (acl_get_perm(permset, ACL_READ) ? 4 : 0) + | (acl_get_perm(permset, ACL_WRITE) ? 2 : 0) + | (acl_get_perm(permset, ACL_EXECUTE) ? 1 : 0); + + if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP) { + void *qual; + if ((qual = acl_get_qualifier(entry)) == NULL) + return -1; + *u_g_id_p = *(id_t*)qual; + acl_free(qual); + } + + return 0; } SMB_ACL_T sys_acl_init( int count) @@ -166,18 +124,32 @@ int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) return acl_create_entry(pacl, pentry); } -int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) +int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id) { - return acl_set_tag_type(entry, tagtype); -} + if (acl_set_tag_type(entry, tag_type) != 0) + return -1; -int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual) -{ - return acl_set_qualifier(entry, qual); + if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP) { + if (acl_set_qualifier(entry, (void*)&u_g_id) != 0) + return -1; + } + + return sys_acl_set_access_bits(entry, bits); } -int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) +int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits) { + acl_permset_t permset; + int rc; + if ((rc = acl_get_permset(entry, &permset)) != 0) + return rc; + acl_clear_perms(permset); + if (bits & 4) + acl_add_perm(permset, ACL_READ); + if (bits & 2) + acl_add_perm(permset, ACL_WRITE); + if (bits & 1) + acl_add_perm(permset, ACL_EXECUTE); return acl_set_permset(entry, permset); } @@ -191,32 +163,24 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) return acl_set_file(name, acltype, theacl); } +#if 0 int sys_acl_set_fd( int fd, SMB_ACL_T theacl) { return acl_set_fd(fd, theacl); } +#endif int sys_acl_delete_def_file(const char *name) { return acl_delete_def_file(name); } -int sys_acl_free_text(char *text) -{ - return acl_free(text); -} - int sys_acl_free_acl(SMB_ACL_T the_acl) { return acl_free(the_acl); } -int sys_acl_free_qualifier(void *qual, UNUSED(SMB_ACL_TAG_T tagtype)) -{ - return acl_free(qual); -} - -#elif defined(HAVE_TRU64_ACLS) +#elif defined(HAVE_TRU64_ACLS) /*--------------------------------------------*/ /* * The interface to DEC/Compaq Tru64 UNIX ACLs * is based on Draft 13 of the POSIX spec which is @@ -249,53 +213,37 @@ int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) return acl_get_tag_type( entry_d, tag_type_p); } -int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - return acl_get_permset( entry_d, permset_p); -} - -void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d) -{ - return acl_get_qualifier( entry_d); -} - SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type) { return acl_get_file((char *)path_p, type); } +#if 0 SMB_ACL_T sys_acl_get_fd(int fd) { return acl_get_fd(fd, ACL_TYPE_ACCESS); } +#endif -int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset) +int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p) { - *permset = 0; /* acl_clear_perm() is broken on Tru64 */ + acl_permset_t permset; - return 0; -} - -int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - if (perm & ~(SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE)) { - errno = EINVAL; + if (acl_get_tag_type(entry, tag_type_p) != 0 + || acl_get_permset(entry, &permset) != 0) return -1; - } - *permset |= perm; /* acl_add_perm() is broken on Tru64 */ + *bits_p = *permset & 7; /* Tru64 doesn't have acl_get_perm() */ - return 0; -} - -int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return *permset & perm; /* Tru64 doesn't have acl_get_perm() */ -} + if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP) { + void *qual; + if ((qual = acl_get_qualifier(entry)) == NULL) + return -1; + *u_g_id_p = *(id_t*)qual; + acl_free_qualifier(qual, *tag_type_p); + } -char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen) -{ - return acl_to_text( the_acl, plen); + return 0; } SMB_ACL_T sys_acl_init( int count) @@ -315,18 +263,26 @@ int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) return 0; } -int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) +int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id) { - return acl_set_tag_type(entry, tagtype); -} + if (acl_set_tag_type(entry, tag_type) != 0) + return -1; -int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual) -{ - return acl_set_qualifier(entry, qual); + if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP) { + if (acl_set_qualifier(entry, (void*)&u_g_id) != 0) + return -1; + } + + return sys_acl_set_access_bits(entry, bits); } -int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) +int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits) { + acl_permset_t permset; + int rc; + if ((rc = acl_get_permset(entry, &permset)) != 0) + return rc; + *permset = bits & 7; return acl_set_permset(entry, permset); } @@ -342,37 +298,24 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl return acl_set_file((char *)name, acltype, theacl); } +#if 0 int sys_acl_set_fd( int fd, SMB_ACL_T theacl) { return acl_set_fd(fd, ACL_TYPE_ACCESS, theacl); } +#endif int sys_acl_delete_def_file(const char *name) { return acl_delete_def_file((char *)name); } -int sys_acl_free_text(char *text) -{ - /* - * (void) cast and explicit return 0 are for DEC UNIX - * which just #defines acl_free_text() to be free() - */ - (void) acl_free_text(text); - return 0; -} - int sys_acl_free_acl(SMB_ACL_T the_acl) { return acl_free(the_acl); } -int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype) -{ - return acl_free_qualifier(qual, tagtype); -} - -#elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS) +#elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS) /*-----------*/ /* * Donated by Michael Davidson for UnixWare / OpenUNIX. @@ -444,24 +387,6 @@ int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p) return 0; } -int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - *permset_p = &entry_d->a_perm; - - return 0; -} - -void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d) -{ - if (entry_d->a_type != SMB_ACL_USER - && entry_d->a_type != SMB_ACL_GROUP) { - errno = EINVAL; - return NULL; - } - - return &entry_d->a_id; -} - /* * There is no way of knowing what size the ACL returned by * GETACL will be unless you first call GETACLCNT which means @@ -554,6 +479,7 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type) return acl_d; } +#if 0 SMB_ACL_T sys_acl_get_fd(int fd) { SMB_ACL_T acl_d; @@ -596,144 +522,20 @@ SMB_ACL_T sys_acl_get_fd(int fd) return acl_d; } +#endif -int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d) -{ - *permset_d = 0; - - return 0; -} - -int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm) +int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p) { - if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE - && perm != SMB_ACL_EXECUTE) { - errno = EINVAL; - return -1; - } + *tag_type_p = entry->a_type; - if (permset_d == NULL) { - errno = EINVAL; - return -1; - } - - *permset_d |= perm; + *bits_p = entry->a_perm; + if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP) + *u_g_id_p = entry->a_id; + return 0; } -int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm) -{ - return *permset_d & perm; -} - -char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p) -{ - int i; - int len, maxlen; - char *text; - - /* - * use an initial estimate of 20 bytes per ACL entry - * when allocating memory for the text representation - * of the ACL - */ - len = 0; - maxlen = 20 * acl_d->count; - if ((text = SMB_MALLOC(maxlen)) == NULL) { - errno = ENOMEM; - return NULL; - } - - for (i = 0; i < acl_d->count; i++) { - struct acl *ap = &acl_d->acl[i]; - struct group *gr; - char tagbuf[12]; - char idbuf[12]; - char *tag; - char *id = ""; - char perms[4]; - int nbytes; - - switch (ap->a_type) { - /* - * for debugging purposes it's probably more - * useful to dump unknown tag types rather - * than just returning an error - */ - default: - slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x", - ap->a_type); - tag = tagbuf; - slprintf(idbuf, sizeof(idbuf)-1, "%ld", - (long)ap->a_id); - id = idbuf; - break; - - case SMB_ACL_USER: - id = uidtoname(ap->a_id); - case SMB_ACL_USER_OBJ: - tag = "user"; - break; - - case SMB_ACL_GROUP: - if ((gr = getgrgid(ap->a_id)) == NULL) { - slprintf(idbuf, sizeof(idbuf)-1, "%ld", - (long)ap->a_id); - id = idbuf; - } else { - id = gr->gr_name; - } - case SMB_ACL_GROUP_OBJ: - tag = "group"; - break; - - case SMB_ACL_OTHER: - tag = "other"; - break; - - case SMB_ACL_MASK: - tag = "mask"; - break; - - } - - perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-'; - perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-'; - perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-'; - perms[3] = '\0'; - - /* : : rwx \n \0 */ - nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1; - - /* - * If this entry would overflow the buffer - * allocate enough additional memory for this - * entry and an estimate of another 20 bytes - * for each entry still to be processed - */ - if ((len + nbytes) > maxlen) { - char *oldtext = text; - - maxlen += nbytes + 20 * (acl_d->count - i); - - if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) { - SAFE_FREE(oldtext); - errno = ENOMEM; - return NULL; - } - } - - slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms); - len += nbytes - 1; - } - - if (len_p) - *len_p = len; - - return text; -} - SMB_ACL_T sys_acl_init(int count) { SMB_ACL_T a; @@ -749,7 +551,7 @@ SMB_ACL_T sys_acl_init(int count) * acl[] array, this actually allocates an ACL with room * for (count+1) entries */ - if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) { + if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + count * sizeof (struct acl))) == NULL) { errno = ENOMEM; return NULL; } @@ -786,46 +588,21 @@ int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p) return 0; } -int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type) +int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id) { - switch (tag_type) { - case SMB_ACL_USER: - case SMB_ACL_USER_OBJ: - case SMB_ACL_GROUP: - case SMB_ACL_GROUP_OBJ: - case SMB_ACL_OTHER: - case SMB_ACL_MASK: - entry_d->a_type = tag_type; - break; - default: - errno = EINVAL; - return -1; - } - - return 0; -} + entry->a_type = tag_type; -int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p) -{ - if (entry_d->a_type != SMB_ACL_GROUP - && entry_d->a_type != SMB_ACL_USER) { - errno = EINVAL; - return -1; - } + if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP) + entry->a_id = u_g_id; - entry_d->a_id = *((id_t *)qual_p); + entry->a_perm = bits; return 0; } -int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d) +int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry_d, uint32 bits) { - if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) { - return EINVAL; - } - - entry_d->a_perm = *permset_d; - + entry_d->a_perm = bits; return 0; } @@ -951,6 +728,7 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) return ret; } +#if 0 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d) { if (acl_sort(acl_d) != 0) { @@ -959,6 +737,7 @@ int sys_acl_set_fd(int fd, SMB_ACL_T acl_d) return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]); } +#endif int sys_acl_delete_def_file(const char *path) { @@ -980,24 +759,14 @@ int sys_acl_delete_def_file(const char *path) return ret; } -int sys_acl_free_text(char *text) -{ - SAFE_FREE(text); - return 0; -} - int sys_acl_free_acl(SMB_ACL_T acl_d) { SAFE_FREE(acl_d); return 0; } -int sys_acl_free_qualifier(UNUSED(void *qual), UNUSED(SMB_ACL_TAG_T tagtype)) -{ - return 0; -} +#elif defined(HAVE_HPUX_ACLS) /*---------------------------------------------*/ -#elif defined(HAVE_HPUX_ACLS) #include /* @@ -1090,24 +859,6 @@ int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p) return 0; } -int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - *permset_p = &entry_d->a_perm; - - return 0; -} - -void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d) -{ - if (entry_d->a_type != SMB_ACL_USER - && entry_d->a_type != SMB_ACL_GROUP) { - errno = EINVAL; - return NULL; - } - - return &entry_d->a_id; -} - /* * There is no way of knowing what size the ACL returned by * ACL_GET will be unless you first call ACL_CNT which means @@ -1229,143 +980,18 @@ SMB_ACL_T sys_acl_get_fd(int fd) } #endif -int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d) +int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p) { - *permset_d = 0; + *tag_type_p = entry->a_type; - return 0; -} + *bits_p = entry->a_perm; -int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm) -{ - if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE - && perm != SMB_ACL_EXECUTE) { - errno = EINVAL; - return -1; - } - - if (permset_d == NULL) { - errno = EINVAL; - return -1; - } - - *permset_d |= perm; + if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP) + *u_g_id_p = entry->a_id; return 0; } -int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm) -{ - return *permset_d & perm; -} - -char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p) -{ - int i; - int len, maxlen; - char *text; - - /* - * use an initial estimate of 20 bytes per ACL entry - * when allocating memory for the text representation - * of the ACL - */ - len = 0; - maxlen = 20 * acl_d->count; - if ((text = SMB_MALLOC(maxlen)) == NULL) { - errno = ENOMEM; - return NULL; - } - - for (i = 0; i < acl_d->count; i++) { - struct acl *ap = &acl_d->acl[i]; - struct group *gr; - char tagbuf[12]; - char idbuf[12]; - char *tag; - char *id = ""; - char perms[4]; - int nbytes; - - switch (ap->a_type) { - /* - * for debugging purposes it's probably more - * useful to dump unknown tag types rather - * than just returning an error - */ - default: - slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x", - ap->a_type); - tag = tagbuf; - slprintf(idbuf, sizeof(idbuf)-1, "%ld", - (long)ap->a_id); - id = idbuf; - break; - - case SMB_ACL_USER: - id = uidtoname(ap->a_id); - case SMB_ACL_USER_OBJ: - tag = "user"; - break; - - case SMB_ACL_GROUP: - if ((gr = getgrgid(ap->a_id)) == NULL) { - slprintf(idbuf, sizeof(idbuf)-1, "%ld", - (long)ap->a_id); - id = idbuf; - } else { - id = gr->gr_name; - } - case SMB_ACL_GROUP_OBJ: - tag = "group"; - break; - - case SMB_ACL_OTHER: - tag = "other"; - break; - - case SMB_ACL_MASK: - tag = "mask"; - break; - - } - - perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-'; - perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-'; - perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-'; - perms[3] = '\0'; - - /* : : rwx \n \0 */ - nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1; - - /* - * If this entry would overflow the buffer - * allocate enough additional memory for this - * entry and an estimate of another 20 bytes - * for each entry still to be processed - */ - if ((len + nbytes) > maxlen) { - char *oldtext = text; - - maxlen += nbytes + 20 * (acl_d->count - i); - - if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) { - free(oldtext); - errno = ENOMEM; - return NULL; - } - } - - slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms); - len += nbytes - 1; - } - - if (len_p) - *len_p = len; - - return text; -} - SMB_ACL_T sys_acl_init(int count) { SMB_ACL_T a; @@ -1381,7 +1007,7 @@ SMB_ACL_T sys_acl_init(int count) * acl[] array, this actually allocates an ACL with room * for (count+1) entries */ - if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) { + if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + count * sizeof(struct acl))) == NULL) { errno = ENOMEM; return NULL; } @@ -1418,45 +1044,21 @@ int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p) return 0; } -int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type) +int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id) { - switch (tag_type) { - case SMB_ACL_USER: - case SMB_ACL_USER_OBJ: - case SMB_ACL_GROUP: - case SMB_ACL_GROUP_OBJ: - case SMB_ACL_OTHER: - case SMB_ACL_MASK: - entry_d->a_type = tag_type; - break; - default: - errno = EINVAL; - return -1; - } + entry->a_type = tag_type; - return 0; -} + if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP) + entry->a_id = u_g_id; -int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p) -{ - if (entry_d->a_type != SMB_ACL_GROUP - && entry_d->a_type != SMB_ACL_USER) { - errno = EINVAL; - return -1; - } - - entry_d->a_id = *((id_t *)qual_p); + entry->a_perm = bits; return 0; } -int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d) +int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry_d, uint32 bits) { - if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) { - return EINVAL; - } - - entry_d->a_perm = *permset_d; + entry_d->a_perm = bits; return 0; } @@ -1499,7 +1101,7 @@ struct hpux_acl_types { * acl types. */ -static int hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_types *acl_type_count) +static void hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_types *acl_type_count) { int i; @@ -1934,24 +1536,13 @@ int sys_acl_delete_def_file(const char *path) return ret; } -int sys_acl_free_text(char *text) -{ - free(text); - return 0; -} - int sys_acl_free_acl(SMB_ACL_T acl_d) { free(acl_d); return 0; } -int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype) -{ - return 0; -} - -#elif defined(HAVE_IRIX_ACLS) +#elif defined(HAVE_IRIX_ACLS) /*---------------------------------------------*/ int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p) { @@ -1990,24 +1581,6 @@ int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p) return 0; } -int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - *permset_p = entry_d; - - return 0; -} - -void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d) -{ - if (entry_d->ae_tag != SMB_ACL_USER - && entry_d->ae_tag != SMB_ACL_GROUP) { - errno = EINVAL; - return NULL; - } - - return &entry_d->ae_id; -} - SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type) { SMB_ACL_T a; @@ -2025,6 +1598,7 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type) return a; } +#if 0 SMB_ACL_T sys_acl_get_fd(int fd) { SMB_ACL_T a; @@ -2041,42 +1615,20 @@ SMB_ACL_T sys_acl_get_fd(int fd) a->freeaclp = True; return a; } +#endif -int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d) +int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p) { - permset_d->ae_perm = 0; + *tag_type_p = entry->ae_tag; - return 0; -} + *bits_p = entry->ae_perm; -int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm) -{ - if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE - && perm != SMB_ACL_EXECUTE) { - errno = EINVAL; - return -1; - } - - if (permset_d == NULL) { - errno = EINVAL; - return -1; - } - - permset_d->ae_perm |= perm; + if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP) + *u_g_id_p = entry->ae_id; return 0; } -int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm) -{ - return permset_d->ae_perm & perm; -} - -char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p) -{ - return acl_to_text(acl_d->aclp, len_p); -} - SMB_ACL_T sys_acl_init(int count) { SMB_ACL_T a; @@ -2086,14 +1638,14 @@ SMB_ACL_T sys_acl_init(int count) return NULL; } - if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + sizeof(struct acl))) == NULL) { + if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + sizeof (struct acl))) == NULL) { errno = ENOMEM; return NULL; } a->next = -1; a->freeaclp = False; - a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *)); + a->aclp = (struct acl *)((char *)a + sizeof a[0]); a->aclp->acl_cnt = 0; return a; @@ -2124,45 +1676,21 @@ int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p) return 0; } -int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type) +int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id) { - switch (tag_type) { - case SMB_ACL_USER: - case SMB_ACL_USER_OBJ: - case SMB_ACL_GROUP: - case SMB_ACL_GROUP_OBJ: - case SMB_ACL_OTHER: - case SMB_ACL_MASK: - entry_d->ae_tag = tag_type; - break; - default: - errno = EINVAL; - return -1; - } - - return 0; -} + entry->ae_tag = tag_type; -int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p) -{ - if (entry_d->ae_tag != SMB_ACL_GROUP - && entry_d->ae_tag != SMB_ACL_USER) { - errno = EINVAL; - return -1; - } + if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP) + entry->ae_id = u_g_id; - entry_d->ae_id = *((id_t *)qual_p); + entry->ae_perm = bits; return 0; } -int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d) +int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry_d, uint32 bits) { - if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) { - return EINVAL; - } - - entry_d->ae_perm = permset_d->ae_perm; + entry_d->ae_perm = bits; return 0; } @@ -2177,21 +1705,18 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) return acl_set_file(name, type, acl_d->aclp); } +#if 0 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d) { return acl_set_fd(fd, acl_d->aclp); } +#endif int sys_acl_delete_def_file(const char *name) { return acl_delete_def_file(name); } -int sys_acl_free_text(char *text) -{ - return acl_free(text); -} - int sys_acl_free_acl(SMB_ACL_T acl_d) { if (acl_d->freeaclp) { @@ -2201,12 +1726,7 @@ int sys_acl_free_acl(SMB_ACL_T acl_d) return 0; } -int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype) -{ - return 0; -} - -#elif defined(HAVE_AIX_ACLS) +#elif defined(HAVE_AIX_ACLS) /*----------------------------------------------*/ /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */ @@ -2216,6 +1736,13 @@ int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) struct new_acl_entry *entry; int keep_going; + if (entry_id == SMB_ACL_FIRST_ENTRY) + theacl->count = 0; + else if (entry_id != SMB_ACL_NEXT_ENTRY) { + errno = EINVAL; + return -1; + } + DEBUG(10,("This is the count: %d\n",theacl->count)); /* Check if count was previously set to -1. * @@ -2267,7 +1794,7 @@ int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) case SMB_ACL_OTHER: *tag_type_p = entry_d->ace_id->id_type; break; - + default: return(-1); } @@ -2275,26 +1802,6 @@ int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) return(0); } -int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) -{ - DEBUG(10,("Starting AIX sys_acl_get_permset\n")); - *permset_p = &entry_d->ace_access; - DEBUG(10,("**permset_p is %d\n",**permset_p)); - if(!(**permset_p & S_IXUSR) && - !(**permset_p & S_IWUSR) && - !(**permset_p & S_IRUSR) && - (**permset_p != 0)) - return(-1); - - DEBUG(10,("Ending AIX sys_acl_get_permset\n")); - return(0); -} - -void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d) -{ - return(entry_d->ace_id->id_data); -} - SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type) { struct acl *file_acl = (struct acl *)NULL; @@ -2305,11 +1812,14 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type) struct acl_entry_link *acl_entry_link_head; int i; int rc = 0; - uid_t user_id; /* AIX has no DEFAULT */ if ( type == SMB_ACL_TYPE_DEFAULT ) { +#ifdef ENOTSUP errno = ENOTSUP; +#else + errno = ENOSYS; +#endif return NULL; } @@ -2515,6 +2025,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type) return(acl_entry_link_head); } +#if 0 SMB_ACL_T sys_acl_get_fd(int fd) { struct acl *file_acl = (struct acl *)NULL; @@ -2525,7 +2036,6 @@ SMB_ACL_T sys_acl_get_fd(int fd) struct acl_entry_link *acl_entry_link_head; int i; int rc = 0; - uid_t user_id; /* Get the acl using fstatacl */ @@ -2729,33 +2239,37 @@ SMB_ACL_T sys_acl_get_fd(int fd) return(acl_entry_link_head); } +#endif -int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset) +int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p) { - *permset = *permset & ~0777; - return(0); -} + uint *permset; -int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - if((perm != 0) && - (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0) - return(-1); + if (sys_acl_get_tag_type(entry, tag_type_p) != 0) + return -1; - *permset |= perm; - DEBUG(10,("This is the permset now: %d\n",*permset)); - return(0); -} + if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP) + memcpy(u_g_id_p, entry->ace_id->id_data, sizeof (id_t)); -char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen) -{ - return(NULL); + permset = &entry->ace_access; + + DEBUG(10,("*permset is %d\n",*permset)); + *bits_p = (*permset & S_IRUSR ? 4 : 0) + | (*permset & S_IWUSR ? 2 : 0) + | (*permset & S_IXUSR ? 1 : 0); + + return 0; } SMB_ACL_T sys_acl_init( int count) { struct acl_entry_link *theacl = NULL; + if (count < 0) { + errno = EINVAL; + return NULL; + } + DEBUG(10,("Entering sys_acl_init\n")); theacl = SMB_MALLOC_P(struct acl_entry_link); @@ -2822,32 +2336,24 @@ int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) return(0); } -int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) +int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id) { - DEBUG(10,("Starting AIX sys_acl_set_tag_type\n")); - entry->ace_id->id_type = tagtype; + entry->ace_id->id_type = tag_type; DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type)); - DEBUG(10,("Ending AIX sys_acl_set_tag_type\n")); -} -int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual) -{ - DEBUG(10,("Starting AIX sys_acl_set_qualifier\n")); - memcpy(entry->ace_id->id_data,qual,sizeof(uid_t)); - DEBUG(10,("Ending AIX sys_acl_set_qualifier\n")); - return(0); + if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP) + memcpy(entry->ace_id->id_data, &u_g_id, sizeof (id_t)); + + entry->ace_access = bits; + DEBUG(10,("entry->ace_access = %d\n",entry->ace_access)); + + return 0; } -int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) +int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits) { DEBUG(10,("Starting AIX sys_acl_set_permset\n")); - if(!(*permset & S_IXUSR) && - !(*permset & S_IWUSR) && - !(*permset & S_IRUSR) && - (*permset != 0)) - return(-1); - - entry->ace_access = *permset; + entry->ace_access = bits; DEBUG(10,("entry->ace_access = %d\n",entry->ace_access)); DEBUG(10,("Ending AIX sys_acl_set_permset\n")); return(0); @@ -2882,7 +2388,6 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl struct acl_entry *acl_entry = NULL; struct ace_id *ace_id = NULL; uint id_type; - uint ace_access; uint user_id; uint acl_length; uint rc; @@ -2961,7 +2466,7 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t)); } - rc = chacl(name,file_acl,file_acl->acl_len); + rc = chacl((char*)name,file_acl,file_acl->acl_len); DEBUG(10,("errno is %d\n",errno)); DEBUG(10,("return code is %d\n",rc)); SAFE_FREE(file_acl); @@ -2969,6 +2474,7 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl return(rc); } +#if 0 int sys_acl_set_fd( int fd, SMB_ACL_T theacl) { struct acl_entry_link *acl_entry_link = NULL; @@ -3057,23 +2563,14 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl) DEBUG(10,("Exiting sys_acl_set_fd\n")); return(rc); } +#endif -int sys_acl_delete_def_file(const char *name) +int sys_acl_delete_def_file(UNUSED(const char *name)) { /* AIX has no default ACL */ return 0; } -int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - return(*permset & perm); -} - -int sys_acl_free_text(char *text) -{ - return(0); -} - int sys_acl_free_acl(SMB_ACL_T posix_acl) { struct acl_entry_link *acl_entry_link; @@ -3091,146 +2588,177 @@ int sys_acl_free_acl(SMB_ACL_T posix_acl) return(0); } -int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype) -{ - return(0); -} +#elif defined(HAVE_OSX_ACLS) /*----------------------------------------------*/ -#else /* No ACLs. */ +#define OSX_BROKEN_GETENTRY /* returns 0 instead of 1 */ -int sys_acl_get_entry(UNUSED(SMB_ACL_T the_acl), UNUSED(int entry_id), UNUSED(SMB_ACL_ENTRY_T *entry_p)) -{ - errno = ENOSYS; - return -1; -} +#include -int sys_acl_get_tag_type(UNUSED(SMB_ACL_ENTRY_T entry_d), UNUSED(SMB_ACL_TAG_T *tag_type_p)) +int sys_acl_get_entry(SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p) { - errno = ENOSYS; - return -1; + int ret = acl_get_entry(the_acl, entry_id, entry_p); +#ifdef OSX_BROKEN_GETENTRY + if (ret == 0) + ret = 1; + else if (ret == -1 && errno == 22) + ret = 0; +#endif + return ret; } -int sys_acl_get_permset(UNUSED(SMB_ACL_ENTRY_T entry_d), UNUSED(SMB_ACL_PERMSET_T *permset_p)) +SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type) { - errno = ENOSYS; - return -1; + if (type == ACL_TYPE_DEFAULT) { + errno = ENOTSUP; + return NULL; + } + errno = 0; + return acl_get_file(path_p, type); } -void *sys_acl_get_qualifier(UNUSED(SMB_ACL_ENTRY_T entry_d)) +#if 0 +SMB_ACL_T sys_acl_get_fd(int fd) { - errno = ENOSYS; - return NULL; + return acl_get_fd(fd); } +#endif -SMB_ACL_T sys_acl_get_file(UNUSED(const char *path_p), UNUSED(SMB_ACL_TYPE_T type)) +int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p) { - errno = ENOSYS; - return (SMB_ACL_T)NULL; -} + uuid_t *uup; + acl_tag_t tag; + acl_flagset_t flagset; + acl_permset_t permset; + uint32 bits, fb, bb, pb; + int id_type = -1; + int rc; -SMB_ACL_T sys_acl_get_fd(UNUSED(int fd)) -{ - errno = ENOSYS; - return (SMB_ACL_T)NULL; -} + if (acl_get_tag_type(entry, &tag) != 0 + || acl_get_flagset_np(entry, &flagset) != 0 + || acl_get_permset(entry, &permset) != 0 + || (uup = acl_get_qualifier(entry)) == NULL) + return -1; -int sys_acl_clear_perms(UNUSED(SMB_ACL_PERMSET_T permset)) -{ - errno = ENOSYS; - return -1; -} + rc = mbr_uuid_to_id(*uup, u_g_id_p, &id_type); + acl_free(uup); + if (rc != 0) + return rc; -int sys_acl_add_perm( UNUSED(SMB_ACL_PERMSET_T permset), UNUSED(SMB_ACL_PERM_T perm)) -{ - errno = ENOSYS; - return -1; -} + if (id_type == ID_TYPE_UID) + *tag_type_p = SMB_ACL_USER; + else + *tag_type_p = SMB_ACL_GROUP; -int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) -{ - errno = ENOSYS; - return (permset & perm) ? 1 : 0; -} + bits = tag == ACL_EXTENDED_ALLOW ? 1 : 0; -char *sys_acl_to_text(UNUSED(SMB_ACL_T the_acl), UNUSED(ssize_t *plen)) -{ - errno = ENOSYS; - return NULL; -} + for (fb = (1u<<4), bb = (1u<<1); bb < (1u<<12); fb *= 2, bb *= 2) { + if (acl_get_flag_np(flagset, fb) == 1) + bits |= bb; + } -int sys_acl_free_text(UNUSED(char *text)) -{ - errno = ENOSYS; - return -1; -} + for (pb = (1u<<1), bb = (1u<<12); bb < (1u<<25); pb *= 2, bb *= 2) { + if (acl_get_perm_np(permset, pb) == 1) + bits |= bb; + } -SMB_ACL_T sys_acl_init(UNUSED(int count)) -{ - errno = ENOSYS; - return NULL; -} + *bits_p = bits; -int sys_acl_create_entry(UNUSED(SMB_ACL_T *pacl), UNUSED(SMB_ACL_ENTRY_T *pentry)) -{ - errno = ENOSYS; - return -1; + return 0; } -int sys_acl_set_tag_type(UNUSED(SMB_ACL_ENTRY_T entry), UNUSED(SMB_ACL_TAG_T tagtype)) +SMB_ACL_T sys_acl_init(int count) { - errno = ENOSYS; - return -1; + return acl_init(count); } -int sys_acl_set_qualifier(UNUSED(SMB_ACL_ENTRY_T entry), UNUSED(void *qual)) +int sys_acl_create_entry(SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) { - errno = ENOSYS; - return -1; + return acl_create_entry(pacl, pentry); } -int sys_acl_set_permset(UNUSED(SMB_ACL_ENTRY_T entry), UNUSED(SMB_ACL_PERMSET_T permset)) +int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id) { - errno = ENOSYS; - return -1; + acl_flagset_t flagset; + acl_permset_t permset; + uint32 fb, bb, pb; + int is_user = tag_type == SMB_ACL_USER; + uuid_t uu; + int rc; + + tag_type = bits & 1 ? ACL_EXTENDED_ALLOW : ACL_EXTENDED_DENY; + + if (acl_get_flagset_np(entry, &flagset) != 0 + || acl_get_permset(entry, &permset) != 0) + return -1; + + acl_clear_flags_np(flagset); + acl_clear_perms(permset); + + for (fb = (1u<<4), bb = (1u<<1); bb < (1u<<12); fb *= 2, bb *= 2) { + if (bits & bb) + acl_add_flag_np(flagset, fb); + } + + for (pb = (1u<<1), bb = (1u<<12); bb < (1u<<25); pb *= 2, bb *= 2) { + if (bits & bb) + acl_add_perm(permset, pb); + } + + if (is_user) + rc = mbr_uid_to_uuid(u_g_id, uu); + else + rc = mbr_gid_to_uuid(u_g_id, uu); + if (rc != 0) + return rc; + + if (acl_set_tag_type(entry, tag_type) != 0 + || acl_set_qualifier(entry, &uu) != 0 + || acl_set_permset(entry, permset) != 0 + || acl_set_flagset_np(entry, flagset) != 0) + return -1; + + return 0; } -int sys_acl_valid(UNUSED(SMB_ACL_T theacl)) +#if 0 +int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits) { - errno = ENOSYS; - return -1; + return -1; /* Not needed for OS X. */ } +#endif -int sys_acl_set_file(UNUSED(const char *name), UNUSED(SMB_ACL_TYPE_T acltype), UNUSED(SMB_ACL_T theacl)) +int sys_acl_valid(SMB_ACL_T theacl) { - errno = ENOSYS; - return -1; + return acl_valid(theacl); } -int sys_acl_set_fd(UNUSED(int fd), UNUSED(SMB_ACL_T theacl)) +int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) { - errno = ENOSYS; - return -1; + return acl_set_file(name, acltype, theacl); } -int sys_acl_delete_def_file(UNUSED(const char *name)) +#if 0 +int sys_acl_set_fd(int fd, SMB_ACL_T theacl) { - errno = ENOSYS; - return -1; + return acl_set_fd(fd, theacl); } +#endif -int sys_acl_free_acl(UNUSED(SMB_ACL_T the_acl)) +int sys_acl_delete_def_file(const char *name) { - errno = ENOSYS; - return -1; + return acl_delete_def_file(name); } -int sys_acl_free_qualifier(UNUSED(void *qual), UNUSED(SMB_ACL_TAG_T tagtype)) +int sys_acl_free_acl(SMB_ACL_T the_acl) { - errno = ENOSYS; - return -1; + return acl_free(the_acl); } -#endif /* No ACLs. */ +#else /* No ACLs. */ + +#error No ACL functions defined for this platform! + +#endif /************************************************************************ Deliberately outside the ACL defines. Return 1 if this is a "no acls" @@ -3239,6 +2767,10 @@ int sys_acl_free_qualifier(UNUSED(void *qual), UNUSED(SMB_ACL_TAG_T tagtype)) int no_acl_syscall_error(int err) { +#ifdef HAVE_OSX_ACLS + if (err == ENOENT) + return 1; /* Weird problem with directory ACLs. */ +#endif #if defined(ENOSYS) if (err == ENOSYS) { return 1;