Removed version number from file header.
[Samba/ekacnet.git] / source / lib / sysacls.c
blobdb3e2bb67dac4d31a9b5c77b29f2005edf556d37
1 /*
2 Unix SMB/CIFS implementation.
3 Samba system utilities for ACL support.
4 Copyright (C) Jeremy Allison 2000.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
24 This file wraps all differing system ACL interfaces into a consistent
25 one based on the POSIX interface. It also returns the correct errors
26 for older UNIX systems that don't support ACLs.
28 The interfaces that each ACL implementation must support are as follows :
30 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
31 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
32 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p
33 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
34 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
35 SMB_ACL_T sys_acl_get_fd(int fd)
36 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
37 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
38 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
39 SMB_ACL_T sys_acl_init( int count)
40 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
41 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
42 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
43 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
44 int sys_acl_valid( SMB_ACL_T theacl )
45 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
46 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
47 int sys_acl_delete_def_file(const char *path)
49 This next one is not POSIX complient - but we *have* to have it !
50 More POSIX braindamage.
52 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
54 The generic POSIX free is the following call. We split this into
55 several different free functions as we may need to add tag info
56 to structures when emulating the POSIX interface.
58 int sys_acl_free( void *obj_p)
60 The calls we actually use are :
62 int sys_acl_free_text(char *text) - free acl_to_text
63 int sys_acl_free_acl(SMB_ACL_T posix_acl)
64 int sys_acl_free_qualifier(void *qualifier, SMB_ACL_TAG_T tagtype)
68 #if defined(HAVE_POSIX_ACLS)
70 /* Identity mapping - easy. */
72 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
74 return acl_get_entry( the_acl, entry_id, entry_p);
77 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
79 return acl_get_tag_type( entry_d, tag_type_p);
82 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
84 return acl_get_permset( entry_d, permset_p);
87 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
89 return acl_get_qualifier( entry_d);
92 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
94 return acl_get_file( path_p, type);
97 SMB_ACL_T sys_acl_get_fd(int fd)
99 return acl_get_fd(fd);
102 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
104 return acl_clear_perms(permset);
107 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
109 return acl_add_perm(permset, perm);
112 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
114 #if defined(HAVE_ACL_GET_PERM_NP)
116 * Required for TrustedBSD-based ACL implementations where
117 * non-POSIX.1e functions are denoted by a _np (non-portable)
118 * suffix.
120 return acl_get_perm_np(permset, perm);
121 #else
122 return acl_get_perm(permset, perm);
123 #endif
126 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
128 return acl_to_text( the_acl, plen);
131 SMB_ACL_T sys_acl_init( int count)
133 return acl_init(count);
136 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
138 return acl_create_entry(pacl, pentry);
141 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
143 return acl_set_tag_type(entry, tagtype);
146 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
148 return acl_set_qualifier(entry, qual);
151 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
153 return acl_set_permset(entry, permset);
156 int sys_acl_valid( SMB_ACL_T theacl )
158 return acl_valid(theacl);
161 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
163 return acl_set_file(name, acltype, theacl);
166 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
168 return acl_set_fd(fd, theacl);
171 int sys_acl_delete_def_file(const char *name)
173 return acl_delete_def_file(name);
176 int sys_acl_free_text(char *text)
178 return acl_free(text);
181 int sys_acl_free_acl(SMB_ACL_T the_acl)
183 return acl_free(the_acl);
186 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
188 return acl_free(qual);
191 #elif defined(HAVE_TRU64_ACLS)
193 * The interface to DEC/Compaq Tru64 UNIX ACLs
194 * is based on Draft 13 of the POSIX spec which is
195 * slightly different from the Draft 16 interface.
197 * Also, some of the permset manipulation functions
198 * such as acl_clear_perm() and acl_add_perm() appear
199 * to be broken on Tru64 so we have to manipulate
200 * the permission bits in the permset directly.
202 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
204 SMB_ACL_ENTRY_T entry;
206 if (entry_id == SMB_ACL_FIRST_ENTRY && acl_first_entry(the_acl) != 0) {
207 return -1;
210 errno = 0;
211 if ((entry = acl_get_entry(the_acl)) != NULL) {
212 *entry_p = entry;
213 return 1;
216 return errno ? -1 : 0;
219 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
221 return acl_get_tag_type( entry_d, tag_type_p);
224 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
226 return acl_get_permset( entry_d, permset_p);
229 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
231 return acl_get_qualifier( entry_d);
234 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
236 return acl_get_file((char *)path_p, type);
239 SMB_ACL_T sys_acl_get_fd(int fd)
241 return acl_get_fd(fd, ACL_TYPE_ACCESS);
244 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
246 *permset = 0; /* acl_clear_perm() is broken on Tru64 */
248 return 0;
251 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
253 if (perm & ~(SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE)) {
254 errno = EINVAL;
255 return -1;
258 *permset |= perm; /* acl_add_perm() is broken on Tru64 */
260 return 0;
263 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
265 return *permset & perm; /* Tru64 doesn't have acl_get_perm() */
268 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
270 return acl_to_text( the_acl, plen);
273 SMB_ACL_T sys_acl_init( int count)
275 return acl_init(count);
278 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
280 SMB_ACL_ENTRY_T entry;
282 if ((entry = acl_create_entry(pacl)) == NULL) {
283 return -1;
286 *pentry = entry;
287 return 0;
290 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
292 return acl_set_tag_type(entry, tagtype);
295 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
297 return acl_set_qualifier(entry, qual);
300 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
302 return acl_set_permset(entry, permset);
305 int sys_acl_valid( SMB_ACL_T theacl )
307 acl_entry_t entry;
309 return acl_valid(theacl, &entry);
312 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
314 return acl_set_file((char *)name, acltype, theacl);
317 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
319 return acl_set_fd(fd, ACL_TYPE_ACCESS, theacl);
322 int sys_acl_delete_def_file(const char *name)
324 return acl_delete_def_file((char *)name);
327 int sys_acl_free_text(char *text)
330 * (void) cast and explicit return 0 are for DEC UNIX
331 * which just #defines acl_free_text() to be free()
333 (void) acl_free_text(text);
334 return 0;
337 int sys_acl_free_acl(SMB_ACL_T the_acl)
339 return acl_free(the_acl);
342 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
344 return acl_free_qualifier(qual, tagtype);
347 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
350 * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
351 * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
355 * Note that while this code implements sufficient functionality
356 * to support the sys_acl_* interfaces it does not provide all
357 * of the semantics of the POSIX ACL interfaces.
359 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
360 * from a call to sys_acl_get_entry() should not be assumed to be
361 * valid after calling any of the following functions, which may
362 * reorder the entries in the ACL.
364 * sys_acl_valid()
365 * sys_acl_set_file()
366 * sys_acl_set_fd()
370 * The only difference between Solaris and UnixWare / OpenUNIX is
371 * that the #defines for the ACL operations have different names
373 #if defined(HAVE_UNIXWARE_ACLS)
375 #define SETACL ACL_SET
376 #define GETACL ACL_GET
377 #define GETACLCNT ACL_CNT
379 #endif
382 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
384 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
385 errno = EINVAL;
386 return -1;
389 if (entry_p == NULL) {
390 errno = EINVAL;
391 return -1;
394 if (entry_id == SMB_ACL_FIRST_ENTRY) {
395 acl_d->next = 0;
398 if (acl_d->next < 0) {
399 errno = EINVAL;
400 return -1;
403 if (acl_d->next >= acl_d->count) {
404 return 0;
407 *entry_p = &acl_d->acl[acl_d->next++];
409 return 1;
412 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
414 *type_p = entry_d->a_type;
416 return 0;
419 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
421 *permset_p = &entry_d->a_perm;
423 return 0;
426 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
428 if (entry_d->a_type != SMB_ACL_USER
429 && entry_d->a_type != SMB_ACL_GROUP) {
430 errno = EINVAL;
431 return NULL;
434 return &entry_d->a_id;
438 * There is no way of knowing what size the ACL returned by
439 * GETACL will be unless you first call GETACLCNT which means
440 * making an additional system call.
442 * In the hope of avoiding the cost of the additional system
443 * call in most cases, we initially allocate enough space for
444 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
445 * be too small then we use GETACLCNT to find out the actual
446 * size, reallocate the ACL buffer, and then call GETACL again.
449 #define INITIAL_ACL_SIZE 16
451 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
453 SMB_ACL_T acl_d;
454 int count; /* # of ACL entries allocated */
455 int naccess; /* # of access ACL entries */
456 int ndefault; /* # of default ACL entries */
458 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
459 errno = EINVAL;
460 return NULL;
463 count = INITIAL_ACL_SIZE;
464 if ((acl_d = sys_acl_init(count)) == NULL) {
465 return NULL;
469 * If there isn't enough space for the ACL entries we use
470 * GETACLCNT to determine the actual number of ACL entries
471 * reallocate and try again. This is in a loop because it
472 * is possible that someone else could modify the ACL and
473 * increase the number of entries between the call to
474 * GETACLCNT and the call to GETACL.
476 while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0
477 && errno == ENOSPC) {
479 sys_acl_free_acl(acl_d);
481 if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) {
482 return NULL;
485 if ((acl_d = sys_acl_init(count)) == NULL) {
486 return NULL;
490 if (count < 0) {
491 sys_acl_free_acl(acl_d);
492 return NULL;
496 * calculate the number of access and default ACL entries
498 * Note: we assume that the acl() system call returned a
499 * well formed ACL which is sorted so that all of the
500 * access ACL entries preceed any default ACL entries
502 for (naccess = 0; naccess < count; naccess++) {
503 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
504 break;
506 ndefault = count - naccess;
509 * if the caller wants the default ACL we have to copy
510 * the entries down to the start of the acl[] buffer
511 * and mask out the ACL_DEFAULT flag from the type field
513 if (type == SMB_ACL_TYPE_DEFAULT) {
514 int i, j;
516 for (i = 0, j = naccess; i < ndefault; i++, j++) {
517 acl_d->acl[i] = acl_d->acl[j];
518 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
521 acl_d->count = ndefault;
522 } else {
523 acl_d->count = naccess;
526 return acl_d;
529 SMB_ACL_T sys_acl_get_fd(int fd)
531 SMB_ACL_T acl_d;
532 int count; /* # of ACL entries allocated */
533 int naccess; /* # of access ACL entries */
535 count = INITIAL_ACL_SIZE;
536 if ((acl_d = sys_acl_init(count)) == NULL) {
537 return NULL;
540 while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0
541 && errno == ENOSPC) {
543 sys_acl_free_acl(acl_d);
545 if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) {
546 return NULL;
549 if ((acl_d = sys_acl_init(count)) == NULL) {
550 return NULL;
554 if (count < 0) {
555 sys_acl_free_acl(acl_d);
556 return NULL;
560 * calculate the number of access ACL entries
562 for (naccess = 0; naccess < count; naccess++) {
563 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
564 break;
567 acl_d->count = naccess;
569 return acl_d;
572 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
574 *permset_d = 0;
576 return 0;
579 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
581 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
582 && perm != SMB_ACL_EXECUTE) {
583 errno = EINVAL;
584 return -1;
587 if (permset_d == NULL) {
588 errno = EINVAL;
589 return -1;
592 *permset_d |= perm;
594 return 0;
597 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
599 return *permset_d & perm;
602 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
604 int i;
605 int len, maxlen;
606 char *text;
609 * use an initial estimate of 20 bytes per ACL entry
610 * when allocating memory for the text representation
611 * of the ACL
613 len = 0;
614 maxlen = 20 * acl_d->count;
615 if ((text = malloc(maxlen)) == NULL) {
616 errno = ENOMEM;
617 return NULL;
620 for (i = 0; i < acl_d->count; i++) {
621 struct acl *ap = &acl_d->acl[i];
622 struct passwd *pw;
623 struct group *gr;
624 char tagbuf[12];
625 char idbuf[12];
626 char *tag;
627 char *id = "";
628 char perms[4];
629 int nbytes;
631 switch (ap->a_type) {
633 * for debugging purposes it's probably more
634 * useful to dump unknown tag types rather
635 * than just returning an error
637 default:
638 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
639 ap->a_type);
640 tag = tagbuf;
641 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
642 (long)ap->a_id);
643 id = idbuf;
644 break;
646 case SMB_ACL_USER:
647 if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
648 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
649 (long)ap->a_id);
650 id = idbuf;
651 } else {
652 id = pw->pw_name;
654 case SMB_ACL_USER_OBJ:
655 tag = "user";
656 break;
658 case SMB_ACL_GROUP:
659 if ((gr = getgrgid(ap->a_id)) == NULL) {
660 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
661 (long)ap->a_id);
662 id = idbuf;
663 } else {
664 id = gr->gr_name;
666 case SMB_ACL_GROUP_OBJ:
667 tag = "group";
668 break;
670 case SMB_ACL_OTHER:
671 tag = "other";
672 break;
674 case SMB_ACL_MASK:
675 tag = "mask";
676 break;
680 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
681 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
682 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
683 perms[3] = '\0';
685 /* <tag> : <qualifier> : rwx \n \0 */
686 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
689 * If this entry would overflow the buffer
690 * allocate enough additional memory for this
691 * entry and an estimate of another 20 bytes
692 * for each entry still to be processed
694 if ((len + nbytes) > maxlen) {
695 char *oldtext = text;
697 maxlen += nbytes + 20 * (acl_d->count - i);
699 if ((text = Realloc(oldtext, maxlen)) == NULL) {
700 SAFE_FREE(oldtext);
701 errno = ENOMEM;
702 return NULL;
706 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
707 len += nbytes - 1;
710 if (len_p)
711 *len_p = len;
713 return text;
716 SMB_ACL_T sys_acl_init(int count)
718 SMB_ACL_T a;
720 if (count < 0) {
721 errno = EINVAL;
722 return NULL;
726 * note that since the definition of the structure pointed
727 * to by the SMB_ACL_T includes the first element of the
728 * acl[] array, this actually allocates an ACL with room
729 * for (count+1) entries
731 if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
732 errno = ENOMEM;
733 return NULL;
736 a->size = count + 1;
737 a->count = 0;
738 a->next = -1;
740 return a;
744 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
746 SMB_ACL_T acl_d;
747 SMB_ACL_ENTRY_T entry_d;
749 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
750 errno = EINVAL;
751 return -1;
754 if (acl_d->count >= acl_d->size) {
755 errno = ENOSPC;
756 return -1;
759 entry_d = &acl_d->acl[acl_d->count++];
760 entry_d->a_type = 0;
761 entry_d->a_id = -1;
762 entry_d->a_perm = 0;
763 *entry_p = entry_d;
765 return 0;
768 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
770 switch (tag_type) {
771 case SMB_ACL_USER:
772 case SMB_ACL_USER_OBJ:
773 case SMB_ACL_GROUP:
774 case SMB_ACL_GROUP_OBJ:
775 case SMB_ACL_OTHER:
776 case SMB_ACL_MASK:
777 entry_d->a_type = tag_type;
778 break;
779 default:
780 errno = EINVAL;
781 return -1;
784 return 0;
787 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
789 if (entry_d->a_type != SMB_ACL_GROUP
790 && entry_d->a_type != SMB_ACL_USER) {
791 errno = EINVAL;
792 return -1;
795 entry_d->a_id = *((id_t *)qual_p);
797 return 0;
800 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
802 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
803 return EINVAL;
806 entry_d->a_perm = *permset_d;
808 return 0;
812 * sort the ACL and check it for validity
814 * if it's a minimal ACL with only 4 entries then we
815 * need to recalculate the mask permissions to make
816 * sure that they are the same as the GROUP_OBJ
817 * permissions as required by the UnixWare acl() system call.
819 * (note: since POSIX allows minimal ACLs which only contain
820 * 3 entries - ie there is no mask entry - we should, in theory,
821 * check for this and add a mask entry if necessary - however
822 * we "know" that the caller of this interface always specifies
823 * a mask so, in practice "this never happens" (tm) - if it *does*
824 * happen aclsort() will fail and return an error and someone will
825 * have to fix it ...)
828 static int acl_sort(SMB_ACL_T acl_d)
830 int fixmask = (acl_d->count <= 4);
832 if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {
833 errno = EINVAL;
834 return -1;
836 return 0;
839 int sys_acl_valid(SMB_ACL_T acl_d)
841 return acl_sort(acl_d);
844 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
846 struct stat s;
847 struct acl *acl_p;
848 int acl_count;
849 struct acl *acl_buf = NULL;
850 int ret;
852 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
853 errno = EINVAL;
854 return -1;
857 if (acl_sort(acl_d) != 0) {
858 return -1;
861 acl_p = &acl_d->acl[0];
862 acl_count = acl_d->count;
865 * if it's a directory there is extra work to do
866 * since the acl() system call will replace both
867 * the access ACLs and the default ACLs (if any)
869 if (stat(name, &s) != 0) {
870 return -1;
872 if (S_ISDIR(s.st_mode)) {
873 SMB_ACL_T acc_acl;
874 SMB_ACL_T def_acl;
875 SMB_ACL_T tmp_acl;
876 int i;
878 if (type == SMB_ACL_TYPE_ACCESS) {
879 acc_acl = acl_d;
880 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
882 } else {
883 def_acl = acl_d;
884 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
887 if (tmp_acl == NULL) {
888 return -1;
892 * allocate a temporary buffer for the complete ACL
894 acl_count = acc_acl->count + def_acl->count;
895 acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
897 if (acl_buf == NULL) {
898 sys_acl_free_acl(tmp_acl);
899 errno = ENOMEM;
900 return -1;
904 * copy the access control and default entries into the buffer
906 memcpy(&acl_buf[0], &acc_acl->acl[0],
907 acc_acl->count * sizeof(acl_buf[0]));
909 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
910 def_acl->count * sizeof(acl_buf[0]));
913 * set the ACL_DEFAULT flag on the default entries
915 for (i = acc_acl->count; i < acl_count; i++) {
916 acl_buf[i].a_type |= ACL_DEFAULT;
919 sys_acl_free_acl(tmp_acl);
921 } else if (type != SMB_ACL_TYPE_ACCESS) {
922 errno = EINVAL;
923 return -1;
926 ret = acl(name, SETACL, acl_count, acl_p);
928 SAFE_FREE(acl_buf);
930 return ret;
933 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
935 if (acl_sort(acl_d) != 0) {
936 return -1;
939 return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
942 int sys_acl_delete_def_file(const char *path)
944 SMB_ACL_T acl_d;
945 int ret;
948 * fetching the access ACL and rewriting it has
949 * the effect of deleting the default ACL
951 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
952 return -1;
955 ret = acl(path, SETACL, acl_d->count, acl_d->acl);
957 sys_acl_free_acl(acl_d);
959 return ret;
962 int sys_acl_free_text(char *text)
964 SAFE_FREE(text);
965 return 0;
968 int sys_acl_free_acl(SMB_ACL_T acl_d)
970 SAFE_FREE(acl_d);
971 return 0;
974 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
976 return 0;
979 #elif defined(HAVE_HPUX_ACLS)
980 #include <dl.h>
983 * Based on the Solaris/SCO code - with modifications.
987 * Note that while this code implements sufficient functionality
988 * to support the sys_acl_* interfaces it does not provide all
989 * of the semantics of the POSIX ACL interfaces.
991 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
992 * from a call to sys_acl_get_entry() should not be assumed to be
993 * valid after calling any of the following functions, which may
994 * reorder the entries in the ACL.
996 * sys_acl_valid()
997 * sys_acl_set_file()
998 * sys_acl_set_fd()
1001 /* This checks if the POSIX ACL system call is defined */
1002 /* which basically corresponds to whether JFS 3.3 or */
1003 /* higher is installed. If acl() was called when it */
1004 /* isn't defined, it causes the process to core dump */
1005 /* so it is important to check this and avoid acl() */
1006 /* calls if it isn't there. */
1008 static BOOL hpux_acl_call_presence(void)
1011 shl_t handle = NULL;
1012 void *value;
1013 int ret_val=0;
1014 static BOOL already_checked=0;
1016 if(already_checked)
1017 return True;
1020 ret_val = shl_findsym(&handle, "acl", TYPE_PROCEDURE, &value);
1022 if(ret_val != 0) {
1023 DEBUG(5, ("hpux_acl_call_presence: shl_findsym() returned %d, errno = %d, error %s\n",
1024 ret_val, errno, strerror(errno)));
1025 DEBUG(5,("hpux_acl_call_presence: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
1026 return False;
1029 DEBUG(10,("hpux_acl_call_presence: acl() system call is present. We have JFS 3.3 or above \n"));
1031 already_checked = True;
1032 return True;
1035 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1037 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
1038 errno = EINVAL;
1039 return -1;
1042 if (entry_p == NULL) {
1043 errno = EINVAL;
1044 return -1;
1047 if (entry_id == SMB_ACL_FIRST_ENTRY) {
1048 acl_d->next = 0;
1051 if (acl_d->next < 0) {
1052 errno = EINVAL;
1053 return -1;
1056 if (acl_d->next >= acl_d->count) {
1057 return 0;
1060 *entry_p = &acl_d->acl[acl_d->next++];
1062 return 1;
1065 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
1067 *type_p = entry_d->a_type;
1069 return 0;
1072 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1074 *permset_p = &entry_d->a_perm;
1076 return 0;
1079 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
1081 if (entry_d->a_type != SMB_ACL_USER
1082 && entry_d->a_type != SMB_ACL_GROUP) {
1083 errno = EINVAL;
1084 return NULL;
1087 return &entry_d->a_id;
1091 * There is no way of knowing what size the ACL returned by
1092 * ACL_GET will be unless you first call ACL_CNT which means
1093 * making an additional system call.
1095 * In the hope of avoiding the cost of the additional system
1096 * call in most cases, we initially allocate enough space for
1097 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
1098 * be too small then we use ACL_CNT to find out the actual
1099 * size, reallocate the ACL buffer, and then call ACL_GET again.
1102 #define INITIAL_ACL_SIZE 16
1104 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
1106 SMB_ACL_T acl_d;
1107 int count; /* # of ACL entries allocated */
1108 int naccess; /* # of access ACL entries */
1109 int ndefault; /* # of default ACL entries */
1111 if(hpux_acl_call_presence() == False) {
1112 /* Looks like we don't have the acl() system call on HPUX.
1113 * May be the system doesn't have the latest version of JFS.
1115 return NULL;
1118 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
1119 errno = EINVAL;
1120 return NULL;
1123 count = INITIAL_ACL_SIZE;
1124 if ((acl_d = sys_acl_init(count)) == NULL) {
1125 return NULL;
1129 * If there isn't enough space for the ACL entries we use
1130 * ACL_CNT to determine the actual number of ACL entries
1131 * reallocate and try again. This is in a loop because it
1132 * is possible that someone else could modify the ACL and
1133 * increase the number of entries between the call to
1134 * ACL_CNT and the call to ACL_GET.
1136 while ((count = acl(path_p, ACL_GET, count, &acl_d->acl[0])) < 0 && errno == ENOSPC) {
1138 sys_acl_free_acl(acl_d);
1140 if ((count = acl(path_p, ACL_CNT, 0, NULL)) < 0) {
1141 return NULL;
1144 if ((acl_d = sys_acl_init(count)) == NULL) {
1145 return NULL;
1149 if (count < 0) {
1150 sys_acl_free_acl(acl_d);
1151 return NULL;
1155 * calculate the number of access and default ACL entries
1157 * Note: we assume that the acl() system call returned a
1158 * well formed ACL which is sorted so that all of the
1159 * access ACL entries preceed any default ACL entries
1161 for (naccess = 0; naccess < count; naccess++) {
1162 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
1163 break;
1165 ndefault = count - naccess;
1168 * if the caller wants the default ACL we have to copy
1169 * the entries down to the start of the acl[] buffer
1170 * and mask out the ACL_DEFAULT flag from the type field
1172 if (type == SMB_ACL_TYPE_DEFAULT) {
1173 int i, j;
1175 for (i = 0, j = naccess; i < ndefault; i++, j++) {
1176 acl_d->acl[i] = acl_d->acl[j];
1177 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
1180 acl_d->count = ndefault;
1181 } else {
1182 acl_d->count = naccess;
1185 return acl_d;
1188 SMB_ACL_T sys_acl_get_fd(int fd)
1191 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1194 files_struct *fsp = file_find_fd(fd);
1196 if (fsp == NULL) {
1197 errno = EBADF;
1198 return NULL;
1202 * We know we're in the same conn context. So we
1203 * can use the relative path.
1206 return sys_acl_get_file(dos_to_unix(fsp->fsp_name,False), SMB_ACL_TYPE_ACCESS);
1209 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
1211 *permset_d = 0;
1213 return 0;
1216 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1218 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
1219 && perm != SMB_ACL_EXECUTE) {
1220 errno = EINVAL;
1221 return -1;
1224 if (permset_d == NULL) {
1225 errno = EINVAL;
1226 return -1;
1229 *permset_d |= perm;
1231 return 0;
1234 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1236 return *permset_d & perm;
1239 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
1241 int i;
1242 int len, maxlen;
1243 char *text;
1246 * use an initial estimate of 20 bytes per ACL entry
1247 * when allocating memory for the text representation
1248 * of the ACL
1250 len = 0;
1251 maxlen = 20 * acl_d->count;
1252 if ((text = malloc(maxlen)) == NULL) {
1253 errno = ENOMEM;
1254 return NULL;
1257 for (i = 0; i < acl_d->count; i++) {
1258 struct acl *ap = &acl_d->acl[i];
1259 struct passwd *pw;
1260 struct group *gr;
1261 char tagbuf[12];
1262 char idbuf[12];
1263 char *tag;
1264 char *id = "";
1265 char perms[4];
1266 int nbytes;
1268 switch (ap->a_type) {
1270 * for debugging purposes it's probably more
1271 * useful to dump unknown tag types rather
1272 * than just returning an error
1274 default:
1275 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
1276 ap->a_type);
1277 tag = tagbuf;
1278 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
1279 (long)ap->a_id);
1280 id = idbuf;
1281 break;
1283 case SMB_ACL_USER:
1284 if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
1285 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
1286 (long)ap->a_id);
1287 id = idbuf;
1288 } else {
1289 id = pw->pw_name;
1291 case SMB_ACL_USER_OBJ:
1292 tag = "user";
1293 break;
1295 case SMB_ACL_GROUP:
1296 if ((gr = getgrgid(ap->a_id)) == NULL) {
1297 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
1298 (long)ap->a_id);
1299 id = idbuf;
1300 } else {
1301 id = gr->gr_name;
1303 case SMB_ACL_GROUP_OBJ:
1304 tag = "group";
1305 break;
1307 case SMB_ACL_OTHER:
1308 tag = "other";
1309 break;
1311 case SMB_ACL_MASK:
1312 tag = "mask";
1313 break;
1317 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
1318 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
1319 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
1320 perms[3] = '\0';
1322 /* <tag> : <qualifier> : rwx \n \0 */
1323 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
1326 * If this entry would overflow the buffer
1327 * allocate enough additional memory for this
1328 * entry and an estimate of another 20 bytes
1329 * for each entry still to be processed
1331 if ((len + nbytes) > maxlen) {
1332 char *oldtext = text;
1334 maxlen += nbytes + 20 * (acl_d->count - i);
1336 if ((text = Realloc(oldtext, maxlen)) == NULL) {
1337 free(oldtext);
1338 errno = ENOMEM;
1339 return NULL;
1343 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
1344 len += nbytes - 1;
1347 if (len_p)
1348 *len_p = len;
1350 return text;
1353 SMB_ACL_T sys_acl_init(int count)
1355 SMB_ACL_T a;
1357 if (count < 0) {
1358 errno = EINVAL;
1359 return NULL;
1363 * note that since the definition of the structure pointed
1364 * to by the SMB_ACL_T includes the first element of the
1365 * acl[] array, this actually allocates an ACL with room
1366 * for (count+1) entries
1368 if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
1369 errno = ENOMEM;
1370 return NULL;
1373 a->size = count + 1;
1374 a->count = 0;
1375 a->next = -1;
1377 return a;
1381 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1383 SMB_ACL_T acl_d;
1384 SMB_ACL_ENTRY_T entry_d;
1386 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
1387 errno = EINVAL;
1388 return -1;
1391 if (acl_d->count >= acl_d->size) {
1392 errno = ENOSPC;
1393 return -1;
1396 entry_d = &acl_d->acl[acl_d->count++];
1397 entry_d->a_type = 0;
1398 entry_d->a_id = -1;
1399 entry_d->a_perm = 0;
1400 *entry_p = entry_d;
1402 return 0;
1405 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1407 switch (tag_type) {
1408 case SMB_ACL_USER:
1409 case SMB_ACL_USER_OBJ:
1410 case SMB_ACL_GROUP:
1411 case SMB_ACL_GROUP_OBJ:
1412 case SMB_ACL_OTHER:
1413 case SMB_ACL_MASK:
1414 entry_d->a_type = tag_type;
1415 break;
1416 default:
1417 errno = EINVAL;
1418 return -1;
1421 return 0;
1424 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
1426 if (entry_d->a_type != SMB_ACL_GROUP
1427 && entry_d->a_type != SMB_ACL_USER) {
1428 errno = EINVAL;
1429 return -1;
1432 entry_d->a_id = *((id_t *)qual_p);
1434 return 0;
1437 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1439 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1440 return EINVAL;
1443 entry_d->a_perm = *permset_d;
1445 return 0;
1448 /* Structure to capture the count for each type of ACE. */
1450 struct hpux_acl_types {
1451 int n_user;
1452 int n_def_user;
1453 int n_user_obj;
1454 int n_def_user_obj;
1456 int n_group;
1457 int n_def_group;
1458 int n_group_obj;
1459 int n_def_group_obj;
1461 int n_other;
1462 int n_other_obj;
1463 int n_def_other_obj;
1465 int n_class_obj;
1466 int n_def_class_obj;
1468 int n_illegal_obj;
1471 /* count_obj:
1472 * Counts the different number of objects in a given array of ACL
1473 * structures.
1474 * Inputs:
1476 * acl_count - Count of ACLs in the array of ACL strucutres.
1477 * aclp - Array of ACL structures.
1478 * acl_type_count - Pointer to acl_types structure. Should already be
1479 * allocated.
1480 * Output:
1482 * acl_type_count - This structure is filled up with counts of various
1483 * acl types.
1486 static int hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_types *acl_type_count)
1488 int i;
1490 memset(acl_type_count, 0, sizeof(struct hpux_acl_types));
1492 for(i=0;i<acl_count;i++) {
1493 switch(aclp[i].a_type) {
1494 case USER:
1495 acl_type_count->n_user++;
1496 break;
1497 case USER_OBJ:
1498 acl_type_count->n_user_obj++;
1499 break;
1500 case DEF_USER_OBJ:
1501 acl_type_count->n_def_user_obj++;
1502 break;
1503 case GROUP:
1504 acl_type_count->n_group++;
1505 break;
1506 case GROUP_OBJ:
1507 acl_type_count->n_group_obj++;
1508 break;
1509 case DEF_GROUP_OBJ:
1510 acl_type_count->n_def_group_obj++;
1511 break;
1512 case OTHER_OBJ:
1513 acl_type_count->n_other_obj++;
1514 break;
1515 case DEF_OTHER_OBJ:
1516 acl_type_count->n_def_other_obj++;
1517 break;
1518 case CLASS_OBJ:
1519 acl_type_count->n_class_obj++;
1520 break;
1521 case DEF_CLASS_OBJ:
1522 acl_type_count->n_def_class_obj++;
1523 break;
1524 case DEF_USER:
1525 acl_type_count->n_def_user++;
1526 break;
1527 case DEF_GROUP:
1528 acl_type_count->n_def_group++;
1529 break;
1530 default:
1531 acl_type_count->n_illegal_obj++;
1532 break;
1537 /* swap_acl_entries: Swaps two ACL entries.
1539 * Inputs: aclp0, aclp1 - ACL entries to be swapped.
1542 static void hpux_swap_acl_entries(struct acl *aclp0, struct acl *aclp1)
1544 struct acl temp_acl;
1546 temp_acl.a_type = aclp0->a_type;
1547 temp_acl.a_id = aclp0->a_id;
1548 temp_acl.a_perm = aclp0->a_perm;
1550 aclp0->a_type = aclp1->a_type;
1551 aclp0->a_id = aclp1->a_id;
1552 aclp0->a_perm = aclp1->a_perm;
1554 aclp1->a_type = temp_acl.a_type;
1555 aclp1->a_id = temp_acl.a_id;
1556 aclp1->a_perm = temp_acl.a_perm;
1559 /* prohibited_duplicate_type
1560 * Identifies if given ACL type can have duplicate entries or
1561 * not.
1563 * Inputs: acl_type - ACL Type.
1565 * Outputs:
1567 * Return..
1569 * True - If the ACL type matches any of the prohibited types.
1570 * False - If the ACL type doesn't match any of the prohibited types.
1573 static BOOL hpux_prohibited_duplicate_type(int acl_type)
1575 switch(acl_type) {
1576 case USER:
1577 case GROUP:
1578 case DEF_USER:
1579 case DEF_GROUP:
1580 return True;
1581 default:
1582 return False;
1586 /* get_needed_class_perm
1587 * Returns the permissions of a ACL structure only if the ACL
1588 * type matches one of the pre-determined types for computing
1589 * CLASS_OBJ permissions.
1591 * Inputs: aclp - Pointer to ACL structure.
1594 static int hpux_get_needed_class_perm(struct acl *aclp)
1596 switch(aclp->a_type) {
1597 case USER:
1598 case GROUP_OBJ:
1599 case GROUP:
1600 case DEF_USER_OBJ:
1601 case DEF_USER:
1602 case DEF_GROUP_OBJ:
1603 case DEF_GROUP:
1604 case DEF_CLASS_OBJ:
1605 case DEF_OTHER_OBJ:
1606 return aclp->a_perm;
1607 default:
1608 return 0;
1612 /* acl_sort for HPUX.
1613 * Sorts the array of ACL structures as per the description in
1614 * aclsort man page. Refer to aclsort man page for more details
1616 * Inputs:
1618 * acl_count - Count of ACLs in the array of ACL structures.
1619 * calclass - If this is not zero, then we compute the CLASS_OBJ
1620 * permissions.
1621 * aclp - Array of ACL structures.
1623 * Outputs:
1625 * aclp - Sorted array of ACL structures.
1627 * Outputs:
1629 * Returns 0 for success -1 for failure. Prints a message to the Samba
1630 * debug log in case of failure.
1633 static int hpux_acl_sort(int acl_count, int calclass, struct acl *aclp)
1635 #if !defined(HAVE_HPUX_ACLSORT)
1637 * The aclsort() system call is availabe on the latest HPUX General
1638 * Patch Bundles. So for HPUX, we developed our version of acl_sort
1639 * function. Because, we don't want to update to a new
1640 * HPUX GR bundle just for aclsort() call.
1643 struct hpux_acl_types acl_obj_count;
1644 int n_class_obj_perm = 0;
1645 int i, j;
1647 if(!acl_count) {
1648 DEBUG(10,("Zero acl count passed. Returning Success\n"));
1649 return 0;
1652 if(aclp == NULL) {
1653 DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
1654 return -1;
1657 /* Count different types of ACLs in the ACLs array */
1659 hpux_count_obj(acl_count, aclp, &acl_obj_count);
1661 /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
1662 * CLASS_OBJ and OTHER_OBJ
1665 if( (acl_obj_count.n_user_obj != 1) ||
1666 (acl_obj_count.n_group_obj != 1) ||
1667 (acl_obj_count.n_class_obj != 1) ||
1668 (acl_obj_count.n_other_obj != 1)
1670 DEBUG(0,("hpux_acl_sort: More than one entry or no entries for \
1671 USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
1672 return -1;
1675 /* If any of the default objects are present, there should be only
1676 * one of them each.
1679 if( (acl_obj_count.n_def_user_obj > 1) || (acl_obj_count.n_def_group_obj > 1) ||
1680 (acl_obj_count.n_def_other_obj > 1) || (acl_obj_count.n_def_class_obj > 1) ) {
1681 DEBUG(0,("hpux_acl_sort: More than one entry for DEF_CLASS_OBJ \
1682 or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
1683 return -1;
1686 /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
1687 * structures.
1689 * Sorting crieteria - First sort by ACL type. If there are multiple entries of
1690 * same ACL type, sort by ACL id.
1692 * I am using the trival kind of sorting method here because, performance isn't
1693 * really effected by the ACLs feature. More over there aren't going to be more
1694 * than 17 entries on HPUX.
1697 for(i=0; i<acl_count;i++) {
1698 for (j=i+1; j<acl_count; j++) {
1699 if( aclp[i].a_type > aclp[j].a_type ) {
1700 /* ACL entries out of order, swap them */
1702 hpux_swap_acl_entries((aclp+i), (aclp+j));
1704 } else if ( aclp[i].a_type == aclp[j].a_type ) {
1706 /* ACL entries of same type, sort by id */
1708 if(aclp[i].a_id > aclp[j].a_id) {
1709 hpux_swap_acl_entries((aclp+i), (aclp+j));
1710 } else if (aclp[i].a_id == aclp[j].a_id) {
1711 /* We have a duplicate entry. */
1712 if(hpux_prohibited_duplicate_type(aclp[i].a_type)) {
1713 DEBUG(0, ("hpux_acl_sort: Duplicate entry: Type(hex): %x Id: %d\n",
1714 aclp[i].a_type, aclp[i].a_id));
1715 return -1;
1723 /* set the class obj permissions to the computed one. */
1724 if(calclass) {
1725 int n_class_obj_index = -1;
1727 for(i=0;i<acl_count;i++) {
1728 n_class_obj_perm |= hpux_get_needed_class_perm((aclp+i));
1730 if(aclp[i].a_type == CLASS_OBJ)
1731 n_class_obj_index = i;
1733 aclp[n_class_obj_index].a_perm = n_class_obj_perm;
1736 return 0;
1737 #else
1738 return aclsort(acl_count, calclass, aclp);
1739 #endif
1743 * sort the ACL and check it for validity
1745 * if it's a minimal ACL with only 4 entries then we
1746 * need to recalculate the mask permissions to make
1747 * sure that they are the same as the GROUP_OBJ
1748 * permissions as required by the UnixWare acl() system call.
1750 * (note: since POSIX allows minimal ACLs which only contain
1751 * 3 entries - ie there is no mask entry - we should, in theory,
1752 * check for this and add a mask entry if necessary - however
1753 * we "know" that the caller of this interface always specifies
1754 * a mask so, in practice "this never happens" (tm) - if it *does*
1755 * happen aclsort() will fail and return an error and someone will
1756 * have to fix it ...)
1759 static int acl_sort(SMB_ACL_T acl_d)
1761 int fixmask = (acl_d->count <= 4);
1763 if (hpux_acl_sort(acl_d->count, fixmask, acl_d->acl) != 0) {
1764 errno = EINVAL;
1765 return -1;
1767 return 0;
1770 int sys_acl_valid(SMB_ACL_T acl_d)
1772 return acl_sort(acl_d);
1775 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
1777 struct stat s;
1778 struct acl *acl_p;
1779 int acl_count;
1780 struct acl *acl_buf = NULL;
1781 int ret;
1783 if(hpux_acl_call_presence() == False) {
1784 /* Looks like we don't have the acl() system call on HPUX.
1785 * May be the system doesn't have the latest version of JFS.
1787 errno=ENOSYS;
1788 return -1;
1791 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
1792 errno = EINVAL;
1793 return -1;
1796 if (acl_sort(acl_d) != 0) {
1797 return -1;
1800 acl_p = &acl_d->acl[0];
1801 acl_count = acl_d->count;
1804 * if it's a directory there is extra work to do
1805 * since the acl() system call will replace both
1806 * the access ACLs and the default ACLs (if any)
1808 if (stat(name, &s) != 0) {
1809 return -1;
1811 if (S_ISDIR(s.st_mode)) {
1812 SMB_ACL_T acc_acl;
1813 SMB_ACL_T def_acl;
1814 SMB_ACL_T tmp_acl;
1815 int i;
1817 if (type == SMB_ACL_TYPE_ACCESS) {
1818 acc_acl = acl_d;
1819 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
1821 } else {
1822 def_acl = acl_d;
1823 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
1826 if (tmp_acl == NULL) {
1827 return -1;
1831 * allocate a temporary buffer for the complete ACL
1833 acl_count = acc_acl->count + def_acl->count;
1834 acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
1836 if (acl_buf == NULL) {
1837 sys_acl_free_acl(tmp_acl);
1838 errno = ENOMEM;
1839 return -1;
1843 * copy the access control and default entries into the buffer
1845 memcpy(&acl_buf[0], &acc_acl->acl[0],
1846 acc_acl->count * sizeof(acl_buf[0]));
1848 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
1849 def_acl->count * sizeof(acl_buf[0]));
1852 * set the ACL_DEFAULT flag on the default entries
1854 for (i = acc_acl->count; i < acl_count; i++) {
1855 acl_buf[i].a_type |= ACL_DEFAULT;
1858 sys_acl_free_acl(tmp_acl);
1860 } else if (type != SMB_ACL_TYPE_ACCESS) {
1861 errno = EINVAL;
1862 return -1;
1865 ret = acl(name, ACL_SET, acl_count, acl_p);
1867 if (acl_buf) {
1868 free(acl_buf);
1871 return ret;
1874 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
1877 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1880 files_struct *fsp = file_find_fd(fd);
1882 if (fsp == NULL) {
1883 errno = EBADF;
1884 return NULL;
1887 if (acl_sort(acl_d) != 0) {
1888 return -1;
1892 * We know we're in the same conn context. So we
1893 * can use the relative path.
1896 return sys_acl_set_file(dos_to_unix(fsp->fsp_name,False), SMB_ACL_TYPE_ACCESS, acl_d);
1899 int sys_acl_delete_def_file(const char *path)
1901 SMB_ACL_T acl_d;
1902 int ret;
1905 * fetching the access ACL and rewriting it has
1906 * the effect of deleting the default ACL
1908 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
1909 return -1;
1912 ret = acl(path, ACL_SET, acl_d->count, acl_d->acl);
1914 sys_acl_free_acl(acl_d);
1916 return ret;
1919 int sys_acl_free_text(char *text)
1921 free(text);
1922 return 0;
1925 int sys_acl_free_acl(SMB_ACL_T acl_d)
1927 free(acl_d);
1928 return 0;
1931 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
1933 return 0;
1936 #elif defined(HAVE_IRIX_ACLS)
1938 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1940 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
1941 errno = EINVAL;
1942 return -1;
1945 if (entry_p == NULL) {
1946 errno = EINVAL;
1947 return -1;
1950 if (entry_id == SMB_ACL_FIRST_ENTRY) {
1951 acl_d->next = 0;
1954 if (acl_d->next < 0) {
1955 errno = EINVAL;
1956 return -1;
1959 if (acl_d->next >= acl_d->aclp->acl_cnt) {
1960 return 0;
1963 *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
1965 return 1;
1968 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
1970 *type_p = entry_d->ae_tag;
1972 return 0;
1975 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1977 *permset_p = entry_d;
1979 return 0;
1982 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
1984 if (entry_d->ae_tag != SMB_ACL_USER
1985 && entry_d->ae_tag != SMB_ACL_GROUP) {
1986 errno = EINVAL;
1987 return NULL;
1990 return &entry_d->ae_id;
1993 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
1995 SMB_ACL_T a;
1997 if ((a = malloc(sizeof(*a))) == NULL) {
1998 errno = ENOMEM;
1999 return NULL;
2001 if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
2002 SAFE_FREE(a);
2003 return NULL;
2005 a->next = -1;
2006 a->freeaclp = True;
2007 return a;
2010 SMB_ACL_T sys_acl_get_fd(int fd)
2012 SMB_ACL_T a;
2014 if ((a = malloc(sizeof(*a))) == NULL) {
2015 errno = ENOMEM;
2016 return NULL;
2018 if ((a->aclp = acl_get_fd(fd)) == NULL) {
2019 SAFE_FREE(a);
2020 return NULL;
2022 a->next = -1;
2023 a->freeaclp = True;
2024 return a;
2027 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
2029 permset_d->ae_perm = 0;
2031 return 0;
2034 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
2036 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
2037 && perm != SMB_ACL_EXECUTE) {
2038 errno = EINVAL;
2039 return -1;
2042 if (permset_d == NULL) {
2043 errno = EINVAL;
2044 return -1;
2047 permset_d->ae_perm |= perm;
2049 return 0;
2052 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
2054 return permset_d->ae_perm & perm;
2057 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
2059 return acl_to_text(acl_d->aclp, len_p);
2062 SMB_ACL_T sys_acl_init(int count)
2064 SMB_ACL_T a;
2066 if (count < 0) {
2067 errno = EINVAL;
2068 return NULL;
2071 if ((a = malloc(sizeof(*a) + sizeof(struct acl))) == NULL) {
2072 errno = ENOMEM;
2073 return NULL;
2076 a->next = -1;
2077 a->freeaclp = False;
2078 a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
2079 a->aclp->acl_cnt = 0;
2081 return a;
2085 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
2087 SMB_ACL_T acl_d;
2088 SMB_ACL_ENTRY_T entry_d;
2090 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
2091 errno = EINVAL;
2092 return -1;
2095 if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
2096 errno = ENOSPC;
2097 return -1;
2100 entry_d = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
2101 entry_d->ae_tag = 0;
2102 entry_d->ae_id = 0;
2103 entry_d->ae_perm = 0;
2104 *entry_p = entry_d;
2106 return 0;
2109 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
2111 switch (tag_type) {
2112 case SMB_ACL_USER:
2113 case SMB_ACL_USER_OBJ:
2114 case SMB_ACL_GROUP:
2115 case SMB_ACL_GROUP_OBJ:
2116 case SMB_ACL_OTHER:
2117 case SMB_ACL_MASK:
2118 entry_d->ae_tag = tag_type;
2119 break;
2120 default:
2121 errno = EINVAL;
2122 return -1;
2125 return 0;
2128 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
2130 if (entry_d->ae_tag != SMB_ACL_GROUP
2131 && entry_d->ae_tag != SMB_ACL_USER) {
2132 errno = EINVAL;
2133 return -1;
2136 entry_d->ae_id = *((id_t *)qual_p);
2138 return 0;
2141 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
2143 if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
2144 return EINVAL;
2147 entry_d->ae_perm = permset_d->ae_perm;
2149 return 0;
2152 int sys_acl_valid(SMB_ACL_T acl_d)
2154 return acl_valid(acl_d->aclp);
2157 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
2159 return acl_set_file(name, type, acl_d->aclp);
2162 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
2164 return acl_set_fd(fd, acl_d->aclp);
2167 int sys_acl_delete_def_file(const char *name)
2169 return acl_delete_def_file(name);
2172 int sys_acl_free_text(char *text)
2174 return acl_free(text);
2177 int sys_acl_free_acl(SMB_ACL_T acl_d)
2179 if (acl_d->freeaclp) {
2180 acl_free(acl_d->aclp);
2182 acl_free(acl_d);
2183 return 0;
2186 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
2188 return 0;
2191 #elif defined(HAVE_AIX_ACLS)
2193 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
2195 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
2197 struct acl_entry_link *link;
2198 struct new_acl_entry *entry;
2199 int keep_going;
2201 DEBUG(10,("This is the count: %d\n",theacl->count));
2203 /* Check if count was previously set to -1. *
2204 * If it was, that means we reached the end *
2205 * of the acl last time. */
2206 if(theacl->count == -1)
2207 return(0);
2209 link = theacl;
2210 /* To get to the next acl, traverse linked list until index *
2211 * of acl matches the count we are keeping. This count is *
2212 * incremented each time we return an acl entry. */
2214 for(keep_going = 0; keep_going < theacl->count; keep_going++)
2215 link = link->nextp;
2217 entry = *entry_p = link->entryp;
2219 DEBUG(10,("*entry_p is %d\n",entry_p));
2220 DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
2222 /* Increment count */
2223 theacl->count++;
2224 if(link->nextp == NULL)
2225 theacl->count = -1;
2227 return(1);
2230 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
2232 /* Initialize tag type */
2234 *tag_type_p = -1;
2235 DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
2237 /* Depending on what type of entry we have, *
2238 * return tag type. */
2239 switch(entry_d->ace_id->id_type) {
2240 case ACEID_USER:
2241 *tag_type_p = SMB_ACL_USER;
2242 break;
2243 case ACEID_GROUP:
2244 *tag_type_p = SMB_ACL_GROUP;
2245 break;
2247 case SMB_ACL_USER_OBJ:
2248 case SMB_ACL_GROUP_OBJ:
2249 case SMB_ACL_OTHER:
2250 *tag_type_p = entry_d->ace_id->id_type;
2251 break;
2253 default:
2254 return(-1);
2257 return(0);
2260 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
2262 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
2263 *permset_p = &entry_d->ace_access;
2264 DEBUG(10,("**permset_p is %d\n",**permset_p));
2265 if(!(**permset_p & S_IXUSR) &&
2266 !(**permset_p & S_IWUSR) &&
2267 !(**permset_p & S_IRUSR) &&
2268 (**permset_p != 0))
2269 return(-1);
2271 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
2272 return(0);
2275 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
2277 return(entry_d->ace_id->id_data);
2280 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
2282 struct acl *file_acl = (struct acl *)NULL;
2283 struct acl_entry *acl_entry;
2284 struct new_acl_entry *new_acl_entry;
2285 struct ace_id *idp;
2286 struct acl_entry_link *acl_entry_link;
2287 struct acl_entry_link *acl_entry_link_head;
2288 int i;
2289 int rc = 0;
2290 uid_t user_id;
2292 /* Get the acl using statacl */
2294 DEBUG(10,("Entering sys_acl_get_file\n"));
2295 DEBUG(10,("path_p is %s\n",path_p));
2297 file_acl = (struct acl *)malloc(BUFSIZ);
2299 if(file_acl == NULL) {
2300 errno=ENOMEM;
2301 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
2302 return(NULL);
2305 memset(file_acl,0,BUFSIZ);
2307 rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
2308 if(rc == -1) {
2309 DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
2310 SAFE_FREE(file_acl);
2311 return(NULL);
2314 DEBUG(10,("Got facl and returned it\n"));
2316 /* Point to the first acl entry in the acl */
2317 acl_entry = file_acl->acl_ext;
2319 /* Begin setting up the head of the linked list *
2320 * that will be used for the storing the acl *
2321 * in a way that is useful for the posix_acls.c *
2322 * code. */
2324 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
2325 if(acl_entry_link_head == NULL)
2326 return(NULL);
2328 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
2329 if(acl_entry_link->entryp == NULL) {
2330 SAFE_FREE(file_acl);
2331 errno = ENOMEM;
2332 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2333 return(NULL);
2336 DEBUG(10,("acl_entry is %d\n",acl_entry));
2337 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
2339 /* Check if the extended acl bit is on. *
2340 * If it isn't, do not show the *
2341 * contents of the acl since AIX intends *
2342 * the extended info to remain unused */
2344 if(file_acl->acl_mode & S_IXACL){
2345 /* while we are not pointing to the very end */
2346 while(acl_entry < acl_last(file_acl)) {
2347 /* before we malloc anything, make sure this is */
2348 /* a valid acl entry and one that we want to map */
2349 idp = id_nxt(acl_entry->ace_id);
2350 if((acl_entry->ace_type == ACC_SPECIFY ||
2351 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
2352 acl_entry = acl_nxt(acl_entry);
2353 continue;
2356 idp = acl_entry->ace_id;
2358 /* Check if this is the first entry in the linked list. *
2359 * The first entry needs to keep prevp pointing to NULL *
2360 * and already has entryp allocated. */
2362 if(acl_entry_link_head->count != 0) {
2363 acl_entry_link->nextp = (struct acl_entry_link *)
2364 malloc(sizeof(struct acl_entry_link));
2366 if(acl_entry_link->nextp == NULL) {
2367 SAFE_FREE(file_acl);
2368 errno = ENOMEM;
2369 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2370 return(NULL);
2373 acl_entry_link->nextp->prevp = acl_entry_link;
2374 acl_entry_link = acl_entry_link->nextp;
2375 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
2376 if(acl_entry_link->entryp == NULL) {
2377 SAFE_FREE(file_acl);
2378 errno = ENOMEM;
2379 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2380 return(NULL);
2382 acl_entry_link->nextp = NULL;
2385 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
2387 /* Don't really need this since all types are going *
2388 * to be specified but, it's better than leaving it 0 */
2390 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
2392 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2394 memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
2396 /* The access in the acl entries must be left shifted by *
2397 * three bites, because they will ultimately be compared *
2398 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2400 switch(acl_entry->ace_type){
2401 case ACC_PERMIT:
2402 case ACC_SPECIFY:
2403 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2404 acl_entry_link->entryp->ace_access <<= 6;
2405 acl_entry_link_head->count++;
2406 break;
2407 case ACC_DENY:
2408 /* Since there is no way to return a DENY acl entry *
2409 * change to PERMIT and then shift. */
2410 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
2411 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
2412 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
2413 acl_entry_link->entryp->ace_access <<= 6;
2414 acl_entry_link_head->count++;
2415 break;
2416 default:
2417 return(0);
2420 DEBUG(10,("acl_entry = %d\n",acl_entry));
2421 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
2423 acl_entry = acl_nxt(acl_entry);
2425 } /* end of if enabled */
2427 /* Since owner, group, other acl entries are not *
2428 * part of the acl entries in an acl, they must *
2429 * be dummied up to become part of the list. */
2431 for( i = 1; i < 4; i++) {
2432 DEBUG(10,("i is %d\n",i));
2433 if(acl_entry_link_head->count != 0) {
2434 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
2435 if(acl_entry_link->nextp == NULL) {
2436 SAFE_FREE(file_acl);
2437 errno = ENOMEM;
2438 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2439 return(NULL);
2442 acl_entry_link->nextp->prevp = acl_entry_link;
2443 acl_entry_link = acl_entry_link->nextp;
2444 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
2445 if(acl_entry_link->entryp == NULL) {
2446 SAFE_FREE(file_acl);
2447 errno = ENOMEM;
2448 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2449 return(NULL);
2453 acl_entry_link->nextp = NULL;
2455 new_acl_entry = acl_entry_link->entryp;
2456 idp = new_acl_entry->ace_id;
2458 new_acl_entry->ace_len = sizeof(struct acl_entry);
2459 new_acl_entry->ace_type = ACC_PERMIT;
2460 idp->id_len = sizeof(struct ace_id);
2461 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
2462 memset(idp->id_data,0,sizeof(uid_t));
2464 switch(i) {
2465 case 2:
2466 new_acl_entry->ace_access = file_acl->g_access << 6;
2467 idp->id_type = SMB_ACL_GROUP_OBJ;
2468 break;
2470 case 3:
2471 new_acl_entry->ace_access = file_acl->o_access << 6;
2472 idp->id_type = SMB_ACL_OTHER;
2473 break;
2475 case 1:
2476 new_acl_entry->ace_access = file_acl->u_access << 6;
2477 idp->id_type = SMB_ACL_USER_OBJ;
2478 break;
2480 default:
2481 return(NULL);
2485 acl_entry_link_head->count++;
2486 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
2489 acl_entry_link_head->count = 0;
2490 SAFE_FREE(file_acl);
2492 return(acl_entry_link_head);
2495 SMB_ACL_T sys_acl_get_fd(int fd)
2497 struct acl *file_acl = (struct acl *)NULL;
2498 struct acl_entry *acl_entry;
2499 struct new_acl_entry *new_acl_entry;
2500 struct ace_id *idp;
2501 struct acl_entry_link *acl_entry_link;
2502 struct acl_entry_link *acl_entry_link_head;
2503 int i;
2504 int rc = 0;
2505 uid_t user_id;
2507 /* Get the acl using fstatacl */
2509 DEBUG(10,("Entering sys_acl_get_fd\n"));
2510 DEBUG(10,("fd is %d\n",fd));
2511 file_acl = (struct acl *)malloc(BUFSIZ);
2513 if(file_acl == NULL) {
2514 errno=ENOMEM;
2515 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2516 return(NULL);
2519 memset(file_acl,0,BUFSIZ);
2521 rc = fstatacl(fd,0,file_acl,BUFSIZ);
2522 if(rc == -1) {
2523 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
2524 SAFE_FREE(file_acl);
2525 return(NULL);
2528 DEBUG(10,("Got facl and returned it\n"));
2530 /* Point to the first acl entry in the acl */
2532 acl_entry = file_acl->acl_ext;
2533 /* Begin setting up the head of the linked list *
2534 * that will be used for the storing the acl *
2535 * in a way that is useful for the posix_acls.c *
2536 * code. */
2538 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
2539 if(acl_entry_link_head == NULL){
2540 SAFE_FREE(file_acl);
2541 return(NULL);
2544 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
2546 if(acl_entry_link->entryp == NULL) {
2547 errno = ENOMEM;
2548 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2549 SAFE_FREE(file_acl);
2550 return(NULL);
2553 DEBUG(10,("acl_entry is %d\n",acl_entry));
2554 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
2556 /* Check if the extended acl bit is on. *
2557 * If it isn't, do not show the *
2558 * contents of the acl since AIX intends *
2559 * the extended info to remain unused */
2561 if(file_acl->acl_mode & S_IXACL){
2562 /* while we are not pointing to the very end */
2563 while(acl_entry < acl_last(file_acl)) {
2564 /* before we malloc anything, make sure this is */
2565 /* a valid acl entry and one that we want to map */
2567 idp = id_nxt(acl_entry->ace_id);
2568 if((acl_entry->ace_type == ACC_SPECIFY ||
2569 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
2570 acl_entry = acl_nxt(acl_entry);
2571 continue;
2574 idp = acl_entry->ace_id;
2576 /* Check if this is the first entry in the linked list. *
2577 * The first entry needs to keep prevp pointing to NULL *
2578 * and already has entryp allocated. */
2580 if(acl_entry_link_head->count != 0) {
2581 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
2582 if(acl_entry_link->nextp == NULL) {
2583 errno = ENOMEM;
2584 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2585 SAFE_FREE(file_acl);
2586 return(NULL);
2588 acl_entry_link->nextp->prevp = acl_entry_link;
2589 acl_entry_link = acl_entry_link->nextp;
2590 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
2591 if(acl_entry_link->entryp == NULL) {
2592 errno = ENOMEM;
2593 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2594 SAFE_FREE(file_acl);
2595 return(NULL);
2598 acl_entry_link->nextp = NULL;
2601 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
2603 /* Don't really need this since all types are going *
2604 * to be specified but, it's better than leaving it 0 */
2606 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
2607 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2609 memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
2611 /* The access in the acl entries must be left shifted by *
2612 * three bites, because they will ultimately be compared *
2613 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2615 switch(acl_entry->ace_type){
2616 case ACC_PERMIT:
2617 case ACC_SPECIFY:
2618 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2619 acl_entry_link->entryp->ace_access <<= 6;
2620 acl_entry_link_head->count++;
2621 break;
2622 case ACC_DENY:
2623 /* Since there is no way to return a DENY acl entry *
2624 * change to PERMIT and then shift. */
2625 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
2626 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
2627 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
2628 acl_entry_link->entryp->ace_access <<= 6;
2629 acl_entry_link_head->count++;
2630 break;
2631 default:
2632 return(0);
2635 DEBUG(10,("acl_entry = %d\n",acl_entry));
2636 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
2638 acl_entry = acl_nxt(acl_entry);
2640 } /* end of if enabled */
2642 /* Since owner, group, other acl entries are not *
2643 * part of the acl entries in an acl, they must *
2644 * be dummied up to become part of the list. */
2646 for( i = 1; i < 4; i++) {
2647 DEBUG(10,("i is %d\n",i));
2648 if(acl_entry_link_head->count != 0){
2649 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
2650 if(acl_entry_link->nextp == NULL) {
2651 errno = ENOMEM;
2652 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2653 SAFE_FREE(file_acl);
2654 return(NULL);
2657 acl_entry_link->nextp->prevp = acl_entry_link;
2658 acl_entry_link = acl_entry_link->nextp;
2659 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
2661 if(acl_entry_link->entryp == NULL) {
2662 SAFE_FREE(file_acl);
2663 errno = ENOMEM;
2664 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2665 return(NULL);
2669 acl_entry_link->nextp = NULL;
2671 new_acl_entry = acl_entry_link->entryp;
2672 idp = new_acl_entry->ace_id;
2674 new_acl_entry->ace_len = sizeof(struct acl_entry);
2675 new_acl_entry->ace_type = ACC_PERMIT;
2676 idp->id_len = sizeof(struct ace_id);
2677 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
2678 memset(idp->id_data,0,sizeof(uid_t));
2680 switch(i) {
2681 case 2:
2682 new_acl_entry->ace_access = file_acl->g_access << 6;
2683 idp->id_type = SMB_ACL_GROUP_OBJ;
2684 break;
2686 case 3:
2687 new_acl_entry->ace_access = file_acl->o_access << 6;
2688 idp->id_type = SMB_ACL_OTHER;
2689 break;
2691 case 1:
2692 new_acl_entry->ace_access = file_acl->u_access << 6;
2693 idp->id_type = SMB_ACL_USER_OBJ;
2694 break;
2696 default:
2697 return(NULL);
2700 acl_entry_link_head->count++;
2701 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
2704 acl_entry_link_head->count = 0;
2705 SAFE_FREE(file_acl);
2707 return(acl_entry_link_head);
2710 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
2712 *permset = *permset & ~0777;
2713 return(0);
2716 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2718 if((perm != 0) &&
2719 (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0)
2720 return(-1);
2722 *permset |= perm;
2723 DEBUG(10,("This is the permset now: %d\n",*permset));
2724 return(0);
2727 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
2729 return(NULL);
2732 SMB_ACL_T sys_acl_init( int count)
2734 struct acl_entry_link *theacl = NULL;
2736 DEBUG(10,("Entering sys_acl_init\n"));
2738 theacl = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
2739 if(theacl == NULL) {
2740 errno = ENOMEM;
2741 DEBUG(0,("Error in sys_acl_init is %d\n",errno));
2742 return(NULL);
2745 theacl->count = 0;
2746 theacl->nextp = NULL;
2747 theacl->prevp = NULL;
2748 theacl->entryp = NULL;
2749 DEBUG(10,("Exiting sys_acl_init\n"));
2750 return(theacl);
2753 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2755 struct acl_entry_link *theacl;
2756 struct acl_entry_link *acl_entryp;
2757 struct acl_entry_link *temp_entry;
2758 int counting;
2760 DEBUG(10,("Entering the sys_acl_create_entry\n"));
2762 theacl = acl_entryp = *pacl;
2764 /* Get to the end of the acl before adding entry */
2766 for(counting=0; counting < theacl->count; counting++){
2767 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
2768 temp_entry = acl_entryp;
2769 acl_entryp = acl_entryp->nextp;
2772 if(theacl->count != 0){
2773 temp_entry->nextp = acl_entryp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
2774 if(acl_entryp == NULL) {
2775 errno = ENOMEM;
2776 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
2777 return(-1);
2780 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
2781 acl_entryp->prevp = temp_entry;
2782 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
2785 *pentry = acl_entryp->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
2786 if(*pentry == NULL) {
2787 errno = ENOMEM;
2788 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
2789 return(-1);
2792 memset(*pentry,0,sizeof(struct new_acl_entry));
2793 acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
2794 acl_entryp->entryp->ace_type = ACC_PERMIT;
2795 acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
2796 acl_entryp->nextp = NULL;
2797 theacl->count++;
2798 DEBUG(10,("Exiting sys_acl_create_entry\n"));
2799 return(0);
2802 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2804 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
2805 entry->ace_id->id_type = tagtype;
2806 DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
2807 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
2810 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
2812 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
2813 memcpy(entry->ace_id->id_data,qual,sizeof(uid_t));
2814 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
2815 return(0);
2818 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2820 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
2821 if(!(*permset & S_IXUSR) &&
2822 !(*permset & S_IWUSR) &&
2823 !(*permset & S_IRUSR) &&
2824 (*permset != 0))
2825 return(-1);
2827 entry->ace_access = *permset;
2828 DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
2829 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
2830 return(0);
2833 int sys_acl_valid( SMB_ACL_T theacl )
2835 int user_obj = 0;
2836 int group_obj = 0;
2837 int other_obj = 0;
2838 struct acl_entry_link *acl_entry;
2840 for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
2841 user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
2842 group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
2843 other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
2846 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
2848 if(user_obj != 1 || group_obj != 1 || other_obj != 1)
2849 return(-1);
2851 return(0);
2854 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2856 struct acl_entry_link *acl_entry_link = NULL;
2857 struct acl *file_acl = NULL;
2858 struct acl *file_acl_temp = NULL;
2859 struct acl_entry *acl_entry = NULL;
2860 struct ace_id *ace_id = NULL;
2861 uint id_type;
2862 uint ace_access;
2863 uint user_id;
2864 uint acl_length;
2865 uint rc;
2867 DEBUG(10,("Entering sys_acl_set_file\n"));
2868 DEBUG(10,("File name is %s\n",name));
2870 /* AIX has no default ACL */
2871 if(acltype == SMB_ACL_TYPE_DEFAULT)
2872 return(0);
2874 acl_length = BUFSIZ;
2875 file_acl = (struct acl *)malloc(BUFSIZ);
2877 if(file_acl == NULL) {
2878 errno = ENOMEM;
2879 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2880 return(-1);
2883 memset(file_acl,0,BUFSIZ);
2885 file_acl->acl_len = ACL_SIZ;
2886 file_acl->acl_mode = S_IXACL;
2888 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2889 acl_entry_link->entryp->ace_access >>= 6;
2890 id_type = acl_entry_link->entryp->ace_id->id_type;
2892 switch(id_type) {
2893 case SMB_ACL_USER_OBJ:
2894 file_acl->u_access = acl_entry_link->entryp->ace_access;
2895 continue;
2896 case SMB_ACL_GROUP_OBJ:
2897 file_acl->g_access = acl_entry_link->entryp->ace_access;
2898 continue;
2899 case SMB_ACL_OTHER:
2900 file_acl->o_access = acl_entry_link->entryp->ace_access;
2901 continue;
2902 case SMB_ACL_MASK:
2903 continue;
2906 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2907 acl_length += sizeof(struct acl_entry);
2908 file_acl_temp = (struct acl *)malloc(acl_length);
2909 if(file_acl_temp == NULL) {
2910 SAFE_FREE(file_acl);
2911 errno = ENOMEM;
2912 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2913 return(-1);
2916 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2917 SAFE_FREE(file_acl);
2918 file_acl = file_acl_temp;
2921 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2922 file_acl->acl_len += sizeof(struct acl_entry);
2923 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2924 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2926 /* In order to use this, we'll need to wait until we can get denies */
2927 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2928 acl_entry->ace_type = ACC_SPECIFY; */
2930 acl_entry->ace_type = ACC_SPECIFY;
2932 ace_id = acl_entry->ace_id;
2934 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2935 DEBUG(10,("The id type is %d\n",ace_id->id_type));
2936 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2937 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2938 memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
2941 rc = chacl(name,file_acl,file_acl->acl_len);
2942 DEBUG(10,("errno is %d\n",errno));
2943 DEBUG(10,("return code is %d\n",rc));
2944 SAFE_FREE(file_acl);
2945 DEBUG(10,("Exiting the sys_acl_set_file\n"));
2946 return(rc);
2949 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2951 struct acl_entry_link *acl_entry_link = NULL;
2952 struct acl *file_acl = NULL;
2953 struct acl *file_acl_temp = NULL;
2954 struct acl_entry *acl_entry = NULL;
2955 struct ace_id *ace_id = NULL;
2956 uint id_type;
2957 uint user_id;
2958 uint acl_length;
2959 uint rc;
2961 DEBUG(10,("Entering sys_acl_set_fd\n"));
2962 acl_length = BUFSIZ;
2963 file_acl = (struct acl *)malloc(BUFSIZ);
2965 if(file_acl == NULL) {
2966 errno = ENOMEM;
2967 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2968 return(-1);
2971 memset(file_acl,0,BUFSIZ);
2973 file_acl->acl_len = ACL_SIZ;
2974 file_acl->acl_mode = S_IXACL;
2976 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2977 acl_entry_link->entryp->ace_access >>= 6;
2978 id_type = acl_entry_link->entryp->ace_id->id_type;
2979 DEBUG(10,("The id_type is %d\n",id_type));
2981 switch(id_type) {
2982 case SMB_ACL_USER_OBJ:
2983 file_acl->u_access = acl_entry_link->entryp->ace_access;
2984 continue;
2985 case SMB_ACL_GROUP_OBJ:
2986 file_acl->g_access = acl_entry_link->entryp->ace_access;
2987 continue;
2988 case SMB_ACL_OTHER:
2989 file_acl->o_access = acl_entry_link->entryp->ace_access;
2990 continue;
2991 case SMB_ACL_MASK:
2992 continue;
2995 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2996 acl_length += sizeof(struct acl_entry);
2997 file_acl_temp = (struct acl *)malloc(acl_length);
2998 if(file_acl_temp == NULL) {
2999 SAFE_FREE(file_acl);
3000 errno = ENOMEM;
3001 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
3002 return(-1);
3005 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
3006 SAFE_FREE(file_acl);
3007 file_acl = file_acl_temp;
3010 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
3011 file_acl->acl_len += sizeof(struct acl_entry);
3012 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
3013 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
3015 /* In order to use this, we'll need to wait until we can get denies */
3016 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
3017 acl_entry->ace_type = ACC_SPECIFY; */
3019 acl_entry->ace_type = ACC_SPECIFY;
3021 ace_id = acl_entry->ace_id;
3023 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
3024 DEBUG(10,("The id type is %d\n",ace_id->id_type));
3025 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
3026 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
3027 memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
3030 rc = fchacl(fd,file_acl,file_acl->acl_len);
3031 DEBUG(10,("errno is %d\n",errno));
3032 DEBUG(10,("return code is %d\n",rc));
3033 SAFE_FREE(file_acl);
3034 DEBUG(10,("Exiting sys_acl_set_fd\n"));
3035 return(rc);
3038 int sys_acl_delete_def_file(const char *name)
3040 /* AIX has no default ACL */
3041 return 0;
3044 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
3046 return(*permset & perm);
3049 int sys_acl_free_text(char *text)
3051 return(0);
3054 int sys_acl_free_acl(SMB_ACL_T posix_acl)
3056 struct acl_entry_link *acl_entry_link;
3058 for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
3059 SAFE_FREE(acl_entry_link->prevp->entryp);
3060 SAFE_FREE(acl_entry_link->prevp);
3063 SAFE_FREE(acl_entry_link->prevp->entryp);
3064 SAFE_FREE(acl_entry_link->prevp);
3065 SAFE_FREE(acl_entry_link->entryp);
3066 SAFE_FREE(acl_entry_link);
3068 return(0);
3071 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
3073 return(0);
3076 #else /* No ACLs. */
3078 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
3080 errno = ENOSYS;
3081 return -1;
3084 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
3086 errno = ENOSYS;
3087 return -1;
3090 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
3092 errno = ENOSYS;
3093 return -1;
3096 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
3098 errno = ENOSYS;
3099 return NULL;
3102 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
3104 errno = ENOSYS;
3105 return (SMB_ACL_T)NULL;
3108 SMB_ACL_T sys_acl_get_fd(int fd)
3110 errno = ENOSYS;
3111 return (SMB_ACL_T)NULL;
3114 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
3116 errno = ENOSYS;
3117 return -1;
3120 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
3122 errno = ENOSYS;
3123 return -1;
3126 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
3128 errno = ENOSYS;
3129 return (permset & perm) ? 1 : 0;
3132 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
3134 errno = ENOSYS;
3135 return NULL;
3138 int sys_acl_free_text(char *text)
3140 errno = ENOSYS;
3141 return -1;
3144 SMB_ACL_T sys_acl_init( int count)
3146 errno = ENOSYS;
3147 return NULL;
3150 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
3152 errno = ENOSYS;
3153 return -1;
3156 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
3158 errno = ENOSYS;
3159 return -1;
3162 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
3164 errno = ENOSYS;
3165 return -1;
3168 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
3170 errno = ENOSYS;
3171 return -1;
3174 int sys_acl_valid( SMB_ACL_T theacl )
3176 errno = ENOSYS;
3177 return -1;
3180 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
3182 errno = ENOSYS;
3183 return -1;
3186 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
3188 errno = ENOSYS;
3189 return -1;
3192 int sys_acl_delete_def_file(const char *name)
3194 errno = ENOSYS;
3195 return -1;
3198 int sys_acl_free_acl(SMB_ACL_T the_acl)
3200 errno = ENOSYS;
3201 return -1;
3204 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
3206 errno = ENOSYS;
3207 return -1;
3210 #endif /* No ACLs. */