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( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
49 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
50 int sys_acl_delete_def_file(const char *path)
52 This next one is not POSIX complient - but we *have* to have it !
53 More POSIX braindamage.
55 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
57 The generic POSIX free is the following call. We split this into
58 several different free functions as we may need to add tag info
59 to structures when emulating the POSIX interface.
61 int sys_acl_free( void *obj_p)
63 The calls we actually use are :
65 int sys_acl_free_text(char *text) - free acl_to_text
66 int sys_acl_free_acl(SMB_ACL_T posix_acl)
67 int sys_acl_free_qualifier(void *qualifier, SMB_ACL_TAG_T tagtype)
71 #if defined(HAVE_POSIX_ACLS)
73 /* Identity mapping - easy. */
75 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
77 return acl_get_entry( the_acl, entry_id, entry_p);
80 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
82 return acl_get_tag_type( entry_d, tag_type_p);
85 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
87 return acl_get_permset( entry_d, permset_p);
90 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
92 return acl_get_qualifier( entry_d);
95 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
97 return acl_get_file( path_p, type);
100 SMB_ACL_T sys_acl_get_fd(int fd)
102 return acl_get_fd(fd);
105 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
107 return acl_clear_perms(permset);
110 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
112 return acl_add_perm(permset, perm);
115 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
117 #if defined(HAVE_ACL_GET_PERM_NP)
119 * Required for TrustedBSD-based ACL implementations where
120 * non-POSIX.1e functions are denoted by a _np (non-portable)
123 return acl_get_perm_np(permset, perm);
125 return acl_get_perm(permset, perm);
129 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
131 return acl_to_text( the_acl, plen);
134 SMB_ACL_T sys_acl_init( int count)
136 return acl_init(count);
139 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
141 return acl_create_entry(pacl, pentry);
144 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
146 return acl_set_tag_type(entry, tagtype);
149 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
151 return acl_set_qualifier(entry, qual);
154 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
156 return acl_set_permset(entry, permset);
159 int sys_acl_valid( SMB_ACL_T theacl )
161 return acl_valid(theacl);
164 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
166 return acl_set_file(name, acltype, theacl);
169 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
171 return acl_set_fd(fd, theacl);
174 int sys_acl_delete_def_file(const char *name)
176 return acl_delete_def_file(name);
179 int sys_acl_free_text(char *text)
181 return acl_free(text);
184 int sys_acl_free_acl(SMB_ACL_T the_acl)
186 return acl_free(the_acl);
189 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
191 return acl_free(qual);
194 #elif defined(HAVE_TRU64_ACLS)
196 * The interface to DEC/Compaq Tru64 UNIX ACLs
197 * is based on Draft 13 of the POSIX spec which is
198 * slightly different from the Draft 16 interface.
200 * Also, some of the permset manipulation functions
201 * such as acl_clear_perm() and acl_add_perm() appear
202 * to be broken on Tru64 so we have to manipulate
203 * the permission bits in the permset directly.
205 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
207 SMB_ACL_ENTRY_T entry;
209 if (entry_id == SMB_ACL_FIRST_ENTRY && acl_first_entry(the_acl) != 0) {
214 if ((entry = acl_get_entry(the_acl)) != NULL) {
219 return errno ? -1 : 0;
222 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
224 return acl_get_tag_type( entry_d, tag_type_p);
227 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
229 return acl_get_permset( entry_d, permset_p);
232 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
234 return acl_get_qualifier( entry_d);
237 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
239 return acl_get_file((char *)path_p, type);
242 SMB_ACL_T sys_acl_get_fd(int fd)
244 return acl_get_fd(fd, ACL_TYPE_ACCESS);
247 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
249 *permset = 0; /* acl_clear_perm() is broken on Tru64 */
254 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
256 if (perm & ~(SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE)) {
261 *permset |= perm; /* acl_add_perm() is broken on Tru64 */
266 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
268 return *permset & perm; /* Tru64 doesn't have acl_get_perm() */
271 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
273 return acl_to_text( the_acl, plen);
276 SMB_ACL_T sys_acl_init( int count)
278 return acl_init(count);
281 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
283 SMB_ACL_ENTRY_T entry;
285 if ((entry = acl_create_entry(pacl)) == NULL) {
293 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
295 return acl_set_tag_type(entry, tagtype);
298 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
300 return acl_set_qualifier(entry, qual);
303 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
305 return acl_set_permset(entry, permset);
308 int sys_acl_valid( SMB_ACL_T theacl )
312 return acl_valid(theacl, &entry);
315 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
317 return acl_set_file((char *)name, acltype, theacl);
320 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
322 return acl_set_fd(fd, ACL_TYPE_ACCESS, theacl);
325 int sys_acl_delete_def_file(const char *name)
327 return acl_delete_def_file((char *)name);
330 int sys_acl_free_text(char *text)
333 * (void) cast and explicit return 0 are for DEC UNIX
334 * which just #defines acl_free_text() to be free()
336 (void) acl_free_text(text);
340 int sys_acl_free_acl(SMB_ACL_T the_acl)
342 return acl_free(the_acl);
345 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
347 return acl_free_qualifier(qual, tagtype);
350 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
353 * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
354 * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
358 * Note that while this code implements sufficient functionality
359 * to support the sys_acl_* interfaces it does not provide all
360 * of the semantics of the POSIX ACL interfaces.
362 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
363 * from a call to sys_acl_get_entry() should not be assumed to be
364 * valid after calling any of the following functions, which may
365 * reorder the entries in the ACL.
373 * The only difference between Solaris and UnixWare / OpenUNIX is
374 * that the #defines for the ACL operations have different names
376 #if defined(HAVE_UNIXWARE_ACLS)
378 #define SETACL ACL_SET
379 #define GETACL ACL_GET
380 #define GETACLCNT ACL_CNT
385 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
387 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
392 if (entry_p == NULL) {
397 if (entry_id == SMB_ACL_FIRST_ENTRY) {
401 if (acl_d->next < 0) {
406 if (acl_d->next >= acl_d->count) {
410 *entry_p = &acl_d->acl[acl_d->next++];
415 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
417 *type_p = entry_d->a_type;
422 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
424 *permset_p = &entry_d->a_perm;
429 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
431 if (entry_d->a_type != SMB_ACL_USER
432 && entry_d->a_type != SMB_ACL_GROUP) {
437 return &entry_d->a_id;
441 * There is no way of knowing what size the ACL returned by
442 * GETACL will be unless you first call GETACLCNT which means
443 * making an additional system call.
445 * In the hope of avoiding the cost of the additional system
446 * call in most cases, we initially allocate enough space for
447 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
448 * be too small then we use GETACLCNT to find out the actual
449 * size, reallocate the ACL buffer, and then call GETACL again.
452 #define INITIAL_ACL_SIZE 16
454 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
457 int count; /* # of ACL entries allocated */
458 int naccess; /* # of access ACL entries */
459 int ndefault; /* # of default ACL entries */
461 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
466 count = INITIAL_ACL_SIZE;
467 if ((acl_d = sys_acl_init(count)) == NULL) {
472 * If there isn't enough space for the ACL entries we use
473 * GETACLCNT to determine the actual number of ACL entries
474 * reallocate and try again. This is in a loop because it
475 * is possible that someone else could modify the ACL and
476 * increase the number of entries between the call to
477 * GETACLCNT and the call to GETACL.
479 while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0
480 && errno == ENOSPC) {
482 sys_acl_free_acl(acl_d);
484 if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) {
488 if ((acl_d = sys_acl_init(count)) == NULL) {
494 sys_acl_free_acl(acl_d);
499 * calculate the number of access and default ACL entries
501 * Note: we assume that the acl() system call returned a
502 * well formed ACL which is sorted so that all of the
503 * access ACL entries preceed any default ACL entries
505 for (naccess = 0; naccess < count; naccess++) {
506 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
509 ndefault = count - naccess;
512 * if the caller wants the default ACL we have to copy
513 * the entries down to the start of the acl[] buffer
514 * and mask out the ACL_DEFAULT flag from the type field
516 if (type == SMB_ACL_TYPE_DEFAULT) {
519 for (i = 0, j = naccess; i < ndefault; i++, j++) {
520 acl_d->acl[i] = acl_d->acl[j];
521 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
524 acl_d->count = ndefault;
526 acl_d->count = naccess;
532 SMB_ACL_T sys_acl_get_fd(int fd)
535 int count; /* # of ACL entries allocated */
536 int naccess; /* # of access ACL entries */
538 count = INITIAL_ACL_SIZE;
539 if ((acl_d = sys_acl_init(count)) == NULL) {
543 while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0
544 && errno == ENOSPC) {
546 sys_acl_free_acl(acl_d);
548 if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) {
552 if ((acl_d = sys_acl_init(count)) == NULL) {
558 sys_acl_free_acl(acl_d);
563 * calculate the number of access ACL entries
565 for (naccess = 0; naccess < count; naccess++) {
566 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
570 acl_d->count = naccess;
575 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
582 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
584 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
585 && perm != SMB_ACL_EXECUTE) {
590 if (permset_d == NULL) {
600 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
602 return *permset_d & perm;
605 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
612 * use an initial estimate of 20 bytes per ACL entry
613 * when allocating memory for the text representation
617 maxlen = 20 * acl_d->count;
618 if ((text = malloc(maxlen)) == NULL) {
623 for (i = 0; i < acl_d->count; i++) {
624 struct acl *ap = &acl_d->acl[i];
634 switch (ap->a_type) {
636 * for debugging purposes it's probably more
637 * useful to dump unknown tag types rather
638 * than just returning an error
641 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
644 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
650 if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
651 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
657 case SMB_ACL_USER_OBJ:
662 if ((gr = getgrgid(ap->a_id)) == NULL) {
663 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
669 case SMB_ACL_GROUP_OBJ:
683 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
684 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
685 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
688 /* <tag> : <qualifier> : rwx \n \0 */
689 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
692 * If this entry would overflow the buffer
693 * allocate enough additional memory for this
694 * entry and an estimate of another 20 bytes
695 * for each entry still to be processed
697 if ((len + nbytes) > maxlen) {
698 char *oldtext = text;
700 maxlen += nbytes + 20 * (acl_d->count - i);
702 if ((text = Realloc(oldtext, maxlen)) == NULL) {
709 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
719 SMB_ACL_T sys_acl_init(int count)
729 * note that since the definition of the structure pointed
730 * to by the SMB_ACL_T includes the first element of the
731 * acl[] array, this actually allocates an ACL with room
732 * for (count+1) entries
734 if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
747 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
750 SMB_ACL_ENTRY_T entry_d;
752 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
757 if (acl_d->count >= acl_d->size) {
762 entry_d = &acl_d->acl[acl_d->count++];
771 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
775 case SMB_ACL_USER_OBJ:
777 case SMB_ACL_GROUP_OBJ:
780 entry_d->a_type = tag_type;
790 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
792 if (entry_d->a_type != SMB_ACL_GROUP
793 && entry_d->a_type != SMB_ACL_USER) {
798 entry_d->a_id = *((id_t *)qual_p);
803 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
805 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
809 entry_d->a_perm = *permset_d;
815 * sort the ACL and check it for validity
817 * if it's a minimal ACL with only 4 entries then we
818 * need to recalculate the mask permissions to make
819 * sure that they are the same as the GROUP_OBJ
820 * permissions as required by the UnixWare acl() system call.
822 * (note: since POSIX allows minimal ACLs which only contain
823 * 3 entries - ie there is no mask entry - we should, in theory,
824 * check for this and add a mask entry if necessary - however
825 * we "know" that the caller of this interface always specifies
826 * a mask so, in practice "this never happens" (tm) - if it *does*
827 * happen aclsort() will fail and return an error and someone will
828 * have to fix it ...)
831 static int acl_sort(SMB_ACL_T acl_d)
833 int fixmask = (acl_d->count <= 4);
835 if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {
842 int sys_acl_valid(SMB_ACL_T acl_d)
844 return acl_sort(acl_d);
847 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
852 struct acl *acl_buf = NULL;
855 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
860 if (acl_sort(acl_d) != 0) {
864 acl_p = &acl_d->acl[0];
865 acl_count = acl_d->count;
868 * if it's a directory there is extra work to do
869 * since the acl() system call will replace both
870 * the access ACLs and the default ACLs (if any)
872 if (stat(name, &s) != 0) {
875 if (S_ISDIR(s.st_mode)) {
881 if (type == SMB_ACL_TYPE_ACCESS) {
883 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
887 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
890 if (tmp_acl == NULL) {
895 * allocate a temporary buffer for the complete ACL
897 acl_count = acc_acl->count + def_acl->count;
898 acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
900 if (acl_buf == NULL) {
901 sys_acl_free_acl(tmp_acl);
907 * copy the access control and default entries into the buffer
909 memcpy(&acl_buf[0], &acc_acl->acl[0],
910 acc_acl->count * sizeof(acl_buf[0]));
912 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
913 def_acl->count * sizeof(acl_buf[0]));
916 * set the ACL_DEFAULT flag on the default entries
918 for (i = acc_acl->count; i < acl_count; i++) {
919 acl_buf[i].a_type |= ACL_DEFAULT;
922 sys_acl_free_acl(tmp_acl);
924 } else if (type != SMB_ACL_TYPE_ACCESS) {
929 ret = acl(name, SETACL, acl_count, acl_p);
936 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
938 if (acl_sort(acl_d) != 0) {
942 return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
945 int sys_acl_delete_def_file(const char *path)
951 * fetching the access ACL and rewriting it has
952 * the effect of deleting the default ACL
954 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
958 ret = acl(path, SETACL, acl_d->count, acl_d->acl);
960 sys_acl_free_acl(acl_d);
965 int sys_acl_free_text(char *text)
971 int sys_acl_free_acl(SMB_ACL_T acl_d)
977 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
982 #elif defined(HAVE_IRIX_ACLS)
984 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
986 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
991 if (entry_p == NULL) {
996 if (entry_id == SMB_ACL_FIRST_ENTRY) {
1000 if (acl_d->next < 0) {
1005 if (acl_d->next >= acl_d->aclp->acl_cnt) {
1009 *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
1014 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
1016 *type_p = entry_d->ae_tag;
1021 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1023 *permset_p = entry_d;
1028 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
1030 if (entry_d->ae_tag != SMB_ACL_USER
1031 && entry_d->ae_tag != SMB_ACL_GROUP) {
1036 return &entry_d->ae_id;
1039 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
1043 if ((a = malloc(sizeof(*a))) == NULL) {
1047 if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
1056 SMB_ACL_T sys_acl_get_fd(int fd)
1060 if ((a = malloc(sizeof(*a))) == NULL) {
1064 if ((a->aclp = acl_get_fd(fd)) == NULL) {
1073 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
1075 permset_d->ae_perm = 0;
1080 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1082 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
1083 && perm != SMB_ACL_EXECUTE) {
1088 if (permset_d == NULL) {
1093 permset_d->ae_perm |= perm;
1098 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1100 return permset_d->ae_perm & perm;
1103 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
1105 return acl_to_text(acl_d->aclp, len_p);
1108 SMB_ACL_T sys_acl_init(int count)
1117 if ((a = malloc(sizeof(*a) + sizeof(struct acl))) == NULL) {
1123 a->freeaclp = False;
1124 a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
1125 a->aclp->acl_cnt = 0;
1131 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1134 SMB_ACL_ENTRY_T entry_d;
1136 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
1141 if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
1146 entry_d = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
1147 entry_d->ae_tag = 0;
1149 entry_d->ae_perm = 0;
1155 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1159 case SMB_ACL_USER_OBJ:
1161 case SMB_ACL_GROUP_OBJ:
1164 entry_d->ae_tag = tag_type;
1174 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
1176 if (entry_d->ae_tag != SMB_ACL_GROUP
1177 && entry_d->ae_tag != SMB_ACL_USER) {
1182 entry_d->ae_id = *((id_t *)qual_p);
1187 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1189 if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1193 entry_d->ae_perm = permset_d->ae_perm;
1198 int sys_acl_valid(SMB_ACL_T acl_d)
1200 return acl_valid(acl_d->aclp);
1203 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
1205 return acl_set_file(name, type, acl_d->aclp);
1208 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
1210 return acl_set_fd(fd, acl_d->aclp);
1213 int sys_acl_delete_def_file(const char *name)
1215 return acl_delete_def_file(name);
1218 int sys_acl_free_text(char *text)
1220 return acl_free(text);
1223 int sys_acl_free_acl(SMB_ACL_T acl_d)
1225 if (acl_d->freeaclp) {
1226 acl_free(acl_d->aclp);
1232 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
1237 #elif defined(HAVE_AIX_ACLS)
1239 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
1241 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1243 struct acl_entry_link *link;
1244 struct new_acl_entry *entry;
1247 DEBUG(10,("This is the count: %d\n",theacl->count));
1249 /* Check if count was previously set to -1. *
1250 * If it was, that means we reached the end *
1251 * of the acl last time. */
1252 if(theacl->count == -1)
1256 /* To get to the next acl, traverse linked list until index *
1257 * of acl matches the count we are keeping. This count is *
1258 * incremented each time we return an acl entry. */
1260 for(keep_going = 0; keep_going < theacl->count; keep_going++)
1263 entry = *entry_p = link->entryp;
1265 DEBUG(10,("*entry_p is %d\n",entry_p));
1266 DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
1268 /* Increment count */
1270 if(link->nextp == NULL)
1276 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1278 /* Initialize tag type */
1281 DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
1283 /* Depending on what type of entry we have, *
1284 * return tag type. */
1285 switch(entry_d->ace_id->id_type) {
1287 *tag_type_p = SMB_ACL_USER;
1290 *tag_type_p = SMB_ACL_GROUP;
1293 case SMB_ACL_USER_OBJ:
1294 case SMB_ACL_GROUP_OBJ:
1296 *tag_type_p = entry_d->ace_id->id_type;
1306 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1308 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
1309 *permset_p = &entry_d->ace_access;
1310 DEBUG(10,("**permset_p is %d\n",**permset_p));
1311 if(!(**permset_p & S_IXUSR) &&
1312 !(**permset_p & S_IWUSR) &&
1313 !(**permset_p & S_IRUSR) &&
1317 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
1321 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1323 return(entry_d->ace_id->id_data);
1326 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1328 struct acl *file_acl = (struct acl *)NULL;
1329 struct acl_entry *acl_entry;
1330 struct new_acl_entry *new_acl_entry;
1332 struct acl_entry_link *acl_entry_link;
1333 struct acl_entry_link *acl_entry_link_head;
1338 /* Get the acl using statacl */
1340 DEBUG(10,("Entering sys_acl_get_file\n"));
1341 DEBUG(10,("path_p is %s\n",path_p));
1343 file_acl = (struct acl *)malloc(BUFSIZ);
1345 if(file_acl == NULL) {
1347 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
1351 memset(file_acl,0,BUFSIZ);
1353 rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
1355 DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
1356 SAFE_FREE(file_acl);
1360 DEBUG(10,("Got facl and returned it\n"));
1362 /* Point to the first acl entry in the acl */
1363 acl_entry = file_acl->acl_ext;
1365 /* Begin setting up the head of the linked list *
1366 * that will be used for the storing the acl *
1367 * in a way that is useful for the posix_acls.c *
1370 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1371 if(acl_entry_link_head == NULL)
1374 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1375 if(acl_entry_link->entryp == NULL) {
1376 SAFE_FREE(file_acl);
1378 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1382 DEBUG(10,("acl_entry is %d\n",acl_entry));
1383 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1385 /* Check if the extended acl bit is on. *
1386 * If it isn't, do not show the *
1387 * contents of the acl since AIX intends *
1388 * the extended info to remain unused */
1390 if(file_acl->acl_mode & S_IXACL){
1391 /* while we are not pointing to the very end */
1392 while(acl_entry < acl_last(file_acl)) {
1393 /* before we malloc anything, make sure this is */
1394 /* a valid acl entry and one that we want to map */
1395 idp = id_nxt(acl_entry->ace_id);
1396 if((acl_entry->ace_type == ACC_SPECIFY ||
1397 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1398 acl_entry = acl_nxt(acl_entry);
1402 idp = acl_entry->ace_id;
1404 /* Check if this is the first entry in the linked list. *
1405 * The first entry needs to keep prevp pointing to NULL *
1406 * and already has entryp allocated. */
1408 if(acl_entry_link_head->count != 0) {
1409 acl_entry_link->nextp = (struct acl_entry_link *)
1410 malloc(sizeof(struct acl_entry_link));
1412 if(acl_entry_link->nextp == NULL) {
1413 SAFE_FREE(file_acl);
1415 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1419 acl_entry_link->nextp->prevp = acl_entry_link;
1420 acl_entry_link = acl_entry_link->nextp;
1421 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1422 if(acl_entry_link->entryp == NULL) {
1423 SAFE_FREE(file_acl);
1425 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1428 acl_entry_link->nextp = NULL;
1431 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1433 /* Don't really need this since all types are going *
1434 * to be specified but, it's better than leaving it 0 */
1436 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1438 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1440 memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
1442 /* The access in the acl entries must be left shifted by *
1443 * three bites, because they will ultimately be compared *
1444 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1446 switch(acl_entry->ace_type){
1449 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1450 acl_entry_link->entryp->ace_access <<= 6;
1451 acl_entry_link_head->count++;
1454 /* Since there is no way to return a DENY acl entry *
1455 * change to PERMIT and then shift. */
1456 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1457 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1458 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1459 acl_entry_link->entryp->ace_access <<= 6;
1460 acl_entry_link_head->count++;
1466 DEBUG(10,("acl_entry = %d\n",acl_entry));
1467 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1469 acl_entry = acl_nxt(acl_entry);
1471 } /* end of if enabled */
1473 /* Since owner, group, other acl entries are not *
1474 * part of the acl entries in an acl, they must *
1475 * be dummied up to become part of the list. */
1477 for( i = 1; i < 4; i++) {
1478 DEBUG(10,("i is %d\n",i));
1479 if(acl_entry_link_head->count != 0) {
1480 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1481 if(acl_entry_link->nextp == NULL) {
1482 SAFE_FREE(file_acl);
1484 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1488 acl_entry_link->nextp->prevp = acl_entry_link;
1489 acl_entry_link = acl_entry_link->nextp;
1490 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1491 if(acl_entry_link->entryp == NULL) {
1492 SAFE_FREE(file_acl);
1494 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1499 acl_entry_link->nextp = NULL;
1501 new_acl_entry = acl_entry_link->entryp;
1502 idp = new_acl_entry->ace_id;
1504 new_acl_entry->ace_len = sizeof(struct acl_entry);
1505 new_acl_entry->ace_type = ACC_PERMIT;
1506 idp->id_len = sizeof(struct ace_id);
1507 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1508 memset(idp->id_data,0,sizeof(uid_t));
1512 new_acl_entry->ace_access = file_acl->g_access << 6;
1513 idp->id_type = SMB_ACL_GROUP_OBJ;
1517 new_acl_entry->ace_access = file_acl->o_access << 6;
1518 idp->id_type = SMB_ACL_OTHER;
1522 new_acl_entry->ace_access = file_acl->u_access << 6;
1523 idp->id_type = SMB_ACL_USER_OBJ;
1531 acl_entry_link_head->count++;
1532 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1535 acl_entry_link_head->count = 0;
1536 SAFE_FREE(file_acl);
1538 return(acl_entry_link_head);
1541 SMB_ACL_T sys_acl_get_fd(int fd)
1543 struct acl *file_acl = (struct acl *)NULL;
1544 struct acl_entry *acl_entry;
1545 struct new_acl_entry *new_acl_entry;
1547 struct acl_entry_link *acl_entry_link;
1548 struct acl_entry_link *acl_entry_link_head;
1553 /* Get the acl using fstatacl */
1555 DEBUG(10,("Entering sys_acl_get_fd\n"));
1556 DEBUG(10,("fd is %d\n",fd));
1557 file_acl = (struct acl *)malloc(BUFSIZ);
1559 if(file_acl == NULL) {
1561 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1565 memset(file_acl,0,BUFSIZ);
1567 rc = fstatacl(fd,0,file_acl,BUFSIZ);
1569 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
1570 SAFE_FREE(file_acl);
1574 DEBUG(10,("Got facl and returned it\n"));
1576 /* Point to the first acl entry in the acl */
1578 acl_entry = file_acl->acl_ext;
1579 /* Begin setting up the head of the linked list *
1580 * that will be used for the storing the acl *
1581 * in a way that is useful for the posix_acls.c *
1584 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1585 if(acl_entry_link_head == NULL){
1586 SAFE_FREE(file_acl);
1590 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1592 if(acl_entry_link->entryp == NULL) {
1594 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1595 SAFE_FREE(file_acl);
1599 DEBUG(10,("acl_entry is %d\n",acl_entry));
1600 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1602 /* Check if the extended acl bit is on. *
1603 * If it isn't, do not show the *
1604 * contents of the acl since AIX intends *
1605 * the extended info to remain unused */
1607 if(file_acl->acl_mode & S_IXACL){
1608 /* while we are not pointing to the very end */
1609 while(acl_entry < acl_last(file_acl)) {
1610 /* before we malloc anything, make sure this is */
1611 /* a valid acl entry and one that we want to map */
1613 idp = id_nxt(acl_entry->ace_id);
1614 if((acl_entry->ace_type == ACC_SPECIFY ||
1615 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1616 acl_entry = acl_nxt(acl_entry);
1620 idp = acl_entry->ace_id;
1622 /* Check if this is the first entry in the linked list. *
1623 * The first entry needs to keep prevp pointing to NULL *
1624 * and already has entryp allocated. */
1626 if(acl_entry_link_head->count != 0) {
1627 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1628 if(acl_entry_link->nextp == NULL) {
1630 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1631 SAFE_FREE(file_acl);
1634 acl_entry_link->nextp->prevp = acl_entry_link;
1635 acl_entry_link = acl_entry_link->nextp;
1636 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1637 if(acl_entry_link->entryp == NULL) {
1639 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1640 SAFE_FREE(file_acl);
1644 acl_entry_link->nextp = NULL;
1647 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1649 /* Don't really need this since all types are going *
1650 * to be specified but, it's better than leaving it 0 */
1652 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1653 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1655 memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
1657 /* The access in the acl entries must be left shifted by *
1658 * three bites, because they will ultimately be compared *
1659 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1661 switch(acl_entry->ace_type){
1664 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1665 acl_entry_link->entryp->ace_access <<= 6;
1666 acl_entry_link_head->count++;
1669 /* Since there is no way to return a DENY acl entry *
1670 * change to PERMIT and then shift. */
1671 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1672 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1673 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1674 acl_entry_link->entryp->ace_access <<= 6;
1675 acl_entry_link_head->count++;
1681 DEBUG(10,("acl_entry = %d\n",acl_entry));
1682 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1684 acl_entry = acl_nxt(acl_entry);
1686 } /* end of if enabled */
1688 /* Since owner, group, other acl entries are not *
1689 * part of the acl entries in an acl, they must *
1690 * be dummied up to become part of the list. */
1692 for( i = 1; i < 4; i++) {
1693 DEBUG(10,("i is %d\n",i));
1694 if(acl_entry_link_head->count != 0){
1695 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1696 if(acl_entry_link->nextp == NULL) {
1698 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1699 SAFE_FREE(file_acl);
1703 acl_entry_link->nextp->prevp = acl_entry_link;
1704 acl_entry_link = acl_entry_link->nextp;
1705 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1707 if(acl_entry_link->entryp == NULL) {
1708 SAFE_FREE(file_acl);
1710 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1715 acl_entry_link->nextp = NULL;
1717 new_acl_entry = acl_entry_link->entryp;
1718 idp = new_acl_entry->ace_id;
1720 new_acl_entry->ace_len = sizeof(struct acl_entry);
1721 new_acl_entry->ace_type = ACC_PERMIT;
1722 idp->id_len = sizeof(struct ace_id);
1723 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1724 memset(idp->id_data,0,sizeof(uid_t));
1728 new_acl_entry->ace_access = file_acl->g_access << 6;
1729 idp->id_type = SMB_ACL_GROUP_OBJ;
1733 new_acl_entry->ace_access = file_acl->o_access << 6;
1734 idp->id_type = SMB_ACL_OTHER;
1738 new_acl_entry->ace_access = file_acl->u_access << 6;
1739 idp->id_type = SMB_ACL_USER_OBJ;
1746 acl_entry_link_head->count++;
1747 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1750 acl_entry_link_head->count = 0;
1751 SAFE_FREE(file_acl);
1753 return(acl_entry_link_head);
1756 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
1758 *permset = *permset & ~0777;
1762 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1765 (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0)
1769 DEBUG(10,("This is the permset now: %d\n",*permset));
1773 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
1778 SMB_ACL_T sys_acl_init( int count)
1780 struct acl_entry_link *theacl = NULL;
1782 DEBUG(10,("Entering sys_acl_init\n"));
1784 theacl = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1785 if(theacl == NULL) {
1787 DEBUG(0,("Error in sys_acl_init is %d\n",errno));
1792 theacl->nextp = NULL;
1793 theacl->prevp = NULL;
1794 theacl->entryp = NULL;
1795 DEBUG(10,("Exiting sys_acl_init\n"));
1799 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1801 struct acl_entry_link *theacl;
1802 struct acl_entry_link *acl_entryp;
1803 struct acl_entry_link *temp_entry;
1806 DEBUG(10,("Entering the sys_acl_create_entry\n"));
1808 theacl = acl_entryp = *pacl;
1810 /* Get to the end of the acl before adding entry */
1812 for(counting=0; counting < theacl->count; counting++){
1813 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1814 temp_entry = acl_entryp;
1815 acl_entryp = acl_entryp->nextp;
1818 if(theacl->count != 0){
1819 temp_entry->nextp = acl_entryp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1820 if(acl_entryp == NULL) {
1822 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1826 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1827 acl_entryp->prevp = temp_entry;
1828 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
1831 *pentry = acl_entryp->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1832 if(*pentry == NULL) {
1834 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1838 memset(*pentry,0,sizeof(struct new_acl_entry));
1839 acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
1840 acl_entryp->entryp->ace_type = ACC_PERMIT;
1841 acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
1842 acl_entryp->nextp = NULL;
1844 DEBUG(10,("Exiting sys_acl_create_entry\n"));
1848 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1850 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
1851 entry->ace_id->id_type = tagtype;
1852 DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
1853 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
1856 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
1858 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
1859 memcpy(entry->ace_id->id_data,qual,sizeof(uid_t));
1860 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
1864 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1866 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
1867 if(!(*permset & S_IXUSR) &&
1868 !(*permset & S_IWUSR) &&
1869 !(*permset & S_IRUSR) &&
1873 entry->ace_access = *permset;
1874 DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
1875 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
1879 int sys_acl_valid( SMB_ACL_T theacl )
1884 struct acl_entry_link *acl_entry;
1886 for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
1887 user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
1888 group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
1889 other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
1892 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
1894 if(user_obj != 1 || group_obj != 1 || other_obj != 1)
1900 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1902 struct acl_entry_link *acl_entry_link = NULL;
1903 struct acl *file_acl = NULL;
1904 struct acl *file_acl_temp = NULL;
1905 struct acl_entry *acl_entry = NULL;
1906 struct ace_id *ace_id = NULL;
1913 DEBUG(10,("Entering sys_acl_set_file\n"));
1914 DEBUG(10,("File name is %s\n",name));
1916 /* AIX has no default ACL */
1917 if(acltype == SMB_ACL_TYPE_DEFAULT)
1920 acl_length = BUFSIZ;
1921 file_acl = (struct acl *)malloc(BUFSIZ);
1923 if(file_acl == NULL) {
1925 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
1929 memset(file_acl,0,BUFSIZ);
1931 file_acl->acl_len = ACL_SIZ;
1932 file_acl->acl_mode = S_IXACL;
1934 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
1935 acl_entry_link->entryp->ace_access >>= 6;
1936 id_type = acl_entry_link->entryp->ace_id->id_type;
1939 case SMB_ACL_USER_OBJ:
1940 file_acl->u_access = acl_entry_link->entryp->ace_access;
1942 case SMB_ACL_GROUP_OBJ:
1943 file_acl->g_access = acl_entry_link->entryp->ace_access;
1946 file_acl->o_access = acl_entry_link->entryp->ace_access;
1952 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
1953 acl_length += sizeof(struct acl_entry);
1954 file_acl_temp = (struct acl *)malloc(acl_length);
1955 if(file_acl_temp == NULL) {
1956 SAFE_FREE(file_acl);
1958 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
1962 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
1963 SAFE_FREE(file_acl);
1964 file_acl = file_acl_temp;
1967 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
1968 file_acl->acl_len += sizeof(struct acl_entry);
1969 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
1970 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
1972 /* In order to use this, we'll need to wait until we can get denies */
1973 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
1974 acl_entry->ace_type = ACC_SPECIFY; */
1976 acl_entry->ace_type = ACC_SPECIFY;
1978 ace_id = acl_entry->ace_id;
1980 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
1981 DEBUG(10,("The id type is %d\n",ace_id->id_type));
1982 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
1983 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
1984 memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
1987 rc = chacl(name,file_acl,file_acl->acl_len);
1988 DEBUG(10,("errno is %d\n",errno));
1989 DEBUG(10,("return code is %d\n",rc));
1990 SAFE_FREE(file_acl);
1991 DEBUG(10,("Exiting the sys_acl_set_file\n"));
1995 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
1997 struct acl_entry_link *acl_entry_link = NULL;
1998 struct acl *file_acl = NULL;
1999 struct acl *file_acl_temp = NULL;
2000 struct acl_entry *acl_entry = NULL;
2001 struct ace_id *ace_id = NULL;
2007 DEBUG(10,("Entering sys_acl_set_fd\n"));
2008 acl_length = BUFSIZ;
2009 file_acl = (struct acl *)malloc(BUFSIZ);
2011 if(file_acl == NULL) {
2013 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2017 memset(file_acl,0,BUFSIZ);
2019 file_acl->acl_len = ACL_SIZ;
2020 file_acl->acl_mode = S_IXACL;
2022 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2023 acl_entry_link->entryp->ace_access >>= 6;
2024 id_type = acl_entry_link->entryp->ace_id->id_type;
2025 DEBUG(10,("The id_type is %d\n",id_type));
2028 case SMB_ACL_USER_OBJ:
2029 file_acl->u_access = acl_entry_link->entryp->ace_access;
2031 case SMB_ACL_GROUP_OBJ:
2032 file_acl->g_access = acl_entry_link->entryp->ace_access;
2035 file_acl->o_access = acl_entry_link->entryp->ace_access;
2041 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2042 acl_length += sizeof(struct acl_entry);
2043 file_acl_temp = (struct acl *)malloc(acl_length);
2044 if(file_acl_temp == NULL) {
2045 SAFE_FREE(file_acl);
2047 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2051 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2052 SAFE_FREE(file_acl);
2053 file_acl = file_acl_temp;
2056 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2057 file_acl->acl_len += sizeof(struct acl_entry);
2058 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2059 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2061 /* In order to use this, we'll need to wait until we can get denies */
2062 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2063 acl_entry->ace_type = ACC_SPECIFY; */
2065 acl_entry->ace_type = ACC_SPECIFY;
2067 ace_id = acl_entry->ace_id;
2069 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2070 DEBUG(10,("The id type is %d\n",ace_id->id_type));
2071 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2072 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2073 memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
2076 rc = fchacl(fd,file_acl,file_acl->acl_len);
2077 DEBUG(10,("errno is %d\n",errno));
2078 DEBUG(10,("return code is %d\n",rc));
2079 SAFE_FREE(file_acl);
2080 DEBUG(10,("Exiting sys_acl_set_fd\n"));
2084 int sys_acl_delete_def_file(const char *name)
2086 /* AIX has no default ACL */
2090 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2092 return(*permset & perm);
2095 int sys_acl_free_text(char *text)
2100 int sys_acl_free_acl(SMB_ACL_T posix_acl)
2102 struct acl_entry_link *acl_entry_link;
2104 for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
2105 SAFE_FREE(acl_entry_link->prevp->entryp);
2106 SAFE_FREE(acl_entry_link->prevp);
2109 SAFE_FREE(acl_entry_link->prevp->entryp);
2110 SAFE_FREE(acl_entry_link->prevp);
2111 SAFE_FREE(acl_entry_link->entryp);
2112 SAFE_FREE(acl_entry_link);
2117 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
2122 #else /* No ACLs. */
2124 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
2130 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
2136 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
2142 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
2148 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
2151 return (SMB_ACL_T)NULL;
2154 SMB_ACL_T sys_acl_get_fd(int fd)
2157 return (SMB_ACL_T)NULL;
2160 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
2166 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2172 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2175 return (permset & perm) ? 1 : 0;
2178 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
2184 int sys_acl_free_text(char *text)
2190 SMB_ACL_T sys_acl_init( int count)
2196 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2202 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2208 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
2214 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2220 int sys_acl_valid( SMB_ACL_T theacl )
2226 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2232 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2238 int sys_acl_delete_def_file(const char *name)
2244 int sys_acl_free_acl(SMB_ACL_T the_acl)
2250 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
2256 #endif /* No ACLs. */