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) != 0) {
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_delete_def_file(const char *name)
1061 return acl_delete_def_file(name);
1064 int sys_acl_free_text(char *text)
1066 return acl_free(text);
1069 int sys_acl_free_acl(SMB_ACL_T acl_d)
1071 if (acl_d->freeaclp) {
1072 acl_free(acl_d->aclp);
1078 int sys_acl_free_qualifier(void *qual)
1083 #elif defined(HAVE_XFS_ACLS)
1084 /* For Linux SGI/XFS Filesystems
1085 * contributed by J Trostel, Connex
1088 /* based on the implementation for Solaris by Toomas Soome.. which is
1089 * based on the implementation by Micheal Davidson for Unixware...
1091 * Linux XFS is a 'work-in-progress'
1092 * This interface may change...
1093 * You've been warned ;-> */
1095 /* First, do the identity mapping */
1097 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1099 if( acl_get_entry( the_acl, entry_id, entry_p) >= 0) {
1107 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1109 return acl_get_file( path_p, type);
1112 SMB_ACL_T sys_acl_get_fd(int fd)
1114 return acl_get_fd(fd);
1117 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
1119 return acl_to_text( the_acl, plen);
1122 int sys_acl_valid( SMB_ACL_T theacl )
1124 return acl_valid(theacl);
1127 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1129 return acl_set_file(name, acltype, theacl);
1132 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
1134 return acl_set_fd(fd, theacl);
1137 /* Now the functions I need to define for XFS */
1139 int sys_acl_create_entry( SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1148 if((*acl_p == NULL) || (ace == NULL)){
1154 if( (cnt + 1) > ACL_MAX_ENTRIES ){
1159 newacl = (acl_t)malloc(sizeof(struct acl));
1166 newacl->acl_entry[cnt] = *ace;
1167 newacl->acl_cnt = cnt + 1;
1171 *entry_p = &newacl->acl_entry[cnt];
1176 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1178 *tag_type_p = entry_d->ae_tag;
1182 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1184 *permset_p = &entry_d->ae_perm;
1188 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1190 if (entry_d->ae_tag != SMB_ACL_USER
1191 && entry_d->ae_tag != SMB_ACL_GROUP) {
1195 return &entry_d->ae_id;
1198 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
1204 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1206 return (*permset & perm);
1209 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1212 /* TO DO: Add in ALL possible permissions here */
1213 /* TO DO: Include extended ones!! */
1215 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE && perm != SMB_ACL_EXECUTE) {
1220 if(permset == NULL) {
1230 SMB_ACL_T sys_acl_init( int count)
1233 if((count > ACL_MAX_ENTRIES) || (count < 0)) {
1238 a = (struct acl *)malloc(sizeof(struct acl)); /* where is this memory freed? */
1244 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1249 case SMB_ACL_USER_OBJ:
1251 case SMB_ACL_GROUP_OBJ:
1254 entry_d->ae_tag = tag_type;
1263 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry_d, void *qual_p)
1265 if(entry_d->ae_tag != SMB_ACL_GROUP &&
1266 entry_d->ae_tag != SMB_ACL_USER) {
1271 entry_d->ae_id = *((uid_t *)qual_p);
1276 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1278 /* TO DO: expand to extended permissions eventually! */
1280 if(*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1287 int sys_acl_free_text(char *text)
1289 return acl_free(text);
1292 int sys_acl_free_acl(SMB_ACL_T the_acl)
1294 return acl_free(the_acl);
1297 int sys_acl_free_qualifier(void *qual)
1302 #elif defined(HAVE_AIX_ACLS)
1304 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
1306 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1308 struct acl_entry_link *link;
1309 struct new_acl_entry *entry;
1312 DEBUG(10,("This is the count: %d\n",theacl->count));
1314 /* Check if count was previously set to -1. *
1315 * If it was, that means we reached the end *
1316 * of the acl last time. */
1317 if(theacl->count == -1)
1321 /* To get to the next acl, traverse linked list until index *
1322 * of acl matches the count we are keeping. This count is *
1323 * incremented each time we return an acl entry. */
1325 for(keep_going = 0; keep_going < theacl->count; keep_going++)
1328 entry = *entry_p = link->entryp;
1330 DEBUG(10,("*entry_p is %d\n",entry_p));
1331 DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
1333 /* Increment count */
1335 if(link->nextp == NULL)
1341 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1343 /* Initialize tag type */
1346 DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
1348 /* Depending on what type of entry we have, *
1349 * return tag type. */
1350 switch(entry_d->ace_id->id_type) {
1352 *tag_type_p = SMB_ACL_USER;
1355 *tag_type_p = SMB_ACL_GROUP;
1358 case SMB_ACL_USER_OBJ:
1359 case SMB_ACL_GROUP_OBJ:
1361 *tag_type_p = entry_d->ace_id->id_type;
1371 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1373 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
1374 *permset_p = &entry_d->ace_access;
1375 DEBUG(10,("**permset_p is %d\n",**permset_p));
1376 if(!(**permset_p & S_IXUSR) &&
1377 !(**permset_p & S_IWUSR) &&
1378 !(**permset_p & S_IRUSR) &&
1382 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
1386 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1388 return(entry_d->ace_id->id_data);
1391 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1393 struct acl *file_acl = (struct acl *)NULL;
1394 struct acl_entry *acl_entry;
1395 struct new_acl_entry *new_acl_entry;
1397 struct acl_entry_link *acl_entry_link;
1398 struct acl_entry_link *acl_entry_link_head;
1403 /* Get the acl using statacl */
1405 DEBUG(10,("Entering sys_acl_get_file\n"));
1406 DEBUG(10,("path_p is %s\n",path_p));
1408 file_acl = (struct acl *)malloc(BUFSIZ);
1410 if(file_acl == NULL) {
1412 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
1416 memset(file_acl,0,BUFSIZ);
1418 rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
1420 DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
1425 DEBUG(10,("Got facl and returned it\n"));
1427 /* Point to the first acl entry in the acl */
1428 acl_entry = file_acl->acl_ext;
1430 /* Begin setting up the head of the linked list *
1431 * that will be used for the storing the acl *
1432 * in a way that is useful for the posix_acls.c *
1435 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1436 if(acl_entry_link_head == NULL)
1439 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1440 if(acl_entry_link->entryp == NULL) {
1443 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1447 DEBUG(10,("acl_entry is %d\n",acl_entry));
1448 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1450 /* Check if the extended acl bit is on. *
1451 * If it isn't, do not show the *
1452 * contents of the acl since AIX intends *
1453 * the extended info to remain unused */
1455 if(file_acl->acl_mode & S_IXACL){
1456 /* while we are not pointing to the very end */
1457 while(acl_entry < acl_last(file_acl)) {
1458 /* before we malloc anything, make sure this is */
1459 /* a valid acl entry and one that we want to map */
1460 idp = id_nxt(acl_entry->ace_id);
1461 if((acl_entry->ace_type == ACC_SPECIFY ||
1462 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1463 acl_entry = acl_nxt(acl_entry);
1467 idp = acl_entry->ace_id;
1469 /* Check if this is the first entry in the linked list. *
1470 * The first entry needs to keep prevp pointing to NULL *
1471 * and already has entryp allocated. */
1473 if(acl_entry_link_head->count != 0) {
1474 acl_entry_link->nextp = (struct acl_entry_link *)
1475 malloc(sizeof(struct acl_entry_link));
1477 if(acl_entry_link->nextp == NULL) {
1480 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1484 acl_entry_link->nextp->prevp = acl_entry_link;
1485 acl_entry_link = acl_entry_link->nextp;
1486 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1487 if(acl_entry_link->entryp == NULL) {
1490 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1493 acl_entry_link->nextp = NULL;
1496 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1498 /* Don't really need this since all types are going *
1499 * to be specified but, it's better than leaving it 0 */
1501 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1503 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1505 memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
1507 /* The access in the acl entries must be left shifted by *
1508 * three bites, because they will ultimately be compared *
1509 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1511 switch(acl_entry->ace_type){
1514 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1515 acl_entry_link->entryp->ace_access <<= 6;
1516 acl_entry_link_head->count++;
1519 /* Since there is no way to return a DENY acl entry *
1520 * change to PERMIT and then shift. */
1521 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1522 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1523 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1524 acl_entry_link->entryp->ace_access <<= 6;
1525 acl_entry_link_head->count++;
1531 DEBUG(10,("acl_entry = %d\n",acl_entry));
1532 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1534 acl_entry = acl_nxt(acl_entry);
1536 } /* end of if enabled */
1538 /* Since owner, group, other acl entries are not *
1539 * part of the acl entries in an acl, they must *
1540 * be dummied up to become part of the list. */
1542 for( i = 1; i < 4; i++) {
1543 DEBUG(10,("i is %d\n",i));
1544 if(acl_entry_link_head->count != 0) {
1545 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1546 if(acl_entry_link->nextp == NULL) {
1549 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1553 acl_entry_link->nextp->prevp = acl_entry_link;
1554 acl_entry_link = acl_entry_link->nextp;
1555 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1556 if(acl_entry_link->entryp == NULL) {
1559 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1564 acl_entry_link->nextp = NULL;
1566 new_acl_entry = acl_entry_link->entryp;
1567 idp = new_acl_entry->ace_id;
1569 new_acl_entry->ace_len = sizeof(struct acl_entry);
1570 new_acl_entry->ace_type = ACC_PERMIT;
1571 idp->id_len = sizeof(struct ace_id);
1572 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1573 memset(idp->id_data,0,sizeof(uid_t));
1577 new_acl_entry->ace_access = file_acl->g_access << 6;
1578 idp->id_type = SMB_ACL_GROUP_OBJ;
1582 new_acl_entry->ace_access = file_acl->o_access << 6;
1583 idp->id_type = SMB_ACL_OTHER;
1587 new_acl_entry->ace_access = file_acl->u_access << 6;
1588 idp->id_type = SMB_ACL_USER_OBJ;
1596 acl_entry_link_head->count++;
1597 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1600 acl_entry_link_head->count = 0;
1603 return(acl_entry_link_head);
1606 SMB_ACL_T sys_acl_get_fd(int fd)
1608 struct acl *file_acl = (struct acl *)NULL;
1609 struct acl_entry *acl_entry;
1610 struct new_acl_entry *new_acl_entry;
1612 struct acl_entry_link *acl_entry_link;
1613 struct acl_entry_link *acl_entry_link_head;
1618 /* Get the acl using fstatacl */
1620 DEBUG(10,("Entering sys_acl_get_fd\n"));
1621 DEBUG(10,("fd is %d\n",fd));
1622 file_acl = (struct acl *)malloc(BUFSIZ);
1624 if(file_acl == NULL) {
1626 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1630 memset(file_acl,0,BUFSIZ);
1632 rc = fstatacl(fd,0,file_acl,BUFSIZ);
1634 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
1639 DEBUG(10,("Got facl and returned it\n"));
1641 /* Point to the first acl entry in the acl */
1643 acl_entry = file_acl->acl_ext;
1644 /* Begin setting up the head of the linked list *
1645 * that will be used for the storing the acl *
1646 * in a way that is useful for the posix_acls.c *
1649 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1650 if(acl_entry_link_head == NULL){
1655 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1657 if(acl_entry_link->entryp == NULL) {
1659 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1664 DEBUG(10,("acl_entry is %d\n",acl_entry));
1665 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1667 /* Check if the extended acl bit is on. *
1668 * If it isn't, do not show the *
1669 * contents of the acl since AIX intends *
1670 * the extended info to remain unused */
1672 if(file_acl->acl_mode & S_IXACL){
1673 /* while we are not pointing to the very end */
1674 while(acl_entry < acl_last(file_acl)) {
1675 /* before we malloc anything, make sure this is */
1676 /* a valid acl entry and one that we want to map */
1678 idp = id_nxt(acl_entry->ace_id);
1679 if((acl_entry->ace_type == ACC_SPECIFY ||
1680 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1681 acl_entry = acl_nxt(acl_entry);
1685 idp = acl_entry->ace_id;
1687 /* Check if this is the first entry in the linked list. *
1688 * The first entry needs to keep prevp pointing to NULL *
1689 * and already has entryp allocated. */
1691 if(acl_entry_link_head->count != 0) {
1692 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1693 if(acl_entry_link->nextp == NULL) {
1695 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1699 acl_entry_link->nextp->prevp = acl_entry_link;
1700 acl_entry_link = acl_entry_link->nextp;
1701 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1702 if(acl_entry_link->entryp == NULL) {
1704 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1709 acl_entry_link->nextp = NULL;
1712 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1714 /* Don't really need this since all types are going *
1715 * to be specified but, it's better than leaving it 0 */
1717 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1718 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1720 memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
1722 /* The access in the acl entries must be left shifted by *
1723 * three bites, because they will ultimately be compared *
1724 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1726 switch(acl_entry->ace_type){
1729 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1730 acl_entry_link->entryp->ace_access <<= 6;
1731 acl_entry_link_head->count++;
1734 /* Since there is no way to return a DENY acl entry *
1735 * change to PERMIT and then shift. */
1736 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1737 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1738 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1739 acl_entry_link->entryp->ace_access <<= 6;
1740 acl_entry_link_head->count++;
1746 DEBUG(10,("acl_entry = %d\n",acl_entry));
1747 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1749 acl_entry = acl_nxt(acl_entry);
1751 } /* end of if enabled */
1753 /* Since owner, group, other acl entries are not *
1754 * part of the acl entries in an acl, they must *
1755 * be dummied up to become part of the list. */
1757 for( i = 1; i < 4; i++) {
1758 DEBUG(10,("i is %d\n",i));
1759 if(acl_entry_link_head->count != 0){
1760 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1761 if(acl_entry_link->nextp == NULL) {
1763 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1768 acl_entry_link->nextp->prevp = acl_entry_link;
1769 acl_entry_link = acl_entry_link->nextp;
1770 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1772 if(acl_entry_link->entryp == NULL) {
1775 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1780 acl_entry_link->nextp = NULL;
1782 new_acl_entry = acl_entry_link->entryp;
1783 idp = new_acl_entry->ace_id;
1785 new_acl_entry->ace_len = sizeof(struct acl_entry);
1786 new_acl_entry->ace_type = ACC_PERMIT;
1787 idp->id_len = sizeof(struct ace_id);
1788 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1789 memset(idp->id_data,0,sizeof(uid_t));
1793 new_acl_entry->ace_access = file_acl->g_access << 6;
1794 idp->id_type = SMB_ACL_GROUP_OBJ;
1798 new_acl_entry->ace_access = file_acl->o_access << 6;
1799 idp->id_type = SMB_ACL_OTHER;
1803 new_acl_entry->ace_access = file_acl->u_access << 6;
1804 idp->id_type = SMB_ACL_USER_OBJ;
1811 acl_entry_link_head->count++;
1812 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1815 acl_entry_link_head->count = 0;
1818 return(acl_entry_link_head);
1821 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
1823 *permset = *permset & ~0777;
1827 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1830 (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0)
1834 DEBUG(10,("This is the permset now: %d\n",*permset));
1838 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
1843 SMB_ACL_T sys_acl_init( int count)
1845 struct acl_entry_link *theacl = NULL;
1847 DEBUG(10,("Entering sys_acl_init\n"));
1849 theacl = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1850 if(theacl == NULL) {
1852 DEBUG(0,("Error in sys_acl_init is %d\n",errno));
1857 theacl->nextp = NULL;
1858 theacl->prevp = NULL;
1859 theacl->entryp = NULL;
1860 DEBUG(10,("Exiting sys_acl_init\n"));
1864 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1866 struct acl_entry_link *theacl;
1867 struct acl_entry_link *acl_entryp;
1868 struct acl_entry_link *temp_entry;
1871 DEBUG(10,("Entering the sys_acl_create_entry\n"));
1873 theacl = acl_entryp = *pacl;
1875 /* Get to the end of the acl before adding entry */
1877 for(counting=0; counting < theacl->count; counting++){
1878 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1879 temp_entry = acl_entryp;
1880 acl_entryp = acl_entryp->nextp;
1883 if(theacl->count != 0){
1884 temp_entry->nextp = acl_entryp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1885 if(acl_entryp == NULL) {
1887 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1891 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1892 acl_entryp->prevp = temp_entry;
1893 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
1896 *pentry = acl_entryp->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1897 if(*pentry == NULL) {
1899 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1903 memset(*pentry,0,sizeof(struct new_acl_entry));
1904 acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
1905 acl_entryp->entryp->ace_type = ACC_PERMIT;
1906 acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
1907 acl_entryp->nextp = NULL;
1909 DEBUG(10,("Exiting sys_acl_create_entry\n"));
1913 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1915 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
1916 entry->ace_id->id_type = tagtype;
1917 DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
1918 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
1921 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
1923 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
1924 memcpy(entry->ace_id->id_data,qual,sizeof(uid_t));
1925 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
1929 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1931 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
1932 if(!(*permset & S_IXUSR) &&
1933 !(*permset & S_IWUSR) &&
1934 !(*permset & S_IRUSR) &&
1938 entry->ace_access = *permset;
1939 DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
1940 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
1944 int sys_acl_valid( SMB_ACL_T theacl )
1949 struct acl_entry_link *acl_entry;
1951 for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
1952 user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
1953 group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
1954 other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
1957 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
1959 if(user_obj != 1 || group_obj != 1 || other_obj != 1)
1965 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1967 struct acl_entry_link *acl_entry_link = NULL;
1968 struct acl *file_acl = NULL;
1969 struct acl *file_acl_temp = NULL;
1970 struct acl_entry *acl_entry = NULL;
1971 struct ace_id *ace_id = NULL;
1978 DEBUG(10,("Entering sys_acl_set_file\n"));
1979 DEBUG(10,("File name is %s\n",name));
1981 /* AIX has no default ACL */
1982 if(acltype == SMB_ACL_TYPE_DEFAULT)
1985 acl_length = BUFSIZ;
1986 file_acl = (struct acl *)malloc(BUFSIZ);
1988 if(file_acl == NULL) {
1990 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
1994 memset(file_acl,0,BUFSIZ);
1996 file_acl->acl_len = ACL_SIZ;
1997 file_acl->acl_mode = S_IXACL;
1999 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2000 acl_entry_link->entryp->ace_access >>= 6;
2001 id_type = acl_entry_link->entryp->ace_id->id_type;
2004 case SMB_ACL_USER_OBJ:
2005 file_acl->u_access = acl_entry_link->entryp->ace_access;
2007 case SMB_ACL_GROUP_OBJ:
2008 file_acl->g_access = acl_entry_link->entryp->ace_access;
2011 file_acl->o_access = acl_entry_link->entryp->ace_access;
2017 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2018 acl_length += sizeof(struct acl_entry);
2019 file_acl_temp = (struct acl *)malloc(acl_length);
2020 if(file_acl_temp == NULL) {
2023 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2027 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2029 file_acl = file_acl_temp;
2032 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2033 file_acl->acl_len += sizeof(struct acl_entry);
2034 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2035 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2037 /* In order to use this, we'll need to wait until we can get denies */
2038 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2039 acl_entry->ace_type = ACC_SPECIFY; */
2041 acl_entry->ace_type = ACC_SPECIFY;
2043 ace_id = acl_entry->ace_id;
2045 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2046 DEBUG(10,("The id type is %d\n",ace_id->id_type));
2047 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2048 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2049 memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
2052 rc = chacl(name,file_acl,file_acl->acl_len);
2053 DEBUG(10,("errno is %d\n",errno));
2054 DEBUG(10,("return code is %d\n",rc));
2056 DEBUG(10,("Exiting the sys_acl_set_file\n"));
2060 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2062 struct acl_entry_link *acl_entry_link = NULL;
2063 struct acl *file_acl = NULL;
2064 struct acl *file_acl_temp = NULL;
2065 struct acl_entry *acl_entry = NULL;
2066 struct ace_id *ace_id = NULL;
2072 DEBUG(10,("Entering sys_acl_set_fd\n"));
2073 acl_length = BUFSIZ;
2074 file_acl = (struct acl *)malloc(BUFSIZ);
2076 if(file_acl == NULL) {
2078 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2082 memset(file_acl,0,BUFSIZ);
2084 file_acl->acl_len = ACL_SIZ;
2085 file_acl->acl_mode = S_IXACL;
2087 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2088 acl_entry_link->entryp->ace_access >>= 6;
2089 id_type = acl_entry_link->entryp->ace_id->id_type;
2090 DEBUG(10,("The id_type is %d\n",id_type));
2093 case SMB_ACL_USER_OBJ:
2094 file_acl->u_access = acl_entry_link->entryp->ace_access;
2096 case SMB_ACL_GROUP_OBJ:
2097 file_acl->g_access = acl_entry_link->entryp->ace_access;
2100 file_acl->o_access = acl_entry_link->entryp->ace_access;
2106 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2107 acl_length += sizeof(struct acl_entry);
2108 file_acl_temp = (struct acl *)malloc(acl_length);
2109 if(file_acl_temp == NULL) {
2112 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2116 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2118 file_acl = file_acl_temp;
2121 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2122 file_acl->acl_len += sizeof(struct acl_entry);
2123 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2124 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2126 /* In order to use this, we'll need to wait until we can get denies */
2127 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2128 acl_entry->ace_type = ACC_SPECIFY; */
2130 acl_entry->ace_type = ACC_SPECIFY;
2132 ace_id = acl_entry->ace_id;
2134 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2135 DEBUG(10,("The id type is %d\n",ace_id->id_type));
2136 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2137 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2138 memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
2141 rc = fchacl(fd,file_acl,file_acl->acl_len);
2142 DEBUG(10,("errno is %d\n",errno));
2143 DEBUG(10,("return code is %d\n",rc));
2145 DEBUG(10,("Exiting sys_acl_set_fd\n"));
2149 int sys_acl_delete_def_file(const char *name)
2151 /* AIX has no default ACL */
2155 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2157 return(*permset & perm);
2160 int sys_acl_free_text(char *text)
2165 int sys_acl_free_acl(SMB_ACL_T posix_acl)
2167 struct acl_entry_link *acl_entry_link;
2169 for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
2170 free(acl_entry_link->prevp->entryp);
2171 free(acl_entry_link->prevp);
2174 free(acl_entry_link->prevp->entryp);
2175 free(acl_entry_link->prevp);
2176 free(acl_entry_link->entryp);
2177 free(acl_entry_link);
2182 int sys_acl_free_qualifier(void *qual)
2187 #else /* No ACLs. */
2189 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
2195 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
2201 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
2207 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
2213 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
2216 return (SMB_ACL_T)NULL;
2219 SMB_ACL_T sys_acl_get_fd(int fd)
2222 return (SMB_ACL_T)NULL;
2225 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
2231 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2237 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2240 return (permset & perm) ? 1 : 0;
2243 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
2249 int sys_acl_free_text(char *text)
2255 SMB_ACL_T sys_acl_init( int count)
2261 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2267 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2273 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
2279 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2285 int sys_acl_valid( SMB_ACL_T theacl )
2291 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2297 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2303 int sys_acl_delete_def_file(const char *name)
2309 int sys_acl_free_acl(SMB_ACL_T the_acl)
2315 int sys_acl_free_qualifier(void *qual)
2321 #endif /* No ACLs. */