2 * Unix SMB/CIFS implementation.
3 * Based on the Samba ACL support code.
4 * Copyright (C) Jeremy Allison 2000.
5 * Copyright (C) 2007-2022 Wayne Davison
7 * The permission functions have been changed to get/set all bits via
8 * one call. Some functions that rsync doesn't need were also removed.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * with this program; if not, visit the http://fsf.org website.
34 void SAFE_FREE(void *mem
)
41 This file wraps all differing system ACL interfaces into a consistent
42 one based on the POSIX interface. It also returns the correct errors
43 for older UNIX systems that don't support ACLs.
45 The interfaces that each ACL implementation must support are as follows :
47 int sys_acl_get_entry(SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
48 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
49 int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p)
50 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
51 SMB_ACL_T sys_acl_get_fd(int fd)
52 SMB_ACL_T sys_acl_init(int count)
53 int sys_acl_create_entry(SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
54 int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id)
55 int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits)
56 int sys_acl_valid(SMB_ACL_T theacl)
57 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
58 int sys_acl_set_fd(int fd, SMB_ACL_T theacl)
59 int sys_acl_delete_def_file(const char *path)
60 int sys_acl_free_acl(SMB_ACL_T posix_acl)
64 #if defined(HAVE_POSIX_ACLS) /*--------------------------------------------*/
66 /* Identity mapping - easy. */
68 int sys_acl_get_entry(SMB_ACL_T the_acl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
70 return acl_get_entry(the_acl
, entry_id
, entry_p
);
73 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
75 return acl_get_tag_type(entry_d
, tag_type_p
);
78 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
80 return acl_get_file(path_p
, type
);
84 SMB_ACL_T
sys_acl_get_fd(int fd
)
86 return acl_get_fd(fd
);
90 #if defined(HAVE_ACL_GET_PERM_NP)
91 #define acl_get_perm(p, b) acl_get_perm_np(p, b)
94 int sys_acl_get_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T
*tag_type_p
, uint32
*bits_p
, id_t
*u_g_id_p
)
96 acl_permset_t permset
;
98 if (acl_get_tag_type(entry
, tag_type_p
) != 0
99 || acl_get_permset(entry
, &permset
) != 0)
102 *bits_p
= (acl_get_perm(permset
, ACL_READ
) ? 4 : 0)
103 | (acl_get_perm(permset
, ACL_WRITE
) ? 2 : 0)
104 | (acl_get_perm(permset
, ACL_EXECUTE
) ? 1 : 0);
106 if (*tag_type_p
== SMB_ACL_USER
|| *tag_type_p
== SMB_ACL_GROUP
) {
108 if ((qual
= acl_get_qualifier(entry
)) == NULL
)
110 *u_g_id_p
= *(id_t
*)qual
;
117 SMB_ACL_T
sys_acl_init(int count
)
119 return acl_init(count
);
122 int sys_acl_create_entry(SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
124 return acl_create_entry(pacl
, pentry
);
127 int sys_acl_set_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tag_type
, uint32 bits
, id_t u_g_id
)
129 if (acl_set_tag_type(entry
, tag_type
) != 0)
132 if (tag_type
== SMB_ACL_USER
|| tag_type
== SMB_ACL_GROUP
) {
133 if (acl_set_qualifier(entry
, (void*)&u_g_id
) != 0)
137 return sys_acl_set_access_bits(entry
, bits
);
140 int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry
, uint32 bits
)
142 acl_permset_t permset
;
144 if ((rc
= acl_get_permset(entry
, &permset
)) != 0)
146 acl_clear_perms(permset
);
148 acl_add_perm(permset
, ACL_READ
);
150 acl_add_perm(permset
, ACL_WRITE
);
152 acl_add_perm(permset
, ACL_EXECUTE
);
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
);
167 int sys_acl_set_fd(int fd
, SMB_ACL_T theacl
)
169 return acl_set_fd(fd
, theacl
);
173 int sys_acl_delete_def_file(const char *name
)
175 return acl_delete_def_file(name
);
178 int sys_acl_free_acl(SMB_ACL_T the_acl
)
180 return acl_free(the_acl
);
183 #elif defined(HAVE_TRU64_ACLS) /*--------------------------------------------*/
185 * The interface to DEC/Compaq Tru64 UNIX ACLs
186 * is based on Draft 13 of the POSIX spec which is
187 * slightly different from the Draft 16 interface.
189 * Also, some of the permset manipulation functions
190 * such as acl_clear_perm() and acl_add_perm() appear
191 * to be broken on Tru64 so we have to manipulate
192 * the permission bits in the permset directly.
194 int sys_acl_get_entry(SMB_ACL_T the_acl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
196 SMB_ACL_ENTRY_T entry
;
198 if (entry_id
== SMB_ACL_FIRST_ENTRY
&& acl_first_entry(the_acl
) != 0) {
203 if ((entry
= acl_get_entry(the_acl
)) != NULL
) {
208 return errno
? -1 : 0;
211 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
213 return acl_get_tag_type(entry_d
, tag_type_p
);
216 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
218 return acl_get_file((char *)path_p
, type
);
222 SMB_ACL_T
sys_acl_get_fd(int fd
)
224 return acl_get_fd(fd
, ACL_TYPE_ACCESS
);
228 int sys_acl_get_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T
*tag_type_p
, uint32
*bits_p
, id_t
*u_g_id_p
)
230 acl_permset_t permset
;
232 if (acl_get_tag_type(entry
, tag_type_p
) != 0
233 || acl_get_permset(entry
, &permset
) != 0)
236 *bits_p
= *permset
& 7; /* Tru64 doesn't have acl_get_perm() */
238 if (*tag_type_p
== SMB_ACL_USER
|| *tag_type_p
== SMB_ACL_GROUP
) {
240 if ((qual
= acl_get_qualifier(entry
)) == NULL
)
242 *u_g_id_p
= *(id_t
*)qual
;
243 acl_free_qualifier(qual
, *tag_type_p
);
249 SMB_ACL_T
sys_acl_init(int count
)
251 return acl_init(count
);
254 int sys_acl_create_entry(SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
256 SMB_ACL_ENTRY_T entry
;
258 if ((entry
= acl_create_entry(pacl
)) == NULL
) {
266 int sys_acl_set_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tag_type
, uint32 bits
, id_t u_g_id
)
268 if (acl_set_tag_type(entry
, tag_type
) != 0)
271 if (tag_type
== SMB_ACL_USER
|| tag_type
== SMB_ACL_GROUP
) {
272 if (acl_set_qualifier(entry
, (void*)&u_g_id
) != 0)
276 return sys_acl_set_access_bits(entry
, bits
);
279 int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry
, uint32 bits
)
281 acl_permset_t permset
;
283 if ((rc
= acl_get_permset(entry
, &permset
)) != 0)
286 return acl_set_permset(entry
, permset
);
289 int sys_acl_valid(SMB_ACL_T theacl
)
293 return acl_valid(theacl
, &entry
);
296 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
298 return acl_set_file((char *)name
, acltype
, theacl
);
302 int sys_acl_set_fd(int fd
, SMB_ACL_T theacl
)
304 return acl_set_fd(fd
, ACL_TYPE_ACCESS
, theacl
);
308 int sys_acl_delete_def_file(const char *name
)
310 return acl_delete_def_file((char *)name
);
313 int sys_acl_free_acl(SMB_ACL_T the_acl
)
315 return acl_free(the_acl
);
318 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS) /*-----------*/
321 * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
322 * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
326 * Note that while this code implements sufficient functionality
327 * to support the sys_acl_* interfaces it does not provide all
328 * of the semantics of the POSIX ACL interfaces.
330 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
331 * from a call to sys_acl_get_entry() should not be assumed to be
332 * valid after calling any of the following functions, which may
333 * reorder the entries in the ACL.
341 * The only difference between Solaris and UnixWare / OpenUNIX is
342 * that the #defines for the ACL operations have different names
344 #if defined(HAVE_UNIXWARE_ACLS)
346 #define SETACL ACL_SET
347 #define GETACL ACL_GET
348 #define GETACLCNT ACL_CNT
353 int sys_acl_get_entry(SMB_ACL_T acl_d
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
355 if (entry_id
!= SMB_ACL_FIRST_ENTRY
&& entry_id
!= SMB_ACL_NEXT_ENTRY
) {
360 if (entry_p
== NULL
) {
365 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
369 if (acl_d
->next
< 0) {
374 if (acl_d
->next
>= acl_d
->count
) {
378 *entry_p
= &acl_d
->acl
[acl_d
->next
++];
383 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*type_p
)
385 *type_p
= entry_d
->a_type
;
391 * There is no way of knowing what size the ACL returned by
392 * GETACL will be unless you first call GETACLCNT which means
393 * making an additional system call.
395 * In the hope of avoiding the cost of the additional system
396 * call in most cases, we initially allocate enough space for
397 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
398 * be too small then we use GETACLCNT to find out the actual
399 * size, reallocate the ACL buffer, and then call GETACL again.
402 #define INITIAL_ACL_SIZE 16
404 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
407 int count
; /* # of ACL entries allocated */
408 int naccess
; /* # of access ACL entries */
409 int ndefault
; /* # of default ACL entries */
411 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
416 count
= INITIAL_ACL_SIZE
;
417 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
422 * If there isn't enough space for the ACL entries we use
423 * GETACLCNT to determine the actual number of ACL entries
424 * reallocate and try again. This is in a loop because it
425 * is possible that someone else could modify the ACL and
426 * increase the number of entries between the call to
427 * GETACLCNT and the call to GETACL.
429 while ((count
= acl(path_p
, GETACL
, count
, &acl_d
->acl
[0])) < 0
430 && errno
== ENOSPC
) {
432 sys_acl_free_acl(acl_d
);
434 if ((count
= acl(path_p
, GETACLCNT
, 0, NULL
)) < 0) {
438 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
444 sys_acl_free_acl(acl_d
);
449 * calculate the number of access and default ACL entries
451 * Note: we assume that the acl() system call returned a
452 * well formed ACL which is sorted so that all of the
453 * access ACL entries precede any default ACL entries
455 for (naccess
= 0; naccess
< count
; naccess
++) {
456 if (acl_d
->acl
[naccess
].a_type
& ACL_DEFAULT
)
459 ndefault
= count
- naccess
;
462 * if the caller wants the default ACL we have to copy
463 * the entries down to the start of the acl[] buffer
464 * and mask out the ACL_DEFAULT flag from the type field
466 if (type
== SMB_ACL_TYPE_DEFAULT
) {
469 for (i
= 0, j
= naccess
; i
< ndefault
; i
++, j
++) {
470 acl_d
->acl
[i
] = acl_d
->acl
[j
];
471 acl_d
->acl
[i
].a_type
&= ~ACL_DEFAULT
;
474 acl_d
->count
= ndefault
;
476 acl_d
->count
= naccess
;
483 SMB_ACL_T
sys_acl_get_fd(int fd
)
486 int count
; /* # of ACL entries allocated */
487 int naccess
; /* # of access ACL entries */
489 count
= INITIAL_ACL_SIZE
;
490 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
494 while ((count
= facl(fd
, GETACL
, count
, &acl_d
->acl
[0])) < 0
495 && errno
== ENOSPC
) {
497 sys_acl_free_acl(acl_d
);
499 if ((count
= facl(fd
, GETACLCNT
, 0, NULL
)) < 0) {
503 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
509 sys_acl_free_acl(acl_d
);
514 * calculate the number of access ACL entries
516 for (naccess
= 0; naccess
< count
; naccess
++) {
517 if (acl_d
->acl
[naccess
].a_type
& ACL_DEFAULT
)
521 acl_d
->count
= naccess
;
527 int sys_acl_get_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T
*tag_type_p
, uint32
*bits_p
, id_t
*u_g_id_p
)
529 *tag_type_p
= entry
->a_type
;
531 *bits_p
= entry
->a_perm
;
533 if (*tag_type_p
== SMB_ACL_USER
|| *tag_type_p
== SMB_ACL_GROUP
)
534 *u_g_id_p
= entry
->a_id
;
539 SMB_ACL_T
sys_acl_init(int count
)
549 * note that since the definition of the structure pointed
550 * to by the SMB_ACL_T includes the first element of the
551 * acl[] array, this actually allocates an ACL with room
552 * for (count+1) entries
554 if ((a
= (SMB_ACL_T
)SMB_MALLOC(sizeof a
[0] + count
* sizeof (struct acl
))) == NULL
) {
567 int sys_acl_create_entry(SMB_ACL_T
*acl_p
, SMB_ACL_ENTRY_T
*entry_p
)
570 SMB_ACL_ENTRY_T entry_d
;
572 if (acl_p
== NULL
|| entry_p
== NULL
|| (acl_d
= *acl_p
) == NULL
) {
577 if (acl_d
->count
>= acl_d
->size
) {
582 entry_d
= &acl_d
->acl
[acl_d
->count
++];
591 int sys_acl_set_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tag_type
, uint32 bits
, id_t u_g_id
)
593 entry
->a_type
= tag_type
;
595 if (tag_type
== SMB_ACL_USER
|| tag_type
== SMB_ACL_GROUP
)
596 entry
->a_id
= u_g_id
;
598 entry
->a_perm
= bits
;
603 int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry_d
, uint32 bits
)
605 entry_d
->a_perm
= bits
;
610 * sort the ACL and check it for validity
612 * if it's a minimal ACL with only 4 entries then we
613 * need to recalculate the mask permissions to make
614 * sure that they are the same as the GROUP_OBJ
615 * permissions as required by the UnixWare acl() system call.
617 * (note: since POSIX allows minimal ACLs which only contain
618 * 3 entries - ie there is no mask entry - we should, in theory,
619 * check for this and add a mask entry if necessary - however
620 * we "know" that the caller of this interface always specifies
621 * a mask so, in practice "this never happens" (tm) - if it *does*
622 * happen aclsort() will fail and return an error and someone will
623 * have to fix it ...)
626 static int acl_sort(SMB_ACL_T acl_d
)
628 int fixmask
= (acl_d
->count
<= 4);
630 if (aclsort(acl_d
->count
, fixmask
, acl_d
->acl
) != 0) {
637 int sys_acl_valid(SMB_ACL_T acl_d
)
639 return acl_sort(acl_d
);
642 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T type
, SMB_ACL_T acl_d
)
647 struct acl
*acl_buf
= NULL
;
650 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
655 if (acl_sort(acl_d
) != 0) {
659 acl_p
= &acl_d
->acl
[0];
660 acl_count
= acl_d
->count
;
663 * if it's a directory there is extra work to do
664 * since the acl() system call will replace both
665 * the access ACLs and the default ACLs (if any)
667 if (stat(name
, &s
) != 0) {
670 if (S_ISDIR(s
.st_mode
)) {
676 if (type
== SMB_ACL_TYPE_ACCESS
) {
678 def_acl
= tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_DEFAULT
);
682 acc_acl
= tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_ACCESS
);
685 if (tmp_acl
== NULL
) {
690 * allocate a temporary buffer for the complete ACL
692 acl_count
= acc_acl
->count
+ def_acl
->count
;
693 acl_p
= acl_buf
= SMB_MALLOC_ARRAY(struct acl
, acl_count
);
695 if (acl_buf
== NULL
) {
696 sys_acl_free_acl(tmp_acl
);
702 * copy the access control and default entries into the buffer
704 memcpy(&acl_buf
[0], &acc_acl
->acl
[0],
705 acc_acl
->count
* sizeof acl_buf
[0]);
707 memcpy(&acl_buf
[acc_acl
->count
], &def_acl
->acl
[0],
708 def_acl
->count
* sizeof acl_buf
[0]);
711 * set the ACL_DEFAULT flag on the default entries
713 for (i
= acc_acl
->count
; i
< acl_count
; i
++) {
714 acl_buf
[i
].a_type
|= ACL_DEFAULT
;
717 sys_acl_free_acl(tmp_acl
);
719 } else if (type
!= SMB_ACL_TYPE_ACCESS
) {
724 ret
= acl(name
, SETACL
, acl_count
, acl_p
);
732 int sys_acl_set_fd(int fd
, SMB_ACL_T acl_d
)
734 if (acl_sort(acl_d
) != 0) {
738 return facl(fd
, SETACL
, acl_d
->count
, &acl_d
->acl
[0]);
742 int sys_acl_delete_def_file(const char *path
)
748 * fetching the access ACL and rewriting it has
749 * the effect of deleting the default ACL
751 if ((acl_d
= sys_acl_get_file(path
, SMB_ACL_TYPE_ACCESS
)) == NULL
) {
755 ret
= acl(path
, SETACL
, acl_d
->count
, acl_d
->acl
);
757 sys_acl_free_acl(acl_d
);
762 int sys_acl_free_acl(SMB_ACL_T acl_d
)
768 #elif defined(HAVE_HPUX_ACLS) /*---------------------------------------------*/
775 * Based on the Solaris/SCO code - with modifications.
779 * Note that while this code implements sufficient functionality
780 * to support the sys_acl_* interfaces it does not provide all
781 * of the semantics of the POSIX ACL interfaces.
783 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
784 * from a call to sys_acl_get_entry() should not be assumed to be
785 * valid after calling any of the following functions, which may
786 * reorder the entries in the ACL.
793 /* This checks if the POSIX ACL system call is defined */
794 /* which basically corresponds to whether JFS 3.3 or */
795 /* higher is installed. If acl() was called when it */
796 /* isn't defined, it causes the process to core dump */
797 /* so it is important to check this and avoid acl() */
798 /* calls if it isn't there. */
801 inline int do_acl(const char *path_p
, int cmd
, int nentries
, struct acl
*aclbufp
)
803 return acl((char*)path_p
, cmd
, nentries
, aclbufp
);
805 #define acl(p,c,n,a) do_acl(p,c,n,a)
808 static BOOL
hpux_acl_call_presence(void)
814 static BOOL already_checked
=0;
819 ret_val
= shl_findsym(&handle
, "acl", TYPE_PROCEDURE
, &value
);
822 DEBUG(5, ("hpux_acl_call_presence: shl_findsym() returned %d, errno = %d, error %s\n",
823 ret_val
, errno
, strerror(errno
)));
824 DEBUG(5, ("hpux_acl_call_presence: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
828 DEBUG(10, ("hpux_acl_call_presence: acl() system call is present. We have JFS 3.3 or above \n"));
830 already_checked
= True
;
835 int sys_acl_get_entry(SMB_ACL_T acl_d
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
837 if (entry_id
!= SMB_ACL_FIRST_ENTRY
&& entry_id
!= SMB_ACL_NEXT_ENTRY
) {
842 if (entry_p
== NULL
) {
847 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
851 if (acl_d
->next
< 0) {
856 if (acl_d
->next
>= acl_d
->count
) {
860 *entry_p
= &acl_d
->acl
[acl_d
->next
++];
865 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*type_p
)
867 *type_p
= entry_d
->a_type
;
873 * There is no way of knowing what size the ACL returned by
874 * ACL_GET will be unless you first call ACL_CNT which means
875 * making an additional system call.
877 * In the hope of avoiding the cost of the additional system
878 * call in most cases, we initially allocate enough space for
879 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
880 * be too small then we use ACL_CNT to find out the actual
881 * size, reallocate the ACL buffer, and then call ACL_GET again.
884 #define INITIAL_ACL_SIZE 16
887 #define NACLENTRIES 0
890 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
893 int count
; /* # of ACL entries allocated */
894 int naccess
; /* # of access ACL entries */
895 int ndefault
; /* # of default ACL entries */
897 if (hpux_acl_call_presence() == False
) {
898 /* Looks like we don't have the acl() system call on HPUX.
899 * May be the system doesn't have the latest version of JFS.
904 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
909 count
= INITIAL_ACL_SIZE
;
910 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
915 * If there isn't enough space for the ACL entries we use
916 * ACL_CNT to determine the actual number of ACL entries
917 * reallocate and try again. This is in a loop because it
918 * is possible that someone else could modify the ACL and
919 * increase the number of entries between the call to
920 * ACL_CNT and the call to ACL_GET.
922 while ((count
= acl(path_p
, ACL_GET
, count
, &acl_d
->acl
[0])) < 0 && errno
== ENOSPC
) {
924 sys_acl_free_acl(acl_d
);
926 if ((count
= acl(path_p
, ACL_CNT
, NACLENTRIES
, NULL
)) < 0) {
930 if ((acl_d
= sys_acl_init(count
)) == NULL
) {
936 sys_acl_free_acl(acl_d
);
941 * calculate the number of access and default ACL entries
943 * Note: we assume that the acl() system call returned a
944 * well formed ACL which is sorted so that all of the
945 * access ACL entries precede any default ACL entries
947 for (naccess
= 0; naccess
< count
; naccess
++) {
948 if (acl_d
->acl
[naccess
].a_type
& ACL_DEFAULT
)
951 ndefault
= count
- naccess
;
954 * if the caller wants the default ACL we have to copy
955 * the entries down to the start of the acl[] buffer
956 * and mask out the ACL_DEFAULT flag from the type field
958 if (type
== SMB_ACL_TYPE_DEFAULT
) {
961 for (i
= 0, j
= naccess
; i
< ndefault
; i
++, j
++) {
962 acl_d
->acl
[i
] = acl_d
->acl
[j
];
963 acl_d
->acl
[i
].a_type
&= ~ACL_DEFAULT
;
966 acl_d
->count
= ndefault
;
968 acl_d
->count
= naccess
;
975 SMB_ACL_T
sys_acl_get_fd(int fd
)
978 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
981 files_struct
*fsp
= file_find_fd(fd
);
989 * We know we're in the same conn context. So we
990 * can use the relative path.
993 return sys_acl_get_file(fsp
->fsp_name
, SMB_ACL_TYPE_ACCESS
);
997 int sys_acl_get_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T
*tag_type_p
, uint32
*bits_p
, id_t
*u_g_id_p
)
999 *tag_type_p
= entry
->a_type
;
1001 *bits_p
= entry
->a_perm
;
1003 if (*tag_type_p
== SMB_ACL_USER
|| *tag_type_p
== SMB_ACL_GROUP
)
1004 *u_g_id_p
= entry
->a_id
;
1009 SMB_ACL_T
sys_acl_init(int count
)
1019 * note that since the definition of the structure pointed
1020 * to by the SMB_ACL_T includes the first element of the
1021 * acl[] array, this actually allocates an ACL with room
1022 * for (count+1) entries
1024 if ((a
= (SMB_ACL_T
)SMB_MALLOC(sizeof a
[0] + count
* sizeof (struct acl
))) == NULL
) {
1029 a
->size
= count
+ 1;
1037 int sys_acl_create_entry(SMB_ACL_T
*acl_p
, SMB_ACL_ENTRY_T
*entry_p
)
1040 SMB_ACL_ENTRY_T entry_d
;
1042 if (acl_p
== NULL
|| entry_p
== NULL
|| (acl_d
= *acl_p
) == NULL
) {
1047 if (acl_d
->count
>= acl_d
->size
) {
1052 entry_d
= &acl_d
->acl
[acl_d
->count
++];
1053 entry_d
->a_type
= 0;
1055 entry_d
->a_perm
= 0;
1061 int sys_acl_set_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tag_type
, uint32 bits
, id_t u_g_id
)
1063 entry
->a_type
= tag_type
;
1065 if (tag_type
== SMB_ACL_USER
|| tag_type
== SMB_ACL_GROUP
)
1066 entry
->a_id
= u_g_id
;
1068 entry
->a_perm
= bits
;
1073 int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry_d
, uint32 bits
)
1075 entry_d
->a_perm
= bits
;
1080 /* Structure to capture the count for each type of ACE. */
1082 struct hpux_acl_types
{
1091 int n_def_group_obj
;
1095 int n_def_other_obj
;
1098 int n_def_class_obj
;
1104 * Counts the different number of objects in a given array of ACL
1108 * acl_count - Count of ACLs in the array of ACL structures.
1109 * aclp - Array of ACL structures.
1110 * acl_type_count - Pointer to acl_types structure. Should already be
1114 * acl_type_count - This structure is filled up with counts of various
1118 static void hpux_count_obj(int acl_count
, struct acl
*aclp
, struct hpux_acl_types
*acl_type_count
)
1122 memset(acl_type_count
, 0, sizeof (struct hpux_acl_types
));
1124 for (i
= 0; i
< acl_count
; i
++) {
1125 switch (aclp
[i
].a_type
) {
1127 acl_type_count
->n_user
++;
1130 acl_type_count
->n_user_obj
++;
1133 acl_type_count
->n_def_user_obj
++;
1136 acl_type_count
->n_group
++;
1139 acl_type_count
->n_group_obj
++;
1142 acl_type_count
->n_def_group_obj
++;
1145 acl_type_count
->n_other_obj
++;
1148 acl_type_count
->n_def_other_obj
++;
1151 acl_type_count
->n_class_obj
++;
1154 acl_type_count
->n_def_class_obj
++;
1157 acl_type_count
->n_def_user
++;
1160 acl_type_count
->n_def_group
++;
1163 acl_type_count
->n_illegal_obj
++;
1169 /* swap_acl_entries: Swaps two ACL entries.
1171 * Inputs: aclp0, aclp1 - ACL entries to be swapped.
1174 static void hpux_swap_acl_entries(struct acl
*aclp0
, struct acl
*aclp1
)
1176 struct acl temp_acl
;
1178 temp_acl
.a_type
= aclp0
->a_type
;
1179 temp_acl
.a_id
= aclp0
->a_id
;
1180 temp_acl
.a_perm
= aclp0
->a_perm
;
1182 aclp0
->a_type
= aclp1
->a_type
;
1183 aclp0
->a_id
= aclp1
->a_id
;
1184 aclp0
->a_perm
= aclp1
->a_perm
;
1186 aclp1
->a_type
= temp_acl
.a_type
;
1187 aclp1
->a_id
= temp_acl
.a_id
;
1188 aclp1
->a_perm
= temp_acl
.a_perm
;
1191 /* prohibited_duplicate_type
1192 * Identifies if given ACL type can have duplicate entries or
1195 * Inputs: acl_type - ACL Type.
1201 * True - If the ACL type matches any of the prohibited types.
1202 * False - If the ACL type doesn't match any of the prohibited types.
1205 static BOOL
hpux_prohibited_duplicate_type(int acl_type
)
1218 /* get_needed_class_perm
1219 * Returns the permissions of a ACL structure only if the ACL
1220 * type matches one of the pre-determined types for computing
1221 * CLASS_OBJ permissions.
1223 * Inputs: aclp - Pointer to ACL structure.
1226 static int hpux_get_needed_class_perm(struct acl
*aclp
)
1228 switch (aclp
->a_type
) {
1238 return aclp
->a_perm
;
1244 /* acl_sort for HPUX.
1245 * Sorts the array of ACL structures as per the description in
1246 * aclsort man page. Refer to aclsort man page for more details
1250 * acl_count - Count of ACLs in the array of ACL structures.
1251 * calclass - If this is not zero, then we compute the CLASS_OBJ
1253 * aclp - Array of ACL structures.
1257 * aclp - Sorted array of ACL structures.
1261 * Returns 0 for success -1 for failure. Prints a message to the Samba
1262 * debug log in case of failure.
1265 static int hpux_acl_sort(int acl_count
, int calclass
, struct acl
*aclp
)
1267 #if !defined(HAVE_HPUX_ACLSORT)
1269 * The aclsort() system call is available on the latest HPUX General
1270 * Patch Bundles. So for HPUX, we developed our version of acl_sort
1271 * function. Because, we don't want to update to a new
1272 * HPUX GR bundle just for aclsort() call.
1275 struct hpux_acl_types acl_obj_count
;
1276 int n_class_obj_perm
= 0;
1280 DEBUG(10, ("Zero acl count passed. Returning Success\n"));
1285 DEBUG(0, ("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
1289 /* Count different types of ACLs in the ACLs array */
1291 hpux_count_obj(acl_count
, aclp
, &acl_obj_count
);
1293 /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
1294 * CLASS_OBJ and OTHER_OBJ
1297 if (acl_obj_count
.n_user_obj
!= 1
1298 || acl_obj_count
.n_group_obj
!= 1
1299 || acl_obj_count
.n_class_obj
!= 1
1300 || acl_obj_count
.n_other_obj
!= 1) {
1301 DEBUG(0, ("hpux_acl_sort: More than one entry or no entries for \
1302 USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
1306 /* If any of the default objects are present, there should be only
1309 if (acl_obj_count
.n_def_user_obj
> 1 || acl_obj_count
.n_def_group_obj
> 1
1310 || acl_obj_count
.n_def_other_obj
> 1 || acl_obj_count
.n_def_class_obj
> 1) {
1311 DEBUG(0, ("hpux_acl_sort: More than one entry for DEF_CLASS_OBJ \
1312 or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
1316 /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
1319 * Sorting crieteria - First sort by ACL type. If there are multiple entries of
1320 * same ACL type, sort by ACL id.
1322 * I am using the trivial kind of sorting method here because, performance isn't
1323 * really effected by the ACLs feature. More over there aren't going to be more
1324 * than 17 entries on HPUX.
1327 for (i
= 0; i
< acl_count
; i
++) {
1328 for (j
= i
+1; j
< acl_count
; j
++) {
1329 if (aclp
[i
].a_type
> aclp
[j
].a_type
) {
1330 /* ACL entries out of order, swap them */
1331 hpux_swap_acl_entries((aclp
+i
), (aclp
+j
));
1332 } else if (aclp
[i
].a_type
== aclp
[j
].a_type
) {
1333 /* ACL entries of same type, sort by id */
1334 if (aclp
[i
].a_id
> aclp
[j
].a_id
) {
1335 hpux_swap_acl_entries((aclp
+i
), (aclp
+j
));
1336 } else if (aclp
[i
].a_id
== aclp
[j
].a_id
) {
1337 /* We have a duplicate entry. */
1338 if (hpux_prohibited_duplicate_type(aclp
[i
].a_type
)) {
1339 DEBUG(0, ("hpux_acl_sort: Duplicate entry: Type(hex): %x Id: %d\n",
1340 aclp
[i
].a_type
, aclp
[i
].a_id
));
1348 /* set the class obj permissions to the computed one. */
1350 int n_class_obj_index
= -1;
1352 for (i
= 0;i
< acl_count
; i
++) {
1353 n_class_obj_perm
|= hpux_get_needed_class_perm((aclp
+i
));
1354 if (aclp
[i
].a_type
== CLASS_OBJ
)
1355 n_class_obj_index
= i
;
1357 aclp
[n_class_obj_index
].a_perm
= n_class_obj_perm
;
1362 return aclsort(acl_count
, calclass
, aclp
);
1367 * sort the ACL and check it for validity
1369 * if it's a minimal ACL with only 4 entries then we
1370 * need to recalculate the mask permissions to make
1371 * sure that they are the same as the GROUP_OBJ
1372 * permissions as required by the UnixWare acl() system call.
1374 * (note: since POSIX allows minimal ACLs which only contain
1375 * 3 entries - ie there is no mask entry - we should, in theory,
1376 * check for this and add a mask entry if necessary - however
1377 * we "know" that the caller of this interface always specifies
1378 * a mask so, in practice "this never happens" (tm) - if it *does*
1379 * happen aclsort() will fail and return an error and someone will
1380 * have to fix it ...)
1383 static int acl_sort(SMB_ACL_T acl_d
)
1385 int fixmask
= (acl_d
->count
<= 4);
1387 if (hpux_acl_sort(acl_d
->count
, fixmask
, acl_d
->acl
) != 0) {
1394 int sys_acl_valid(SMB_ACL_T acl_d
)
1396 return acl_sort(acl_d
);
1399 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T type
, SMB_ACL_T acl_d
)
1404 struct acl
*acl_buf
= NULL
;
1407 if (hpux_acl_call_presence() == False
) {
1408 /* Looks like we don't have the acl() system call on HPUX.
1409 * May be the system doesn't have the latest version of JFS.
1415 if (type
!= SMB_ACL_TYPE_ACCESS
&& type
!= SMB_ACL_TYPE_DEFAULT
) {
1420 if (acl_sort(acl_d
) != 0) {
1424 acl_p
= &acl_d
->acl
[0];
1425 acl_count
= acl_d
->count
;
1428 * if it's a directory there is extra work to do
1429 * since the acl() system call will replace both
1430 * the access ACLs and the default ACLs (if any)
1432 if (stat(name
, &s
) != 0) {
1435 if (S_ISDIR(s
.st_mode
)) {
1441 if (type
== SMB_ACL_TYPE_ACCESS
) {
1443 def_acl
= tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_DEFAULT
);
1447 acc_acl
= tmp_acl
= sys_acl_get_file(name
, SMB_ACL_TYPE_ACCESS
);
1450 if (tmp_acl
== NULL
) {
1455 * allocate a temporary buffer for the complete ACL
1457 acl_count
= acc_acl
->count
+ def_acl
->count
;
1458 acl_p
= acl_buf
= SMB_MALLOC_ARRAY(struct acl
, acl_count
);
1460 if (acl_buf
== NULL
) {
1461 sys_acl_free_acl(tmp_acl
);
1467 * copy the access control and default entries into the buffer
1469 memcpy(&acl_buf
[0], &acc_acl
->acl
[0],
1470 acc_acl
->count
* sizeof acl_buf
[0]);
1472 memcpy(&acl_buf
[acc_acl
->count
], &def_acl
->acl
[0],
1473 def_acl
->count
* sizeof acl_buf
[0]);
1476 * set the ACL_DEFAULT flag on the default entries
1478 for (i
= acc_acl
->count
; i
< acl_count
; i
++) {
1479 acl_buf
[i
].a_type
|= ACL_DEFAULT
;
1482 sys_acl_free_acl(tmp_acl
);
1484 } else if (type
!= SMB_ACL_TYPE_ACCESS
) {
1489 ret
= acl(name
, ACL_SET
, acl_count
, acl_p
);
1499 int sys_acl_set_fd(int fd
, SMB_ACL_T acl_d
)
1502 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1505 files_struct
*fsp
= file_find_fd(fd
);
1512 if (acl_sort(acl_d
) != 0) {
1517 * We know we're in the same conn context. So we
1518 * can use the relative path.
1521 return sys_acl_set_file(fsp
->fsp_name
, SMB_ACL_TYPE_ACCESS
, acl_d
);
1525 int sys_acl_delete_def_file(const char *path
)
1531 * fetching the access ACL and rewriting it has
1532 * the effect of deleting the default ACL
1534 if ((acl_d
= sys_acl_get_file(path
, SMB_ACL_TYPE_ACCESS
)) == NULL
) {
1538 ret
= acl(path
, ACL_SET
, acl_d
->count
, acl_d
->acl
);
1540 sys_acl_free_acl(acl_d
);
1545 int sys_acl_free_acl(SMB_ACL_T acl_d
)
1551 #elif defined(HAVE_IRIX_ACLS) /*---------------------------------------------*/
1553 int sys_acl_get_entry(SMB_ACL_T acl_d
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
1555 if (entry_id
!= SMB_ACL_FIRST_ENTRY
&& entry_id
!= SMB_ACL_NEXT_ENTRY
) {
1560 if (entry_p
== NULL
) {
1565 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
1569 if (acl_d
->next
< 0) {
1574 if (acl_d
->next
>= acl_d
->aclp
->acl_cnt
) {
1578 *entry_p
= &acl_d
->aclp
->acl_entry
[acl_d
->next
++];
1583 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*type_p
)
1585 *type_p
= entry_d
->ae_tag
;
1590 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
1594 if ((a
= SMB_MALLOC_P(struct SMB_ACL_T
)) == NULL
) {
1598 if ((a
->aclp
= acl_get_file(path_p
, type
)) == NULL
) {
1608 SMB_ACL_T
sys_acl_get_fd(int fd
)
1612 if ((a
= SMB_MALLOC_P(struct SMB_ACL_T
)) == NULL
) {
1616 if ((a
->aclp
= acl_get_fd(fd
)) == NULL
) {
1626 int sys_acl_get_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T
*tag_type_p
, uint32
*bits_p
, id_t
*u_g_id_p
)
1628 *tag_type_p
= entry
->ae_tag
;
1630 *bits_p
= entry
->ae_perm
;
1632 if (*tag_type_p
== SMB_ACL_USER
|| *tag_type_p
== SMB_ACL_GROUP
)
1633 *u_g_id_p
= entry
->ae_id
;
1638 SMB_ACL_T
sys_acl_init(int count
)
1647 if ((a
= (SMB_ACL_T
)SMB_MALLOC(sizeof a
[0] + sizeof (struct acl
))) == NULL
) {
1653 a
->freeaclp
= False
;
1654 a
->aclp
= (struct acl
*)((char *)a
+ sizeof a
[0]);
1655 a
->aclp
->acl_cnt
= 0;
1661 int sys_acl_create_entry(SMB_ACL_T
*acl_p
, SMB_ACL_ENTRY_T
*entry_p
)
1664 SMB_ACL_ENTRY_T entry_d
;
1666 if (acl_p
== NULL
|| entry_p
== NULL
|| (acl_d
= *acl_p
) == NULL
) {
1671 if (acl_d
->aclp
->acl_cnt
>= ACL_MAX_ENTRIES
) {
1676 entry_d
= &acl_d
->aclp
->acl_entry
[acl_d
->aclp
->acl_cnt
++];
1677 entry_d
->ae_tag
= 0;
1679 entry_d
->ae_perm
= 0;
1685 int sys_acl_set_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tag_type
, uint32 bits
, id_t u_g_id
)
1687 entry
->ae_tag
= tag_type
;
1689 if (tag_type
== SMB_ACL_USER
|| tag_type
== SMB_ACL_GROUP
)
1690 entry
->ae_id
= u_g_id
;
1692 entry
->ae_perm
= bits
;
1697 int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry_d
, uint32 bits
)
1699 entry_d
->ae_perm
= bits
;
1704 int sys_acl_valid(SMB_ACL_T acl_d
)
1706 return acl_valid(acl_d
->aclp
);
1709 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T type
, SMB_ACL_T acl_d
)
1711 return acl_set_file(name
, type
, acl_d
->aclp
);
1715 int sys_acl_set_fd(int fd
, SMB_ACL_T acl_d
)
1717 return acl_set_fd(fd
, acl_d
->aclp
);
1721 int sys_acl_delete_def_file(const char *name
)
1723 return acl_delete_def_file(name
);
1726 int sys_acl_free_acl(SMB_ACL_T acl_d
)
1728 if (acl_d
->freeaclp
) {
1729 acl_free(acl_d
->aclp
);
1735 #elif defined(HAVE_AIX_ACLS) /*----------------------------------------------*/
1737 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
1739 int sys_acl_get_entry(SMB_ACL_T theacl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
1741 struct acl_entry_link
*link
;
1744 if (entry_id
== SMB_ACL_FIRST_ENTRY
)
1746 else if (entry_id
!= SMB_ACL_NEXT_ENTRY
) {
1751 DEBUG(10, ("This is the count: %d\n", theacl
->count
));
1753 /* Check if count was previously set to -1. *
1754 * If it was, that means we reached the end *
1755 * of the acl last time. */
1756 if (theacl
->count
== -1)
1760 /* To get to the next acl, traverse linked list until index *
1761 * of acl matches the count we are keeping. This count is *
1762 * incremented each time we return an acl entry. */
1764 for (keep_going
= 0; keep_going
< theacl
->count
; keep_going
++)
1767 *entry_p
= link
->entryp
;
1771 struct new_acl_entry
*entry
= *entry_p
;
1772 DEBUG(10, ("*entry_p is %lx\n", (long)entry
));
1773 DEBUG(10, ("*entry_p->ace_access is %d\n", entry
->ace_access
));
1777 /* Increment count */
1779 if (link
->nextp
== NULL
)
1785 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
1787 /* Initialize tag type */
1790 DEBUG(10, ("the tagtype is %d\n", entry_d
->ace_id
->id_type
));
1792 /* Depending on what type of entry we have, *
1793 * return tag type. */
1794 switch (entry_d
->ace_id
->id_type
) {
1796 *tag_type_p
= SMB_ACL_USER
;
1799 *tag_type_p
= SMB_ACL_GROUP
;
1802 case SMB_ACL_USER_OBJ
:
1803 case SMB_ACL_GROUP_OBJ
:
1805 *tag_type_p
= entry_d
->ace_id
->id_type
;
1815 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
1817 struct acl
*file_acl
= (struct acl
*)NULL
;
1818 struct acl_entry
*acl_entry
;
1819 struct new_acl_entry
*new_acl_entry
;
1821 struct acl_entry_link
*acl_entry_link
;
1822 struct acl_entry_link
*acl_entry_link_head
;
1826 /* AIX has no DEFAULT */
1827 if (type
== SMB_ACL_TYPE_DEFAULT
) {
1836 /* Get the acl using statacl */
1838 DEBUG(10, ("Entering sys_acl_get_file\n"));
1839 DEBUG(10, ("path_p is %s\n", path_p
));
1841 file_acl
= (struct acl
*)SMB_MALLOC(BUFSIZ
);
1843 if (file_acl
== NULL
) {
1845 DEBUG(0, ("Error in AIX sys_acl_get_file: %d\n", errno
));
1849 memset(file_acl
, 0, BUFSIZ
);
1851 rc
= statacl((char *)path_p
, 0, file_acl
, BUFSIZ
);
1853 DEBUG(0, ("statacl returned %d with errno %d\n", rc
, errno
));
1854 SAFE_FREE(file_acl
);
1858 DEBUG(10, ("Got facl and returned it\n"));
1860 /* Point to the first acl entry in the acl */
1861 acl_entry
= file_acl
->acl_ext
;
1863 /* Begin setting up the head of the linked list *
1864 * that will be used for the storing the acl *
1865 * in a way that is useful for the posix_acls.c *
1868 acl_entry_link_head
= acl_entry_link
= sys_acl_init(0);
1869 if (acl_entry_link_head
== NULL
)
1872 acl_entry_link
->entryp
= SMB_MALLOC_P(struct new_acl_entry
);
1873 if (acl_entry_link
->entryp
== NULL
) {
1874 SAFE_FREE(file_acl
);
1876 DEBUG(0, ("Error in AIX sys_acl_get_file is %d\n", errno
));
1880 DEBUG(10, ("acl_entry is %d\n", acl_entry
));
1881 DEBUG(10, ("acl_last(file_acl) id %d\n", acl_last(file_acl
)));
1883 /* Check if the extended acl bit is on. *
1884 * If it isn't, do not show the *
1885 * contents of the acl since AIX intends *
1886 * the extended info to remain unused */
1888 if (file_acl
->acl_mode
& S_IXACL
){
1889 /* while we are not pointing to the very end */
1890 while (acl_entry
< acl_last(file_acl
)) {
1891 /* before we malloc anything, make sure this is */
1892 /* a valid acl entry and one that we want to map */
1893 idp
= id_nxt(acl_entry
->ace_id
);
1894 if ((acl_entry
->ace_type
== ACC_SPECIFY
|| acl_entry
->ace_type
== ACC_PERMIT
)
1895 && idp
!= id_last(acl_entry
)) {
1896 acl_entry
= acl_nxt(acl_entry
);
1900 idp
= acl_entry
->ace_id
;
1902 /* Check if this is the first entry in the linked list. *
1903 * The first entry needs to keep prevp pointing to NULL *
1904 * and already has entryp allocated. */
1906 if (acl_entry_link_head
->count
!= 0) {
1907 acl_entry_link
->nextp
= SMB_MALLOC_P(struct acl_entry_link
);
1909 if (acl_entry_link
->nextp
== NULL
) {
1910 SAFE_FREE(file_acl
);
1912 DEBUG(0, ("Error in AIX sys_acl_get_file is %d\n", errno
));
1916 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
1917 acl_entry_link
= acl_entry_link
->nextp
;
1918 acl_entry_link
->entryp
= SMB_MALLOC_P(struct new_acl_entry
);
1919 if (acl_entry_link
->entryp
== NULL
) {
1920 SAFE_FREE(file_acl
);
1922 DEBUG(0, ("Error in AIX sys_acl_get_file is %d\n", errno
));
1925 acl_entry_link
->nextp
= NULL
;
1928 acl_entry_link
->entryp
->ace_len
= acl_entry
->ace_len
;
1930 /* Don't really need this since all types are going *
1931 * to be specified but, it's better than leaving it 0 */
1933 acl_entry_link
->entryp
->ace_type
= acl_entry
->ace_type
;
1935 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
1937 memcpy(acl_entry_link
->entryp
->ace_id
, idp
, sizeof (struct ace_id
));
1939 /* The access in the acl entries must be left shifted by *
1940 * three bites, because they will ultimately be compared *
1941 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1943 switch (acl_entry
->ace_type
){
1946 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
1947 acl_entry_link
->entryp
->ace_access
<<= 6;
1948 acl_entry_link_head
->count
++;
1951 /* Since there is no way to return a DENY acl entry *
1952 * change to PERMIT and then shift. */
1953 DEBUG(10, ("acl_entry->ace_access is %d\n", acl_entry
->ace_access
));
1954 acl_entry_link
->entryp
->ace_access
= ~acl_entry
->ace_access
& 7;
1955 DEBUG(10, ("acl_entry_link->entryp->ace_access is %d\n", acl_entry_link
->entryp
->ace_access
));
1956 acl_entry_link
->entryp
->ace_access
<<= 6;
1957 acl_entry_link_head
->count
++;
1963 DEBUG(10, ("acl_entry = %d\n", acl_entry
));
1964 DEBUG(10, ("The ace_type is %d\n", acl_entry
->ace_type
));
1966 acl_entry
= acl_nxt(acl_entry
);
1968 } /* end of if enabled */
1970 /* Since owner, group, other acl entries are not *
1971 * part of the acl entries in an acl, they must *
1972 * be dummied up to become part of the list. */
1974 for (i
= 1; i
< 4; i
++) {
1975 DEBUG(10, ("i is %d\n", i
));
1976 if (acl_entry_link_head
->count
!= 0) {
1977 acl_entry_link
->nextp
= SMB_MALLOC_P(struct acl_entry_link
);
1978 if (acl_entry_link
->nextp
== NULL
) {
1979 SAFE_FREE(file_acl
);
1981 DEBUG(0, ("Error in AIX sys_acl_get_file is %d\n", errno
));
1985 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
1986 acl_entry_link
= acl_entry_link
->nextp
;
1987 acl_entry_link
->entryp
= SMB_MALLOC_P(struct new_acl_entry
);
1988 if (acl_entry_link
->entryp
== NULL
) {
1989 SAFE_FREE(file_acl
);
1991 DEBUG(0, ("Error in AIX sys_acl_get_file is %d\n", errno
));
1996 acl_entry_link
->nextp
= NULL
;
1998 new_acl_entry
= acl_entry_link
->entryp
;
1999 idp
= new_acl_entry
->ace_id
;
2001 new_acl_entry
->ace_len
= sizeof (struct acl_entry
);
2002 new_acl_entry
->ace_type
= ACC_PERMIT
;
2003 idp
->id_len
= sizeof (struct ace_id
);
2004 DEBUG(10, ("idp->id_len = %d\n", idp
->id_len
));
2005 memset(idp
->id_data
, 0, sizeof (uid_t
));
2009 new_acl_entry
->ace_access
= file_acl
->g_access
<< 6;
2010 idp
->id_type
= SMB_ACL_GROUP_OBJ
;
2014 new_acl_entry
->ace_access
= file_acl
->o_access
<< 6;
2015 idp
->id_type
= SMB_ACL_OTHER
;
2019 new_acl_entry
->ace_access
= file_acl
->u_access
<< 6;
2020 idp
->id_type
= SMB_ACL_USER_OBJ
;
2028 acl_entry_link_head
->count
++;
2029 DEBUG(10, ("new_acl_entry->ace_access = %d\n", new_acl_entry
->ace_access
));
2032 acl_entry_link_head
->count
= 0;
2033 SAFE_FREE(file_acl
);
2035 return acl_entry_link_head
;
2039 SMB_ACL_T
sys_acl_get_fd(int fd
)
2041 struct acl
*file_acl
= (struct acl
*)NULL
;
2042 struct acl_entry
*acl_entry
;
2043 struct new_acl_entry
*new_acl_entry
;
2045 struct acl_entry_link
*acl_entry_link
;
2046 struct acl_entry_link
*acl_entry_link_head
;
2050 /* Get the acl using fstatacl */
2052 DEBUG(10, ("Entering sys_acl_get_fd\n"));
2053 DEBUG(10, ("fd is %d\n", fd
));
2054 file_acl
= (struct acl
*)SMB_MALLOC(BUFSIZ
);
2056 if (file_acl
== NULL
) {
2058 DEBUG(0, ("Error in sys_acl_get_fd is %d\n", errno
));
2062 memset(file_acl
, 0, BUFSIZ
);
2064 rc
= fstatacl(fd
, 0, file_acl
, BUFSIZ
);
2066 DEBUG(0, ("The fstatacl call returned %d with errno %d\n", rc
, errno
));
2067 SAFE_FREE(file_acl
);
2071 DEBUG(10, ("Got facl and returned it\n"));
2073 /* Point to the first acl entry in the acl */
2075 acl_entry
= file_acl
->acl_ext
;
2076 /* Begin setting up the head of the linked list *
2077 * that will be used for the storing the acl *
2078 * in a way that is useful for the posix_acls.c *
2081 acl_entry_link_head
= acl_entry_link
= sys_acl_init(0);
2082 if (acl_entry_link_head
== NULL
){
2083 SAFE_FREE(file_acl
);
2087 acl_entry_link
->entryp
= SMB_MALLOC_P(struct new_acl_entry
);
2089 if (acl_entry_link
->entryp
== NULL
) {
2091 DEBUG(0, ("Error in sys_acl_get_fd is %d\n", errno
));
2092 SAFE_FREE(file_acl
);
2096 DEBUG(10, ("acl_entry is %d\n", acl_entry
));
2097 DEBUG(10, ("acl_last(file_acl) id %d\n", acl_last(file_acl
)));
2099 /* Check if the extended acl bit is on. *
2100 * If it isn't, do not show the *
2101 * contents of the acl since AIX intends *
2102 * the extended info to remain unused */
2104 if (file_acl
->acl_mode
& S_IXACL
){
2105 /* while we are not pointing to the very end */
2106 while (acl_entry
< acl_last(file_acl
)) {
2107 /* before we malloc anything, make sure this is */
2108 /* a valid acl entry and one that we want to map */
2110 idp
= id_nxt(acl_entry
->ace_id
);
2111 if ((acl_entry
->ace_type
== ACC_SPECIFY
||
2112 (acl_entry
->ace_type
== ACC_PERMIT
)) && (idp
!= id_last(acl_entry
))) {
2113 acl_entry
= acl_nxt(acl_entry
);
2117 idp
= acl_entry
->ace_id
;
2119 /* Check if this is the first entry in the linked list. *
2120 * The first entry needs to keep prevp pointing to NULL *
2121 * and already has entryp allocated. */
2123 if (acl_entry_link_head
->count
!= 0) {
2124 acl_entry_link
->nextp
= SMB_MALLOC_P(struct acl_entry_link
);
2125 if (acl_entry_link
->nextp
== NULL
) {
2127 DEBUG(0, ("Error in sys_acl_get_fd is %d\n", errno
));
2128 SAFE_FREE(file_acl
);
2131 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
2132 acl_entry_link
= acl_entry_link
->nextp
;
2133 acl_entry_link
->entryp
= SMB_MALLOC_P(struct new_acl_entry
);
2134 if (acl_entry_link
->entryp
== NULL
) {
2136 DEBUG(0, ("Error in sys_acl_get_fd is %d\n", errno
));
2137 SAFE_FREE(file_acl
);
2141 acl_entry_link
->nextp
= NULL
;
2144 acl_entry_link
->entryp
->ace_len
= acl_entry
->ace_len
;
2146 /* Don't really need this since all types are going *
2147 * to be specified but, it's better than leaving it 0 */
2149 acl_entry_link
->entryp
->ace_type
= acl_entry
->ace_type
;
2150 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
2152 memcpy(acl_entry_link
->entryp
->ace_id
, idp
, sizeof (struct ace_id
));
2154 /* The access in the acl entries must be left shifted by *
2155 * three bites, because they will ultimately be compared *
2156 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2158 switch (acl_entry
->ace_type
){
2161 acl_entry_link
->entryp
->ace_access
= acl_entry
->ace_access
;
2162 acl_entry_link
->entryp
->ace_access
<<= 6;
2163 acl_entry_link_head
->count
++;
2166 /* Since there is no way to return a DENY acl entry *
2167 * change to PERMIT and then shift. */
2168 DEBUG(10, ("acl_entry->ace_access is %d\n", acl_entry
->ace_access
));
2169 acl_entry_link
->entryp
->ace_access
= ~acl_entry
->ace_access
& 7;
2170 DEBUG(10, ("acl_entry_link->entryp->ace_access is %d\n", acl_entry_link
->entryp
->ace_access
));
2171 acl_entry_link
->entryp
->ace_access
<<= 6;
2172 acl_entry_link_head
->count
++;
2178 DEBUG(10, ("acl_entry = %d\n", acl_entry
));
2179 DEBUG(10, ("The ace_type is %d\n", acl_entry
->ace_type
));
2181 acl_entry
= acl_nxt(acl_entry
);
2183 } /* end of if enabled */
2185 /* Since owner, group, other acl entries are not *
2186 * part of the acl entries in an acl, they must *
2187 * be dummied up to become part of the list. */
2189 for (i
= 1; i
< 4; i
++) {
2190 DEBUG(10, ("i is %d\n", i
));
2191 if (acl_entry_link_head
->count
!= 0){
2192 acl_entry_link
->nextp
= SMB_MALLOC_P(struct acl_entry_link
);
2193 if (acl_entry_link
->nextp
== NULL
) {
2195 DEBUG(0, ("Error in sys_acl_get_fd is %d\n", errno
));
2196 SAFE_FREE(file_acl
);
2200 acl_entry_link
->nextp
->prevp
= acl_entry_link
;
2201 acl_entry_link
= acl_entry_link
->nextp
;
2202 acl_entry_link
->entryp
= SMB_MALLOC_P(struct new_acl_entry
);
2204 if (acl_entry_link
->entryp
== NULL
) {
2205 SAFE_FREE(file_acl
);
2207 DEBUG(0, ("Error in sys_acl_get_fd is %d\n", errno
));
2212 acl_entry_link
->nextp
= NULL
;
2214 new_acl_entry
= acl_entry_link
->entryp
;
2215 idp
= new_acl_entry
->ace_id
;
2217 new_acl_entry
->ace_len
= sizeof (struct acl_entry
);
2218 new_acl_entry
->ace_type
= ACC_PERMIT
;
2219 idp
->id_len
= sizeof (struct ace_id
);
2220 DEBUG(10, ("idp->id_len = %d\n", idp
->id_len
));
2221 memset(idp
->id_data
, 0, sizeof (uid_t
));
2225 new_acl_entry
->ace_access
= file_acl
->g_access
<< 6;
2226 idp
->id_type
= SMB_ACL_GROUP_OBJ
;
2230 new_acl_entry
->ace_access
= file_acl
->o_access
<< 6;
2231 idp
->id_type
= SMB_ACL_OTHER
;
2235 new_acl_entry
->ace_access
= file_acl
->u_access
<< 6;
2236 idp
->id_type
= SMB_ACL_USER_OBJ
;
2243 acl_entry_link_head
->count
++;
2244 DEBUG(10, ("new_acl_entry->ace_access = %d\n", new_acl_entry
->ace_access
));
2247 acl_entry_link_head
->count
= 0;
2248 SAFE_FREE(file_acl
);
2250 return acl_entry_link_head
;
2254 int sys_acl_get_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T
*tag_type_p
, uint32
*bits_p
, id_t
*u_g_id_p
)
2258 if (sys_acl_get_tag_type(entry
, tag_type_p
) != 0)
2261 if (*tag_type_p
== SMB_ACL_USER
|| *tag_type_p
== SMB_ACL_GROUP
)
2262 memcpy(u_g_id_p
, entry
->ace_id
->id_data
, sizeof (id_t
));
2264 permset
= &entry
->ace_access
;
2266 DEBUG(10, ("*permset is %d\n", *permset
));
2267 *bits_p
= (*permset
& S_IRUSR
? 4 : 0)
2268 | (*permset
& S_IWUSR
? 2 : 0)
2269 | (*permset
& S_IXUSR
? 1 : 0);
2274 SMB_ACL_T
sys_acl_init(int count
)
2276 struct acl_entry_link
*theacl
= NULL
;
2283 DEBUG(10, ("Entering sys_acl_init\n"));
2285 theacl
= SMB_MALLOC_P(struct acl_entry_link
);
2286 if (theacl
== NULL
) {
2288 DEBUG(0, ("Error in sys_acl_init is %d\n", errno
));
2293 theacl
->nextp
= NULL
;
2294 theacl
->prevp
= NULL
;
2295 theacl
->entryp
= NULL
;
2296 DEBUG(10, ("Exiting sys_acl_init\n"));
2300 int sys_acl_create_entry(SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
2302 struct acl_entry_link
*theacl
;
2303 struct acl_entry_link
*acl_entryp
;
2304 struct acl_entry_link
*temp_entry
= NULL
;
2307 DEBUG(10, ("Entering the sys_acl_create_entry\n"));
2309 theacl
= acl_entryp
= *pacl
;
2311 /* Get to the end of the acl before adding entry */
2313 for (counting
= 0; counting
< theacl
->count
; counting
++){
2314 DEBUG(10, ("The acl_entryp is %d\n", acl_entryp
));
2315 temp_entry
= acl_entryp
;
2316 acl_entryp
= acl_entryp
->nextp
;
2319 if (theacl
->count
!= 0){
2320 temp_entry
->nextp
= acl_entryp
= SMB_MALLOC_P(struct acl_entry_link
);
2321 if (acl_entryp
== NULL
) {
2323 DEBUG(0, ("Error in sys_acl_create_entry is %d\n", errno
));
2327 DEBUG(10, ("The acl_entryp is %d\n", acl_entryp
));
2328 acl_entryp
->prevp
= temp_entry
;
2329 DEBUG(10, ("The acl_entryp->prevp is %d\n", acl_entryp
->prevp
));
2332 *pentry
= acl_entryp
->entryp
= SMB_MALLOC_P(struct new_acl_entry
);
2333 if (*pentry
== NULL
) {
2335 DEBUG(0, ("Error in sys_acl_create_entry is %d\n", errno
));
2339 memset(*pentry
, 0, sizeof (struct new_acl_entry
));
2340 acl_entryp
->entryp
->ace_len
= sizeof (struct acl_entry
);
2341 acl_entryp
->entryp
->ace_type
= ACC_PERMIT
;
2342 acl_entryp
->entryp
->ace_id
->id_len
= sizeof (struct ace_id
);
2343 acl_entryp
->nextp
= NULL
;
2345 DEBUG(10, ("Exiting sys_acl_create_entry\n"));
2349 int sys_acl_set_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tag_type
, uint32 bits
, id_t u_g_id
)
2351 entry
->ace_id
->id_type
= tag_type
;
2352 DEBUG(10, ("The tag type is %d\n", entry
->ace_id
->id_type
));
2354 if (tag_type
== SMB_ACL_USER
|| tag_type
== SMB_ACL_GROUP
)
2355 memcpy(entry
->ace_id
->id_data
, &u_g_id
, sizeof (id_t
));
2357 entry
->ace_access
= bits
;
2358 DEBUG(10, ("entry->ace_access = %d\n", entry
->ace_access
));
2363 int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry
, uint32 bits
)
2365 DEBUG(10, ("Starting AIX sys_acl_set_permset\n"));
2366 entry
->ace_access
= bits
;
2367 DEBUG(10, ("entry->ace_access = %d\n", entry
->ace_access
));
2368 DEBUG(10, ("Ending AIX sys_acl_set_permset\n"));
2372 int sys_acl_valid(SMB_ACL_T theacl
)
2377 struct acl_entry_link
*acl_entry
;
2379 for (acl_entry
=theacl
; acl_entry
!= NULL
; acl_entry
= acl_entry
->nextp
) {
2380 user_obj
+= (acl_entry
->entryp
->ace_id
->id_type
== SMB_ACL_USER_OBJ
);
2381 group_obj
+= (acl_entry
->entryp
->ace_id
->id_type
== SMB_ACL_GROUP_OBJ
);
2382 other_obj
+= (acl_entry
->entryp
->ace_id
->id_type
== SMB_ACL_OTHER
);
2385 DEBUG(10, ("user_obj=%d, group_obj=%d, other_obj=%d\n", user_obj
, group_obj
, other_obj
));
2387 if (user_obj
!= 1 || group_obj
!= 1 || other_obj
!= 1)
2393 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
2395 struct acl_entry_link
*acl_entry_link
= NULL
;
2396 struct acl
*file_acl
= NULL
;
2397 struct acl
*file_acl_temp
= NULL
;
2398 struct acl_entry
*acl_entry
= NULL
;
2399 struct ace_id
*ace_id
= NULL
;
2405 DEBUG(10, ("Entering sys_acl_set_file\n"));
2406 DEBUG(10, ("File name is %s\n", name
));
2408 /* AIX has no default ACL */
2409 if (acltype
== SMB_ACL_TYPE_DEFAULT
)
2412 acl_length
= BUFSIZ
;
2413 file_acl
= (struct acl
*)SMB_MALLOC(BUFSIZ
);
2415 if (file_acl
== NULL
) {
2417 DEBUG(0, ("Error in sys_acl_set_file is %d\n", errno
));
2421 memset(file_acl
, 0, BUFSIZ
);
2423 file_acl
->acl_len
= ACL_SIZ
;
2424 file_acl
->acl_mode
= S_IXACL
;
2426 for (acl_entry_link
=theacl
; acl_entry_link
!= NULL
; acl_entry_link
= acl_entry_link
->nextp
) {
2427 acl_entry_link
->entryp
->ace_access
>>= 6;
2428 id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
2431 case SMB_ACL_USER_OBJ
:
2432 file_acl
->u_access
= acl_entry_link
->entryp
->ace_access
;
2434 case SMB_ACL_GROUP_OBJ
:
2435 file_acl
->g_access
= acl_entry_link
->entryp
->ace_access
;
2438 file_acl
->o_access
= acl_entry_link
->entryp
->ace_access
;
2444 if ((file_acl
->acl_len
+ sizeof (struct acl_entry
)) > acl_length
) {
2445 acl_length
+= sizeof (struct acl_entry
);
2446 file_acl_temp
= (struct acl
*)SMB_MALLOC(acl_length
);
2447 if (file_acl_temp
== NULL
) {
2448 SAFE_FREE(file_acl
);
2450 DEBUG(0, ("Error in sys_acl_set_file is %d\n", errno
));
2454 memcpy(file_acl_temp
, file_acl
, file_acl
->acl_len
);
2455 SAFE_FREE(file_acl
);
2456 file_acl
= file_acl_temp
;
2459 acl_entry
= (struct acl_entry
*)((char *)file_acl
+ file_acl
->acl_len
);
2460 file_acl
->acl_len
+= sizeof (struct acl_entry
);
2461 acl_entry
->ace_len
= acl_entry_link
->entryp
->ace_len
;
2462 acl_entry
->ace_access
= acl_entry_link
->entryp
->ace_access
;
2464 /* In order to use this, we'll need to wait until we can get denies */
2465 /* if (!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2466 acl_entry->ace_type = ACC_SPECIFY; */
2468 acl_entry
->ace_type
= ACC_SPECIFY
;
2470 ace_id
= acl_entry
->ace_id
;
2472 ace_id
->id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
2473 DEBUG(10, ("The id type is %d\n", ace_id
->id_type
));
2474 ace_id
->id_len
= acl_entry_link
->entryp
->ace_id
->id_len
;
2475 memcpy(&user_id
, acl_entry_link
->entryp
->ace_id
->id_data
, sizeof (uid_t
));
2476 memcpy(acl_entry
->ace_id
->id_data
, &user_id
, sizeof (uid_t
));
2479 rc
= chacl((char*)name
, file_acl
, file_acl
->acl_len
);
2480 DEBUG(10, ("errno is %d\n", errno
));
2481 DEBUG(10, ("return code is %d\n", rc
));
2482 SAFE_FREE(file_acl
);
2483 DEBUG(10, ("Exiting the sys_acl_set_file\n"));
2488 int sys_acl_set_fd(int fd
, SMB_ACL_T theacl
)
2490 struct acl_entry_link
*acl_entry_link
= NULL
;
2491 struct acl
*file_acl
= NULL
;
2492 struct acl
*file_acl_temp
= NULL
;
2493 struct acl_entry
*acl_entry
= NULL
;
2494 struct ace_id
*ace_id
= NULL
;
2500 DEBUG(10, ("Entering sys_acl_set_fd\n"));
2501 acl_length
= BUFSIZ
;
2502 file_acl
= (struct acl
*)SMB_MALLOC(BUFSIZ
);
2504 if (file_acl
== NULL
) {
2506 DEBUG(0, ("Error in sys_acl_set_fd is %d\n", errno
));
2510 memset(file_acl
, 0, BUFSIZ
);
2512 file_acl
->acl_len
= ACL_SIZ
;
2513 file_acl
->acl_mode
= S_IXACL
;
2515 for (acl_entry_link
=theacl
; acl_entry_link
!= NULL
; acl_entry_link
= acl_entry_link
->nextp
) {
2516 acl_entry_link
->entryp
->ace_access
>>= 6;
2517 id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
2518 DEBUG(10, ("The id_type is %d\n", id_type
));
2521 case SMB_ACL_USER_OBJ
:
2522 file_acl
->u_access
= acl_entry_link
->entryp
->ace_access
;
2524 case SMB_ACL_GROUP_OBJ
:
2525 file_acl
->g_access
= acl_entry_link
->entryp
->ace_access
;
2528 file_acl
->o_access
= acl_entry_link
->entryp
->ace_access
;
2534 if ((file_acl
->acl_len
+ sizeof (struct acl_entry
)) > acl_length
) {
2535 acl_length
+= sizeof (struct acl_entry
);
2536 file_acl_temp
= (struct acl
*)SMB_MALLOC(acl_length
);
2537 if (file_acl_temp
== NULL
) {
2538 SAFE_FREE(file_acl
);
2540 DEBUG(0, ("Error in sys_acl_set_fd is %d\n", errno
));
2544 memcpy(file_acl_temp
, file_acl
, file_acl
->acl_len
);
2545 SAFE_FREE(file_acl
);
2546 file_acl
= file_acl_temp
;
2549 acl_entry
= (struct acl_entry
*)((char *)file_acl
+ file_acl
->acl_len
);
2550 file_acl
->acl_len
+= sizeof (struct acl_entry
);
2551 acl_entry
->ace_len
= acl_entry_link
->entryp
->ace_len
;
2552 acl_entry
->ace_access
= acl_entry_link
->entryp
->ace_access
;
2554 /* In order to use this, we'll need to wait until we can get denies */
2555 /* if (!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2556 acl_entry->ace_type = ACC_SPECIFY; */
2558 acl_entry
->ace_type
= ACC_SPECIFY
;
2560 ace_id
= acl_entry
->ace_id
;
2562 ace_id
->id_type
= acl_entry_link
->entryp
->ace_id
->id_type
;
2563 DEBUG(10, ("The id type is %d\n", ace_id
->id_type
));
2564 ace_id
->id_len
= acl_entry_link
->entryp
->ace_id
->id_len
;
2565 memcpy(&user_id
, acl_entry_link
->entryp
->ace_id
->id_data
, sizeof (uid_t
));
2566 memcpy(ace_id
->id_data
, &user_id
, sizeof (uid_t
));
2569 rc
= fchacl(fd
, file_acl
, file_acl
->acl_len
);
2570 DEBUG(10, ("errno is %d\n", errno
));
2571 DEBUG(10, ("return code is %d\n", rc
));
2572 SAFE_FREE(file_acl
);
2573 DEBUG(10, ("Exiting sys_acl_set_fd\n"));
2578 int sys_acl_delete_def_file(UNUSED(const char *name
))
2580 /* AIX has no default ACL */
2584 int sys_acl_free_acl(SMB_ACL_T posix_acl
)
2586 struct acl_entry_link
*acl_entry_link
;
2588 for (acl_entry_link
= posix_acl
->nextp
; acl_entry_link
->nextp
!= NULL
; acl_entry_link
= acl_entry_link
->nextp
) {
2589 SAFE_FREE(acl_entry_link
->prevp
->entryp
);
2590 SAFE_FREE(acl_entry_link
->prevp
);
2593 SAFE_FREE(acl_entry_link
->prevp
->entryp
);
2594 SAFE_FREE(acl_entry_link
->prevp
);
2595 SAFE_FREE(acl_entry_link
->entryp
);
2596 SAFE_FREE(acl_entry_link
);
2601 #elif defined(HAVE_OSX_ACLS) /*----------------------------------------------*/
2603 #define OSX_BROKEN_GETENTRY /* returns 0 instead of 1 */
2605 #include <membership.h>
2607 int sys_acl_get_entry(SMB_ACL_T the_acl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
2609 int ret
= acl_get_entry(the_acl
, entry_id
, entry_p
);
2610 #ifdef OSX_BROKEN_GETENTRY
2613 else if (ret
== -1 && errno
== 22)
2619 SMB_ACL_T
sys_acl_get_file(const char *path_p
, SMB_ACL_TYPE_T type
)
2621 if (type
== ACL_TYPE_DEFAULT
) {
2626 return acl_get_file(path_p
, type
);
2630 SMB_ACL_T
sys_acl_get_fd(int fd
)
2632 return acl_get_fd(fd
);
2636 int sys_acl_get_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T
*tag_type_p
, uint32
*bits_p
, id_t
*u_g_id_p
)
2640 acl_flagset_t flagset
;
2641 acl_permset_t permset
;
2642 uint32 bits
, fb
, bb
, pb
;
2646 if (acl_get_tag_type(entry
, &tag
) != 0
2647 || acl_get_flagset_np(entry
, &flagset
) != 0
2648 || acl_get_permset(entry
, &permset
) != 0
2649 || (uup
= acl_get_qualifier(entry
)) == NULL
)
2652 rc
= mbr_uuid_to_id(*uup
, u_g_id_p
, &id_type
);
2657 if (id_type
== ID_TYPE_UID
)
2658 *tag_type_p
= SMB_ACL_USER
;
2660 *tag_type_p
= SMB_ACL_GROUP
;
2662 bits
= tag
== ACL_EXTENDED_ALLOW
? 1 : 0;
2664 for (fb
= (1u<<4), bb
= (1u<<1); bb
< (1u<<12); fb
*= 2, bb
*= 2) {
2665 if (acl_get_flag_np(flagset
, fb
) == 1)
2669 for (pb
= (1u<<1), bb
= (1u<<12); bb
< (1u<<25); pb
*= 2, bb
*= 2) {
2670 if (acl_get_perm_np(permset
, pb
) == 1)
2679 SMB_ACL_T
sys_acl_init(int count
)
2681 return acl_init(count
);
2684 int sys_acl_create_entry(SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
2686 return acl_create_entry(pacl
, pentry
);
2689 int sys_acl_set_info(SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tag_type
, uint32 bits
, id_t u_g_id
)
2691 acl_flagset_t flagset
;
2692 acl_permset_t permset
;
2694 int is_user
= tag_type
== SMB_ACL_USER
;
2698 tag_type
= bits
& 1 ? ACL_EXTENDED_ALLOW
: ACL_EXTENDED_DENY
;
2700 if (acl_get_flagset_np(entry
, &flagset
) != 0
2701 || acl_get_permset(entry
, &permset
) != 0)
2704 acl_clear_flags_np(flagset
);
2705 acl_clear_perms(permset
);
2707 for (fb
= (1u<<4), bb
= (1u<<1); bb
< (1u<<12); fb
*= 2, bb
*= 2) {
2709 acl_add_flag_np(flagset
, fb
);
2712 for (pb
= (1u<<1), bb
= (1u<<12); bb
< (1u<<25); pb
*= 2, bb
*= 2) {
2714 acl_add_perm(permset
, pb
);
2718 rc
= mbr_uid_to_uuid(u_g_id
, uu
);
2720 rc
= mbr_gid_to_uuid(u_g_id
, uu
);
2724 if (acl_set_tag_type(entry
, tag_type
) != 0
2725 || acl_set_qualifier(entry
, &uu
) != 0
2726 || acl_set_permset(entry
, permset
) != 0
2727 || acl_set_flagset_np(entry
, flagset
) != 0)
2734 int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry
, uint32 bits
)
2736 return -1; /* Not needed for OS X. */
2740 int sys_acl_valid(SMB_ACL_T theacl
)
2742 return acl_valid(theacl
);
2745 int sys_acl_set_file(const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
2747 return acl_set_file(name
, acltype
, theacl
);
2751 int sys_acl_set_fd(int fd
, SMB_ACL_T theacl
)
2753 return acl_set_fd(fd
, theacl
);
2757 int sys_acl_delete_def_file(const char *name
)
2759 return acl_delete_def_file(name
);
2762 int sys_acl_free_acl(SMB_ACL_T the_acl
)
2764 return acl_free(the_acl
);
2767 #else /* No ACLs. */
2769 #error No ACL functions defined for this platform!
2773 /************************************************************************
2774 Deliberately outside the ACL defines. Return 1 if this is a "no acls"
2776 ************************************************************************/
2778 int no_acl_syscall_error(int err
)
2780 #ifdef HAVE_OSX_ACLS
2782 return 1; /* Weird problem with directory ACLs. */
2785 if (err
== ENOSYS
) {
2789 #if defined(ENOTSUP)
2790 if (err
== ENOTSUP
) {
2794 if (err
== EINVAL
) {
2795 /* If the type of SMB_ACL_TYPE_ACCESS or SMB_ACL_TYPE_DEFAULT
2796 * isn't valid, then the ACLs must be non-POSIX. */
2802 #endif /* SUPPORT_ACLS */