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( char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
49 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
51 This next one is not POSIX complient - but we *have* to have it !
52 More POSIX braindamage.
54 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
56 The generic POSIX free is the following call. We split this into
57 several different free functions as we may need to add tag info
58 to structures when emulating the POSIX interface.
60 int sys_acl_free( void *obj_p)
62 The calls we actually use are :
64 int sys_acl_free_text(char *text) - free acl_to_text
65 int sys_acl_free_acl(SMB_ACL_T posix_acl)
66 int sys_acl_free_qualifier(SMB_ACL_T posix_acl)
70 #if defined(HAVE_POSIX_ACLS)
72 /* Identity mapping - easy. */
74 int sys_acl_get_entry( SMB_ACL_T the_acl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
76 return acl_get_entry( the_acl
, entry_id
, entry_p
);
79 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
81 return acl_get_tag_type( entry_d
, tag_type_p
);
84 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
86 return acl_get_permset( entry_d
, permset_p
);
89 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d
)
91 return acl_get_qualifier( entry_d
);
94 SMB_ACL_T
sys_acl_get_file( const char *path_p
, SMB_ACL_TYPE_T type
)
96 return acl_get_file( path_p
, type
);
99 SMB_ACL_T
sys_acl_get_fd(int fd
)
101 return acl_get_fd(fd
);
104 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset
)
106 return acl_clear_perms(permset
);
109 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
111 return acl_add_perm(permset
, perm
);
114 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
116 #if defined(HAVE_ACL_GET_PERM_NP)
118 * Required for TrustedBSD-based ACL implementations where
119 * non-POSIX.1e functions are denoted by a _np (non-portable)
122 return acl_get_perm_np(permset
, perm
);
124 return acl_get_perm(permset
, perm
);
128 char *sys_acl_to_text( SMB_ACL_T the_acl
, ssize_t
*plen
)
130 return acl_to_text( the_acl
, plen
);
133 SMB_ACL_T
sys_acl_init( int count
)
135 return acl_init(count
);
138 int sys_acl_create_entry( SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
140 return acl_create_entry(pacl
, pentry
);
143 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tagtype
)
145 return acl_set_tag_type(entry
, tagtype
);
148 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry
, void *qual
)
150 return acl_set_qualifier(entry
, qual
);
153 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry
, SMB_ACL_PERMSET_T permset
)
155 return acl_set_permset(entry
, permset
);
158 int sys_acl_valid( SMB_ACL_T theacl
)
160 return acl_valid(theacl
);
163 int sys_acl_set_file( char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
165 return acl_set_file(name
, acltype
, theacl
);
168 int sys_acl_set_fd( int fd
, SMB_ACL_T theacl
)
170 return acl_set_fd(fd
, theacl
);
173 int sys_acl_free_text(char *text
)
175 return acl_free(text
);
178 int sys_acl_free_acl(SMB_ACL_T the_acl
)
180 return acl_free(the_acl
);
183 int sys_acl_free_qualifier(void *qual
)
185 return acl_free(qual
);
188 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
191 * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
192 * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
196 * Note that while this code implements sufficient functionality
197 * to support the sys_acl_* interfaces it does not provide all
198 * of the semantics of the POSIX ACL interfaces.
200 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
201 * from a call to sys_acl_get_entry() should not be assumed to be
202 * valid after calling any of the following functions, which may
203 * reorder the entries in the ACL.
211 * The only difference between Solaris and UnixWare / OpenUNIX is
212 * that the #defines for the ACL operations have different names
214 #if defined(HAVE_UNIXWARE_ACLS)
216 #define SETACL ACL_SET
217 #define GETACL ACL_GET
218 #define GETACLCNT ACL_CNT
223 int sys_acl_get_entry(SMB_ACL_T acl_d
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
225 if (entry_id
!= SMB_ACL_FIRST_ENTRY
&& entry_id
!= SMB_ACL_NEXT_ENTRY
) {
230 if (entry_p
== NULL
) {
235 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
239 if (acl_d
->next
< 0) {
244 if (acl_d
->next
>= acl_d
->count
) {
248 *entry_p
= &acl_d
->acl
[acl_d
->next
++];
253 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*type_p
)
255 *type_p
= entry_d
->a_type
;
260 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
262 *permset_p
= &entry_d
->a_perm
;
267 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d
)
269 if (entry_d
->a_type
!= SMB_ACL_USER
270 && entry_d
->a_type
!= SMB_ACL_GROUP
) {
275 return &entry_d
->a_id
;
279 * There is no way of knowing what size the ACL returned by
280 * GETACL will be unless you first call GETACLCNT which means
281 * making an additional system call.
283 * In the hope of avoiding the cost of the additional system
284 * call in most cases, we initially allocate enough space for
285 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
286 * be too small then we use GETACLCNT to find out the actual
287 * size, reallocate the ACL buffer, and then call GETACL again.
290 #define INITIAL_ACL_SIZE 16
292 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
295 int count
; /* # of ACL entries allocated */
296 int naccess
; /* # of access ACL entries */
297 int ndefault
; /* # of default ACL entries */
299 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
304 count
= INITIAL_ACL_SIZE
;
305 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
310 * If there isn't enough space for the ACL entries we use
311 * GETACLCNT to determine the actual number of ACL entries
312 * reallocate and try again. This is in a loop because it
313 * is possible that someone else could modify the ACL and
314 * increase the number of entries between the call to
315 * GETACLCNT and the call to GETACL.
317 while ((count
= acl(path_p
, GETACL
, count
, &acl_d
->acl
[0])) < 0
318 && errno
== ENOSPC
) {
320 sys_acl_free_acl(acl_d
);
322 if ((count
= acl(path_p
, GETACLCNT
, 0, NULL
)) < 0) {
326 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
332 sys_acl_free_acl(acl_d
);
337 * calculate the number of access and default ACL entries
339 * Note: we assume that the acl() system call returned a
340 * well formed ACL which is sorted so that all of the
341 * access ACL entries preceed any default ACL entries
343 for (naccess
= 0; naccess
< count
; naccess
++) {
344 if (acl_d
->acl
[naccess
].a_type
& ACL_DEFAULT
)
347 ndefault
= count
- naccess
;
350 * if the caller wants the default ACL we have to copy
351 * the entries down to the start of the acl[] buffer
352 * and mask out the ACL_DEFAULT flag from the type field
354 if (type
== SMB_ACL_TYPE_DEFAULT
) {
357 for (i
= 0, j
= naccess
; i
< ndefault
; i
++, j
++) {
358 acl_d
->acl
[i
] = acl_d
->acl
[j
];
359 acl_d
->acl
[i
].a_type
&= ~ACL_DEFAULT
;
362 acl_d
->count
= ndefault
;
364 acl_d
->count
= naccess
;
370 SMB_ACL_T
sys_acl_get_fd(int fd
)
373 int count
; /* # of ACL entries allocated */
374 int naccess
; /* # of access ACL entries */
376 count
= INITIAL_ACL_SIZE
;
377 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
381 while ((count
= facl(fd
, GETACL
, count
, &acl_d
->acl
[0])) < 0
382 && errno
== ENOSPC
) {
384 sys_acl_free_acl(acl_d
);
386 if ((count
= facl(fd
, GETACLCNT
, 0, NULL
)) < 0) {
390 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
396 sys_acl_free_acl(acl_d
);
401 * calculate the number of access ACL entries
403 for (naccess
= 0; naccess
< count
; naccess
++) {
404 if (acl_d
->acl
[naccess
].a_type
& ACL_DEFAULT
)
408 acl_d
->count
= naccess
;
413 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d
)
420 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
422 if (perm
!= SMB_ACL_READ
&& perm
!= SMB_ACL_WRITE
423 && perm
!= SMB_ACL_EXECUTE
) {
428 if (permset_d
== NULL
) {
438 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
440 return *permset_d
& perm
;
443 char *sys_acl_to_text(SMB_ACL_T acl_d
, ssize_t
*len_p
)
450 * use an initial estimate of 20 bytes per ACL entry
451 * when allocating memory for the text representation
455 maxlen
= 20 * acl_d
->count
;
456 if ((text
= malloc(maxlen
)) == NULL
) {
461 for (i
= 0; i
< acl_d
->count
; i
++) {
462 struct acl
*ap
= &acl_d
->acl
[i
];
472 switch (ap
->a_type
) {
474 * for debugging purposes it's probably more
475 * useful to dump unknown tag types rather
476 * than just returning an error
479 slprintf(tagbuf
, sizeof(tagbuf
)-1, "0x%x",
482 slprintf(idbuf
, sizeof(idbuf
)-1, "%ld",
488 if ((pw
= sys_getpwuid(ap
->a_id
)) == NULL
) {
489 slprintf(idbuf
, sizeof(idbuf
)-1, "%ld",
495 case SMB_ACL_USER_OBJ
:
500 if ((gr
= getgrgid(ap
->a_id
)) == NULL
) {
501 slprintf(idbuf
, sizeof(idbuf
)-1, "%ld",
507 case SMB_ACL_GROUP_OBJ
:
521 perms
[0] = (ap
->a_perm
& SMB_ACL_READ
) ? 'r' : '-';
522 perms
[1] = (ap
->a_perm
& SMB_ACL_WRITE
) ? 'w' : '-';
523 perms
[2] = (ap
->a_perm
& SMB_ACL_EXECUTE
) ? 'x' : '-';
526 /* <tag> : <qualifier> : rwx \n \0 */
527 nbytes
= strlen(tag
) + 1 + strlen(id
) + 1 + 3 + 1 + 1;
530 * If this entry would overflow the buffer
531 * allocate enough additional memory for this
532 * entry and an estimate of another 20 bytes
533 * for each entry still to be processed
535 if ((len
+ nbytes
) > maxlen
) {
536 char *oldtext
= text
;
538 maxlen
+= nbytes
+ 20 * (acl_d
->count
- i
);
540 if ((text
= realloc(oldtext
, maxlen
)) == NULL
) {
547 slprintf(&text
[len
], nbytes
-1, "%s:%s:%s\n", tag
, id
, perms
);
557 SMB_ACL_T
sys_acl_init(int count
)
567 * note that since the definition of the structure pointed
568 * to by the SMB_ACL_T includes the first element of the
569 * acl[] array, this actually allocates an ACL with room
570 * for (count+1) entries
572 if ((a
= malloc(sizeof(*a
) + count
* sizeof(struct acl
))) == NULL
) {
585 int sys_acl_create_entry(SMB_ACL_T
*acl_p
, SMB_ACL_ENTRY_T
*entry_p
)
588 SMB_ACL_ENTRY_T entry_d
;
590 if (acl_p
== NULL
|| entry_p
== NULL
|| (acl_d
= *acl_p
) == NULL
) {
595 if (acl_d
->count
>= acl_d
->size
) {
600 entry_d
= &acl_d
->acl
[acl_d
->count
++];
609 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T tag_type
)
613 case SMB_ACL_USER_OBJ
:
615 case SMB_ACL_GROUP_OBJ
:
618 entry_d
->a_type
= tag_type
;
628 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d
, void *qual_p
)
630 if (entry_d
->a_type
!= SMB_ACL_GROUP
631 && entry_d
->a_type
!= SMB_ACL_USER
) {
636 entry_d
->a_id
= *((id_t
*)qual_p
);
641 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T permset_d
)
643 if (*permset_d
& ~(SMB_ACL_READ
|SMB_ACL_WRITE
|SMB_ACL_EXECUTE
)) {
647 entry_d
->a_perm
= *permset_d
;
652 int sys_acl_valid(SMB_ACL_T acl_d
)
654 if (aclsort(acl_d
->count
, 1, acl_d
->acl
) != 0) {
662 int sys_acl_set_file(char *name
, SMB_ACL_TYPE_T type
, SMB_ACL_T acl_d
)
667 struct acl
*acl_buf
= NULL
;
670 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
675 if (stat(name
, &s
) != 0) {
679 acl_p
= &acl_d
->acl
[0];
680 acl_count
= acl_d
->count
;
683 * if it's a directory there is extra work to do
684 * since the acl() system call will replace both
685 * the access ACLs and the default ACLs (if any)
687 if (S_ISDIR(s
.st_mode
)) {
693 if (type
== SMB_ACL_TYPE_ACCESS
) {
696 tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_DEFAULT
);
701 tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_ACCESS
);
704 if (tmp_acl
== NULL
) {
709 * allocate a temporary buffer for the complete ACL
711 acl_count
= acc_acl
->count
+ def_acl
->count
;
713 acl_buf
= malloc(acl_count
* sizeof(acl_buf
[0]));
715 if (acl_buf
== NULL
) {
716 sys_acl_free_acl(tmp_acl
);
722 * copy the access control and default entries into the buffer
724 memcpy(&acl_buf
[0], &acc_acl
->acl
[0],
725 acc_acl
->count
* sizeof(acl_buf
[0]));
727 memcpy(&acl_buf
[acc_acl
->count
], &def_acl
->acl
[0],
728 def_acl
->count
* sizeof(acl_buf
[0]));
731 * set the ACL_DEFAULT flag on the default entries
733 for (i
= acc_acl
->count
; i
< acl_count
; i
++) {
734 acl_buf
[i
].a_type
|= ACL_DEFAULT
;
737 sys_acl_free_acl(tmp_acl
);
739 } else if (type
!= SMB_ACL_TYPE_ACCESS
) {
744 if (aclsort(acl_count
, 1, acl_p
) != 0) {
748 ret
= acl(name
, SETACL
, acl_count
, acl_p
);
758 int sys_acl_set_fd(int fd
, SMB_ACL_T acl_d
)
760 if (aclsort(acl_d
->count
, 1, acl_d
->acl
) != 0) {
765 return facl(fd
, SETACL
, acl_d
->count
, &acl_d
->acl
[0]);
768 int sys_acl_free_text(char *text
)
774 int sys_acl_free_acl(SMB_ACL_T acl_d
)
780 int sys_acl_free_qualifier(void *qual
)
785 #elif defined(HAVE_IRIX_ACLS)
787 int sys_acl_get_entry(SMB_ACL_T acl_d
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
789 if (entry_id
!= SMB_ACL_FIRST_ENTRY
&& entry_id
!= SMB_ACL_NEXT_ENTRY
) {
794 if (entry_p
== NULL
) {
799 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
803 if (acl_d
->next
< 0) {
808 if (acl_d
->next
>= acl_d
->aclp
->acl_cnt
) {
812 *entry_p
= &acl_d
->aclp
->acl_entry
[acl_d
->next
++];
817 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*type_p
)
819 *type_p
= entry_d
->ae_tag
;
824 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
826 *permset_p
= entry_d
;
831 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d
)
833 if (entry_d
->ae_tag
!= SMB_ACL_USER
834 && entry_d
->ae_tag
!= SMB_ACL_GROUP
) {
839 return &entry_d
->ae_id
;
842 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
846 if ((a
= malloc(sizeof(*a
))) == NULL
) {
850 if ((a
->aclp
= acl_get_file(path_p
, type
)) == NULL
) {
859 SMB_ACL_T
sys_acl_get_fd(int fd
)
863 if ((a
= malloc(sizeof(*a
))) == NULL
) {
867 if ((a
->aclp
= acl_get_fd(fd
)) == NULL
) {
876 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d
)
878 permset_d
->ae_perm
= 0;
883 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
885 if (perm
!= SMB_ACL_READ
&& perm
!= SMB_ACL_WRITE
886 && perm
!= SMB_ACL_EXECUTE
) {
891 if (permset_d
== NULL
) {
896 permset_d
->ae_perm
|= perm
;
901 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d
, SMB_ACL_PERM_T perm
)
903 return permset_d
->ae_perm
& perm
;
906 char *sys_acl_to_text(SMB_ACL_T acl_d
, ssize_t
*len_p
)
908 return acl_to_text(acl_d
->aclp
, len_p
);
911 SMB_ACL_T
sys_acl_init(int count
)
920 if ((a
= malloc(sizeof(*a
) + sizeof(struct acl
))) == NULL
) {
927 a
->aclp
= (struct acl
*)(&a
->aclp
+ sizeof(struct acl
*));
928 a
->aclp
->acl_cnt
= 0;
934 int sys_acl_create_entry(SMB_ACL_T
*acl_p
, SMB_ACL_ENTRY_T
*entry_p
)
937 SMB_ACL_ENTRY_T entry_d
;
939 if (acl_p
== NULL
|| entry_p
== NULL
|| (acl_d
= *acl_p
) == NULL
) {
944 if (acl_d
->aclp
->acl_cnt
>= ACL_MAX_ENTRIES
) {
949 entry_d
= &acl_d
->aclp
->acl_entry
[acl_d
->aclp
->acl_cnt
++];
952 entry_d
->ae_perm
= 0;
958 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T tag_type
)
962 case SMB_ACL_USER_OBJ
:
964 case SMB_ACL_GROUP_OBJ
:
967 entry_d
->ae_tag
= tag_type
;
977 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d
, void *qual_p
)
979 if (entry_d
->ae_tag
!= SMB_ACL_GROUP
980 && entry_d
->ae_tag
!= SMB_ACL_USER
) {
985 entry_d
->ae_id
= *((id_t
*)qual_p
);
990 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T permset_d
)
992 if (permset_d
->ae_perm
& ~(SMB_ACL_READ
|SMB_ACL_WRITE
|SMB_ACL_EXECUTE
)) {
996 entry_d
->ae_perm
= permset_d
->ae_perm
;
1001 int sys_acl_valid(SMB_ACL_T acl_d
)
1003 return acl_valid(acl_d
->aclp
);
1006 int sys_acl_set_file(char *name
, SMB_ACL_TYPE_T type
, SMB_ACL_T acl_d
)
1008 return acl_set_file(name
, type
, acl_d
->aclp
);
1011 int sys_acl_set_fd(int fd
, SMB_ACL_T acl_d
)
1013 return acl_set_fd(fd
, acl_d
->aclp
);
1016 int sys_acl_free_text(char *text
)
1018 return acl_free(text
);
1021 int sys_acl_free_acl(SMB_ACL_T acl_d
)
1023 if (acl_d
->freeaclp
) {
1024 acl_free(acl_d
->aclp
);
1030 int sys_acl_free_qualifier(void *qual
)
1035 #elif defined(HAVE_XFS_ACLS)
1036 /* For Linux SGI/XFS Filesystems
1037 * contributed by J Trostel, Connex
1040 /* based on the implementation for Solaris by Toomas Soome.. which is
1041 * based on the implementation by Micheal Davidson for Unixware...
1043 * Linux XFS is a 'work-in-progress'
1044 * This interface may change...
1045 * You've been warned ;-> */
1047 /* First, do the identity mapping */
1049 int sys_acl_get_entry( SMB_ACL_T the_acl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
1051 if( acl_get_entry( the_acl
, entry_id
, entry_p
) >= 0) {
1059 SMB_ACL_T
sys_acl_get_file( const char *path_p
, SMB_ACL_TYPE_T type
)
1061 return acl_get_file( path_p
, type
);
1064 SMB_ACL_T
sys_acl_get_fd(int fd
)
1066 return acl_get_fd(fd
);
1069 char *sys_acl_to_text( SMB_ACL_T the_acl
, ssize_t
*plen
)
1071 return acl_to_text( the_acl
, plen
);
1074 int sys_acl_valid( SMB_ACL_T theacl
)
1076 return acl_valid(theacl
);
1079 int sys_acl_set_file( char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
1081 return acl_set_file(name
, acltype
, theacl
);
1084 int sys_acl_set_fd( int fd
, SMB_ACL_T theacl
)
1086 return acl_set_fd(fd
, theacl
);
1089 /* Now the functions I need to define for XFS */
1091 int sys_acl_create_entry( SMB_ACL_T
*acl_p
, SMB_ACL_ENTRY_T
*entry_p
)
1100 if((*acl_p
== NULL
) || (ace
== NULL
)){
1106 if( (cnt
+ 1) > ACL_MAX_ENTRIES
){
1111 newacl
= (acl_t
)malloc(sizeof(struct acl
));
1118 newacl
->acl_entry
[cnt
] = *ace
;
1119 newacl
->acl_cnt
= cnt
+ 1;
1123 *entry_p
= &newacl
->acl_entry
[cnt
];
1128 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
1130 *tag_type_p
= entry_d
->ae_tag
;
1134 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
1136 *permset_p
= &entry_d
->ae_perm
;
1140 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d
)
1142 if (entry_d
->ae_tag
!= SMB_ACL_USER
1143 && entry_d
->ae_tag
!= SMB_ACL_GROUP
) {
1147 return &entry_d
->ae_id
;
1150 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset
)
1156 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
1158 return (*permset
& perm
);
1161 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
1164 /* TO DO: Add in ALL possible permissions here */
1165 /* TO DO: Include extended ones!! */
1167 if (perm
!= SMB_ACL_READ
&& perm
!= SMB_ACL_WRITE
&& perm
!= SMB_ACL_EXECUTE
) {
1172 if(permset
== NULL
) {
1182 SMB_ACL_T
sys_acl_init( int count
)
1185 if((count
> ACL_MAX_ENTRIES
) || (count
< 0)) {
1190 a
= (struct acl
*)malloc(sizeof(struct acl
)); /* where is this memory freed? */
1196 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T tag_type
)
1201 case SMB_ACL_USER_OBJ
:
1203 case SMB_ACL_GROUP_OBJ
:
1206 entry_d
->ae_tag
= tag_type
;
1215 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry_d
, void *qual_p
)
1217 if(entry_d
->ae_tag
!= SMB_ACL_GROUP
&&
1218 entry_d
->ae_tag
!= SMB_ACL_USER
) {
1223 entry_d
->ae_id
= *((uid_t
*)qual_p
);
1228 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T permset_d
)
1230 /* TO DO: expand to extended permissions eventually! */
1232 if(*permset_d
& ~(SMB_ACL_READ
|SMB_ACL_WRITE
|SMB_ACL_EXECUTE
)) {
1239 int sys_acl_free_text(char *text
)
1241 return acl_free(text
);
1244 int sys_acl_free_acl(SMB_ACL_T the_acl
)
1246 return acl_free(the_acl
);
1249 int sys_acl_free_qualifier(void *qual
)
1254 #elif defined(HAVE_AIX_ACLS)
1256 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
1258 int sys_acl_get_entry( SMB_ACL_T theacl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
1260 struct acl_entry_link
*link
;
1261 struct new_acl_entry
*entry
;
1264 DEBUG(10,("This is the count: %d\n",theacl
->count
));
1266 /* Check if count was previously set to -1. *
1267 * If it was, that means we reached the end *
1268 * of the acl last time. */
1269 if(theacl
->count
== -1)
1273 /* To get to the next acl, traverse linked list until index *
1274 * of acl matches the count we are keeping. This count is *
1275 * incremented each time we return an acl entry. */
1277 for(keep_going
= 0; keep_going
< theacl
->count
; keep_going
++)
1280 entry
= *entry_p
= link
->entryp
;
1282 DEBUG(10,("*entry_p is %d\n",entry_p
));
1283 DEBUG(10,("*entry_p->ace_access is %d\n",entry
->ace_access
));
1285 /* Increment count */
1287 if(link
->nextp
== NULL
)
1293 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
1295 /* Initialize tag type */
1298 DEBUG(10,("the tagtype is %d\n",entry_d
->ace_id
->id_type
));
1300 /* Depending on what type of entry we have, *
1301 * return tag type. */
1302 switch(entry_d
->ace_id
->id_type
) {
1304 *tag_type_p
= SMB_ACL_USER
;
1307 *tag_type_p
= SMB_ACL_GROUP
;
1310 case SMB_ACL_USER_OBJ
:
1311 case SMB_ACL_GROUP_OBJ
:
1313 *tag_type_p
= entry_d
->ace_id
->id_type
;
1323 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
1325 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
1326 *permset_p
= &entry_d
->ace_access
;
1327 DEBUG(10,("**permset_p is %d\n",**permset_p
));
1328 if(!(**permset_p
& S_IXUSR
) &&
1329 !(**permset_p
& S_IWUSR
) &&
1330 !(**permset_p
& S_IRUSR
) &&
1334 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
1338 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d
)
1340 return(entry_d
->ace_id
->id_data
);
1343 SMB_ACL_T
sys_acl_get_file( const char *path_p
, SMB_ACL_TYPE_T type
)
1345 struct acl
*file_acl
= (struct acl
*)NULL
;
1346 struct acl_entry
*acl_entry
;
1347 struct new_acl_entry
*new_acl_entry
;
1349 struct acl_entry_link
*acl_entry_link
;
1350 struct acl_entry_link
*acl_entry_link_head
;
1355 /* Get the acl using statacl */
1357 DEBUG(10,("Entering sys_acl_get_file\n"));
1358 DEBUG(10,("path_p is %s\n",path_p
));
1360 file_acl
= (struct acl
*)malloc(BUFSIZ
);
1362 if(file_acl
== NULL
) {
1364 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno
));
1368 memset(file_acl
,0,BUFSIZ
);
1370 rc
= statacl((char *)path_p
,0,file_acl
,BUFSIZ
);
1372 DEBUG(0,("statacl returned %d with errno %d\n",rc
,errno
));
1377 DEBUG(10,("Got facl and returned it\n"));
1379 /* Point to the first acl entry in the acl */
1380 acl_entry
= file_acl
->acl_ext
;
1382 /* Begin setting up the head of the linked list *
1383 * that will be used for the storing the acl *
1384 * in a way that is useful for the posix_acls.c *
1387 acl_entry_link_head
= acl_entry_link
= sys_acl_init(0);
1388 if(acl_entry_link_head
== NULL
)
1391 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
1392 if(acl_entry_link
->entryp
== NULL
) {
1395 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
1399 DEBUG(10,("acl_entry is %d\n",acl_entry
));
1400 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl
)));
1402 /* Check if the extended acl bit is on. *
1403 * If it isn't, do not show the *
1404 * contents of the acl since AIX intends *
1405 * the extended info to remain unused */
1407 if(file_acl
->acl_mode
& S_IXACL
){
1408 /* while we are not pointing to the very end */
1409 while(acl_entry
< acl_last(file_acl
)) {
1410 /* before we malloc anything, make sure this is */
1411 /* a valid acl entry and one that we want to map */
1412 idp
= id_nxt(acl_entry
->ace_id
);
1413 if((acl_entry
->ace_type
== ACC_SPECIFY
||
1414 (acl_entry
->ace_type
== ACC_PERMIT
)) && (idp
!= id_last(acl_entry
))) {
1415 acl_entry
= acl_nxt(acl_entry
);
1419 idp
= acl_entry
->ace_id
;
1421 /* Check if this is the first entry in the linked list. *
1422 * The first entry needs to keep prevp pointing to NULL *
1423 * and already has entryp allocated. */
1425 if(acl_entry_link_head
->count
!= 0) {
1426 acl_entry_link
->nextp
= (struct acl_entry_link
*)
1427 malloc(sizeof(struct acl_entry_link
));
1429 if(acl_entry_link
->nextp
== NULL
) {
1432 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
1436 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
1437 acl_entry_link
= acl_entry_link
->nextp
;
1438 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
1439 if(acl_entry_link
->entryp
== NULL
) {
1442 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
1445 acl_entry_link
->nextp
= NULL
;
1448 acl_entry_link
->entryp
->ace_len
= acl_entry
->ace_len
;
1450 /* Don't really need this since all types are going *
1451 * to be specified but, it's better than leaving it 0 */
1453 acl_entry_link
->entryp
->ace_type
= acl_entry
->ace_type
;
1455 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
1457 memcpy(acl_entry_link
->entryp
->ace_id
,idp
,sizeof(struct ace_id
));
1459 /* The access in the acl entries must be left shifted by *
1460 * three bites, because they will ultimately be compared *
1461 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1463 switch(acl_entry
->ace_type
){
1466 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
1467 acl_entry_link
->entryp
->ace_access
<<= 6;
1468 acl_entry_link_head
->count
++;
1471 /* Since there is no way to return a DENY acl entry *
1472 * change to PERMIT and then shift. */
1473 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry
->ace_access
));
1474 acl_entry_link
->entryp
->ace_access
= ~acl_entry
->ace_access
& 7;
1475 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link
->entryp
->ace_access
));
1476 acl_entry_link
->entryp
->ace_access
<<= 6;
1477 acl_entry_link_head
->count
++;
1483 DEBUG(10,("acl_entry = %d\n",acl_entry
));
1484 DEBUG(10,("The ace_type is %d\n",acl_entry
->ace_type
));
1486 acl_entry
= acl_nxt(acl_entry
);
1488 } /* end of if enabled */
1490 /* Since owner, group, other acl entries are not *
1491 * part of the acl entries in an acl, they must *
1492 * be dummied up to become part of the list. */
1494 for( i
= 1; i
< 4; i
++) {
1495 DEBUG(10,("i is %d\n",i
));
1496 if(acl_entry_link_head
->count
!= 0) {
1497 acl_entry_link
->nextp
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
1498 if(acl_entry_link
->nextp
== NULL
) {
1501 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
1505 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
1506 acl_entry_link
= acl_entry_link
->nextp
;
1507 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
1508 if(acl_entry_link
->entryp
== NULL
) {
1511 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno
));
1516 acl_entry_link
->nextp
= NULL
;
1518 new_acl_entry
= acl_entry_link
->entryp
;
1519 idp
= new_acl_entry
->ace_id
;
1521 new_acl_entry
->ace_len
= sizeof(struct acl_entry
);
1522 new_acl_entry
->ace_type
= ACC_PERMIT
;
1523 idp
->id_len
= sizeof(struct ace_id
);
1524 DEBUG(10,("idp->id_len = %d\n",idp
->id_len
));
1525 memset(idp
->id_data
,0,sizeof(uid_t
));
1529 new_acl_entry
->ace_access
= file_acl
->g_access
<< 6;
1530 idp
->id_type
= SMB_ACL_GROUP_OBJ
;
1534 new_acl_entry
->ace_access
= file_acl
->o_access
<< 6;
1535 idp
->id_type
= SMB_ACL_OTHER
;
1539 new_acl_entry
->ace_access
= file_acl
->u_access
<< 6;
1540 idp
->id_type
= SMB_ACL_USER_OBJ
;
1548 acl_entry_link_head
->count
++;
1549 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry
->ace_access
));
1552 acl_entry_link_head
->count
= 0;
1555 return(acl_entry_link_head
);
1558 SMB_ACL_T
sys_acl_get_fd(int fd
)
1560 struct acl
*file_acl
= (struct acl
*)NULL
;
1561 struct acl_entry
*acl_entry
;
1562 struct new_acl_entry
*new_acl_entry
;
1564 struct acl_entry_link
*acl_entry_link
;
1565 struct acl_entry_link
*acl_entry_link_head
;
1570 /* Get the acl using fstatacl */
1572 DEBUG(10,("Entering sys_acl_get_fd\n"));
1573 DEBUG(10,("fd is %d\n",fd
));
1574 file_acl
= (struct acl
*)malloc(BUFSIZ
);
1576 if(file_acl
== NULL
) {
1578 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
1582 memset(file_acl
,0,BUFSIZ
);
1584 rc
= fstatacl(fd
,0,file_acl
,BUFSIZ
);
1586 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc
,errno
));
1591 DEBUG(10,("Got facl and returned it\n"));
1593 /* Point to the first acl entry in the acl */
1595 acl_entry
= file_acl
->acl_ext
;
1596 /* Begin setting up the head of the linked list *
1597 * that will be used for the storing the acl *
1598 * in a way that is useful for the posix_acls.c *
1601 acl_entry_link_head
= acl_entry_link
= sys_acl_init(0);
1602 if(acl_entry_link_head
== NULL
){
1607 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
1609 if(acl_entry_link
->entryp
== NULL
) {
1611 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
1616 DEBUG(10,("acl_entry is %d\n",acl_entry
));
1617 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl
)));
1619 /* Check if the extended acl bit is on. *
1620 * If it isn't, do not show the *
1621 * contents of the acl since AIX intends *
1622 * the extended info to remain unused */
1624 if(file_acl
->acl_mode
& S_IXACL
){
1625 /* while we are not pointing to the very end */
1626 while(acl_entry
< acl_last(file_acl
)) {
1627 /* before we malloc anything, make sure this is */
1628 /* a valid acl entry and one that we want to map */
1630 idp
= id_nxt(acl_entry
->ace_id
);
1631 if((acl_entry
->ace_type
== ACC_SPECIFY
||
1632 (acl_entry
->ace_type
== ACC_PERMIT
)) && (idp
!= id_last(acl_entry
))) {
1633 acl_entry
= acl_nxt(acl_entry
);
1637 idp
= acl_entry
->ace_id
;
1639 /* Check if this is the first entry in the linked list. *
1640 * The first entry needs to keep prevp pointing to NULL *
1641 * and already has entryp allocated. */
1643 if(acl_entry_link_head
->count
!= 0) {
1644 acl_entry_link
->nextp
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
1645 if(acl_entry_link
->nextp
== NULL
) {
1647 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
1651 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
1652 acl_entry_link
= acl_entry_link
->nextp
;
1653 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
1654 if(acl_entry_link
->entryp
== NULL
) {
1656 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
1661 acl_entry_link
->nextp
= NULL
;
1664 acl_entry_link
->entryp
->ace_len
= acl_entry
->ace_len
;
1666 /* Don't really need this since all types are going *
1667 * to be specified but, it's better than leaving it 0 */
1669 acl_entry_link
->entryp
->ace_type
= acl_entry
->ace_type
;
1670 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
1672 memcpy(acl_entry_link
->entryp
->ace_id
, idp
, sizeof(struct ace_id
));
1674 /* The access in the acl entries must be left shifted by *
1675 * three bites, because they will ultimately be compared *
1676 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1678 switch(acl_entry
->ace_type
){
1681 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
1682 acl_entry_link
->entryp
->ace_access
<<= 6;
1683 acl_entry_link_head
->count
++;
1686 /* Since there is no way to return a DENY acl entry *
1687 * change to PERMIT and then shift. */
1688 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry
->ace_access
));
1689 acl_entry_link
->entryp
->ace_access
= ~acl_entry
->ace_access
& 7;
1690 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link
->entryp
->ace_access
));
1691 acl_entry_link
->entryp
->ace_access
<<= 6;
1692 acl_entry_link_head
->count
++;
1698 DEBUG(10,("acl_entry = %d\n",acl_entry
));
1699 DEBUG(10,("The ace_type is %d\n",acl_entry
->ace_type
));
1701 acl_entry
= acl_nxt(acl_entry
);
1703 } /* end of if enabled */
1705 /* Since owner, group, other acl entries are not *
1706 * part of the acl entries in an acl, they must *
1707 * be dummied up to become part of the list. */
1709 for( i
= 1; i
< 4; i
++) {
1710 DEBUG(10,("i is %d\n",i
));
1711 if(acl_entry_link_head
->count
!= 0){
1712 acl_entry_link
->nextp
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
1713 if(acl_entry_link
->nextp
== NULL
) {
1715 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
1720 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
1721 acl_entry_link
= acl_entry_link
->nextp
;
1722 acl_entry_link
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
1724 if(acl_entry_link
->entryp
== NULL
) {
1727 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno
));
1732 acl_entry_link
->nextp
= NULL
;
1734 new_acl_entry
= acl_entry_link
->entryp
;
1735 idp
= new_acl_entry
->ace_id
;
1737 new_acl_entry
->ace_len
= sizeof(struct acl_entry
);
1738 new_acl_entry
->ace_type
= ACC_PERMIT
;
1739 idp
->id_len
= sizeof(struct ace_id
);
1740 DEBUG(10,("idp->id_len = %d\n",idp
->id_len
));
1741 memset(idp
->id_data
,0,sizeof(uid_t
));
1745 new_acl_entry
->ace_access
= file_acl
->g_access
<< 6;
1746 idp
->id_type
= SMB_ACL_GROUP_OBJ
;
1750 new_acl_entry
->ace_access
= file_acl
->o_access
<< 6;
1751 idp
->id_type
= SMB_ACL_OTHER
;
1755 new_acl_entry
->ace_access
= file_acl
->u_access
<< 6;
1756 idp
->id_type
= SMB_ACL_USER_OBJ
;
1763 acl_entry_link_head
->count
++;
1764 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry
->ace_access
));
1767 acl_entry_link_head
->count
= 0;
1770 return(acl_entry_link_head
);
1773 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset
)
1775 *permset
= *permset
& ~0777;
1779 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
1782 (perm
& (S_IXUSR
| S_IWUSR
| S_IRUSR
)) == 0)
1786 DEBUG(10,("This is the permset now: %d\n",*permset
));
1790 char *sys_acl_to_text( SMB_ACL_T theacl
, ssize_t
*plen
)
1795 SMB_ACL_T
sys_acl_init( int count
)
1797 struct acl_entry_link
*theacl
= NULL
;
1799 DEBUG(10,("Entering sys_acl_init\n"));
1801 theacl
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
1802 if(theacl
== NULL
) {
1804 DEBUG(0,("Error in sys_acl_init is %d\n",errno
));
1809 theacl
->nextp
= NULL
;
1810 theacl
->prevp
= NULL
;
1811 theacl
->entryp
= NULL
;
1812 DEBUG(10,("Exiting sys_acl_init\n"));
1816 int sys_acl_create_entry( SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
1818 struct acl_entry_link
*theacl
;
1819 struct acl_entry_link
*acl_entryp
;
1820 struct acl_entry_link
*temp_entry
;
1823 DEBUG(10,("Entering the sys_acl_create_entry\n"));
1825 theacl
= acl_entryp
= *pacl
;
1827 /* Get to the end of the acl before adding entry */
1829 for(counting
=0; counting
< theacl
->count
; counting
++){
1830 DEBUG(10,("The acl_entryp is %d\n",acl_entryp
));
1831 temp_entry
= acl_entryp
;
1832 acl_entryp
= acl_entryp
->nextp
;
1835 if(theacl
->count
!= 0){
1836 temp_entry
->nextp
= acl_entryp
= (struct acl_entry_link
*)malloc(sizeof(struct acl_entry_link
));
1837 if(acl_entryp
== NULL
) {
1839 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno
));
1843 DEBUG(10,("The acl_entryp is %d\n",acl_entryp
));
1844 acl_entryp
->prevp
= temp_entry
;
1845 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp
->prevp
));
1848 *pentry
= acl_entryp
->entryp
= (struct new_acl_entry
*)malloc(sizeof(struct new_acl_entry
));
1849 if(*pentry
== NULL
) {
1851 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno
));
1855 memset(*pentry
,0,sizeof(struct new_acl_entry
));
1856 acl_entryp
->entryp
->ace_len
= sizeof(struct acl_entry
);
1857 acl_entryp
->entryp
->ace_type
= ACC_PERMIT
;
1858 acl_entryp
->entryp
->ace_id
->id_len
= sizeof(struct ace_id
);
1859 acl_entryp
->nextp
= NULL
;
1861 DEBUG(10,("Exiting sys_acl_create_entry\n"));
1865 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tagtype
)
1867 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
1868 entry
->ace_id
->id_type
= tagtype
;
1869 DEBUG(10,("The tag type is %d\n",entry
->ace_id
->id_type
));
1870 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
1873 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry
, void *qual
)
1875 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
1876 memcpy(entry
->ace_id
->id_data
,qual
,sizeof(uid_t
));
1877 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
1881 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry
, SMB_ACL_PERMSET_T permset
)
1883 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
1884 if(!(*permset
& S_IXUSR
) &&
1885 !(*permset
& S_IWUSR
) &&
1886 !(*permset
& S_IRUSR
) &&
1890 entry
->ace_access
= *permset
;
1891 DEBUG(10,("entry->ace_access = %d\n",entry
->ace_access
));
1892 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
1896 int sys_acl_valid( SMB_ACL_T theacl
)
1901 struct acl_entry_link
*acl_entry
;
1903 for(acl_entry
=theacl
; acl_entry
!= NULL
; acl_entry
= acl_entry
->nextp
) {
1904 user_obj
+= (acl_entry
->entryp
->ace_id
->id_type
== SMB_ACL_USER_OBJ
);
1905 group_obj
+= (acl_entry
->entryp
->ace_id
->id_type
== SMB_ACL_GROUP_OBJ
);
1906 other_obj
+= (acl_entry
->entryp
->ace_id
->id_type
== SMB_ACL_OTHER
);
1909 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj
,group_obj
,other_obj
));
1911 if(user_obj
!= 1 || group_obj
!= 1 || other_obj
!= 1)
1917 int sys_acl_set_file( char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
1919 struct acl_entry_link
*acl_entry_link
= NULL
;
1920 struct acl
*file_acl
= NULL
;
1921 struct acl
*file_acl_temp
= NULL
;
1922 struct acl_entry
*acl_entry
= NULL
;
1923 struct ace_id
*ace_id
= NULL
;
1930 DEBUG(10,("Entering sys_acl_set_file\n"));
1931 DEBUG(10,("File name is %s\n",name
));
1933 /* AIX has no default ACL */
1934 if(acltype
== SMB_ACL_TYPE_DEFAULT
)
1937 acl_length
= BUFSIZ
;
1938 file_acl
= (struct acl
*)malloc(BUFSIZ
);
1940 if(file_acl
== NULL
) {
1942 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno
));
1946 memset(file_acl
,0,BUFSIZ
);
1948 file_acl
->acl_len
= ACL_SIZ
;
1949 file_acl
->acl_mode
= S_IXACL
;
1951 for(acl_entry_link
=theacl
; acl_entry_link
!= NULL
; acl_entry_link
= acl_entry_link
->nextp
) {
1952 acl_entry_link
->entryp
->ace_access
>>= 6;
1953 id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
1956 case SMB_ACL_USER_OBJ
:
1957 file_acl
->u_access
= acl_entry_link
->entryp
->ace_access
;
1959 case SMB_ACL_GROUP_OBJ
:
1960 file_acl
->g_access
= acl_entry_link
->entryp
->ace_access
;
1963 file_acl
->o_access
= acl_entry_link
->entryp
->ace_access
;
1969 if((file_acl
->acl_len
+ sizeof(struct acl_entry
)) > acl_length
) {
1970 acl_length
+= sizeof(struct acl_entry
);
1971 file_acl_temp
= (struct acl
*)malloc(acl_length
);
1972 if(file_acl_temp
== NULL
) {
1975 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno
));
1979 memcpy(file_acl_temp
,file_acl
,file_acl
->acl_len
);
1981 file_acl
= file_acl_temp
;
1984 acl_entry
= (struct acl_entry
*)((char *)file_acl
+ file_acl
->acl_len
);
1985 file_acl
->acl_len
+= sizeof(struct acl_entry
);
1986 acl_entry
->ace_len
= acl_entry_link
->entryp
->ace_len
;
1987 acl_entry
->ace_access
= acl_entry_link
->entryp
->ace_access
;
1989 /* In order to use this, we'll need to wait until we can get denies */
1990 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
1991 acl_entry->ace_type = ACC_SPECIFY; */
1993 acl_entry
->ace_type
= ACC_SPECIFY
;
1995 ace_id
= acl_entry
->ace_id
;
1997 ace_id
->id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
1998 DEBUG(10,("The id type is %d\n",ace_id
->id_type
));
1999 ace_id
->id_len
= acl_entry_link
->entryp
->ace_id
->id_len
;
2000 memcpy(&user_id
, acl_entry_link
->entryp
->ace_id
->id_data
, sizeof(uid_t
));
2001 memcpy(acl_entry
->ace_id
->id_data
, &user_id
, sizeof(uid_t
));
2004 rc
= chacl(name
,file_acl
,file_acl
->acl_len
);
2005 DEBUG(10,("errno is %d\n",errno
));
2006 DEBUG(10,("return code is %d\n",rc
));
2008 DEBUG(10,("Exiting the sys_acl_set_file\n"));
2012 int sys_acl_set_fd( int fd
, SMB_ACL_T theacl
)
2014 struct acl_entry_link
*acl_entry_link
= NULL
;
2015 struct acl
*file_acl
= NULL
;
2016 struct acl
*file_acl_temp
= NULL
;
2017 struct acl_entry
*acl_entry
= NULL
;
2018 struct ace_id
*ace_id
= NULL
;
2024 DEBUG(10,("Entering sys_acl_set_fd\n"));
2025 acl_length
= BUFSIZ
;
2026 file_acl
= (struct acl
*)malloc(BUFSIZ
);
2028 if(file_acl
== NULL
) {
2030 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno
));
2034 memset(file_acl
,0,BUFSIZ
);
2036 file_acl
->acl_len
= ACL_SIZ
;
2037 file_acl
->acl_mode
= S_IXACL
;
2039 for(acl_entry_link
=theacl
; acl_entry_link
!= NULL
; acl_entry_link
= acl_entry_link
->nextp
) {
2040 acl_entry_link
->entryp
->ace_access
>>= 6;
2041 id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
2042 DEBUG(10,("The id_type is %d\n",id_type
));
2045 case SMB_ACL_USER_OBJ
:
2046 file_acl
->u_access
= acl_entry_link
->entryp
->ace_access
;
2048 case SMB_ACL_GROUP_OBJ
:
2049 file_acl
->g_access
= acl_entry_link
->entryp
->ace_access
;
2052 file_acl
->o_access
= acl_entry_link
->entryp
->ace_access
;
2058 if((file_acl
->acl_len
+ sizeof(struct acl_entry
)) > acl_length
) {
2059 acl_length
+= sizeof(struct acl_entry
);
2060 file_acl_temp
= (struct acl
*)malloc(acl_length
);
2061 if(file_acl_temp
== NULL
) {
2064 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno
));
2068 memcpy(file_acl_temp
,file_acl
,file_acl
->acl_len
);
2070 file_acl
= file_acl_temp
;
2073 acl_entry
= (struct acl_entry
*)((char *)file_acl
+ file_acl
->acl_len
);
2074 file_acl
->acl_len
+= sizeof(struct acl_entry
);
2075 acl_entry
->ace_len
= acl_entry_link
->entryp
->ace_len
;
2076 acl_entry
->ace_access
= acl_entry_link
->entryp
->ace_access
;
2078 /* In order to use this, we'll need to wait until we can get denies */
2079 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2080 acl_entry->ace_type = ACC_SPECIFY; */
2082 acl_entry
->ace_type
= ACC_SPECIFY
;
2084 ace_id
= acl_entry
->ace_id
;
2086 ace_id
->id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
2087 DEBUG(10,("The id type is %d\n",ace_id
->id_type
));
2088 ace_id
->id_len
= acl_entry_link
->entryp
->ace_id
->id_len
;
2089 memcpy(&user_id
, acl_entry_link
->entryp
->ace_id
->id_data
, sizeof(uid_t
));
2090 memcpy(ace_id
->id_data
, &user_id
, sizeof(uid_t
));
2093 rc
= fchacl(fd
,file_acl
,file_acl
->acl_len
);
2094 DEBUG(10,("errno is %d\n",errno
));
2095 DEBUG(10,("return code is %d\n",rc
));
2097 DEBUG(10,("Exiting sys_acl_set_fd\n"));
2101 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
2103 return(*permset
& perm
);
2106 int sys_acl_free_text(char *text
)
2111 int sys_acl_free_acl(SMB_ACL_T posix_acl
)
2113 struct acl_entry_link
*acl_entry_link
;
2115 for(acl_entry_link
= posix_acl
->nextp
; acl_entry_link
->nextp
!= NULL
; acl_entry_link
= acl_entry_link
->nextp
) {
2116 free(acl_entry_link
->prevp
->entryp
);
2117 free(acl_entry_link
->prevp
);
2120 free(acl_entry_link
->prevp
->entryp
);
2121 free(acl_entry_link
->prevp
);
2122 free(acl_entry_link
->entryp
);
2123 free(acl_entry_link
);
2128 int sys_acl_free_qualifier(void *qual
)
2133 #else /* No ACLs. */
2135 int sys_acl_get_entry( SMB_ACL_T the_acl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
2141 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
2147 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
2153 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d
)
2159 SMB_ACL_T
sys_acl_get_file( const char *path_p
, SMB_ACL_TYPE_T type
)
2162 return (SMB_ACL_T
)NULL
;
2165 SMB_ACL_T
sys_acl_get_fd(int fd
)
2168 return (SMB_ACL_T
)NULL
;
2171 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset
)
2177 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
2183 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
2186 return (permset
& perm
) ? 1 : 0;
2189 char *sys_acl_to_text( SMB_ACL_T the_acl
, ssize_t
*plen
)
2195 int sys_acl_free_text(char *text
)
2201 SMB_ACL_T
sys_acl_init( int count
)
2207 int sys_acl_create_entry( SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
2213 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tagtype
)
2219 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry
, void *qual
)
2225 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry
, SMB_ACL_PERMSET_T permset
)
2231 int sys_acl_valid( SMB_ACL_T theacl
)
2237 int sys_acl_set_file( char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
2243 int sys_acl_set_fd( int fd
, SMB_ACL_T theacl
)
2249 int sys_acl_free_acl(SMB_ACL_T the_acl
)
2255 int sys_acl_free_qualifier(void *qual
)
2261 #endif /* No ACLs. */