2 Unix SMB/Netbios implementation.
4 Samba system utilities for ACL support.
5 Copyright (C) Jeremy Allison 2000.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern int DEBUGLEVEL;
27 This file wraps all differing system ACL interfaces into a consistent
28 one based on the POSIX interface. It also returns the correct errors
29 for older UNIX systems that don't support ACLs.
31 The interfaces that each ACL implementation must support are as follows :
33 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
34 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
35 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p
36 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
37 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
38 SMB_ACL_T sys_acl_get_fd(int fd)
39 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
40 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
41 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
42 SMB_ACL_T sys_acl_init( int count)
43 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
44 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
45 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
46 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
47 int sys_acl_valid( SMB_ACL_T theacl )
48 int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
49 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
51 This next one is not POSIX complient - but we *have* to have it !
52 More POSIX braindamage.
54 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
56 The generic POSIX free is the following call. We split this into
57 several different free functions as we may need to add tag info
58 to structures when emulating the POSIX interface.
60 int sys_acl_free( void *obj_p)
62 The calls we actually use are :
64 int sys_acl_free_text(char *text) - free acl_to_text
65 int sys_acl_free_acl(SMB_ACL_T posix_acl)
69 #if defined(HAVE_POSIX_ACLS)
71 /* Identity mapping - easy. */
73 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
75 return acl_get_entry( the_acl, entry_id, entry_p);
78 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
80 return acl_get_tag_type( entry_d, tag_type_p);
83 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
85 return acl_get_permset( entry_d, permset_p);
88 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
90 return acl_get_qualifier( entry_d);
93 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
95 return acl_get_file( path_p, type);
98 SMB_ACL_T sys_acl_get_fd(int fd)
100 return acl_get_fd(fd);
103 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
105 return acl_clear_perms(permset);
108 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
110 return acl_add_perm(permset, perm);
113 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
115 return acl_get_perm(permset, perm);
118 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
120 return acl_to_text( the_acl, plen);
123 SMB_ACL_T sys_acl_init( int count)
125 return acl_init(count);
128 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
130 return acl_create_entry(pacl, pentry);
133 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
135 return acl_set_tag_type(entry, tagtype);
138 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
140 return acl_set_qualifier(entry, qual);
143 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
145 return acl_set_permset(entry, permset);
148 int sys_acl_valid( SMB_ACL_T theacl )
150 return acl_valid(theacl);
153 int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
155 return acl_set_file(name, acltype, theacl);
158 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
160 return acl_set_fd(fd, theacl);
163 int sys_acl_free_text(char *text)
165 return acl_free(text);
168 int sys_acl_free_acl(SMB_ACL_T the_acl)
170 return acl_free(the_acl);
173 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
176 * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
177 * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
181 * Note that while this code implements sufficient functionality
182 * to support the sys_acl_* interfaces it does not provide all
183 * of the semantics of the POSIX ACL interfaces.
185 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
186 * from a call to sys_acl_get_entry() should not be assumed to be
187 * valid after calling any of the following functions, which may
188 * reorder the entries in the ACL.
196 * The only difference between Solaris and UnixWare / OpenUNIX is
197 * that the #defines for the ACL operations have different names
199 #if defined(HAVE_UNIXWARE_ACLS)
201 #define SETACL ACL_SET
202 #define GETACL ACL_GET
203 #define GETACLCNT ACL_CNT
208 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
210 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
215 if (entry_p == NULL) {
220 if (entry_id == SMB_ACL_FIRST_ENTRY) {
224 if (acl_d->next < 0) {
229 if (acl_d->next >= acl_d->count) {
233 *entry_p = &acl_d->acl[acl_d->next++];
238 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
240 *type_p = entry_d->a_type;
245 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
247 *permset_p = &entry_d->a_perm;
252 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
254 if (entry_d->a_type != SMB_ACL_USER
255 && entry_d->a_type != SMB_ACL_GROUP) {
260 return &entry_d->a_id;
264 * There is no way of knowing what size the ACL returned by
265 * GETACL will be unless you first call GETACLCNT which means
266 * making an additional system call.
268 * In the hope of avoiding the cost of the additional system
269 * call in most cases, we initially allocate enough space for
270 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
271 * be too small then we use GETACLCNT to find out the actual
272 * size, reallocate the ACL buffer, and then call GETACL again.
275 #define INITIAL_ACL_SIZE 16
277 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
280 int count; /* # of ACL entries allocated */
281 int naccess; /* # of access ACL entries */
282 int ndefault; /* # of default ACL entries */
284 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
289 count = INITIAL_ACL_SIZE;
290 if ((acl_d = sys_acl_init(count)) == NULL) {
295 * If there isn't enough space for the ACL entries we use
296 * GETACLCNT to determine the actual number of ACL entries
297 * reallocate and try again. This is in a loop because it
298 * is possible that someone else could modify the ACL and
299 * increase the number of entries between the call to
300 * GETACLCNT and the call to GETACL.
302 while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0
303 && errno == ENOSPC) {
305 sys_acl_free_acl(acl_d);
307 if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) {
311 if ((acl_d = sys_acl_init(count)) == NULL) {
317 sys_acl_free_acl(acl_d);
322 * calculate the number of access and default ACL entries
324 * Note: we assume that the acl() system call returned a
325 * well formed ACL which is sorted so that all of the
326 * access ACL entries preceed any default ACL entries
328 for (naccess = 0; naccess < count; naccess++) {
329 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
332 ndefault = count - naccess;
335 * if the caller wants the default ACL we have to copy
336 * the entries down to the start of the acl[] buffer
337 * and mask out the ACL_DEFAULT flag from the type field
339 if (type == SMB_ACL_TYPE_DEFAULT) {
342 for (i = 0, j = naccess; i < ndefault; i++, j++) {
343 acl_d->acl[i] = acl_d->acl[j];
344 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
347 acl_d->count = ndefault;
349 acl_d->count = naccess;
355 SMB_ACL_T sys_acl_get_fd(int fd)
358 int count; /* # of ACL entries allocated */
359 int naccess; /* # of access ACL entries */
361 count = INITIAL_ACL_SIZE;
362 if ((acl_d = sys_acl_init(count)) == NULL) {
366 while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0
367 && errno == ENOSPC) {
369 sys_acl_free_acl(acl_d);
371 if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) {
375 if ((acl_d = sys_acl_init(count)) == NULL) {
381 sys_acl_free_acl(acl_d);
386 * calculate the number of access ACL entries
388 for (naccess = 0; naccess < count; naccess++) {
389 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
393 acl_d->count = naccess;
398 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
405 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
407 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
408 && perm != SMB_ACL_EXECUTE) {
413 if (permset_d == NULL) {
423 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
425 return *permset_d & perm;
428 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
435 * use an initial estimate of 20 bytes per ACL entry
436 * when allocating memory for the text representation
440 maxlen = 20 * acl_d->count;
441 if ((text = malloc(maxlen)) == NULL) {
446 for (i = 0; i < acl_d->count; i++) {
447 struct acl *ap = &acl_d->acl[i];
457 switch (ap->a_type) {
459 * for debugging purposes it's probably more
460 * useful to dump unknown tag types rather
461 * than just returning an error
464 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
467 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
473 if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
474 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
480 case SMB_ACL_USER_OBJ:
485 if ((gr = getgrgid(ap->a_id)) == NULL) {
486 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
492 case SMB_ACL_GROUP_OBJ:
506 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
507 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
508 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
511 /* <tag> : <qualifier> : rwx \n \0 */
512 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
515 * If this entry would overflow the buffer
516 * allocate enough additional memory for this
517 * entry and an estimate of another 20 bytes
518 * for each entry still to be processed
520 if ((len + nbytes) > maxlen) {
521 char *oldtext = text;
523 maxlen += nbytes + 20 * (acl_d->count - i);
525 if ((text = realloc(oldtext, maxlen)) == NULL) {
532 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
542 SMB_ACL_T sys_acl_init(int count)
552 * note that since the definition of the structure pointed
553 * to by the SMB_ACL_T includes the first element of the
554 * acl[] array, this actually allocates an ACL with room
555 * for (count+1) entries
557 if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
570 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
573 SMB_ACL_ENTRY_T entry_d;
575 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
580 if (acl_d->count >= acl_d->size) {
585 entry_d = &acl_d->acl[acl_d->count++];
594 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
598 case SMB_ACL_USER_OBJ:
600 case SMB_ACL_GROUP_OBJ:
603 entry_d->a_type = tag_type;
613 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
615 if (entry_d->a_type != SMB_ACL_GROUP
616 && entry_d->a_type != SMB_ACL_USER) {
621 entry_d->a_id = *((id_t *)qual_p);
626 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
628 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
632 entry_d->a_perm = *permset_d;
637 int sys_acl_valid(SMB_ACL_T acl_d)
639 if (aclsort(acl_d->count, 0, acl_d->acl) != 0) {
647 int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
652 struct acl *acl_buf = NULL;
655 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
660 if (stat(name, &s) != 0) {
664 acl_p = &acl_d->acl[0];
665 acl_count = acl_d->count;
668 * if it's a directory there is extra work to do
669 * since the acl() system call will replace both
670 * the access ACLs and the default ACLs (if any)
672 if (S_ISDIR(s.st_mode)) {
678 if (type == SMB_ACL_TYPE_ACCESS) {
681 tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
686 tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
689 if (tmp_acl == NULL) {
694 * allocate a temporary buffer for the complete ACL
696 acl_count = acc_acl->count + def_acl->count;
698 acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
700 if (acl_buf == NULL) {
701 sys_acl_free_acl(tmp_acl);
707 * copy the access control and default entries into the buffer
709 memcpy(&acl_buf[0], &acc_acl->acl[0],
710 acc_acl->count * sizeof(acl_buf[0]));
712 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
713 def_acl->count * sizeof(acl_buf[0]));
716 * set the ACL_DEFAULT flag on the default entries
718 for (i = acc_acl->count; i < acl_count; i++) {
719 acl_buf[i].a_type |= ACL_DEFAULT;
722 sys_acl_free_acl(tmp_acl);
724 } else if (type != SMB_ACL_TYPE_ACCESS) {
729 if (aclsort(acl_count, 0, acl_p) != 0) {
733 ret = acl(name, SETACL, acl_count, acl_p);
743 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
745 if (aclsort(acl_d->count, 0, acl_d->acl) != 0) {
750 return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
753 int sys_acl_free_text(char *text)
759 int sys_acl_free_acl(SMB_ACL_T acl_d)
765 #elif defined(HAVE_IRIX_ACLS)
767 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
769 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
774 if (entry_p == NULL) {
779 if (entry_id == SMB_ACL_FIRST_ENTRY) {
783 if (acl_d->next < 0) {
788 if (acl_d->next >= acl_d->aclp->acl_cnt) {
792 *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
797 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
799 *type_p = entry_d->ae_tag;
804 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
806 *permset_p = entry_d;
811 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
813 if (entry_d->ae_tag != SMB_ACL_USER
814 && entry_d->ae_tag != SMB_ACL_GROUP) {
819 return &entry_d->ae_id;
822 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
826 if ((a = malloc(sizeof(*a))) == NULL) {
830 if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
839 SMB_ACL_T sys_acl_get_fd(int fd)
843 if ((a = malloc(sizeof(*a))) == NULL) {
847 if ((a->aclp = acl_get_fd(fd)) == NULL) {
856 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
858 permset_d->ae_perm = 0;
863 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
865 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
866 && perm != SMB_ACL_EXECUTE) {
871 if (permset_d == NULL) {
876 permset_d->ae_perm |= perm;
881 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
883 return permset_d->ae_perm & perm;
886 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
888 return acl_to_text(acl_d->aclp, len_p);
891 SMB_ACL_T sys_acl_init(int count)
900 if ((a = malloc(sizeof(*a) + sizeof(struct acl))) == NULL) {
907 a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
908 a->aclp->acl_cnt = 0;
914 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
917 SMB_ACL_ENTRY_T entry_d;
919 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
924 if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
929 entry_d = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
932 entry_d->ae_perm = 0;
938 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
942 case SMB_ACL_USER_OBJ:
944 case SMB_ACL_GROUP_OBJ:
947 entry_d->ae_tag = tag_type;
957 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
959 if (entry_d->ae_tag != SMB_ACL_GROUP
960 && entry_d->ae_tag != SMB_ACL_USER) {
965 entry_d->ae_id = *((id_t *)qual_p);
970 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
972 if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
976 entry_d->ae_perm = permset_d->ae_perm;
981 int sys_acl_valid(SMB_ACL_T acl_d)
983 return acl_valid(acl_d->aclp);
986 int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
988 return acl_set_file(name, type, acl_d->aclp);
991 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
993 return acl_set_fd(fd, acl_d->aclp);
996 int sys_acl_free_text(char *text)
998 return acl_free(text);
1001 int sys_acl_free_acl(SMB_ACL_T acl_d)
1003 if (acl_d->freeaclp) {
1004 acl_free(acl_d->aclp);
1010 #elif defined(HAVE_XFS_ACLS)
1011 /* For Linux SGI/XFS Filesystems
1012 * contributed by J Trostel, Connex
1015 /* based on the implementation for Solaris by Toomas Soome.. which is
1016 * based on the implementation by Micheal Davidson for Unixware...
1018 * Linux XFS is a 'work-in-progress'
1019 * This interface may change...
1020 * You've been warned ;-> */
1022 /* First, do the identity mapping */
1024 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1026 if( acl_get_entry( the_acl, entry_id, entry_p) >= 0) {
1034 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1036 return acl_get_file( path_p, type);
1039 SMB_ACL_T sys_acl_get_fd(int fd)
1041 return acl_get_fd(fd);
1044 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
1046 return acl_to_text( the_acl, plen);
1049 int sys_acl_valid( SMB_ACL_T theacl )
1051 return acl_valid(theacl);
1054 int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1056 return acl_set_file(name, acltype, theacl);
1059 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
1061 return acl_set_fd(fd, theacl);
1064 /* Now the functions I need to define for XFS */
1066 int sys_acl_create_entry( SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1075 if((*acl_p == NULL) || (ace == NULL)){
1081 if( (cnt + 1) > ACL_MAX_ENTRIES ){
1086 newacl = (acl_t)malloc(sizeof(struct acl));
1093 newacl->acl_entry[cnt] = *ace;
1094 newacl->acl_cnt = cnt + 1;
1098 *entry_p = &newacl->acl_entry[cnt];
1103 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1105 *tag_type_p = entry_d->ae_tag;
1109 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1111 *permset_p = &entry_d->ae_perm;
1115 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1117 if (entry_d->ae_tag != SMB_ACL_USER
1118 && entry_d->ae_tag != SMB_ACL_GROUP) {
1122 return &entry_d->ae_id;
1125 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
1131 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1133 return (*permset & perm);
1136 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1139 // TO DO: Add in ALL possible permissions here
1140 // TO DO: Include extended ones!!
1142 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE && perm != SMB_ACL_EXECUTE) {
1147 if(permset == NULL) {
1157 SMB_ACL_T sys_acl_init( int count)
1160 if((count > ACL_MAX_ENTRIES) || (count < 0)) {
1165 a = (struct acl *)malloc(sizeof(struct acl)); // where is this memory freed?
1171 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1176 case SMB_ACL_USER_OBJ:
1178 case SMB_ACL_GROUP_OBJ:
1181 entry_d->ae_tag = tag_type;
1190 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry_d, void *qual_p)
1192 if(entry_d->ae_tag != SMB_ACL_GROUP &&
1193 entry_d->ae_tag != SMB_ACL_USER) {
1198 entry_d->ae_id = *((uid_t *)qual_p);
1203 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1205 // TO DO: expand to extended permissions eventually!
1207 if(*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1214 int sys_acl_free_text(char *text)
1216 return acl_free(text);
1219 int sys_acl_free_acl(SMB_ACL_T the_acl)
1221 return acl_free(the_acl);
1224 #else /* No ACLs. */
1226 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1232 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1238 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1244 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1250 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1253 return (SMB_ACL_T)NULL;
1256 SMB_ACL_T sys_acl_get_fd(int fd)
1259 return (SMB_ACL_T)NULL;
1262 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
1268 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1274 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1277 return (permset & perm) ? 1 : 0;
1280 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
1286 int sys_acl_free_text(char *text)
1292 SMB_ACL_T sys_acl_init( int count)
1298 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1304 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1310 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
1316 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1322 int sys_acl_valid( SMB_ACL_T theacl )
1328 int sys_acl_set_file( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1334 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
1340 int sys_acl_free_acl(SMB_ACL_T the_acl)
1345 #endif /* No ACLs. */