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(SMB_ACL_T posix_acl)
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)
191 return acl_free(qual);
194 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
197 * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
198 * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
202 * Note that while this code implements sufficient functionality
203 * to support the sys_acl_* interfaces it does not provide all
204 * of the semantics of the POSIX ACL interfaces.
206 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
207 * from a call to sys_acl_get_entry() should not be assumed to be
208 * valid after calling any of the following functions, which may
209 * reorder the entries in the ACL.
217 * The only difference between Solaris and UnixWare / OpenUNIX is
218 * that the #defines for the ACL operations have different names
220 #if defined(HAVE_UNIXWARE_ACLS)
222 #define SETACL ACL_SET
223 #define GETACL ACL_GET
224 #define GETACLCNT ACL_CNT
229 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
231 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
236 if (entry_p == NULL) {
241 if (entry_id == SMB_ACL_FIRST_ENTRY) {
245 if (acl_d->next < 0) {
250 if (acl_d->next >= acl_d->count) {
254 *entry_p = &acl_d->acl[acl_d->next++];
259 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
261 *type_p = entry_d->a_type;
266 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
268 *permset_p = &entry_d->a_perm;
273 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
275 if (entry_d->a_type != SMB_ACL_USER
276 && entry_d->a_type != SMB_ACL_GROUP) {
281 return &entry_d->a_id;
285 * There is no way of knowing what size the ACL returned by
286 * GETACL will be unless you first call GETACLCNT which means
287 * making an additional system call.
289 * In the hope of avoiding the cost of the additional system
290 * call in most cases, we initially allocate enough space for
291 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
292 * be too small then we use GETACLCNT to find out the actual
293 * size, reallocate the ACL buffer, and then call GETACL again.
296 #define INITIAL_ACL_SIZE 16
298 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
301 int count; /* # of ACL entries allocated */
302 int naccess; /* # of access ACL entries */
303 int ndefault; /* # of default ACL entries */
305 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
310 count = INITIAL_ACL_SIZE;
311 if ((acl_d = sys_acl_init(count)) == NULL) {
316 * If there isn't enough space for the ACL entries we use
317 * GETACLCNT to determine the actual number of ACL entries
318 * reallocate and try again. This is in a loop because it
319 * is possible that someone else could modify the ACL and
320 * increase the number of entries between the call to
321 * GETACLCNT and the call to GETACL.
323 while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0
324 && errno == ENOSPC) {
326 sys_acl_free_acl(acl_d);
328 if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) {
332 if ((acl_d = sys_acl_init(count)) == NULL) {
338 sys_acl_free_acl(acl_d);
343 * calculate the number of access and default ACL entries
345 * Note: we assume that the acl() system call returned a
346 * well formed ACL which is sorted so that all of the
347 * access ACL entries preceed any default ACL entries
349 for (naccess = 0; naccess < count; naccess++) {
350 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
353 ndefault = count - naccess;
356 * if the caller wants the default ACL we have to copy
357 * the entries down to the start of the acl[] buffer
358 * and mask out the ACL_DEFAULT flag from the type field
360 if (type == SMB_ACL_TYPE_DEFAULT) {
363 for (i = 0, j = naccess; i < ndefault; i++, j++) {
364 acl_d->acl[i] = acl_d->acl[j];
365 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
368 acl_d->count = ndefault;
370 acl_d->count = naccess;
376 SMB_ACL_T sys_acl_get_fd(int fd)
379 int count; /* # of ACL entries allocated */
380 int naccess; /* # of access ACL entries */
382 count = INITIAL_ACL_SIZE;
383 if ((acl_d = sys_acl_init(count)) == NULL) {
387 while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0
388 && errno == ENOSPC) {
390 sys_acl_free_acl(acl_d);
392 if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) {
396 if ((acl_d = sys_acl_init(count)) == NULL) {
402 sys_acl_free_acl(acl_d);
407 * calculate the number of access ACL entries
409 for (naccess = 0; naccess < count; naccess++) {
410 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
414 acl_d->count = naccess;
419 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
426 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
428 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
429 && perm != SMB_ACL_EXECUTE) {
434 if (permset_d == NULL) {
444 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
446 return *permset_d & perm;
449 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
456 * use an initial estimate of 20 bytes per ACL entry
457 * when allocating memory for the text representation
461 maxlen = 20 * acl_d->count;
462 if ((text = malloc(maxlen)) == NULL) {
467 for (i = 0; i < acl_d->count; i++) {
468 struct acl *ap = &acl_d->acl[i];
478 switch (ap->a_type) {
480 * for debugging purposes it's probably more
481 * useful to dump unknown tag types rather
482 * than just returning an error
485 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
488 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
494 if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
495 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
501 case SMB_ACL_USER_OBJ:
506 if ((gr = getgrgid(ap->a_id)) == NULL) {
507 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
513 case SMB_ACL_GROUP_OBJ:
527 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
528 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
529 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
532 /* <tag> : <qualifier> : rwx \n \0 */
533 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
536 * If this entry would overflow the buffer
537 * allocate enough additional memory for this
538 * entry and an estimate of another 20 bytes
539 * for each entry still to be processed
541 if ((len + nbytes) > maxlen) {
542 char *oldtext = text;
544 maxlen += nbytes + 20 * (acl_d->count - i);
546 if ((text = realloc(oldtext, maxlen)) == NULL) {
553 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
563 SMB_ACL_T sys_acl_init(int count)
573 * note that since the definition of the structure pointed
574 * to by the SMB_ACL_T includes the first element of the
575 * acl[] array, this actually allocates an ACL with room
576 * for (count+1) entries
578 if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
591 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
594 SMB_ACL_ENTRY_T entry_d;
596 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
601 if (acl_d->count >= acl_d->size) {
606 entry_d = &acl_d->acl[acl_d->count++];
615 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
619 case SMB_ACL_USER_OBJ:
621 case SMB_ACL_GROUP_OBJ:
624 entry_d->a_type = tag_type;
634 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
636 if (entry_d->a_type != SMB_ACL_GROUP
637 && entry_d->a_type != SMB_ACL_USER) {
642 entry_d->a_id = *((id_t *)qual_p);
647 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
649 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
653 entry_d->a_perm = *permset_d;
659 * sort the ACL and check it for validity
661 * if it's a minimal ACL with only 4 entries then we
662 * need to recalculate the mask permissions to make
663 * sure that they are the same as the GROUP_OBJ
664 * permissions as required by the UnixWare acl() system call.
666 * (note: since POSIX allows minimal ACLs which only contain
667 * 3 entries - ie there is no mask entry - we should, in theory,
668 * check for this and add a mask entry if necessary - however
669 * we "know" that the caller of this interface always specifies
670 * a mask so, in practice "this never happens" (tm) - if it *does*
671 * happen aclsort() will fail and return an error and someone will
672 * have to fix it ...)
675 static int acl_sort(SMB_ACL_T acl_d)
677 int fixmask = (acl_d->count <= 4);
679 if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {
686 int sys_acl_valid(SMB_ACL_T acl_d)
688 return acl_sort(acl_d);
691 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
696 struct acl *acl_buf = NULL;
699 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
704 if (acl_sort(acl_d) != 0) {
708 acl_p = &acl_d->acl[0];
709 acl_count = acl_d->count;
712 * if it's a directory there is extra work to do
713 * since the acl() system call will replace both
714 * the access ACLs and the default ACLs (if any)
716 if (stat(name, &s) != 0) {
719 if (S_ISDIR(s.st_mode)) {
725 if (type == SMB_ACL_TYPE_ACCESS) {
727 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
731 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
734 if (tmp_acl == NULL) {
739 * allocate a temporary buffer for the complete ACL
741 acl_count = acc_acl->count + def_acl->count;
742 acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
744 if (acl_buf == NULL) {
745 sys_acl_free_acl(tmp_acl);
751 * copy the access control and default entries into the buffer
753 memcpy(&acl_buf[0], &acc_acl->acl[0],
754 acc_acl->count * sizeof(acl_buf[0]));
756 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
757 def_acl->count * sizeof(acl_buf[0]));
760 * set the ACL_DEFAULT flag on the default entries
762 for (i = acc_acl->count; i < acl_count; i++) {
763 acl_buf[i].a_type |= ACL_DEFAULT;
766 sys_acl_free_acl(tmp_acl);
768 } else if (type != SMB_ACL_TYPE_ACCESS) {
773 ret = acl(name, SETACL, acl_count, acl_p);
782 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
784 if (acl_sort(acl_d) {
788 return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
791 int sys_acl_delete_def_file(const char *path)
797 * fetching the access ACL and rewriting it has
798 * the effect of deleting the default ACL
800 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
804 ret = acl(path, SETACL, acl_d->count, acl_d->acl);
806 sys_acl_free_acl(acl_d);
811 int sys_acl_free_text(char *text)
817 int sys_acl_free_acl(SMB_ACL_T acl_d)
823 int sys_acl_free_qualifier(void *qual)
828 #elif defined(HAVE_IRIX_ACLS)
830 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
832 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
837 if (entry_p == NULL) {
842 if (entry_id == SMB_ACL_FIRST_ENTRY) {
846 if (acl_d->next < 0) {
851 if (acl_d->next >= acl_d->aclp->acl_cnt) {
855 *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
860 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
862 *type_p = entry_d->ae_tag;
867 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
869 *permset_p = entry_d;
874 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
876 if (entry_d->ae_tag != SMB_ACL_USER
877 && entry_d->ae_tag != SMB_ACL_GROUP) {
882 return &entry_d->ae_id;
885 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
889 if ((a = malloc(sizeof(*a))) == NULL) {
893 if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
902 SMB_ACL_T sys_acl_get_fd(int fd)
906 if ((a = malloc(sizeof(*a))) == NULL) {
910 if ((a->aclp = acl_get_fd(fd)) == NULL) {
919 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
921 permset_d->ae_perm = 0;
926 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
928 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
929 && perm != SMB_ACL_EXECUTE) {
934 if (permset_d == NULL) {
939 permset_d->ae_perm |= perm;
944 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
946 return permset_d->ae_perm & perm;
949 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
951 return acl_to_text(acl_d->aclp, len_p);
954 SMB_ACL_T sys_acl_init(int count)
963 if ((a = malloc(sizeof(*a) + sizeof(struct acl))) == NULL) {
970 a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
971 a->aclp->acl_cnt = 0;
977 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
980 SMB_ACL_ENTRY_T entry_d;
982 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
987 if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
992 entry_d = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
995 entry_d->ae_perm = 0;
1001 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1005 case SMB_ACL_USER_OBJ:
1007 case SMB_ACL_GROUP_OBJ:
1010 entry_d->ae_tag = tag_type;
1020 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
1022 if (entry_d->ae_tag != SMB_ACL_GROUP
1023 && entry_d->ae_tag != SMB_ACL_USER) {
1028 entry_d->ae_id = *((id_t *)qual_p);
1033 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1035 if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1039 entry_d->ae_perm = permset_d->ae_perm;
1044 int sys_acl_valid(SMB_ACL_T acl_d)
1046 return acl_valid(acl_d->aclp);
1049 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
1051 return acl_set_file(name, type, acl_d->aclp);
1054 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
1056 return acl_set_fd(fd, acl_d->aclp);
1059 int sys_acl_free_text(char *text)
1061 return acl_free(text);
1064 int sys_acl_free_acl(SMB_ACL_T acl_d)
1066 if (acl_d->freeaclp) {
1067 acl_free(acl_d->aclp);
1073 int sys_acl_free_qualifier(void *qual)
1078 #elif defined(HAVE_XFS_ACLS)
1079 /* For Linux SGI/XFS Filesystems
1080 * contributed by J Trostel, Connex
1083 /* based on the implementation for Solaris by Toomas Soome.. which is
1084 * based on the implementation by Micheal Davidson for Unixware...
1086 * Linux XFS is a 'work-in-progress'
1087 * This interface may change...
1088 * You've been warned ;-> */
1090 /* First, do the identity mapping */
1092 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1094 if( acl_get_entry( the_acl, entry_id, entry_p) >= 0) {
1102 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1104 return acl_get_file( path_p, type);
1107 SMB_ACL_T sys_acl_get_fd(int fd)
1109 return acl_get_fd(fd);
1112 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
1114 return acl_to_text( the_acl, plen);
1117 int sys_acl_valid( SMB_ACL_T theacl )
1119 return acl_valid(theacl);
1122 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1124 return acl_set_file(name, acltype, theacl);
1127 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
1129 return acl_set_fd(fd, theacl);
1132 /* Now the functions I need to define for XFS */
1134 int sys_acl_create_entry( SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1143 if((*acl_p == NULL) || (ace == NULL)){
1149 if( (cnt + 1) > ACL_MAX_ENTRIES ){
1154 newacl = (acl_t)malloc(sizeof(struct acl));
1161 newacl->acl_entry[cnt] = *ace;
1162 newacl->acl_cnt = cnt + 1;
1166 *entry_p = &newacl->acl_entry[cnt];
1171 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1173 *tag_type_p = entry_d->ae_tag;
1177 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1179 *permset_p = &entry_d->ae_perm;
1183 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1185 if (entry_d->ae_tag != SMB_ACL_USER
1186 && entry_d->ae_tag != SMB_ACL_GROUP) {
1190 return &entry_d->ae_id;
1193 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
1199 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1201 return (*permset & perm);
1204 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1207 /* TO DO: Add in ALL possible permissions here */
1208 /* TO DO: Include extended ones!! */
1210 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE && perm != SMB_ACL_EXECUTE) {
1215 if(permset == NULL) {
1225 SMB_ACL_T sys_acl_init( int count)
1228 if((count > ACL_MAX_ENTRIES) || (count < 0)) {
1233 a = (struct acl *)malloc(sizeof(struct acl)); /* where is this memory freed? */
1239 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1244 case SMB_ACL_USER_OBJ:
1246 case SMB_ACL_GROUP_OBJ:
1249 entry_d->ae_tag = tag_type;
1258 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry_d, void *qual_p)
1260 if(entry_d->ae_tag != SMB_ACL_GROUP &&
1261 entry_d->ae_tag != SMB_ACL_USER) {
1266 entry_d->ae_id = *((uid_t *)qual_p);
1271 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1273 /* TO DO: expand to extended permissions eventually! */
1275 if(*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1282 int sys_acl_free_text(char *text)
1284 return acl_free(text);
1287 int sys_acl_free_acl(SMB_ACL_T the_acl)
1289 return acl_free(the_acl);
1292 int sys_acl_free_qualifier(void *qual)
1297 #elif defined(HAVE_AIX_ACLS)
1299 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
1301 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1303 struct acl_entry_link *link;
1304 struct new_acl_entry *entry;
1307 DEBUG(10,("This is the count: %d\n",theacl->count));
1309 /* Check if count was previously set to -1. *
1310 * If it was, that means we reached the end *
1311 * of the acl last time. */
1312 if(theacl->count == -1)
1316 /* To get to the next acl, traverse linked list until index *
1317 * of acl matches the count we are keeping. This count is *
1318 * incremented each time we return an acl entry. */
1320 for(keep_going = 0; keep_going < theacl->count; keep_going++)
1323 entry = *entry_p = link->entryp;
1325 DEBUG(10,("*entry_p is %d\n",entry_p));
1326 DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
1328 /* Increment count */
1330 if(link->nextp == NULL)
1336 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1338 /* Initialize tag type */
1341 DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
1343 /* Depending on what type of entry we have, *
1344 * return tag type. */
1345 switch(entry_d->ace_id->id_type) {
1347 *tag_type_p = SMB_ACL_USER;
1350 *tag_type_p = SMB_ACL_GROUP;
1353 case SMB_ACL_USER_OBJ:
1354 case SMB_ACL_GROUP_OBJ:
1356 *tag_type_p = entry_d->ace_id->id_type;
1366 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1368 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
1369 *permset_p = &entry_d->ace_access;
1370 DEBUG(10,("**permset_p is %d\n",**permset_p));
1371 if(!(**permset_p & S_IXUSR) &&
1372 !(**permset_p & S_IWUSR) &&
1373 !(**permset_p & S_IRUSR) &&
1377 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
1381 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1383 return(entry_d->ace_id->id_data);
1386 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1388 struct acl *file_acl = (struct acl *)NULL;
1389 struct acl_entry *acl_entry;
1390 struct new_acl_entry *new_acl_entry;
1392 struct acl_entry_link *acl_entry_link;
1393 struct acl_entry_link *acl_entry_link_head;
1398 /* Get the acl using statacl */
1400 DEBUG(10,("Entering sys_acl_get_file\n"));
1401 DEBUG(10,("path_p is %s\n",path_p));
1403 file_acl = (struct acl *)malloc(BUFSIZ);
1405 if(file_acl == NULL) {
1407 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
1411 memset(file_acl,0,BUFSIZ);
1413 rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
1415 DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
1420 DEBUG(10,("Got facl and returned it\n"));
1422 /* Point to the first acl entry in the acl */
1423 acl_entry = file_acl->acl_ext;
1425 /* Begin setting up the head of the linked list *
1426 * that will be used for the storing the acl *
1427 * in a way that is useful for the posix_acls.c *
1430 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1431 if(acl_entry_link_head == NULL)
1434 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1435 if(acl_entry_link->entryp == NULL) {
1438 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1442 DEBUG(10,("acl_entry is %d\n",acl_entry));
1443 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1445 /* Check if the extended acl bit is on. *
1446 * If it isn't, do not show the *
1447 * contents of the acl since AIX intends *
1448 * the extended info to remain unused */
1450 if(file_acl->acl_mode & S_IXACL){
1451 /* while we are not pointing to the very end */
1452 while(acl_entry < acl_last(file_acl)) {
1453 /* before we malloc anything, make sure this is */
1454 /* a valid acl entry and one that we want to map */
1455 idp = id_nxt(acl_entry->ace_id);
1456 if((acl_entry->ace_type == ACC_SPECIFY ||
1457 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1458 acl_entry = acl_nxt(acl_entry);
1462 idp = acl_entry->ace_id;
1464 /* Check if this is the first entry in the linked list. *
1465 * The first entry needs to keep prevp pointing to NULL *
1466 * and already has entryp allocated. */
1468 if(acl_entry_link_head->count != 0) {
1469 acl_entry_link->nextp = (struct acl_entry_link *)
1470 malloc(sizeof(struct acl_entry_link));
1472 if(acl_entry_link->nextp == NULL) {
1475 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1479 acl_entry_link->nextp->prevp = acl_entry_link;
1480 acl_entry_link = acl_entry_link->nextp;
1481 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1482 if(acl_entry_link->entryp == NULL) {
1485 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1488 acl_entry_link->nextp = NULL;
1491 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1493 /* Don't really need this since all types are going *
1494 * to be specified but, it's better than leaving it 0 */
1496 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1498 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1500 memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
1502 /* The access in the acl entries must be left shifted by *
1503 * three bites, because they will ultimately be compared *
1504 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1506 switch(acl_entry->ace_type){
1509 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1510 acl_entry_link->entryp->ace_access <<= 6;
1511 acl_entry_link_head->count++;
1514 /* Since there is no way to return a DENY acl entry *
1515 * change to PERMIT and then shift. */
1516 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1517 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1518 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1519 acl_entry_link->entryp->ace_access <<= 6;
1520 acl_entry_link_head->count++;
1526 DEBUG(10,("acl_entry = %d\n",acl_entry));
1527 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1529 acl_entry = acl_nxt(acl_entry);
1531 } /* end of if enabled */
1533 /* Since owner, group, other acl entries are not *
1534 * part of the acl entries in an acl, they must *
1535 * be dummied up to become part of the list. */
1537 for( i = 1; i < 4; i++) {
1538 DEBUG(10,("i is %d\n",i));
1539 if(acl_entry_link_head->count != 0) {
1540 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1541 if(acl_entry_link->nextp == NULL) {
1544 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1548 acl_entry_link->nextp->prevp = acl_entry_link;
1549 acl_entry_link = acl_entry_link->nextp;
1550 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1551 if(acl_entry_link->entryp == NULL) {
1554 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1559 acl_entry_link->nextp = NULL;
1561 new_acl_entry = acl_entry_link->entryp;
1562 idp = new_acl_entry->ace_id;
1564 new_acl_entry->ace_len = sizeof(struct acl_entry);
1565 new_acl_entry->ace_type = ACC_PERMIT;
1566 idp->id_len = sizeof(struct ace_id);
1567 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1568 memset(idp->id_data,0,sizeof(uid_t));
1572 new_acl_entry->ace_access = file_acl->g_access << 6;
1573 idp->id_type = SMB_ACL_GROUP_OBJ;
1577 new_acl_entry->ace_access = file_acl->o_access << 6;
1578 idp->id_type = SMB_ACL_OTHER;
1582 new_acl_entry->ace_access = file_acl->u_access << 6;
1583 idp->id_type = SMB_ACL_USER_OBJ;
1591 acl_entry_link_head->count++;
1592 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1595 acl_entry_link_head->count = 0;
1598 return(acl_entry_link_head);
1601 SMB_ACL_T sys_acl_get_fd(int fd)
1603 struct acl *file_acl = (struct acl *)NULL;
1604 struct acl_entry *acl_entry;
1605 struct new_acl_entry *new_acl_entry;
1607 struct acl_entry_link *acl_entry_link;
1608 struct acl_entry_link *acl_entry_link_head;
1613 /* Get the acl using fstatacl */
1615 DEBUG(10,("Entering sys_acl_get_fd\n"));
1616 DEBUG(10,("fd is %d\n",fd));
1617 file_acl = (struct acl *)malloc(BUFSIZ);
1619 if(file_acl == NULL) {
1621 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1625 memset(file_acl,0,BUFSIZ);
1627 rc = fstatacl(fd,0,file_acl,BUFSIZ);
1629 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
1634 DEBUG(10,("Got facl and returned it\n"));
1636 /* Point to the first acl entry in the acl */
1638 acl_entry = file_acl->acl_ext;
1639 /* Begin setting up the head of the linked list *
1640 * that will be used for the storing the acl *
1641 * in a way that is useful for the posix_acls.c *
1644 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1645 if(acl_entry_link_head == NULL){
1650 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1652 if(acl_entry_link->entryp == NULL) {
1654 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1659 DEBUG(10,("acl_entry is %d\n",acl_entry));
1660 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1662 /* Check if the extended acl bit is on. *
1663 * If it isn't, do not show the *
1664 * contents of the acl since AIX intends *
1665 * the extended info to remain unused */
1667 if(file_acl->acl_mode & S_IXACL){
1668 /* while we are not pointing to the very end */
1669 while(acl_entry < acl_last(file_acl)) {
1670 /* before we malloc anything, make sure this is */
1671 /* a valid acl entry and one that we want to map */
1673 idp = id_nxt(acl_entry->ace_id);
1674 if((acl_entry->ace_type == ACC_SPECIFY ||
1675 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1676 acl_entry = acl_nxt(acl_entry);
1680 idp = acl_entry->ace_id;
1682 /* Check if this is the first entry in the linked list. *
1683 * The first entry needs to keep prevp pointing to NULL *
1684 * and already has entryp allocated. */
1686 if(acl_entry_link_head->count != 0) {
1687 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1688 if(acl_entry_link->nextp == NULL) {
1690 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1694 acl_entry_link->nextp->prevp = acl_entry_link;
1695 acl_entry_link = acl_entry_link->nextp;
1696 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1697 if(acl_entry_link->entryp == NULL) {
1699 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1704 acl_entry_link->nextp = NULL;
1707 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1709 /* Don't really need this since all types are going *
1710 * to be specified but, it's better than leaving it 0 */
1712 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1713 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1715 memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
1717 /* The access in the acl entries must be left shifted by *
1718 * three bites, because they will ultimately be compared *
1719 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1721 switch(acl_entry->ace_type){
1724 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1725 acl_entry_link->entryp->ace_access <<= 6;
1726 acl_entry_link_head->count++;
1729 /* Since there is no way to return a DENY acl entry *
1730 * change to PERMIT and then shift. */
1731 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1732 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1733 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1734 acl_entry_link->entryp->ace_access <<= 6;
1735 acl_entry_link_head->count++;
1741 DEBUG(10,("acl_entry = %d\n",acl_entry));
1742 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1744 acl_entry = acl_nxt(acl_entry);
1746 } /* end of if enabled */
1748 /* Since owner, group, other acl entries are not *
1749 * part of the acl entries in an acl, they must *
1750 * be dummied up to become part of the list. */
1752 for( i = 1; i < 4; i++) {
1753 DEBUG(10,("i is %d\n",i));
1754 if(acl_entry_link_head->count != 0){
1755 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1756 if(acl_entry_link->nextp == NULL) {
1758 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1763 acl_entry_link->nextp->prevp = acl_entry_link;
1764 acl_entry_link = acl_entry_link->nextp;
1765 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1767 if(acl_entry_link->entryp == NULL) {
1770 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1775 acl_entry_link->nextp = NULL;
1777 new_acl_entry = acl_entry_link->entryp;
1778 idp = new_acl_entry->ace_id;
1780 new_acl_entry->ace_len = sizeof(struct acl_entry);
1781 new_acl_entry->ace_type = ACC_PERMIT;
1782 idp->id_len = sizeof(struct ace_id);
1783 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1784 memset(idp->id_data,0,sizeof(uid_t));
1788 new_acl_entry->ace_access = file_acl->g_access << 6;
1789 idp->id_type = SMB_ACL_GROUP_OBJ;
1793 new_acl_entry->ace_access = file_acl->o_access << 6;
1794 idp->id_type = SMB_ACL_OTHER;
1798 new_acl_entry->ace_access = file_acl->u_access << 6;
1799 idp->id_type = SMB_ACL_USER_OBJ;
1806 acl_entry_link_head->count++;
1807 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1810 acl_entry_link_head->count = 0;
1813 return(acl_entry_link_head);
1816 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
1818 *permset = *permset & ~0777;
1822 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1825 (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0)
1829 DEBUG(10,("This is the permset now: %d\n",*permset));
1833 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
1838 SMB_ACL_T sys_acl_init( int count)
1840 struct acl_entry_link *theacl = NULL;
1842 DEBUG(10,("Entering sys_acl_init\n"));
1844 theacl = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1845 if(theacl == NULL) {
1847 DEBUG(0,("Error in sys_acl_init is %d\n",errno));
1852 theacl->nextp = NULL;
1853 theacl->prevp = NULL;
1854 theacl->entryp = NULL;
1855 DEBUG(10,("Exiting sys_acl_init\n"));
1859 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1861 struct acl_entry_link *theacl;
1862 struct acl_entry_link *acl_entryp;
1863 struct acl_entry_link *temp_entry;
1866 DEBUG(10,("Entering the sys_acl_create_entry\n"));
1868 theacl = acl_entryp = *pacl;
1870 /* Get to the end of the acl before adding entry */
1872 for(counting=0; counting < theacl->count; counting++){
1873 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1874 temp_entry = acl_entryp;
1875 acl_entryp = acl_entryp->nextp;
1878 if(theacl->count != 0){
1879 temp_entry->nextp = acl_entryp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1880 if(acl_entryp == NULL) {
1882 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1886 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1887 acl_entryp->prevp = temp_entry;
1888 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
1891 *pentry = acl_entryp->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1892 if(*pentry == NULL) {
1894 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1898 memset(*pentry,0,sizeof(struct new_acl_entry));
1899 acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
1900 acl_entryp->entryp->ace_type = ACC_PERMIT;
1901 acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
1902 acl_entryp->nextp = NULL;
1904 DEBUG(10,("Exiting sys_acl_create_entry\n"));
1908 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1910 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
1911 entry->ace_id->id_type = tagtype;
1912 DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
1913 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
1916 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
1918 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
1919 memcpy(entry->ace_id->id_data,qual,sizeof(uid_t));
1920 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
1924 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1926 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
1927 if(!(*permset & S_IXUSR) &&
1928 !(*permset & S_IWUSR) &&
1929 !(*permset & S_IRUSR) &&
1933 entry->ace_access = *permset;
1934 DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
1935 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
1939 int sys_acl_valid( SMB_ACL_T theacl )
1944 struct acl_entry_link *acl_entry;
1946 for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
1947 user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
1948 group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
1949 other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
1952 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
1954 if(user_obj != 1 || group_obj != 1 || other_obj != 1)
1960 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1962 struct acl_entry_link *acl_entry_link = NULL;
1963 struct acl *file_acl = NULL;
1964 struct acl *file_acl_temp = NULL;
1965 struct acl_entry *acl_entry = NULL;
1966 struct ace_id *ace_id = NULL;
1973 DEBUG(10,("Entering sys_acl_set_file\n"));
1974 DEBUG(10,("File name is %s\n",name));
1976 /* AIX has no default ACL */
1977 if(acltype == SMB_ACL_TYPE_DEFAULT)
1980 acl_length = BUFSIZ;
1981 file_acl = (struct acl *)malloc(BUFSIZ);
1983 if(file_acl == NULL) {
1985 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
1989 memset(file_acl,0,BUFSIZ);
1991 file_acl->acl_len = ACL_SIZ;
1992 file_acl->acl_mode = S_IXACL;
1994 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
1995 acl_entry_link->entryp->ace_access >>= 6;
1996 id_type = acl_entry_link->entryp->ace_id->id_type;
1999 case SMB_ACL_USER_OBJ:
2000 file_acl->u_access = acl_entry_link->entryp->ace_access;
2002 case SMB_ACL_GROUP_OBJ:
2003 file_acl->g_access = acl_entry_link->entryp->ace_access;
2006 file_acl->o_access = acl_entry_link->entryp->ace_access;
2012 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2013 acl_length += sizeof(struct acl_entry);
2014 file_acl_temp = (struct acl *)malloc(acl_length);
2015 if(file_acl_temp == NULL) {
2018 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2022 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2024 file_acl = file_acl_temp;
2027 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2028 file_acl->acl_len += sizeof(struct acl_entry);
2029 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2030 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2032 /* In order to use this, we'll need to wait until we can get denies */
2033 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2034 acl_entry->ace_type = ACC_SPECIFY; */
2036 acl_entry->ace_type = ACC_SPECIFY;
2038 ace_id = acl_entry->ace_id;
2040 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2041 DEBUG(10,("The id type is %d\n",ace_id->id_type));
2042 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2043 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2044 memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
2047 rc = chacl(name,file_acl,file_acl->acl_len);
2048 DEBUG(10,("errno is %d\n",errno));
2049 DEBUG(10,("return code is %d\n",rc));
2051 DEBUG(10,("Exiting the sys_acl_set_file\n"));
2055 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2057 struct acl_entry_link *acl_entry_link = NULL;
2058 struct acl *file_acl = NULL;
2059 struct acl *file_acl_temp = NULL;
2060 struct acl_entry *acl_entry = NULL;
2061 struct ace_id *ace_id = NULL;
2067 DEBUG(10,("Entering sys_acl_set_fd\n"));
2068 acl_length = BUFSIZ;
2069 file_acl = (struct acl *)malloc(BUFSIZ);
2071 if(file_acl == NULL) {
2073 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2077 memset(file_acl,0,BUFSIZ);
2079 file_acl->acl_len = ACL_SIZ;
2080 file_acl->acl_mode = S_IXACL;
2082 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2083 acl_entry_link->entryp->ace_access >>= 6;
2084 id_type = acl_entry_link->entryp->ace_id->id_type;
2085 DEBUG(10,("The id_type is %d\n",id_type));
2088 case SMB_ACL_USER_OBJ:
2089 file_acl->u_access = acl_entry_link->entryp->ace_access;
2091 case SMB_ACL_GROUP_OBJ:
2092 file_acl->g_access = acl_entry_link->entryp->ace_access;
2095 file_acl->o_access = acl_entry_link->entryp->ace_access;
2101 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2102 acl_length += sizeof(struct acl_entry);
2103 file_acl_temp = (struct acl *)malloc(acl_length);
2104 if(file_acl_temp == NULL) {
2107 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2111 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2113 file_acl = file_acl_temp;
2116 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2117 file_acl->acl_len += sizeof(struct acl_entry);
2118 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2119 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2121 /* In order to use this, we'll need to wait until we can get denies */
2122 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2123 acl_entry->ace_type = ACC_SPECIFY; */
2125 acl_entry->ace_type = ACC_SPECIFY;
2127 ace_id = acl_entry->ace_id;
2129 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2130 DEBUG(10,("The id type is %d\n",ace_id->id_type));
2131 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2132 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2133 memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
2136 rc = fchacl(fd,file_acl,file_acl->acl_len);
2137 DEBUG(10,("errno is %d\n",errno));
2138 DEBUG(10,("return code is %d\n",rc));
2140 DEBUG(10,("Exiting sys_acl_set_fd\n"));
2144 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2146 return(*permset & perm);
2149 int sys_acl_free_text(char *text)
2154 int sys_acl_free_acl(SMB_ACL_T posix_acl)
2156 struct acl_entry_link *acl_entry_link;
2158 for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
2159 free(acl_entry_link->prevp->entryp);
2160 free(acl_entry_link->prevp);
2163 free(acl_entry_link->prevp->entryp);
2164 free(acl_entry_link->prevp);
2165 free(acl_entry_link->entryp);
2166 free(acl_entry_link);
2171 int sys_acl_free_qualifier(void *qual)
2176 #else /* No ACLs. */
2178 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
2184 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
2190 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
2196 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
2202 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
2205 return (SMB_ACL_T)NULL;
2208 SMB_ACL_T sys_acl_get_fd(int fd)
2211 return (SMB_ACL_T)NULL;
2214 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
2220 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2226 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2229 return (permset & perm) ? 1 : 0;
2232 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
2238 int sys_acl_free_text(char *text)
2244 SMB_ACL_T sys_acl_init( int count)
2250 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2256 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2262 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
2268 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2274 int sys_acl_valid( SMB_ACL_T theacl )
2280 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2286 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2292 int sys_acl_delete_def_file(const char *name)
2298 int sys_acl_free_acl(SMB_ACL_T the_acl)
2304 int sys_acl_free_qualifier(void *qual)
2310 #endif /* No ACLs. */