2 Unix SMB/CIFS implementation.
3 Samba system utilities for ACL support.
4 Copyright (C) Jeremy Allison 2000.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 This file wraps all differing system ACL interfaces into a consistent
25 one based on the POSIX interface. It also returns the correct errors
26 for older UNIX systems that don't support ACLs.
28 The interfaces that each ACL implementation must support are as follows :
30 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
31 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
32 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p
33 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
34 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
35 SMB_ACL_T sys_acl_get_fd(int fd)
36 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
37 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
38 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
39 SMB_ACL_T sys_acl_init( int count)
40 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
41 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
42 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
43 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
44 int sys_acl_valid( SMB_ACL_T theacl )
45 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
46 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
47 int sys_acl_delete_def_file(const char *path)
49 This next one is not POSIX complient - but we *have* to have it !
50 More POSIX braindamage.
52 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
54 The generic POSIX free is the following call. We split this into
55 several different free functions as we may need to add tag info
56 to structures when emulating the POSIX interface.
58 int sys_acl_free( void *obj_p)
60 The calls we actually use are :
62 int sys_acl_free_text(char *text) - free acl_to_text
63 int sys_acl_free_acl(SMB_ACL_T posix_acl)
64 int sys_acl_free_qualifier(void *qualifier, SMB_ACL_TAG_T tagtype)
68 #if defined(HAVE_POSIX_ACLS)
70 /* Identity mapping - easy. */
72 int sys_acl_get_entry( SMB_ACL_T the_acl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
74 return acl_get_entry( the_acl
, entry_id
, entry_p
);
77 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
79 return acl_get_tag_type( entry_d
, tag_type_p
);
82 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
84 return acl_get_permset( entry_d
, permset_p
);
87 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d
)
89 return acl_get_qualifier( entry_d
);
92 SMB_ACL_T
sys_acl_get_file( const char *path_p
, SMB_ACL_TYPE_T type
)
94 return acl_get_file( path_p
, type
);
97 SMB_ACL_T
sys_acl_get_fd(int fd
)
99 return acl_get_fd(fd
);
102 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset
)
104 return acl_clear_perms(permset
);
107 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
109 return acl_add_perm(permset
, perm
);
112 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
114 #if defined(HAVE_ACL_GET_PERM_NP)
116 * Required for TrustedBSD-based ACL implementations where
117 * non-POSIX.1e functions are denoted by a _np (non-portable)
120 return acl_get_perm_np(permset
, perm
);
122 return acl_get_perm(permset
, perm
);
126 char *sys_acl_to_text( SMB_ACL_T the_acl
, ssize_t
*plen
)
128 return acl_to_text( the_acl
, plen
);
131 SMB_ACL_T
sys_acl_init( int count
)
133 return acl_init(count
);
136 int sys_acl_create_entry( SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
138 return acl_create_entry(pacl
, pentry
);
141 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tagtype
)
143 return acl_set_tag_type(entry
, tagtype
);
146 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry
, void *qual
)
148 return acl_set_qualifier(entry
, qual
);
151 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry
, SMB_ACL_PERMSET_T permset
)
153 return acl_set_permset(entry
, permset
);
156 int sys_acl_valid( SMB_ACL_T theacl
)
158 return acl_valid(theacl
);
161 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
163 return acl_set_file(name
, acltype
, theacl
);
166 int sys_acl_set_fd( int fd
, SMB_ACL_T theacl
)
168 return acl_set_fd(fd
, theacl
);
171 int sys_acl_delete_def_file(const char *name
)
173 return acl_delete_def_file(name
);
176 int sys_acl_free_text(char *text
)
178 return acl_free(text
);
181 int sys_acl_free_acl(SMB_ACL_T the_acl
)
183 return acl_free(the_acl
);
186 int sys_acl_free_qualifier(void *qual
, SMB_ACL_TAG_T tagtype
)
188 return acl_free(qual
);
191 #elif defined(HAVE_TRU64_ACLS)
193 * The interface to DEC/Compaq Tru64 UNIX ACLs
194 * is based on Draft 13 of the POSIX spec which is
195 * slightly different from the Draft 16 interface.
197 * Also, some of the permset manipulation functions
198 * such as acl_clear_perm() and acl_add_perm() appear
199 * to be broken on Tru64 so we have to manipulate
200 * the permission bits in the permset directly.
202 int sys_acl_get_entry( SMB_ACL_T the_acl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
204 SMB_ACL_ENTRY_T entry
;
206 if (entry_id
== SMB_ACL_FIRST_ENTRY
&& acl_first_entry(the_acl
) != 0) {
211 if ((entry
= acl_get_entry(the_acl
)) != NULL
) {
216 return errno
? -1 : 0;
219 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
221 return acl_get_tag_type( entry_d
, tag_type_p
);
224 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
226 return acl_get_permset( entry_d
, permset_p
);
229 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d
)
231 return acl_get_qualifier( entry_d
);
234 SMB_ACL_T
sys_acl_get_file( const char *path_p
, SMB_ACL_TYPE_T type
)
236 return acl_get_file((char *)path_p
, type
);
239 SMB_ACL_T
sys_acl_get_fd(int fd
)
241 return acl_get_fd(fd
, ACL_TYPE_ACCESS
);
244 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset
)
246 *permset
= 0; /* acl_clear_perm() is broken on Tru64 */
251 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
253 if (perm
& ~(SMB_ACL_READ
| SMB_ACL_WRITE
| SMB_ACL_EXECUTE
)) {
258 *permset
|= perm
; /* acl_add_perm() is broken on Tru64 */
263 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
265 return *permset
& perm
; /* Tru64 doesn't have acl_get_perm() */
268 char *sys_acl_to_text( SMB_ACL_T the_acl
, ssize_t
*plen
)
270 return acl_to_text( the_acl
, plen
);
273 SMB_ACL_T
sys_acl_init( int count
)
275 return acl_init(count
);
278 int sys_acl_create_entry( SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
280 SMB_ACL_ENTRY_T entry
;
282 if ((entry
= acl_create_entry(pacl
)) == NULL
) {
290 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tagtype
)
292 return acl_set_tag_type(entry
, tagtype
);
295 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry
, void *qual
)
297 return acl_set_qualifier(entry
, qual
);
300 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry
, SMB_ACL_PERMSET_T permset
)
302 return acl_set_permset(entry
, permset
);
305 int sys_acl_valid( SMB_ACL_T theacl
)
309 return acl_valid(theacl
, &entry
);
312 int sys_acl_set_file( const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
314 return acl_set_file((char *)name
, acltype
, theacl
);
317 int sys_acl_set_fd( int fd
, SMB_ACL_T theacl
)
319 return acl_set_fd(fd
, ACL_TYPE_ACCESS
, theacl
);
322 int sys_acl_delete_def_file(const char *name
)
324 return acl_delete_def_file((char *)name
);
327 int sys_acl_free_text(char *text
)
330 * (void) cast and explicit return 0 are for DEC UNIX
331 * which just #defines acl_free_text() to be free()
333 (void) acl_free_text(text
);
337 int sys_acl_free_acl(SMB_ACL_T the_acl
)
339 return acl_free(the_acl
);
342 int sys_acl_free_qualifier(void *qual
, SMB_ACL_TAG_T tagtype
)
344 return acl_free_qualifier(qual
, tagtype
);
347 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
350 * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
351 * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
355 * Note that while this code implements sufficient functionality
356 * to support the sys_acl_* interfaces it does not provide all
357 * of the semantics of the POSIX ACL interfaces.
359 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
360 * from a call to sys_acl_get_entry() should not be assumed to be
361 * valid after calling any of the following functions, which may
362 * reorder the entries in the ACL.
370 * The only difference between Solaris and UnixWare / OpenUNIX is
371 * that the #defines for the ACL operations have different names
373 #if defined(HAVE_UNIXWARE_ACLS)
375 #define SETACL ACL_SET
376 #define GETACL ACL_GET
377 #define GETACLCNT ACL_CNT
382 int sys_acl_get_entry(SMB_ACL_T acl_d
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
384 if (entry_id
!= SMB_ACL_FIRST_ENTRY
&& entry_id
!= SMB_ACL_NEXT_ENTRY
) {
389 if (entry_p
== NULL
) {
394 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
398 if (acl_d
->next
< 0) {
403 if (acl_d
->next
>= acl_d
->count
) {
407 *entry_p
= &acl_d
->acl
[acl_d
->next
++];
412 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*type_p
)
414 *type_p
= entry_d
->a_type
;
419 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
421 *permset_p
= &entry_d
->a_perm
;
426 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d
)
428 if (entry_d
->a_type
!= SMB_ACL_USER
429 && entry_d
->a_type
!= SMB_ACL_GROUP
) {
434 return &entry_d
->a_id
;
438 * There is no way of knowing what size the ACL returned by
439 * GETACL will be unless you first call GETACLCNT which means
440 * making an additional system call.
442 * In the hope of avoiding the cost of the additional system
443 * call in most cases, we initially allocate enough space for
444 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
445 * be too small then we use GETACLCNT to find out the actual
446 * size, reallocate the ACL buffer, and then call GETACL again.
449 #define INITIAL_ACL_SIZE 16
451 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
454 int count
; /* # of ACL entries allocated */
455 int naccess
; /* # of access ACL entries */
456 int ndefault
; /* # of default ACL entries */
458 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
463 count
= INITIAL_ACL_SIZE
;
464 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
469 * If there isn't enough space for the ACL entries we use
470 * GETACLCNT to determine the actual number of ACL entries
471 * reallocate and try again. This is in a loop because it
472 * is possible that someone else could modify the ACL and
473 * increase the number of entries between the call to
474 * GETACLCNT and the call to GETACL.
476 while ((count
= acl(path_p
, GETACL
, count
, &acl_d
->acl
[0])) < 0
477 && errno
== ENOSPC
) {
479 sys_acl_free_acl(acl_d
);
481 if ((count
= acl(path_p
, GETACLCNT
, 0, NULL
)) < 0) {
485 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
491 sys_acl_free_acl(acl_d
);
496 * calculate the number of access and default ACL entries
498 * Note: we assume that the acl() system call returned a
499 * well formed ACL which is sorted so that all of the
500 * access ACL entries preceed any default ACL entries
502 for (naccess
= 0; naccess
< count
; naccess
++) {
503 if (acl_d
->acl
[naccess
].a_type
& ACL_DEFAULT
)
506 ndefault
= count
- naccess
;
509 * if the caller wants the default ACL we have to copy
510 * the entries down to the start of the acl[] buffer
511 * and mask out the ACL_DEFAULT flag from the type field
513 if (type
== SMB_ACL_TYPE_DEFAULT
) {
516 for (i
= 0, j
= naccess
; i
< ndefault
; i
++, j
++) {
517 acl_d
->acl
[i
] = acl_d
->acl
[j
];
518 acl_d
->acl
[i
].a_type
&= ~ACL_DEFAULT
;
521 acl_d
->count
= ndefault
;
523 acl_d
->count
= naccess
;
529 SMB_ACL_T
sys_acl_get_fd(int fd
)
532 int count
; /* # of ACL entries allocated */
533 int naccess
; /* # of access ACL entries */
535 count
= INITIAL_ACL_SIZE
;
536 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
540 while ((count
= facl(fd
, GETACL
, count
, &acl_d
->acl
[0])) < 0
541 && errno
== ENOSPC
) {
543 sys_acl_free_acl(acl_d
);
545 if ((count
= facl(fd
, GETACLCNT
, 0, NULL
)) < 0) {
549 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
555 sys_acl_free_acl(acl_d
);
560 * calculate the number of access ACL entries
562 for (naccess
= 0; naccess
< count
; naccess
++) {
563 if (acl_d
->acl
[naccess
].a_type
& ACL_DEFAULT
)
567 acl_d
->count
= naccess
;
572 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d
)
579 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
581 if (perm
!= SMB_ACL_READ
&& perm
!= SMB_ACL_WRITE
582 && perm
!= SMB_ACL_EXECUTE
) {
587 if (permset_d
== NULL
) {
597 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
599 return *permset_d
& perm
;
602 char *sys_acl_to_text(SMB_ACL_T acl_d
, ssize_t
*len_p
)
609 * use an initial estimate of 20 bytes per ACL entry
610 * when allocating memory for the text representation
614 maxlen
= 20 * acl_d
->count
;
615 if ((text
= malloc(maxlen
)) == NULL
) {
620 for (i
= 0; i
< acl_d
->count
; i
++) {
621 struct acl
*ap
= &acl_d
->acl
[i
];
631 switch (ap
->a_type
) {
633 * for debugging purposes it's probably more
634 * useful to dump unknown tag types rather
635 * than just returning an error
638 slprintf(tagbuf
, sizeof(tagbuf
)-1, "0x%x",
641 slprintf(idbuf
, sizeof(idbuf
)-1, "%ld",
647 if ((pw
= sys_getpwuid(ap
->a_id
)) == NULL
) {
648 slprintf(idbuf
, sizeof(idbuf
)-1, "%ld",
654 case SMB_ACL_USER_OBJ
:
659 if ((gr
= getgrgid(ap
->a_id
)) == NULL
) {
660 slprintf(idbuf
, sizeof(idbuf
)-1, "%ld",
666 case SMB_ACL_GROUP_OBJ
:
680 perms
[0] = (ap
->a_perm
& SMB_ACL_READ
) ? 'r' : '-';
681 perms
[1] = (ap
->a_perm
& SMB_ACL_WRITE
) ? 'w' : '-';
682 perms
[2] = (ap
->a_perm
& SMB_ACL_EXECUTE
) ? 'x' : '-';
685 /* <tag> : <qualifier> : rwx \n \0 */
686 nbytes
= strlen(tag
) + 1 + strlen(id
) + 1 + 3 + 1 + 1;
689 * If this entry would overflow the buffer
690 * allocate enough additional memory for this
691 * entry and an estimate of another 20 bytes
692 * for each entry still to be processed
694 if ((len
+ nbytes
) > maxlen
) {
695 char *oldtext
= text
;
697 maxlen
+= nbytes
+ 20 * (acl_d
->count
- i
);
699 if ((text
= Realloc(oldtext
, maxlen
)) == NULL
) {
706 slprintf(&text
[len
], nbytes
-1, "%s:%s:%s\n", tag
, id
, perms
);
716 SMB_ACL_T
sys_acl_init(int count
)
726 * note that since the definition of the structure pointed
727 * to by the SMB_ACL_T includes the first element of the
728 * acl[] array, this actually allocates an ACL with room
729 * for (count+1) entries
731 if ((a
= malloc(sizeof(*a
) + count
* sizeof(struct acl
))) == NULL
) {
744 int sys_acl_create_entry(SMB_ACL_T
*acl_p
, SMB_ACL_ENTRY_T
*entry_p
)
747 SMB_ACL_ENTRY_T entry_d
;
749 if (acl_p
== NULL
|| entry_p
== NULL
|| (acl_d
= *acl_p
) == NULL
) {
754 if (acl_d
->count
>= acl_d
->size
) {
759 entry_d
= &acl_d
->acl
[acl_d
->count
++];
768 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T tag_type
)
772 case SMB_ACL_USER_OBJ
:
774 case SMB_ACL_GROUP_OBJ
:
777 entry_d
->a_type
= tag_type
;
787 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d
, void *qual_p
)
789 if (entry_d
->a_type
!= SMB_ACL_GROUP
790 && entry_d
->a_type
!= SMB_ACL_USER
) {
795 entry_d
->a_id
= *((id_t
*)qual_p
);
800 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T permset_d
)
802 if (*permset_d
& ~(SMB_ACL_READ
|SMB_ACL_WRITE
|SMB_ACL_EXECUTE
)) {
806 entry_d
->a_perm
= *permset_d
;
812 * sort the ACL and check it for validity
814 * if it's a minimal ACL with only 4 entries then we
815 * need to recalculate the mask permissions to make
816 * sure that they are the same as the GROUP_OBJ
817 * permissions as required by the UnixWare acl() system call.
819 * (note: since POSIX allows minimal ACLs which only contain
820 * 3 entries - ie there is no mask entry - we should, in theory,
821 * check for this and add a mask entry if necessary - however
822 * we "know" that the caller of this interface always specifies
823 * a mask so, in practice "this never happens" (tm) - if it *does*
824 * happen aclsort() will fail and return an error and someone will
825 * have to fix it ...)
828 static int acl_sort(SMB_ACL_T acl_d
)
830 int fixmask
= (acl_d
->count
<= 4);
832 if (aclsort(acl_d
->count
, fixmask
, acl_d
->acl
) != 0) {
839 int sys_acl_valid(SMB_ACL_T acl_d
)
841 return acl_sort(acl_d
);
844 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T type
, SMB_ACL_T acl_d
)
849 struct acl
*acl_buf
= NULL
;
852 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
857 if (acl_sort(acl_d
) != 0) {
861 acl_p
= &acl_d
->acl
[0];
862 acl_count
= acl_d
->count
;
865 * if it's a directory there is extra work to do
866 * since the acl() system call will replace both
867 * the access ACLs and the default ACLs (if any)
869 if (stat(name
, &s
) != 0) {
872 if (S_ISDIR(s
.st_mode
)) {
878 if (type
== SMB_ACL_TYPE_ACCESS
) {
880 def_acl
= tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_DEFAULT
);
884 acc_acl
= tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_ACCESS
);
887 if (tmp_acl
== NULL
) {
892 * allocate a temporary buffer for the complete ACL
894 acl_count
= acc_acl
->count
+ def_acl
->count
;
895 acl_p
= acl_buf
= malloc(acl_count
* sizeof(acl_buf
[0]));
897 if (acl_buf
== NULL
) {
898 sys_acl_free_acl(tmp_acl
);
904 * copy the access control and default entries into the buffer
906 memcpy(&acl_buf
[0], &acc_acl
->acl
[0],
907 acc_acl
->count
* sizeof(acl_buf
[0]));
909 memcpy(&acl_buf
[acc_acl
->count
], &def_acl
->acl
[0],
910 def_acl
->count
* sizeof(acl_buf
[0]));
913 * set the ACL_DEFAULT flag on the default entries
915 for (i
= acc_acl
->count
; i
< acl_count
; i
++) {
916 acl_buf
[i
].a_type
|= ACL_DEFAULT
;
919 sys_acl_free_acl(tmp_acl
);
921 } else if (type
!= SMB_ACL_TYPE_ACCESS
) {
926 ret
= acl(name
, SETACL
, acl_count
, acl_p
);
933 int sys_acl_set_fd(int fd
, SMB_ACL_T acl_d
)
935 if (acl_sort(acl_d
) != 0) {
939 return facl(fd
, SETACL
, acl_d
->count
, &acl_d
->acl
[0]);
942 int sys_acl_delete_def_file(const char *path
)
948 * fetching the access ACL and rewriting it has
949 * the effect of deleting the default ACL
951 if ((acl_d
= sys_acl_get_file(path
, SMB_ACL_TYPE_ACCESS
)) == NULL
) {
955 ret
= acl(path
, SETACL
, acl_d
->count
, acl_d
->acl
);
957 sys_acl_free_acl(acl_d
);
962 int sys_acl_free_text(char *text
)
968 int sys_acl_free_acl(SMB_ACL_T acl_d
)
974 int sys_acl_free_qualifier(void *qual
, SMB_ACL_TAG_T tagtype
)
979 #elif defined(HAVE_HPUX_ACLS)
983 * Based on the Solaris/SCO code - with modifications.
987 * Note that while this code implements sufficient functionality
988 * to support the sys_acl_* interfaces it does not provide all
989 * of the semantics of the POSIX ACL interfaces.
991 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
992 * from a call to sys_acl_get_entry() should not be assumed to be
993 * valid after calling any of the following functions, which may
994 * reorder the entries in the ACL.
1001 /* This checks if the POSIX ACL system call is defined */
1002 /* which basically corresponds to whether JFS 3.3 or */
1003 /* higher is installed. If acl() was called when it */
1004 /* isn't defined, it causes the process to core dump */
1005 /* so it is important to check this and avoid acl() */
1006 /* calls if it isn't there. */
1008 static BOOL
hpux_acl_call_presence(void)
1011 shl_t handle
= NULL
;
1014 static BOOL already_checked
=0;
1020 ret_val
= shl_findsym(&handle
, "acl", TYPE_PROCEDURE
, &value
);
1023 DEBUG(5, ("hpux_acl_call_presence: shl_findsym() returned %d, errno = %d, error %s\n",
1024 ret_val
, errno
, strerror(errno
)));
1025 DEBUG(5,("hpux_acl_call_presence: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
1029 DEBUG(10,("hpux_acl_call_presence: acl() system call is present. We have JFS 3.3 or above \n"));
1031 already_checked
= True
;
1035 int sys_acl_get_entry(SMB_ACL_T acl_d
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
1037 if (entry_id
!= SMB_ACL_FIRST_ENTRY
&& entry_id
!= SMB_ACL_NEXT_ENTRY
) {
1042 if (entry_p
== NULL
) {
1047 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
1051 if (acl_d
->next
< 0) {
1056 if (acl_d
->next
>= acl_d
->count
) {
1060 *entry_p
= &acl_d
->acl
[acl_d
->next
++];
1065 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*type_p
)
1067 *type_p
= entry_d
->a_type
;
1072 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
1074 *permset_p
= &entry_d
->a_perm
;
1079 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d
)
1081 if (entry_d
->a_type
!= SMB_ACL_USER
1082 && entry_d
->a_type
!= SMB_ACL_GROUP
) {
1087 return &entry_d
->a_id
;
1091 * There is no way of knowing what size the ACL returned by
1092 * ACL_GET will be unless you first call ACL_CNT which means
1093 * making an additional system call.
1095 * In the hope of avoiding the cost of the additional system
1096 * call in most cases, we initially allocate enough space for
1097 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
1098 * be too small then we use ACL_CNT to find out the actual
1099 * size, reallocate the ACL buffer, and then call ACL_GET again.
1102 #define INITIAL_ACL_SIZE 16
1104 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
1107 int count
; /* # of ACL entries allocated */
1108 int naccess
; /* # of access ACL entries */
1109 int ndefault
; /* # of default ACL entries */
1111 if(hpux_acl_call_presence() == False
) {
1112 /* Looks like we don't have the acl() system call on HPUX.
1113 * May be the system doesn't have the latest version of JFS.
1118 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
1123 count
= INITIAL_ACL_SIZE
;
1124 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
1129 * If there isn't enough space for the ACL entries we use
1130 * ACL_CNT to determine the actual number of ACL entries
1131 * reallocate and try again. This is in a loop because it
1132 * is possible that someone else could modify the ACL and
1133 * increase the number of entries between the call to
1134 * ACL_CNT and the call to ACL_GET.
1136 while ((count
= acl(path_p
, ACL_GET
, count
, &acl_d
->acl
[0])) < 0 && errno
== ENOSPC
) {
1138 sys_acl_free_acl(acl_d
);
1140 if ((count
= acl(path_p
, ACL_CNT
, 0, NULL
)) < 0) {
1144 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
1150 sys_acl_free_acl(acl_d
);
1155 * calculate the number of access and default ACL entries
1157 * Note: we assume that the acl() system call returned a
1158 * well formed ACL which is sorted so that all of the
1159 * access ACL entries preceed any default ACL entries
1161 for (naccess
= 0; naccess
< count
; naccess
++) {
1162 if (acl_d
->acl
[naccess
].a_type
& ACL_DEFAULT
)
1165 ndefault
= count
- naccess
;
1168 * if the caller wants the default ACL we have to copy
1169 * the entries down to the start of the acl[] buffer
1170 * and mask out the ACL_DEFAULT flag from the type field
1172 if (type
== SMB_ACL_TYPE_DEFAULT
) {
1175 for (i
= 0, j
= naccess
; i
< ndefault
; i
++, j
++) {
1176 acl_d
->acl
[i
] = acl_d
->acl
[j
];
1177 acl_d
->acl
[i
].a_type
&= ~ACL_DEFAULT
;
1180 acl_d
->count
= ndefault
;
1182 acl_d
->count
= naccess
;
1188 SMB_ACL_T
sys_acl_get_fd(int fd
)
1191 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1194 files_struct
*fsp
= file_find_fd(fd
);
1202 * We know we're in the same conn context. So we
1203 * can use the relative path.
1206 return sys_acl_get_file(dos_to_unix(fsp
->fsp_name
,False
), SMB_ACL_TYPE_ACCESS
);
1209 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d
)
1216 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
1218 if (perm
!= SMB_ACL_READ
&& perm
!= SMB_ACL_WRITE
1219 && perm
!= SMB_ACL_EXECUTE
) {
1224 if (permset_d
== NULL
) {
1234 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
1236 return *permset_d
& perm
;
1239 char *sys_acl_to_text(SMB_ACL_T acl_d
, ssize_t
*len_p
)
1246 * use an initial estimate of 20 bytes per ACL entry
1247 * when allocating memory for the text representation
1251 maxlen
= 20 * acl_d
->count
;
1252 if ((text
= malloc(maxlen
)) == NULL
) {
1257 for (i
= 0; i
< acl_d
->count
; i
++) {
1258 struct acl
*ap
= &acl_d
->acl
[i
];
1268 switch (ap
->a_type
) {
1270 * for debugging purposes it's probably more
1271 * useful to dump unknown tag types rather
1272 * than just returning an error
1275 slprintf(tagbuf
, sizeof(tagbuf
)-1, "0x%x",
1278 slprintf(idbuf
, sizeof(idbuf
)-1, "%ld",
1284 if ((pw
= sys_getpwuid(ap
->a_id
)) == NULL
) {
1285 slprintf(idbuf
, sizeof(idbuf
)-1, "%ld",
1291 case SMB_ACL_USER_OBJ
:
1296 if ((gr
= getgrgid(ap
->a_id
)) == NULL
) {
1297 slprintf(idbuf
, sizeof(idbuf
)-1, "%ld",
1303 case SMB_ACL_GROUP_OBJ
:
1317 perms
[0] = (ap
->a_perm
& SMB_ACL_READ
) ? 'r' : '-';
1318 perms
[1] = (ap
->a_perm
& SMB_ACL_WRITE
) ? 'w' : '-';
1319 perms
[2] = (ap
->a_perm
& SMB_ACL_EXECUTE
) ? 'x' : '-';
1322 /* <tag> : <qualifier> : rwx \n \0 */
1323 nbytes
= strlen(tag
) + 1 + strlen(id
) + 1 + 3 + 1 + 1;
1326 * If this entry would overflow the buffer
1327 * allocate enough additional memory for this
1328 * entry and an estimate of another 20 bytes
1329 * for each entry still to be processed
1331 if ((len
+ nbytes
) > maxlen
) {
1332 char *oldtext
= text
;
1334 maxlen
+= nbytes
+ 20 * (acl_d
->count
- i
);
1336 if ((text
= Realloc(oldtext
, maxlen
)) == NULL
) {
1343 slprintf(&text
[len
], nbytes
-1, "%s:%s:%s\n", tag
, id
, perms
);
1353 SMB_ACL_T
sys_acl_init(int count
)
1363 * note that since the definition of the structure pointed
1364 * to by the SMB_ACL_T includes the first element of the
1365 * acl[] array, this actually allocates an ACL with room
1366 * for (count+1) entries
1368 if ((a
= malloc(sizeof(*a
) + count
* sizeof(struct acl
))) == NULL
) {
1373 a
->size
= count
+ 1;
1381 int sys_acl_create_entry(SMB_ACL_T
*acl_p
, SMB_ACL_ENTRY_T
*entry_p
)
1384 SMB_ACL_ENTRY_T entry_d
;
1386 if (acl_p
== NULL
|| entry_p
== NULL
|| (acl_d
= *acl_p
) == NULL
) {
1391 if (acl_d
->count
>= acl_d
->size
) {
1396 entry_d
= &acl_d
->acl
[acl_d
->count
++];
1397 entry_d
->a_type
= 0;
1399 entry_d
->a_perm
= 0;
1405 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T tag_type
)
1409 case SMB_ACL_USER_OBJ
:
1411 case SMB_ACL_GROUP_OBJ
:
1414 entry_d
->a_type
= tag_type
;
1424 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d
, void *qual_p
)
1426 if (entry_d
->a_type
!= SMB_ACL_GROUP
1427 && entry_d
->a_type
!= SMB_ACL_USER
) {
1432 entry_d
->a_id
= *((id_t
*)qual_p
);
1437 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T permset_d
)
1439 if (*permset_d
& ~(SMB_ACL_READ
|SMB_ACL_WRITE
|SMB_ACL_EXECUTE
)) {
1443 entry_d
->a_perm
= *permset_d
;
1448 /* Structure to capture the count for each type of ACE. */
1450 struct hpux_acl_types
{
1459 int n_def_group_obj
;
1463 int n_def_other_obj
;
1466 int n_def_class_obj
;
1472 * Counts the different number of objects in a given array of ACL
1476 * acl_count - Count of ACLs in the array of ACL strucutres.
1477 * aclp - Array of ACL structures.
1478 * acl_type_count - Pointer to acl_types structure. Should already be
1482 * acl_type_count - This structure is filled up with counts of various
1486 static int hpux_count_obj(int acl_count
, struct acl
*aclp
, struct hpux_acl_types
*acl_type_count
)
1490 memset(acl_type_count
, 0, sizeof(struct hpux_acl_types
));
1492 for(i
=0;i
<acl_count
;i
++) {
1493 switch(aclp
[i
].a_type
) {
1495 acl_type_count
->n_user
++;
1498 acl_type_count
->n_user_obj
++;
1501 acl_type_count
->n_def_user_obj
++;
1504 acl_type_count
->n_group
++;
1507 acl_type_count
->n_group_obj
++;
1510 acl_type_count
->n_def_group_obj
++;
1513 acl_type_count
->n_other_obj
++;
1516 acl_type_count
->n_def_other_obj
++;
1519 acl_type_count
->n_class_obj
++;
1522 acl_type_count
->n_def_class_obj
++;
1525 acl_type_count
->n_def_user
++;
1528 acl_type_count
->n_def_group
++;
1531 acl_type_count
->n_illegal_obj
++;
1537 /* swap_acl_entries: Swaps two ACL entries.
1539 * Inputs: aclp0, aclp1 - ACL entries to be swapped.
1542 static void hpux_swap_acl_entries(struct acl
*aclp0
, struct acl
*aclp1
)
1544 struct acl temp_acl
;
1546 temp_acl
.a_type
= aclp0
->a_type
;
1547 temp_acl
.a_id
= aclp0
->a_id
;
1548 temp_acl
.a_perm
= aclp0
->a_perm
;
1550 aclp0
->a_type
= aclp1
->a_type
;
1551 aclp0
->a_id
= aclp1
->a_id
;
1552 aclp0
->a_perm
= aclp1
->a_perm
;
1554 aclp1
->a_type
= temp_acl
.a_type
;
1555 aclp1
->a_id
= temp_acl
.a_id
;
1556 aclp1
->a_perm
= temp_acl
.a_perm
;
1559 /* prohibited_duplicate_type
1560 * Identifies if given ACL type can have duplicate entries or
1563 * Inputs: acl_type - ACL Type.
1569 * True - If the ACL type matches any of the prohibited types.
1570 * False - If the ACL type doesn't match any of the prohibited types.
1573 static BOOL
hpux_prohibited_duplicate_type(int acl_type
)
1586 /* get_needed_class_perm
1587 * Returns the permissions of a ACL structure only if the ACL
1588 * type matches one of the pre-determined types for computing
1589 * CLASS_OBJ permissions.
1591 * Inputs: aclp - Pointer to ACL structure.
1594 static int hpux_get_needed_class_perm(struct acl
*aclp
)
1596 switch(aclp
->a_type
) {
1606 return aclp
->a_perm
;
1612 /* acl_sort for HPUX.
1613 * Sorts the array of ACL structures as per the description in
1614 * aclsort man page. Refer to aclsort man page for more details
1618 * acl_count - Count of ACLs in the array of ACL structures.
1619 * calclass - If this is not zero, then we compute the CLASS_OBJ
1621 * aclp - Array of ACL structures.
1625 * aclp - Sorted array of ACL structures.
1629 * Returns 0 for success -1 for failure. Prints a message to the Samba
1630 * debug log in case of failure.
1633 static int hpux_acl_sort(int acl_count
, int calclass
, struct acl
*aclp
)
1635 #if !defined(HAVE_HPUX_ACLSORT)
1637 * The aclsort() system call is availabe on the latest HPUX General
1638 * Patch Bundles. So for HPUX, we developed our version of acl_sort
1639 * function. Because, we don't want to update to a new
1640 * HPUX GR bundle just for aclsort() call.
1643 struct hpux_acl_types acl_obj_count
;
1644 int n_class_obj_perm
= 0;
1648 DEBUG(10,("Zero acl count passed. Returning Success\n"));
1653 DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
1657 /* Count different types of ACLs in the ACLs array */
1659 hpux_count_obj(acl_count
, aclp
, &acl_obj_count
);
1661 /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
1662 * CLASS_OBJ and OTHER_OBJ
1665 if( (acl_obj_count
.n_user_obj
!= 1) ||
1666 (acl_obj_count
.n_group_obj
!= 1) ||
1667 (acl_obj_count
.n_class_obj
!= 1) ||
1668 (acl_obj_count
.n_other_obj
!= 1)
1670 DEBUG(0,("hpux_acl_sort: More than one entry or no entries for \
1671 USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
1675 /* If any of the default objects are present, there should be only
1679 if( (acl_obj_count
.n_def_user_obj
> 1) || (acl_obj_count
.n_def_group_obj
> 1) ||
1680 (acl_obj_count
.n_def_other_obj
> 1) || (acl_obj_count
.n_def_class_obj
> 1) ) {
1681 DEBUG(0,("hpux_acl_sort: More than one entry for DEF_CLASS_OBJ \
1682 or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
1686 /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
1689 * Sorting crieteria - First sort by ACL type. If there are multiple entries of
1690 * same ACL type, sort by ACL id.
1692 * I am using the trival kind of sorting method here because, performance isn't
1693 * really effected by the ACLs feature. More over there aren't going to be more
1694 * than 17 entries on HPUX.
1697 for(i
=0; i
<acl_count
;i
++) {
1698 for (j
=i
+1; j
<acl_count
; j
++) {
1699 if( aclp
[i
].a_type
> aclp
[j
].a_type
) {
1700 /* ACL entries out of order, swap them */
1702 hpux_swap_acl_entries((aclp
+i
), (aclp
+j
));
1704 } else if ( aclp
[i
].a_type
== aclp
[j
].a_type
) {
1706 /* ACL entries of same type, sort by id */
1708 if(aclp
[i
].a_id
> aclp
[j
].a_id
) {
1709 hpux_swap_acl_entries((aclp
+i
), (aclp
+j
));
1710 } else if (aclp
[i
].a_id
== aclp
[j
].a_id
) {
1711 /* We have a duplicate entry. */
1712 if(hpux_prohibited_duplicate_type(aclp
[i
].a_type
)) {
1713 DEBUG(0, ("hpux_acl_sort: Duplicate entry: Type(hex): %x Id: %d\n",
1714 aclp
[i
].a_type
, aclp
[i
].a_id
));
1723 /* set the class obj permissions to the computed one. */
1725 int n_class_obj_index
= -1;
1727 for(i
=0;i
<acl_count
;i
++) {
1728 n_class_obj_perm
|= hpux_get_needed_class_perm((aclp
+i
));
1730 if(aclp
[i
].a_type
== CLASS_OBJ
)
1731 n_class_obj_index
= i
;
1733 aclp
[n_class_obj_index
].a_perm
= n_class_obj_perm
;
1738 return aclsort(acl_count
, calclass
, aclp
);
1743 * sort the ACL and check it for validity
1745 * if it's a minimal ACL with only 4 entries then we
1746 * need to recalculate the mask permissions to make
1747 * sure that they are the same as the GROUP_OBJ
1748 * permissions as required by the UnixWare acl() system call.
1750 * (note: since POSIX allows minimal ACLs which only contain
1751 * 3 entries - ie there is no mask entry - we should, in theory,
1752 * check for this and add a mask entry if necessary - however
1753 * we "know" that the caller of this interface always specifies
1754 * a mask so, in practice "this never happens" (tm) - if it *does*
1755 * happen aclsort() will fail and return an error and someone will
1756 * have to fix it ...)
1759 static int acl_sort(SMB_ACL_T acl_d
)
1761 int fixmask
= (acl_d
->count
<= 4);
1763 if (hpux_acl_sort(acl_d
->count
, fixmask
, acl_d
->acl
) != 0) {
1770 int sys_acl_valid(SMB_ACL_T acl_d
)
1772 return acl_sort(acl_d
);
1775 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T type
, SMB_ACL_T acl_d
)
1780 struct acl
*acl_buf
= NULL
;
1783 if(hpux_acl_call_presence() == False
) {
1784 /* Looks like we don't have the acl() system call on HPUX.
1785 * May be the system doesn't have the latest version of JFS.
1791 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
1796 if (acl_sort(acl_d
) != 0) {
1800 acl_p
= &acl_d
->acl
[0];
1801 acl_count
= acl_d
->count
;
1804 * if it's a directory there is extra work to do
1805 * since the acl() system call will replace both
1806 * the access ACLs and the default ACLs (if any)
1808 if (stat(name
, &s
) != 0) {
1811 if (S_ISDIR(s
.st_mode
)) {
1817 if (type
== SMB_ACL_TYPE_ACCESS
) {
1819 def_acl
= tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_DEFAULT
);
1823 acc_acl
= tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_ACCESS
);
1826 if (tmp_acl
== NULL
) {
1831 * allocate a temporary buffer for the complete ACL
1833 acl_count
= acc_acl
->count
+ def_acl
->count
;
1834 acl_p
= acl_buf
= malloc(acl_count
* sizeof(acl_buf
[0]));
1836 if (acl_buf
== NULL
) {
1837 sys_acl_free_acl(tmp_acl
);
1843 * copy the access control and default entries into the buffer
1845 memcpy(&acl_buf
[0], &acc_acl
->acl
[0],
1846 acc_acl
->count
* sizeof(acl_buf
[0]));
1848 memcpy(&acl_buf
[acc_acl
->count
], &def_acl
->acl
[0],
1849 def_acl
->count
* sizeof(acl_buf
[0]));
1852 * set the ACL_DEFAULT flag on the default entries
1854 for (i
= acc_acl
->count
; i
< acl_count
; i
++) {
1855 acl_buf
[i
].a_type
|= ACL_DEFAULT
;
1858 sys_acl_free_acl(tmp_acl
);
1860 } else if (type
!= SMB_ACL_TYPE_ACCESS
) {
1865 ret
= acl(name
, ACL_SET
, acl_count
, acl_p
);
1874 int sys_acl_set_fd(int fd
, SMB_ACL_T acl_d
)
1877 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1880 files_struct
*fsp
= file_find_fd(fd
);
1887 if (acl_sort(acl_d
) != 0) {
1892 * We know we're in the same conn context. So we
1893 * can use the relative path.
1896 return sys_acl_set_file(dos_to_unix(fsp
->fsp_name
,False
), SMB_ACL_TYPE_ACCESS
, acl_d
);
1899 int sys_acl_delete_def_file(const char *path
)
1905 * fetching the access ACL and rewriting it has
1906 * the effect of deleting the default ACL
1908 if ((acl_d
= sys_acl_get_file(path
, SMB_ACL_TYPE_ACCESS
)) == NULL
) {
1912 ret
= acl(path
, ACL_SET
, acl_d
->count
, acl_d
->acl
);
1914 sys_acl_free_acl(acl_d
);
1919 int sys_acl_free_text(char *text
)
1925 int sys_acl_free_acl(SMB_ACL_T acl_d
)
1931 int sys_acl_free_qualifier(void *qual
, SMB_ACL_TAG_T tagtype
)
1936 #elif defined(HAVE_IRIX_ACLS)
1938 int sys_acl_get_entry(SMB_ACL_T acl_d
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
1940 if (entry_id
!= SMB_ACL_FIRST_ENTRY
&& entry_id
!= SMB_ACL_NEXT_ENTRY
) {
1945 if (entry_p
== NULL
) {
1950 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
1954 if (acl_d
->next
< 0) {
1959 if (acl_d
->next
>= acl_d
->aclp
->acl_cnt
) {
1963 *entry_p
= &acl_d
->aclp
->acl_entry
[acl_d
->next
++];
1968 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*type_p
)
1970 *type_p
= entry_d
->ae_tag
;
1975 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
1977 *permset_p
= entry_d
;
1982 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d
)
1984 if (entry_d
->ae_tag
!= SMB_ACL_USER
1985 && entry_d
->ae_tag
!= SMB_ACL_GROUP
) {
1990 return &entry_d
->ae_id
;
1993 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
1997 if ((a
= malloc(sizeof(*a
))) == NULL
) {
2001 if ((a
->aclp
= acl_get_file(path_p
, type
)) == NULL
) {
2010 SMB_ACL_T
sys_acl_get_fd(int fd
)
2014 if ((a
= malloc(sizeof(*a
))) == NULL
) {
2018 if ((a
->aclp
= acl_get_fd(fd
)) == NULL
) {
2027 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d
)
2029 permset_d
->ae_perm
= 0;
2034 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
2036 if (perm
!= SMB_ACL_READ
&& perm
!= SMB_ACL_WRITE
2037 && perm
!= SMB_ACL_EXECUTE
) {
2042 if (permset_d
== NULL
) {
2047 permset_d
->ae_perm
|= perm
;
2052 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
2054 return permset_d
->ae_perm
& perm
;
2057 char *sys_acl_to_text(SMB_ACL_T acl_d
, ssize_t
*len_p
)
2059 return acl_to_text(acl_d
->aclp
, len_p
);
2062 SMB_ACL_T
sys_acl_init(int count
)
2071 if ((a
= malloc(sizeof(*a
) + sizeof(struct acl
))) == NULL
) {
2077 a
->freeaclp
= False
;
2078 a
->aclp
= (struct acl
*)(&a
->aclp
+ sizeof(struct acl
*));
2079 a
->aclp
->acl_cnt
= 0;
2085 int sys_acl_create_entry(SMB_ACL_T
*acl_p
, SMB_ACL_ENTRY_T
*entry_p
)
2088 SMB_ACL_ENTRY_T entry_d
;
2090 if (acl_p
== NULL
|| entry_p
== NULL
|| (acl_d
= *acl_p
) == NULL
) {
2095 if (acl_d
->aclp
->acl_cnt
>= ACL_MAX_ENTRIES
) {
2100 entry_d
= &acl_d
->aclp
->acl_entry
[acl_d
->aclp
->acl_cnt
++];
2101 entry_d
->ae_tag
= 0;
2103 entry_d
->ae_perm
= 0;
2109 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T tag_type
)
2113 case SMB_ACL_USER_OBJ
:
2115 case SMB_ACL_GROUP_OBJ
:
2118 entry_d
->ae_tag
= tag_type
;
2128 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d
, void *qual_p
)
2130 if (entry_d
->ae_tag
!= SMB_ACL_GROUP
2131 && entry_d
->ae_tag
!= SMB_ACL_USER
) {
2136 entry_d
->ae_id
= *((id_t
*)qual_p
);
2141 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T permset_d
)
2143 if (permset_d
->ae_perm
& ~(SMB_ACL_READ
|SMB_ACL_WRITE
|SMB_ACL_EXECUTE
)) {
2147 entry_d
->ae_perm
= permset_d
->ae_perm
;
2152 int sys_acl_valid(SMB_ACL_T acl_d
)
2154 return acl_valid(acl_d
->aclp
);
2157 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T type
, SMB_ACL_T acl_d
)
2159 return acl_set_file(name
, type
, acl_d
->aclp
);
2162 int sys_acl_set_fd(int fd
, SMB_ACL_T acl_d
)
2164 return acl_set_fd(fd
, acl_d
->aclp
);
2167 int sys_acl_delete_def_file(const char *name
)
2169 return acl_delete_def_file(name
);
2172 int sys_acl_free_text(char *text
)
2174 return acl_free(text
);
2177 int sys_acl_free_acl(SMB_ACL_T acl_d
)
2179 if (acl_d
->freeaclp
) {
2180 acl_free(acl_d
->aclp
);
2186 int sys_acl_free_qualifier(void *qual
, SMB_ACL_TAG_T tagtype
)
2191 #elif defined(HAVE_AIX_ACLS)
2193 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
2195 int sys_acl_get_entry( SMB_ACL_T theacl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
2197 struct acl_entry_link
*link
;
2198 struct new_acl_entry
*entry
;
2201 DEBUG(10,("This is the count: %d\n",theacl
->count
));
2203 /* Check if count was previously set to -1. *
2204 * If it was, that means we reached the end *
2205 * of the acl last time. */
2206 if(theacl
->count
== -1)
2210 /* To get to the next acl, traverse linked list until index *
2211 * of acl matches the count we are keeping. This count is *
2212 * incremented each time we return an acl entry. */
2214 for(keep_going
= 0; keep_going
< theacl
->count
; keep_going
++)
2217 entry
= *entry_p
= link
->entryp
;
2219 DEBUG(10,("*entry_p is %d\n",entry_p
));
2220 DEBUG(10,("*entry_p->ace_access is %d\n",entry
->ace_access
));
2222 /* Increment count */
2224 if(link
->nextp
== NULL
)
2230 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
2232 /* Initialize tag type */
2235 DEBUG(10,("the tagtype is %d\n",entry_d
->ace_id
->id_type
));
2237 /* Depending on what type of entry we have, *
2238 * return tag type. */
2239 switch(entry_d
->ace_id
->id_type
) {
2241 *tag_type_p
= SMB_ACL_USER
;
2244 *tag_type_p
= SMB_ACL_GROUP
;
2247 case SMB_ACL_USER_OBJ
:
2248 case SMB_ACL_GROUP_OBJ
:
2250 *tag_type_p
= entry_d
->ace_id
->id_type
;
2260 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
2262 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
2263 *permset_p
= &entry_d
->ace_access
;
2264 DEBUG(10,("**permset_p is %d\n",**permset_p
));
2265 if(!(**permset_p
& S_IXUSR
) &&
2266 !(**permset_p
& S_IWUSR
) &&
2267 !(**permset_p
& S_IRUSR
) &&
2271 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
2275 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d
)
2277 return(entry_d
->ace_id
->id_data
);
2280 SMB_ACL_T
sys_acl_get_file( const char *path_p
, SMB_ACL_TYPE_T type
)
2282 struct acl
*file_acl
= (struct acl
*)NULL
;
2283 struct acl_entry
*acl_entry
;
2284 struct new_acl_entry
*new_acl_entry
;
2286 struct acl_entry_link
*acl_entry_link
;
2287 struct acl_entry_link
*acl_entry_link_head
;
2292 /* Get the acl using statacl */
2294 DEBUG(10,("Entering sys_acl_get_file\n"));
2295 DEBUG(10,("path_p is %s\n",path_p
));
2297 file_acl
= (struct acl
*)malloc(BUFSIZ
);
2299 if(file_acl
== NULL
) {
2301 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno
));
2305 memset(file_acl
,0,BUFSIZ
);
2307 rc
= statacl((char *)path_p
,0,file_acl
,BUFSIZ
);
2309 DEBUG(0,("statacl returned %d with errno %d\n",rc
,errno
));
2310 SAFE_FREE(file_acl
);
2314 DEBUG(10,("Got facl and returned it\n"));
2316 /* Point to the first acl entry in the acl */
2317 acl_entry
= file_acl
->acl_ext
;
2319 /* Begin setting up the head of the linked list *
2320 * that will be used for the storing the acl *
2321 * in a way that is useful for the posix_acls.c *
2324 acl_entry_link_head
= acl_entry_link
= sys_acl_init(0);
2325 if(acl_entry_link_head
== NULL
)
2328 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
2329 if(acl_entry_link
->entryp
== NULL
) {
2330 SAFE_FREE(file_acl
);
2332 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
2336 DEBUG(10,("acl_entry is %d\n",acl_entry
));
2337 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl
)));
2339 /* Check if the extended acl bit is on. *
2340 * If it isn't, do not show the *
2341 * contents of the acl since AIX intends *
2342 * the extended info to remain unused */
2344 if(file_acl
->acl_mode
& S_IXACL
){
2345 /* while we are not pointing to the very end */
2346 while(acl_entry
< acl_last(file_acl
)) {
2347 /* before we malloc anything, make sure this is */
2348 /* a valid acl entry and one that we want to map */
2349 idp
= id_nxt(acl_entry
->ace_id
);
2350 if((acl_entry
->ace_type
== ACC_SPECIFY
||
2351 (acl_entry
->ace_type
== ACC_PERMIT
)) && (idp
!= id_last(acl_entry
))) {
2352 acl_entry
= acl_nxt(acl_entry
);
2356 idp
= acl_entry
->ace_id
;
2358 /* Check if this is the first entry in the linked list. *
2359 * The first entry needs to keep prevp pointing to NULL *
2360 * and already has entryp allocated. */
2362 if(acl_entry_link_head
->count
!= 0) {
2363 acl_entry_link
->nextp
= (struct acl_entry_link
*)
2364 malloc(sizeof(struct acl_entry_link
));
2366 if(acl_entry_link
->nextp
== NULL
) {
2367 SAFE_FREE(file_acl
);
2369 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
2373 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
2374 acl_entry_link
= acl_entry_link
->nextp
;
2375 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
2376 if(acl_entry_link
->entryp
== NULL
) {
2377 SAFE_FREE(file_acl
);
2379 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
2382 acl_entry_link
->nextp
= NULL
;
2385 acl_entry_link
->entryp
->ace_len
= acl_entry
->ace_len
;
2387 /* Don't really need this since all types are going *
2388 * to be specified but, it's better than leaving it 0 */
2390 acl_entry_link
->entryp
->ace_type
= acl_entry
->ace_type
;
2392 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
2394 memcpy(acl_entry_link
->entryp
->ace_id
,idp
,sizeof(struct ace_id
));
2396 /* The access in the acl entries must be left shifted by *
2397 * three bites, because they will ultimately be compared *
2398 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2400 switch(acl_entry
->ace_type
){
2403 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
2404 acl_entry_link
->entryp
->ace_access
<<= 6;
2405 acl_entry_link_head
->count
++;
2408 /* Since there is no way to return a DENY acl entry *
2409 * change to PERMIT and then shift. */
2410 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry
->ace_access
));
2411 acl_entry_link
->entryp
->ace_access
= ~acl_entry
->ace_access
& 7;
2412 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link
->entryp
->ace_access
));
2413 acl_entry_link
->entryp
->ace_access
<<= 6;
2414 acl_entry_link_head
->count
++;
2420 DEBUG(10,("acl_entry = %d\n",acl_entry
));
2421 DEBUG(10,("The ace_type is %d\n",acl_entry
->ace_type
));
2423 acl_entry
= acl_nxt(acl_entry
);
2425 } /* end of if enabled */
2427 /* Since owner, group, other acl entries are not *
2428 * part of the acl entries in an acl, they must *
2429 * be dummied up to become part of the list. */
2431 for( i
= 1; i
< 4; i
++) {
2432 DEBUG(10,("i is %d\n",i
));
2433 if(acl_entry_link_head
->count
!= 0) {
2434 acl_entry_link
->nextp
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
2435 if(acl_entry_link
->nextp
== NULL
) {
2436 SAFE_FREE(file_acl
);
2438 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
2442 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
2443 acl_entry_link
= acl_entry_link
->nextp
;
2444 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
2445 if(acl_entry_link
->entryp
== NULL
) {
2446 SAFE_FREE(file_acl
);
2448 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
2453 acl_entry_link
->nextp
= NULL
;
2455 new_acl_entry
= acl_entry_link
->entryp
;
2456 idp
= new_acl_entry
->ace_id
;
2458 new_acl_entry
->ace_len
= sizeof(struct acl_entry
);
2459 new_acl_entry
->ace_type
= ACC_PERMIT
;
2460 idp
->id_len
= sizeof(struct ace_id
);
2461 DEBUG(10,("idp->id_len = %d\n",idp
->id_len
));
2462 memset(idp
->id_data
,0,sizeof(uid_t
));
2466 new_acl_entry
->ace_access
= file_acl
->g_access
<< 6;
2467 idp
->id_type
= SMB_ACL_GROUP_OBJ
;
2471 new_acl_entry
->ace_access
= file_acl
->o_access
<< 6;
2472 idp
->id_type
= SMB_ACL_OTHER
;
2476 new_acl_entry
->ace_access
= file_acl
->u_access
<< 6;
2477 idp
->id_type
= SMB_ACL_USER_OBJ
;
2485 acl_entry_link_head
->count
++;
2486 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry
->ace_access
));
2489 acl_entry_link_head
->count
= 0;
2490 SAFE_FREE(file_acl
);
2492 return(acl_entry_link_head
);
2495 SMB_ACL_T
sys_acl_get_fd(int fd
)
2497 struct acl
*file_acl
= (struct acl
*)NULL
;
2498 struct acl_entry
*acl_entry
;
2499 struct new_acl_entry
*new_acl_entry
;
2501 struct acl_entry_link
*acl_entry_link
;
2502 struct acl_entry_link
*acl_entry_link_head
;
2507 /* Get the acl using fstatacl */
2509 DEBUG(10,("Entering sys_acl_get_fd\n"));
2510 DEBUG(10,("fd is %d\n",fd
));
2511 file_acl
= (struct acl
*)malloc(BUFSIZ
);
2513 if(file_acl
== NULL
) {
2515 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
2519 memset(file_acl
,0,BUFSIZ
);
2521 rc
= fstatacl(fd
,0,file_acl
,BUFSIZ
);
2523 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc
,errno
));
2524 SAFE_FREE(file_acl
);
2528 DEBUG(10,("Got facl and returned it\n"));
2530 /* Point to the first acl entry in the acl */
2532 acl_entry
= file_acl
->acl_ext
;
2533 /* Begin setting up the head of the linked list *
2534 * that will be used for the storing the acl *
2535 * in a way that is useful for the posix_acls.c *
2538 acl_entry_link_head
= acl_entry_link
= sys_acl_init(0);
2539 if(acl_entry_link_head
== NULL
){
2540 SAFE_FREE(file_acl
);
2544 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
2546 if(acl_entry_link
->entryp
== NULL
) {
2548 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
2549 SAFE_FREE(file_acl
);
2553 DEBUG(10,("acl_entry is %d\n",acl_entry
));
2554 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl
)));
2556 /* Check if the extended acl bit is on. *
2557 * If it isn't, do not show the *
2558 * contents of the acl since AIX intends *
2559 * the extended info to remain unused */
2561 if(file_acl
->acl_mode
& S_IXACL
){
2562 /* while we are not pointing to the very end */
2563 while(acl_entry
< acl_last(file_acl
)) {
2564 /* before we malloc anything, make sure this is */
2565 /* a valid acl entry and one that we want to map */
2567 idp
= id_nxt(acl_entry
->ace_id
);
2568 if((acl_entry
->ace_type
== ACC_SPECIFY
||
2569 (acl_entry
->ace_type
== ACC_PERMIT
)) && (idp
!= id_last(acl_entry
))) {
2570 acl_entry
= acl_nxt(acl_entry
);
2574 idp
= acl_entry
->ace_id
;
2576 /* Check if this is the first entry in the linked list. *
2577 * The first entry needs to keep prevp pointing to NULL *
2578 * and already has entryp allocated. */
2580 if(acl_entry_link_head
->count
!= 0) {
2581 acl_entry_link
->nextp
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
2582 if(acl_entry_link
->nextp
== NULL
) {
2584 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
2585 SAFE_FREE(file_acl
);
2588 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
2589 acl_entry_link
= acl_entry_link
->nextp
;
2590 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
2591 if(acl_entry_link
->entryp
== NULL
) {
2593 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
2594 SAFE_FREE(file_acl
);
2598 acl_entry_link
->nextp
= NULL
;
2601 acl_entry_link
->entryp
->ace_len
= acl_entry
->ace_len
;
2603 /* Don't really need this since all types are going *
2604 * to be specified but, it's better than leaving it 0 */
2606 acl_entry_link
->entryp
->ace_type
= acl_entry
->ace_type
;
2607 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
2609 memcpy(acl_entry_link
->entryp
->ace_id
, idp
, sizeof(struct ace_id
));
2611 /* The access in the acl entries must be left shifted by *
2612 * three bites, because they will ultimately be compared *
2613 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2615 switch(acl_entry
->ace_type
){
2618 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
2619 acl_entry_link
->entryp
->ace_access
<<= 6;
2620 acl_entry_link_head
->count
++;
2623 /* Since there is no way to return a DENY acl entry *
2624 * change to PERMIT and then shift. */
2625 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry
->ace_access
));
2626 acl_entry_link
->entryp
->ace_access
= ~acl_entry
->ace_access
& 7;
2627 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link
->entryp
->ace_access
));
2628 acl_entry_link
->entryp
->ace_access
<<= 6;
2629 acl_entry_link_head
->count
++;
2635 DEBUG(10,("acl_entry = %d\n",acl_entry
));
2636 DEBUG(10,("The ace_type is %d\n",acl_entry
->ace_type
));
2638 acl_entry
= acl_nxt(acl_entry
);
2640 } /* end of if enabled */
2642 /* Since owner, group, other acl entries are not *
2643 * part of the acl entries in an acl, they must *
2644 * be dummied up to become part of the list. */
2646 for( i
= 1; i
< 4; i
++) {
2647 DEBUG(10,("i is %d\n",i
));
2648 if(acl_entry_link_head
->count
!= 0){
2649 acl_entry_link
->nextp
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
2650 if(acl_entry_link
->nextp
== NULL
) {
2652 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
2653 SAFE_FREE(file_acl
);
2657 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
2658 acl_entry_link
= acl_entry_link
->nextp
;
2659 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
2661 if(acl_entry_link
->entryp
== NULL
) {
2662 SAFE_FREE(file_acl
);
2664 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
2669 acl_entry_link
->nextp
= NULL
;
2671 new_acl_entry
= acl_entry_link
->entryp
;
2672 idp
= new_acl_entry
->ace_id
;
2674 new_acl_entry
->ace_len
= sizeof(struct acl_entry
);
2675 new_acl_entry
->ace_type
= ACC_PERMIT
;
2676 idp
->id_len
= sizeof(struct ace_id
);
2677 DEBUG(10,("idp->id_len = %d\n",idp
->id_len
));
2678 memset(idp
->id_data
,0,sizeof(uid_t
));
2682 new_acl_entry
->ace_access
= file_acl
->g_access
<< 6;
2683 idp
->id_type
= SMB_ACL_GROUP_OBJ
;
2687 new_acl_entry
->ace_access
= file_acl
->o_access
<< 6;
2688 idp
->id_type
= SMB_ACL_OTHER
;
2692 new_acl_entry
->ace_access
= file_acl
->u_access
<< 6;
2693 idp
->id_type
= SMB_ACL_USER_OBJ
;
2700 acl_entry_link_head
->count
++;
2701 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry
->ace_access
));
2704 acl_entry_link_head
->count
= 0;
2705 SAFE_FREE(file_acl
);
2707 return(acl_entry_link_head
);
2710 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset
)
2712 *permset
= *permset
& ~0777;
2716 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
2719 (perm
& (S_IXUSR
| S_IWUSR
| S_IRUSR
)) == 0)
2723 DEBUG(10,("This is the permset now: %d\n",*permset
));
2727 char *sys_acl_to_text( SMB_ACL_T theacl
, ssize_t
*plen
)
2732 SMB_ACL_T
sys_acl_init( int count
)
2734 struct acl_entry_link
*theacl
= NULL
;
2736 DEBUG(10,("Entering sys_acl_init\n"));
2738 theacl
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
2739 if(theacl
== NULL
) {
2741 DEBUG(0,("Error in sys_acl_init is %d\n",errno
));
2746 theacl
->nextp
= NULL
;
2747 theacl
->prevp
= NULL
;
2748 theacl
->entryp
= NULL
;
2749 DEBUG(10,("Exiting sys_acl_init\n"));
2753 int sys_acl_create_entry( SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
2755 struct acl_entry_link
*theacl
;
2756 struct acl_entry_link
*acl_entryp
;
2757 struct acl_entry_link
*temp_entry
;
2760 DEBUG(10,("Entering the sys_acl_create_entry\n"));
2762 theacl
= acl_entryp
= *pacl
;
2764 /* Get to the end of the acl before adding entry */
2766 for(counting
=0; counting
< theacl
->count
; counting
++){
2767 DEBUG(10,("The acl_entryp is %d\n",acl_entryp
));
2768 temp_entry
= acl_entryp
;
2769 acl_entryp
= acl_entryp
->nextp
;
2772 if(theacl
->count
!= 0){
2773 temp_entry
->nextp
= acl_entryp
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
2774 if(acl_entryp
== NULL
) {
2776 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno
));
2780 DEBUG(10,("The acl_entryp is %d\n",acl_entryp
));
2781 acl_entryp
->prevp
= temp_entry
;
2782 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp
->prevp
));
2785 *pentry
= acl_entryp
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
2786 if(*pentry
== NULL
) {
2788 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno
));
2792 memset(*pentry
,0,sizeof(struct new_acl_entry
));
2793 acl_entryp
->entryp
->ace_len
= sizeof(struct acl_entry
);
2794 acl_entryp
->entryp
->ace_type
= ACC_PERMIT
;
2795 acl_entryp
->entryp
->ace_id
->id_len
= sizeof(struct ace_id
);
2796 acl_entryp
->nextp
= NULL
;
2798 DEBUG(10,("Exiting sys_acl_create_entry\n"));
2802 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tagtype
)
2804 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
2805 entry
->ace_id
->id_type
= tagtype
;
2806 DEBUG(10,("The tag type is %d\n",entry
->ace_id
->id_type
));
2807 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
2810 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry
, void *qual
)
2812 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
2813 memcpy(entry
->ace_id
->id_data
,qual
,sizeof(uid_t
));
2814 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
2818 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry
, SMB_ACL_PERMSET_T permset
)
2820 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
2821 if(!(*permset
& S_IXUSR
) &&
2822 !(*permset
& S_IWUSR
) &&
2823 !(*permset
& S_IRUSR
) &&
2827 entry
->ace_access
= *permset
;
2828 DEBUG(10,("entry->ace_access = %d\n",entry
->ace_access
));
2829 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
2833 int sys_acl_valid( SMB_ACL_T theacl
)
2838 struct acl_entry_link
*acl_entry
;
2840 for(acl_entry
=theacl
; acl_entry
!= NULL
; acl_entry
= acl_entry
->nextp
) {
2841 user_obj
+= (acl_entry
->entryp
->ace_id
->id_type
== SMB_ACL_USER_OBJ
);
2842 group_obj
+= (acl_entry
->entryp
->ace_id
->id_type
== SMB_ACL_GROUP_OBJ
);
2843 other_obj
+= (acl_entry
->entryp
->ace_id
->id_type
== SMB_ACL_OTHER
);
2846 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj
,group_obj
,other_obj
));
2848 if(user_obj
!= 1 || group_obj
!= 1 || other_obj
!= 1)
2854 int sys_acl_set_file( const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
2856 struct acl_entry_link
*acl_entry_link
= NULL
;
2857 struct acl
*file_acl
= NULL
;
2858 struct acl
*file_acl_temp
= NULL
;
2859 struct acl_entry
*acl_entry
= NULL
;
2860 struct ace_id
*ace_id
= NULL
;
2867 DEBUG(10,("Entering sys_acl_set_file\n"));
2868 DEBUG(10,("File name is %s\n",name
));
2870 /* AIX has no default ACL */
2871 if(acltype
== SMB_ACL_TYPE_DEFAULT
)
2874 acl_length
= BUFSIZ
;
2875 file_acl
= (struct acl
*)malloc(BUFSIZ
);
2877 if(file_acl
== NULL
) {
2879 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno
));
2883 memset(file_acl
,0,BUFSIZ
);
2885 file_acl
->acl_len
= ACL_SIZ
;
2886 file_acl
->acl_mode
= S_IXACL
;
2888 for(acl_entry_link
=theacl
; acl_entry_link
!= NULL
; acl_entry_link
= acl_entry_link
->nextp
) {
2889 acl_entry_link
->entryp
->ace_access
>>= 6;
2890 id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
2893 case SMB_ACL_USER_OBJ
:
2894 file_acl
->u_access
= acl_entry_link
->entryp
->ace_access
;
2896 case SMB_ACL_GROUP_OBJ
:
2897 file_acl
->g_access
= acl_entry_link
->entryp
->ace_access
;
2900 file_acl
->o_access
= acl_entry_link
->entryp
->ace_access
;
2906 if((file_acl
->acl_len
+ sizeof(struct acl_entry
)) > acl_length
) {
2907 acl_length
+= sizeof(struct acl_entry
);
2908 file_acl_temp
= (struct acl
*)malloc(acl_length
);
2909 if(file_acl_temp
== NULL
) {
2910 SAFE_FREE(file_acl
);
2912 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno
));
2916 memcpy(file_acl_temp
,file_acl
,file_acl
->acl_len
);
2917 SAFE_FREE(file_acl
);
2918 file_acl
= file_acl_temp
;
2921 acl_entry
= (struct acl_entry
*)((char *)file_acl
+ file_acl
->acl_len
);
2922 file_acl
->acl_len
+= sizeof(struct acl_entry
);
2923 acl_entry
->ace_len
= acl_entry_link
->entryp
->ace_len
;
2924 acl_entry
->ace_access
= acl_entry_link
->entryp
->ace_access
;
2926 /* In order to use this, we'll need to wait until we can get denies */
2927 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2928 acl_entry->ace_type = ACC_SPECIFY; */
2930 acl_entry
->ace_type
= ACC_SPECIFY
;
2932 ace_id
= acl_entry
->ace_id
;
2934 ace_id
->id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
2935 DEBUG(10,("The id type is %d\n",ace_id
->id_type
));
2936 ace_id
->id_len
= acl_entry_link
->entryp
->ace_id
->id_len
;
2937 memcpy(&user_id
, acl_entry_link
->entryp
->ace_id
->id_data
, sizeof(uid_t
));
2938 memcpy(acl_entry
->ace_id
->id_data
, &user_id
, sizeof(uid_t
));
2941 rc
= chacl(name
,file_acl
,file_acl
->acl_len
);
2942 DEBUG(10,("errno is %d\n",errno
));
2943 DEBUG(10,("return code is %d\n",rc
));
2944 SAFE_FREE(file_acl
);
2945 DEBUG(10,("Exiting the sys_acl_set_file\n"));
2949 int sys_acl_set_fd( int fd
, SMB_ACL_T theacl
)
2951 struct acl_entry_link
*acl_entry_link
= NULL
;
2952 struct acl
*file_acl
= NULL
;
2953 struct acl
*file_acl_temp
= NULL
;
2954 struct acl_entry
*acl_entry
= NULL
;
2955 struct ace_id
*ace_id
= NULL
;
2961 DEBUG(10,("Entering sys_acl_set_fd\n"));
2962 acl_length
= BUFSIZ
;
2963 file_acl
= (struct acl
*)malloc(BUFSIZ
);
2965 if(file_acl
== NULL
) {
2967 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno
));
2971 memset(file_acl
,0,BUFSIZ
);
2973 file_acl
->acl_len
= ACL_SIZ
;
2974 file_acl
->acl_mode
= S_IXACL
;
2976 for(acl_entry_link
=theacl
; acl_entry_link
!= NULL
; acl_entry_link
= acl_entry_link
->nextp
) {
2977 acl_entry_link
->entryp
->ace_access
>>= 6;
2978 id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
2979 DEBUG(10,("The id_type is %d\n",id_type
));
2982 case SMB_ACL_USER_OBJ
:
2983 file_acl
->u_access
= acl_entry_link
->entryp
->ace_access
;
2985 case SMB_ACL_GROUP_OBJ
:
2986 file_acl
->g_access
= acl_entry_link
->entryp
->ace_access
;
2989 file_acl
->o_access
= acl_entry_link
->entryp
->ace_access
;
2995 if((file_acl
->acl_len
+ sizeof(struct acl_entry
)) > acl_length
) {
2996 acl_length
+= sizeof(struct acl_entry
);
2997 file_acl_temp
= (struct acl
*)malloc(acl_length
);
2998 if(file_acl_temp
== NULL
) {
2999 SAFE_FREE(file_acl
);
3001 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno
));
3005 memcpy(file_acl_temp
,file_acl
,file_acl
->acl_len
);
3006 SAFE_FREE(file_acl
);
3007 file_acl
= file_acl_temp
;
3010 acl_entry
= (struct acl_entry
*)((char *)file_acl
+ file_acl
->acl_len
);
3011 file_acl
->acl_len
+= sizeof(struct acl_entry
);
3012 acl_entry
->ace_len
= acl_entry_link
->entryp
->ace_len
;
3013 acl_entry
->ace_access
= acl_entry_link
->entryp
->ace_access
;
3015 /* In order to use this, we'll need to wait until we can get denies */
3016 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
3017 acl_entry->ace_type = ACC_SPECIFY; */
3019 acl_entry
->ace_type
= ACC_SPECIFY
;
3021 ace_id
= acl_entry
->ace_id
;
3023 ace_id
->id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
3024 DEBUG(10,("The id type is %d\n",ace_id
->id_type
));
3025 ace_id
->id_len
= acl_entry_link
->entryp
->ace_id
->id_len
;
3026 memcpy(&user_id
, acl_entry_link
->entryp
->ace_id
->id_data
, sizeof(uid_t
));
3027 memcpy(ace_id
->id_data
, &user_id
, sizeof(uid_t
));
3030 rc
= fchacl(fd
,file_acl
,file_acl
->acl_len
);
3031 DEBUG(10,("errno is %d\n",errno
));
3032 DEBUG(10,("return code is %d\n",rc
));
3033 SAFE_FREE(file_acl
);
3034 DEBUG(10,("Exiting sys_acl_set_fd\n"));
3038 int sys_acl_delete_def_file(const char *name
)
3040 /* AIX has no default ACL */
3044 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
3046 return(*permset
& perm
);
3049 int sys_acl_free_text(char *text
)
3054 int sys_acl_free_acl(SMB_ACL_T posix_acl
)
3056 struct acl_entry_link
*acl_entry_link
;
3058 for(acl_entry_link
= posix_acl
->nextp
; acl_entry_link
->nextp
!= NULL
; acl_entry_link
= acl_entry_link
->nextp
) {
3059 SAFE_FREE(acl_entry_link
->prevp
->entryp
);
3060 SAFE_FREE(acl_entry_link
->prevp
);
3063 SAFE_FREE(acl_entry_link
->prevp
->entryp
);
3064 SAFE_FREE(acl_entry_link
->prevp
);
3065 SAFE_FREE(acl_entry_link
->entryp
);
3066 SAFE_FREE(acl_entry_link
);
3071 int sys_acl_free_qualifier(void *qual
, SMB_ACL_TAG_T tagtype
)
3076 #else /* No ACLs. */
3078 int sys_acl_get_entry( SMB_ACL_T the_acl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
3084 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
3090 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
3096 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d
)
3102 SMB_ACL_T
sys_acl_get_file( const char *path_p
, SMB_ACL_TYPE_T type
)
3105 return (SMB_ACL_T
)NULL
;
3108 SMB_ACL_T
sys_acl_get_fd(int fd
)
3111 return (SMB_ACL_T
)NULL
;
3114 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset
)
3120 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
3126 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
3129 return (permset
& perm
) ? 1 : 0;
3132 char *sys_acl_to_text( SMB_ACL_T the_acl
, ssize_t
*plen
)
3138 int sys_acl_free_text(char *text
)
3144 SMB_ACL_T
sys_acl_init( int count
)
3150 int sys_acl_create_entry( SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
3156 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tagtype
)
3162 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry
, void *qual
)
3168 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry
, SMB_ACL_PERMSET_T permset
)
3174 int sys_acl_valid( SMB_ACL_T theacl
)
3180 int sys_acl_set_file( const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
3186 int sys_acl_set_fd( int fd
, SMB_ACL_T theacl
)
3192 int sys_acl_delete_def_file(const char *name
)
3198 int sys_acl_free_acl(SMB_ACL_T the_acl
)
3204 int sys_acl_free_qualifier(void *qual
, SMB_ACL_TAG_T tagtype
)
3210 #endif /* No ACLs. */