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.
25 This file wraps all differing system ACL interfaces into a consistent
26 one based on the POSIX interface. It also returns the correct errors
27 for older UNIX systems that don't support ACLs.
29 The interfaces that each ACL implementation must support are as follows :
31 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
32 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
33 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p
34 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
35 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
36 SMB_ACL_T sys_acl_get_fd(int fd)
37 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
38 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
39 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
40 SMB_ACL_T sys_acl_init( int count)
41 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
42 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
43 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
44 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
45 int sys_acl_valid( SMB_ACL_T theacl )
46 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
47 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
48 int sys_acl_delete_def_file(const char *path)
50 This next one is not POSIX complient - but we *have* to have it !
51 More POSIX braindamage.
53 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
55 The generic POSIX free is the following call. We split this into
56 several different free functions as we may need to add tag info
57 to structures when emulating the POSIX interface.
59 int sys_acl_free( void *obj_p)
61 The calls we actually use are :
63 int sys_acl_free_text(char *text) - free acl_to_text
64 int sys_acl_free_acl(SMB_ACL_T posix_acl)
65 int sys_acl_free_qualifier(void *qualifier, SMB_ACL_TAG_T tagtype)
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 #if defined(HAVE_ACL_GET_PERM_NP)
117 * Required for TrustedBSD-based ACL implementations where
118 * non-POSIX.1e functions are denoted by a _np (non-portable)
121 return acl_get_perm_np(permset, perm);
123 return acl_get_perm(permset, perm);
127 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
129 return acl_to_text( the_acl, plen);
132 SMB_ACL_T sys_acl_init( int count)
134 return acl_init(count);
137 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
139 return acl_create_entry(pacl, pentry);
142 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
144 return acl_set_tag_type(entry, tagtype);
147 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
149 return acl_set_qualifier(entry, qual);
152 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
154 return acl_set_permset(entry, permset);
157 int sys_acl_valid( SMB_ACL_T theacl )
159 return acl_valid(theacl);
162 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
164 return acl_set_file(name, acltype, theacl);
167 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
169 return acl_set_fd(fd, theacl);
172 int sys_acl_delete_def_file(const char *name)
174 return acl_delete_def_file(name);
177 int sys_acl_free_text(char *text)
179 return acl_free(text);
182 int sys_acl_free_acl(SMB_ACL_T the_acl)
184 return acl_free(the_acl);
187 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
189 return acl_free(qual);
192 #elif defined(HAVE_TRU64_ACLS)
194 * The interface to DEC/Compaq Tru64 UNIX ACLs
195 * is based on Draft 13 of the POSIX spec which is
196 * slightly different from the Draft 16 interface.
198 * Also, some of the permset manipulation functions
199 * such as acl_clear_perm() and acl_add_perm() appear
200 * to be broken on Tru64 so we have to manipulate
201 * the permission bits in the permset directly.
203 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
205 SMB_ACL_ENTRY_T entry;
207 if (entry_id == SMB_ACL_FIRST_ENTRY && acl_first_entry(the_acl) != 0) {
212 if ((entry = acl_get_entry(the_acl)) != NULL) {
217 return errno ? -1 : 0;
220 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
222 return acl_get_tag_type( entry_d, tag_type_p);
225 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
227 return acl_get_permset( entry_d, permset_p);
230 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
232 return acl_get_qualifier( entry_d);
235 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
237 return acl_get_file((char *)path_p, type);
240 SMB_ACL_T sys_acl_get_fd(int fd)
242 return acl_get_fd(fd, ACL_TYPE_ACCESS);
245 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
247 *permset = 0; /* acl_clear_perm() is broken on Tru64 */
252 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
254 if (perm & ~(SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE)) {
259 *permset |= perm; /* acl_add_perm() is broken on Tru64 */
264 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
266 return *permset & perm; /* Tru64 doesn't have acl_get_perm() */
269 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
271 return acl_to_text( the_acl, plen);
274 SMB_ACL_T sys_acl_init( int count)
276 return acl_init(count);
279 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
281 SMB_ACL_ENTRY_T entry;
283 if ((entry = acl_create_entry(pacl)) == NULL) {
291 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
293 return acl_set_tag_type(entry, tagtype);
296 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
298 return acl_set_qualifier(entry, qual);
301 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
303 return acl_set_permset(entry, permset);
306 int sys_acl_valid( SMB_ACL_T theacl )
310 return acl_valid(theacl, &entry);
313 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
315 return acl_set_file((char *)name, acltype, theacl);
318 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
320 return acl_set_fd(fd, ACL_TYPE_ACCESS, theacl);
323 int sys_acl_delete_def_file(const char *name)
325 return acl_delete_def_file((char *)name);
328 int sys_acl_free_text(char *text)
331 * (void) cast and explicit return 0 are for DEC UNIX
332 * which just #defines acl_free_text() to be free()
334 (void) acl_free_text(text);
338 int sys_acl_free_acl(SMB_ACL_T the_acl)
340 return acl_free(the_acl);
343 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
345 return acl_free_qualifier(qual, tagtype);
348 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
351 * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
352 * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
356 * Note that while this code implements sufficient functionality
357 * to support the sys_acl_* interfaces it does not provide all
358 * of the semantics of the POSIX ACL interfaces.
360 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
361 * from a call to sys_acl_get_entry() should not be assumed to be
362 * valid after calling any of the following functions, which may
363 * reorder the entries in the ACL.
371 * The only difference between Solaris and UnixWare / OpenUNIX is
372 * that the #defines for the ACL operations have different names
374 #if defined(HAVE_UNIXWARE_ACLS)
376 #define SETACL ACL_SET
377 #define GETACL ACL_GET
378 #define GETACLCNT ACL_CNT
383 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
385 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
390 if (entry_p == NULL) {
395 if (entry_id == SMB_ACL_FIRST_ENTRY) {
399 if (acl_d->next < 0) {
404 if (acl_d->next >= acl_d->count) {
408 *entry_p = &acl_d->acl[acl_d->next++];
413 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
415 *type_p = entry_d->a_type;
420 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
422 *permset_p = &entry_d->a_perm;
427 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
429 if (entry_d->a_type != SMB_ACL_USER
430 && entry_d->a_type != SMB_ACL_GROUP) {
435 return &entry_d->a_id;
439 * There is no way of knowing what size the ACL returned by
440 * GETACL will be unless you first call GETACLCNT which means
441 * making an additional system call.
443 * In the hope of avoiding the cost of the additional system
444 * call in most cases, we initially allocate enough space for
445 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
446 * be too small then we use GETACLCNT to find out the actual
447 * size, reallocate the ACL buffer, and then call GETACL again.
450 #define INITIAL_ACL_SIZE 16
452 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
455 int count; /* # of ACL entries allocated */
456 int naccess; /* # of access ACL entries */
457 int ndefault; /* # of default ACL entries */
459 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
464 count = INITIAL_ACL_SIZE;
465 if ((acl_d = sys_acl_init(count)) == NULL) {
470 * If there isn't enough space for the ACL entries we use
471 * GETACLCNT to determine the actual number of ACL entries
472 * reallocate and try again. This is in a loop because it
473 * is possible that someone else could modify the ACL and
474 * increase the number of entries between the call to
475 * GETACLCNT and the call to GETACL.
477 while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0
478 && errno == ENOSPC) {
480 sys_acl_free_acl(acl_d);
482 if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) {
486 if ((acl_d = sys_acl_init(count)) == NULL) {
492 sys_acl_free_acl(acl_d);
497 * calculate the number of access and default ACL entries
499 * Note: we assume that the acl() system call returned a
500 * well formed ACL which is sorted so that all of the
501 * access ACL entries preceed any default ACL entries
503 for (naccess = 0; naccess < count; naccess++) {
504 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
507 ndefault = count - naccess;
510 * if the caller wants the default ACL we have to copy
511 * the entries down to the start of the acl[] buffer
512 * and mask out the ACL_DEFAULT flag from the type field
514 if (type == SMB_ACL_TYPE_DEFAULT) {
517 for (i = 0, j = naccess; i < ndefault; i++, j++) {
518 acl_d->acl[i] = acl_d->acl[j];
519 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
522 acl_d->count = ndefault;
524 acl_d->count = naccess;
530 SMB_ACL_T sys_acl_get_fd(int fd)
533 int count; /* # of ACL entries allocated */
534 int naccess; /* # of access ACL entries */
536 count = INITIAL_ACL_SIZE;
537 if ((acl_d = sys_acl_init(count)) == NULL) {
541 while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0
542 && errno == ENOSPC) {
544 sys_acl_free_acl(acl_d);
546 if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) {
550 if ((acl_d = sys_acl_init(count)) == NULL) {
556 sys_acl_free_acl(acl_d);
561 * calculate the number of access ACL entries
563 for (naccess = 0; naccess < count; naccess++) {
564 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
568 acl_d->count = naccess;
573 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
580 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
582 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
583 && perm != SMB_ACL_EXECUTE) {
588 if (permset_d == NULL) {
598 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
600 return *permset_d & perm;
603 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
610 * use an initial estimate of 20 bytes per ACL entry
611 * when allocating memory for the text representation
615 maxlen = 20 * acl_d->count;
616 if ((text = malloc(maxlen)) == NULL) {
621 for (i = 0; i < acl_d->count; i++) {
622 struct acl *ap = &acl_d->acl[i];
632 switch (ap->a_type) {
634 * for debugging purposes it's probably more
635 * useful to dump unknown tag types rather
636 * than just returning an error
639 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
642 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
648 if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
649 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
655 case SMB_ACL_USER_OBJ:
660 if ((gr = getgrgid(ap->a_id)) == NULL) {
661 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
667 case SMB_ACL_GROUP_OBJ:
681 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
682 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
683 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
686 /* <tag> : <qualifier> : rwx \n \0 */
687 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
690 * If this entry would overflow the buffer
691 * allocate enough additional memory for this
692 * entry and an estimate of another 20 bytes
693 * for each entry still to be processed
695 if ((len + nbytes) > maxlen) {
696 char *oldtext = text;
698 maxlen += nbytes + 20 * (acl_d->count - i);
700 if ((text = Realloc(oldtext, maxlen)) == NULL) {
707 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
717 SMB_ACL_T sys_acl_init(int count)
727 * note that since the definition of the structure pointed
728 * to by the SMB_ACL_T includes the first element of the
729 * acl[] array, this actually allocates an ACL with room
730 * for (count+1) entries
732 if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
745 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
748 SMB_ACL_ENTRY_T entry_d;
750 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
755 if (acl_d->count >= acl_d->size) {
760 entry_d = &acl_d->acl[acl_d->count++];
769 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
773 case SMB_ACL_USER_OBJ:
775 case SMB_ACL_GROUP_OBJ:
778 entry_d->a_type = tag_type;
788 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
790 if (entry_d->a_type != SMB_ACL_GROUP
791 && entry_d->a_type != SMB_ACL_USER) {
796 entry_d->a_id = *((id_t *)qual_p);
801 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
803 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
807 entry_d->a_perm = *permset_d;
813 * sort the ACL and check it for validity
815 * if it's a minimal ACL with only 4 entries then we
816 * need to recalculate the mask permissions to make
817 * sure that they are the same as the GROUP_OBJ
818 * permissions as required by the UnixWare acl() system call.
820 * (note: since POSIX allows minimal ACLs which only contain
821 * 3 entries - ie there is no mask entry - we should, in theory,
822 * check for this and add a mask entry if necessary - however
823 * we "know" that the caller of this interface always specifies
824 * a mask so, in practice "this never happens" (tm) - if it *does*
825 * happen aclsort() will fail and return an error and someone will
826 * have to fix it ...)
829 static int acl_sort(SMB_ACL_T acl_d)
831 int fixmask = (acl_d->count <= 4);
833 if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {
840 int sys_acl_valid(SMB_ACL_T acl_d)
842 return acl_sort(acl_d);
845 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
850 struct acl *acl_buf = NULL;
853 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
858 if (acl_sort(acl_d) != 0) {
862 acl_p = &acl_d->acl[0];
863 acl_count = acl_d->count;
866 * if it's a directory there is extra work to do
867 * since the acl() system call will replace both
868 * the access ACLs and the default ACLs (if any)
870 if (stat(name, &s) != 0) {
873 if (S_ISDIR(s.st_mode)) {
879 if (type == SMB_ACL_TYPE_ACCESS) {
881 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
885 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
888 if (tmp_acl == NULL) {
893 * allocate a temporary buffer for the complete ACL
895 acl_count = acc_acl->count + def_acl->count;
896 acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
898 if (acl_buf == NULL) {
899 sys_acl_free_acl(tmp_acl);
905 * copy the access control and default entries into the buffer
907 memcpy(&acl_buf[0], &acc_acl->acl[0],
908 acc_acl->count * sizeof(acl_buf[0]));
910 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
911 def_acl->count * sizeof(acl_buf[0]));
914 * set the ACL_DEFAULT flag on the default entries
916 for (i = acc_acl->count; i < acl_count; i++) {
917 acl_buf[i].a_type |= ACL_DEFAULT;
920 sys_acl_free_acl(tmp_acl);
922 } else if (type != SMB_ACL_TYPE_ACCESS) {
927 ret = acl(name, SETACL, acl_count, acl_p);
934 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
936 if (acl_sort(acl_d) != 0) {
940 return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
943 int sys_acl_delete_def_file(const char *path)
949 * fetching the access ACL and rewriting it has
950 * the effect of deleting the default ACL
952 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
956 ret = acl(path, SETACL, acl_d->count, acl_d->acl);
958 sys_acl_free_acl(acl_d);
963 int sys_acl_free_text(char *text)
969 int sys_acl_free_acl(SMB_ACL_T acl_d)
975 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
980 #elif defined(HAVE_IRIX_ACLS)
982 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
984 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
989 if (entry_p == NULL) {
994 if (entry_id == SMB_ACL_FIRST_ENTRY) {
998 if (acl_d->next < 0) {
1003 if (acl_d->next >= acl_d->aclp->acl_cnt) {
1007 *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
1012 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
1014 *type_p = entry_d->ae_tag;
1019 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1021 *permset_p = entry_d;
1026 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
1028 if (entry_d->ae_tag != SMB_ACL_USER
1029 && entry_d->ae_tag != SMB_ACL_GROUP) {
1034 return &entry_d->ae_id;
1037 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
1041 if ((a = malloc(sizeof(*a))) == NULL) {
1045 if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
1054 SMB_ACL_T sys_acl_get_fd(int fd)
1058 if ((a = malloc(sizeof(*a))) == NULL) {
1062 if ((a->aclp = acl_get_fd(fd)) == NULL) {
1071 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
1073 permset_d->ae_perm = 0;
1078 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1080 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
1081 && perm != SMB_ACL_EXECUTE) {
1086 if (permset_d == NULL) {
1091 permset_d->ae_perm |= perm;
1096 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1098 return permset_d->ae_perm & perm;
1101 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
1103 return acl_to_text(acl_d->aclp, len_p);
1106 SMB_ACL_T sys_acl_init(int count)
1115 if ((a = malloc(sizeof(*a) + sizeof(struct acl))) == NULL) {
1121 a->freeaclp = False;
1122 a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
1123 a->aclp->acl_cnt = 0;
1129 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1132 SMB_ACL_ENTRY_T entry_d;
1134 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
1139 if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
1144 entry_d = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
1145 entry_d->ae_tag = 0;
1147 entry_d->ae_perm = 0;
1153 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1157 case SMB_ACL_USER_OBJ:
1159 case SMB_ACL_GROUP_OBJ:
1162 entry_d->ae_tag = tag_type;
1172 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
1174 if (entry_d->ae_tag != SMB_ACL_GROUP
1175 && entry_d->ae_tag != SMB_ACL_USER) {
1180 entry_d->ae_id = *((id_t *)qual_p);
1185 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1187 if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1191 entry_d->ae_perm = permset_d->ae_perm;
1196 int sys_acl_valid(SMB_ACL_T acl_d)
1198 return acl_valid(acl_d->aclp);
1201 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
1203 return acl_set_file(name, type, acl_d->aclp);
1206 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
1208 return acl_set_fd(fd, acl_d->aclp);
1211 int sys_acl_delete_def_file(const char *name)
1213 return acl_delete_def_file(name);
1216 int sys_acl_free_text(char *text)
1218 return acl_free(text);
1221 int sys_acl_free_acl(SMB_ACL_T acl_d)
1223 if (acl_d->freeaclp) {
1224 acl_free(acl_d->aclp);
1230 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
1235 #elif defined(HAVE_AIX_ACLS)
1237 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
1239 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1241 struct acl_entry_link *link;
1242 struct new_acl_entry *entry;
1245 DEBUG(10,("This is the count: %d\n",theacl->count));
1247 /* Check if count was previously set to -1. *
1248 * If it was, that means we reached the end *
1249 * of the acl last time. */
1250 if(theacl->count == -1)
1254 /* To get to the next acl, traverse linked list until index *
1255 * of acl matches the count we are keeping. This count is *
1256 * incremented each time we return an acl entry. */
1258 for(keep_going = 0; keep_going < theacl->count; keep_going++)
1261 entry = *entry_p = link->entryp;
1263 DEBUG(10,("*entry_p is %d\n",entry_p));
1264 DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
1266 /* Increment count */
1268 if(link->nextp == NULL)
1274 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1276 /* Initialize tag type */
1279 DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
1281 /* Depending on what type of entry we have, *
1282 * return tag type. */
1283 switch(entry_d->ace_id->id_type) {
1285 *tag_type_p = SMB_ACL_USER;
1288 *tag_type_p = SMB_ACL_GROUP;
1291 case SMB_ACL_USER_OBJ:
1292 case SMB_ACL_GROUP_OBJ:
1294 *tag_type_p = entry_d->ace_id->id_type;
1304 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1306 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
1307 *permset_p = &entry_d->ace_access;
1308 DEBUG(10,("**permset_p is %d\n",**permset_p));
1309 if(!(**permset_p & S_IXUSR) &&
1310 !(**permset_p & S_IWUSR) &&
1311 !(**permset_p & S_IRUSR) &&
1315 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
1319 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1321 return(entry_d->ace_id->id_data);
1324 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1326 struct acl *file_acl = (struct acl *)NULL;
1327 struct acl_entry *acl_entry;
1328 struct new_acl_entry *new_acl_entry;
1330 struct acl_entry_link *acl_entry_link;
1331 struct acl_entry_link *acl_entry_link_head;
1336 /* Get the acl using statacl */
1338 DEBUG(10,("Entering sys_acl_get_file\n"));
1339 DEBUG(10,("path_p is %s\n",path_p));
1341 file_acl = (struct acl *)malloc(BUFSIZ);
1343 if(file_acl == NULL) {
1345 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
1349 memset(file_acl,0,BUFSIZ);
1351 rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
1353 DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
1354 SAFE_FREE(file_acl);
1358 DEBUG(10,("Got facl and returned it\n"));
1360 /* Point to the first acl entry in the acl */
1361 acl_entry = file_acl->acl_ext;
1363 /* Begin setting up the head of the linked list *
1364 * that will be used for the storing the acl *
1365 * in a way that is useful for the posix_acls.c *
1368 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1369 if(acl_entry_link_head == NULL)
1372 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1373 if(acl_entry_link->entryp == NULL) {
1374 SAFE_FREE(file_acl);
1376 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1380 DEBUG(10,("acl_entry is %d\n",acl_entry));
1381 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1383 /* Check if the extended acl bit is on. *
1384 * If it isn't, do not show the *
1385 * contents of the acl since AIX intends *
1386 * the extended info to remain unused */
1388 if(file_acl->acl_mode & S_IXACL){
1389 /* while we are not pointing to the very end */
1390 while(acl_entry < acl_last(file_acl)) {
1391 /* before we malloc anything, make sure this is */
1392 /* a valid acl entry and one that we want to map */
1393 idp = id_nxt(acl_entry->ace_id);
1394 if((acl_entry->ace_type == ACC_SPECIFY ||
1395 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1396 acl_entry = acl_nxt(acl_entry);
1400 idp = acl_entry->ace_id;
1402 /* Check if this is the first entry in the linked list. *
1403 * The first entry needs to keep prevp pointing to NULL *
1404 * and already has entryp allocated. */
1406 if(acl_entry_link_head->count != 0) {
1407 acl_entry_link->nextp = (struct acl_entry_link *)
1408 malloc(sizeof(struct acl_entry_link));
1410 if(acl_entry_link->nextp == NULL) {
1411 SAFE_FREE(file_acl);
1413 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1417 acl_entry_link->nextp->prevp = acl_entry_link;
1418 acl_entry_link = acl_entry_link->nextp;
1419 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1420 if(acl_entry_link->entryp == NULL) {
1421 SAFE_FREE(file_acl);
1423 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1426 acl_entry_link->nextp = NULL;
1429 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1431 /* Don't really need this since all types are going *
1432 * to be specified but, it's better than leaving it 0 */
1434 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1436 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1438 memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
1440 /* The access in the acl entries must be left shifted by *
1441 * three bites, because they will ultimately be compared *
1442 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1444 switch(acl_entry->ace_type){
1447 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1448 acl_entry_link->entryp->ace_access <<= 6;
1449 acl_entry_link_head->count++;
1452 /* Since there is no way to return a DENY acl entry *
1453 * change to PERMIT and then shift. */
1454 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1455 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1456 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1457 acl_entry_link->entryp->ace_access <<= 6;
1458 acl_entry_link_head->count++;
1464 DEBUG(10,("acl_entry = %d\n",acl_entry));
1465 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1467 acl_entry = acl_nxt(acl_entry);
1469 } /* end of if enabled */
1471 /* Since owner, group, other acl entries are not *
1472 * part of the acl entries in an acl, they must *
1473 * be dummied up to become part of the list. */
1475 for( i = 1; i < 4; i++) {
1476 DEBUG(10,("i is %d\n",i));
1477 if(acl_entry_link_head->count != 0) {
1478 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1479 if(acl_entry_link->nextp == NULL) {
1480 SAFE_FREE(file_acl);
1482 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1486 acl_entry_link->nextp->prevp = acl_entry_link;
1487 acl_entry_link = acl_entry_link->nextp;
1488 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1489 if(acl_entry_link->entryp == NULL) {
1490 SAFE_FREE(file_acl);
1492 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1497 acl_entry_link->nextp = NULL;
1499 new_acl_entry = acl_entry_link->entryp;
1500 idp = new_acl_entry->ace_id;
1502 new_acl_entry->ace_len = sizeof(struct acl_entry);
1503 new_acl_entry->ace_type = ACC_PERMIT;
1504 idp->id_len = sizeof(struct ace_id);
1505 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1506 memset(idp->id_data,0,sizeof(uid_t));
1510 new_acl_entry->ace_access = file_acl->g_access << 6;
1511 idp->id_type = SMB_ACL_GROUP_OBJ;
1515 new_acl_entry->ace_access = file_acl->o_access << 6;
1516 idp->id_type = SMB_ACL_OTHER;
1520 new_acl_entry->ace_access = file_acl->u_access << 6;
1521 idp->id_type = SMB_ACL_USER_OBJ;
1529 acl_entry_link_head->count++;
1530 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1533 acl_entry_link_head->count = 0;
1534 SAFE_FREE(file_acl);
1536 return(acl_entry_link_head);
1539 SMB_ACL_T sys_acl_get_fd(int fd)
1541 struct acl *file_acl = (struct acl *)NULL;
1542 struct acl_entry *acl_entry;
1543 struct new_acl_entry *new_acl_entry;
1545 struct acl_entry_link *acl_entry_link;
1546 struct acl_entry_link *acl_entry_link_head;
1551 /* Get the acl using fstatacl */
1553 DEBUG(10,("Entering sys_acl_get_fd\n"));
1554 DEBUG(10,("fd is %d\n",fd));
1555 file_acl = (struct acl *)malloc(BUFSIZ);
1557 if(file_acl == NULL) {
1559 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1563 memset(file_acl,0,BUFSIZ);
1565 rc = fstatacl(fd,0,file_acl,BUFSIZ);
1567 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
1568 SAFE_FREE(file_acl);
1572 DEBUG(10,("Got facl and returned it\n"));
1574 /* Point to the first acl entry in the acl */
1576 acl_entry = file_acl->acl_ext;
1577 /* Begin setting up the head of the linked list *
1578 * that will be used for the storing the acl *
1579 * in a way that is useful for the posix_acls.c *
1582 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1583 if(acl_entry_link_head == NULL){
1584 SAFE_FREE(file_acl);
1588 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1590 if(acl_entry_link->entryp == NULL) {
1592 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1593 SAFE_FREE(file_acl);
1597 DEBUG(10,("acl_entry is %d\n",acl_entry));
1598 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1600 /* Check if the extended acl bit is on. *
1601 * If it isn't, do not show the *
1602 * contents of the acl since AIX intends *
1603 * the extended info to remain unused */
1605 if(file_acl->acl_mode & S_IXACL){
1606 /* while we are not pointing to the very end */
1607 while(acl_entry < acl_last(file_acl)) {
1608 /* before we malloc anything, make sure this is */
1609 /* a valid acl entry and one that we want to map */
1611 idp = id_nxt(acl_entry->ace_id);
1612 if((acl_entry->ace_type == ACC_SPECIFY ||
1613 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1614 acl_entry = acl_nxt(acl_entry);
1618 idp = acl_entry->ace_id;
1620 /* Check if this is the first entry in the linked list. *
1621 * The first entry needs to keep prevp pointing to NULL *
1622 * and already has entryp allocated. */
1624 if(acl_entry_link_head->count != 0) {
1625 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1626 if(acl_entry_link->nextp == NULL) {
1628 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1629 SAFE_FREE(file_acl);
1632 acl_entry_link->nextp->prevp = acl_entry_link;
1633 acl_entry_link = acl_entry_link->nextp;
1634 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1635 if(acl_entry_link->entryp == NULL) {
1637 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1638 SAFE_FREE(file_acl);
1642 acl_entry_link->nextp = NULL;
1645 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1647 /* Don't really need this since all types are going *
1648 * to be specified but, it's better than leaving it 0 */
1650 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1651 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1653 memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
1655 /* The access in the acl entries must be left shifted by *
1656 * three bites, because they will ultimately be compared *
1657 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1659 switch(acl_entry->ace_type){
1662 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1663 acl_entry_link->entryp->ace_access <<= 6;
1664 acl_entry_link_head->count++;
1667 /* Since there is no way to return a DENY acl entry *
1668 * change to PERMIT and then shift. */
1669 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1670 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1671 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1672 acl_entry_link->entryp->ace_access <<= 6;
1673 acl_entry_link_head->count++;
1679 DEBUG(10,("acl_entry = %d\n",acl_entry));
1680 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1682 acl_entry = acl_nxt(acl_entry);
1684 } /* end of if enabled */
1686 /* Since owner, group, other acl entries are not *
1687 * part of the acl entries in an acl, they must *
1688 * be dummied up to become part of the list. */
1690 for( i = 1; i < 4; i++) {
1691 DEBUG(10,("i is %d\n",i));
1692 if(acl_entry_link_head->count != 0){
1693 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1694 if(acl_entry_link->nextp == NULL) {
1696 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1697 SAFE_FREE(file_acl);
1701 acl_entry_link->nextp->prevp = acl_entry_link;
1702 acl_entry_link = acl_entry_link->nextp;
1703 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1705 if(acl_entry_link->entryp == NULL) {
1706 SAFE_FREE(file_acl);
1708 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1713 acl_entry_link->nextp = NULL;
1715 new_acl_entry = acl_entry_link->entryp;
1716 idp = new_acl_entry->ace_id;
1718 new_acl_entry->ace_len = sizeof(struct acl_entry);
1719 new_acl_entry->ace_type = ACC_PERMIT;
1720 idp->id_len = sizeof(struct ace_id);
1721 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1722 memset(idp->id_data,0,sizeof(uid_t));
1726 new_acl_entry->ace_access = file_acl->g_access << 6;
1727 idp->id_type = SMB_ACL_GROUP_OBJ;
1731 new_acl_entry->ace_access = file_acl->o_access << 6;
1732 idp->id_type = SMB_ACL_OTHER;
1736 new_acl_entry->ace_access = file_acl->u_access << 6;
1737 idp->id_type = SMB_ACL_USER_OBJ;
1744 acl_entry_link_head->count++;
1745 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1748 acl_entry_link_head->count = 0;
1749 SAFE_FREE(file_acl);
1751 return(acl_entry_link_head);
1754 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
1756 *permset = *permset & ~0777;
1760 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1763 (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0)
1767 DEBUG(10,("This is the permset now: %d\n",*permset));
1771 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
1776 SMB_ACL_T sys_acl_init( int count)
1778 struct acl_entry_link *theacl = NULL;
1780 DEBUG(10,("Entering sys_acl_init\n"));
1782 theacl = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1783 if(theacl == NULL) {
1785 DEBUG(0,("Error in sys_acl_init is %d\n",errno));
1790 theacl->nextp = NULL;
1791 theacl->prevp = NULL;
1792 theacl->entryp = NULL;
1793 DEBUG(10,("Exiting sys_acl_init\n"));
1797 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1799 struct acl_entry_link *theacl;
1800 struct acl_entry_link *acl_entryp;
1801 struct acl_entry_link *temp_entry;
1804 DEBUG(10,("Entering the sys_acl_create_entry\n"));
1806 theacl = acl_entryp = *pacl;
1808 /* Get to the end of the acl before adding entry */
1810 for(counting=0; counting < theacl->count; counting++){
1811 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1812 temp_entry = acl_entryp;
1813 acl_entryp = acl_entryp->nextp;
1816 if(theacl->count != 0){
1817 temp_entry->nextp = acl_entryp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1818 if(acl_entryp == NULL) {
1820 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1824 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1825 acl_entryp->prevp = temp_entry;
1826 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
1829 *pentry = acl_entryp->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1830 if(*pentry == NULL) {
1832 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1836 memset(*pentry,0,sizeof(struct new_acl_entry));
1837 acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
1838 acl_entryp->entryp->ace_type = ACC_PERMIT;
1839 acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
1840 acl_entryp->nextp = NULL;
1842 DEBUG(10,("Exiting sys_acl_create_entry\n"));
1846 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1848 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
1849 entry->ace_id->id_type = tagtype;
1850 DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
1851 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
1854 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
1856 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
1857 memcpy(entry->ace_id->id_data,qual,sizeof(uid_t));
1858 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
1862 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1864 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
1865 if(!(*permset & S_IXUSR) &&
1866 !(*permset & S_IWUSR) &&
1867 !(*permset & S_IRUSR) &&
1871 entry->ace_access = *permset;
1872 DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
1873 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
1877 int sys_acl_valid( SMB_ACL_T theacl )
1882 struct acl_entry_link *acl_entry;
1884 for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
1885 user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
1886 group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
1887 other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
1890 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
1892 if(user_obj != 1 || group_obj != 1 || other_obj != 1)
1898 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1900 struct acl_entry_link *acl_entry_link = NULL;
1901 struct acl *file_acl = NULL;
1902 struct acl *file_acl_temp = NULL;
1903 struct acl_entry *acl_entry = NULL;
1904 struct ace_id *ace_id = NULL;
1911 DEBUG(10,("Entering sys_acl_set_file\n"));
1912 DEBUG(10,("File name is %s\n",name));
1914 /* AIX has no default ACL */
1915 if(acltype == SMB_ACL_TYPE_DEFAULT)
1918 acl_length = BUFSIZ;
1919 file_acl = (struct acl *)malloc(BUFSIZ);
1921 if(file_acl == NULL) {
1923 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
1927 memset(file_acl,0,BUFSIZ);
1929 file_acl->acl_len = ACL_SIZ;
1930 file_acl->acl_mode = S_IXACL;
1932 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
1933 acl_entry_link->entryp->ace_access >>= 6;
1934 id_type = acl_entry_link->entryp->ace_id->id_type;
1937 case SMB_ACL_USER_OBJ:
1938 file_acl->u_access = acl_entry_link->entryp->ace_access;
1940 case SMB_ACL_GROUP_OBJ:
1941 file_acl->g_access = acl_entry_link->entryp->ace_access;
1944 file_acl->o_access = acl_entry_link->entryp->ace_access;
1950 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
1951 acl_length += sizeof(struct acl_entry);
1952 file_acl_temp = (struct acl *)malloc(acl_length);
1953 if(file_acl_temp == NULL) {
1954 SAFE_FREE(file_acl);
1956 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
1960 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
1961 SAFE_FREE(file_acl);
1962 file_acl = file_acl_temp;
1965 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
1966 file_acl->acl_len += sizeof(struct acl_entry);
1967 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
1968 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
1970 /* In order to use this, we'll need to wait until we can get denies */
1971 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
1972 acl_entry->ace_type = ACC_SPECIFY; */
1974 acl_entry->ace_type = ACC_SPECIFY;
1976 ace_id = acl_entry->ace_id;
1978 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
1979 DEBUG(10,("The id type is %d\n",ace_id->id_type));
1980 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
1981 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
1982 memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
1985 rc = chacl(name,file_acl,file_acl->acl_len);
1986 DEBUG(10,("errno is %d\n",errno));
1987 DEBUG(10,("return code is %d\n",rc));
1988 SAFE_FREE(file_acl);
1989 DEBUG(10,("Exiting the sys_acl_set_file\n"));
1993 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
1995 struct acl_entry_link *acl_entry_link = NULL;
1996 struct acl *file_acl = NULL;
1997 struct acl *file_acl_temp = NULL;
1998 struct acl_entry *acl_entry = NULL;
1999 struct ace_id *ace_id = NULL;
2005 DEBUG(10,("Entering sys_acl_set_fd\n"));
2006 acl_length = BUFSIZ;
2007 file_acl = (struct acl *)malloc(BUFSIZ);
2009 if(file_acl == NULL) {
2011 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2015 memset(file_acl,0,BUFSIZ);
2017 file_acl->acl_len = ACL_SIZ;
2018 file_acl->acl_mode = S_IXACL;
2020 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2021 acl_entry_link->entryp->ace_access >>= 6;
2022 id_type = acl_entry_link->entryp->ace_id->id_type;
2023 DEBUG(10,("The id_type is %d\n",id_type));
2026 case SMB_ACL_USER_OBJ:
2027 file_acl->u_access = acl_entry_link->entryp->ace_access;
2029 case SMB_ACL_GROUP_OBJ:
2030 file_acl->g_access = acl_entry_link->entryp->ace_access;
2033 file_acl->o_access = acl_entry_link->entryp->ace_access;
2039 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2040 acl_length += sizeof(struct acl_entry);
2041 file_acl_temp = (struct acl *)malloc(acl_length);
2042 if(file_acl_temp == NULL) {
2043 SAFE_FREE(file_acl);
2045 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2049 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2050 SAFE_FREE(file_acl);
2051 file_acl = file_acl_temp;
2054 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2055 file_acl->acl_len += sizeof(struct acl_entry);
2056 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2057 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2059 /* In order to use this, we'll need to wait until we can get denies */
2060 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2061 acl_entry->ace_type = ACC_SPECIFY; */
2063 acl_entry->ace_type = ACC_SPECIFY;
2065 ace_id = acl_entry->ace_id;
2067 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2068 DEBUG(10,("The id type is %d\n",ace_id->id_type));
2069 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2070 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2071 memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
2074 rc = fchacl(fd,file_acl,file_acl->acl_len);
2075 DEBUG(10,("errno is %d\n",errno));
2076 DEBUG(10,("return code is %d\n",rc));
2077 SAFE_FREE(file_acl);
2078 DEBUG(10,("Exiting sys_acl_set_fd\n"));
2082 int sys_acl_delete_def_file(const char *name)
2084 /* AIX has no default ACL */
2088 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2090 return(*permset & perm);
2093 int sys_acl_free_text(char *text)
2098 int sys_acl_free_acl(SMB_ACL_T posix_acl)
2100 struct acl_entry_link *acl_entry_link;
2102 for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
2103 SAFE_FREE(acl_entry_link->prevp->entryp);
2104 SAFE_FREE(acl_entry_link->prevp);
2107 SAFE_FREE(acl_entry_link->prevp->entryp);
2108 SAFE_FREE(acl_entry_link->prevp);
2109 SAFE_FREE(acl_entry_link->entryp);
2110 SAFE_FREE(acl_entry_link);
2115 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
2120 #else /* No ACLs. */
2122 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
2128 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
2134 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
2140 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
2146 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
2149 return (SMB_ACL_T)NULL;
2152 SMB_ACL_T sys_acl_get_fd(int fd)
2155 return (SMB_ACL_T)NULL;
2158 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
2164 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2170 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2173 return (permset & perm) ? 1 : 0;
2176 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
2182 int sys_acl_free_text(char *text)
2188 SMB_ACL_T sys_acl_init( int count)
2194 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2200 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2206 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
2212 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2218 int sys_acl_valid( SMB_ACL_T theacl )
2224 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2230 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2236 int sys_acl_delete_def_file(const char *name)
2242 int sys_acl_free_acl(SMB_ACL_T the_acl)
2248 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
2254 #endif /* No ACLs. */