r15566: Fix Coverity bug # 284. The lp_ldap_xx_suffix function only return NULL if
[Samba/bb.git] / source3 / lib / sysacls.c
blob36baf96016cdfbff2cb6274c456128a8609d7869
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"
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_ACLS
27 This file wraps all differing system ACL interfaces into a consistent
28 one based on the POSIX interface. It also returns the correct errors
29 for older UNIX systems that don't support ACLs.
31 The interfaces that each ACL implementation must support are as follows :
33 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
34 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
35 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p
36 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
37 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
38 SMB_ACL_T sys_acl_get_fd(int fd)
39 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
40 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
41 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
42 SMB_ACL_T sys_acl_init( int count)
43 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
44 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
45 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
46 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
47 int sys_acl_valid( SMB_ACL_T theacl )
48 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
49 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
50 int sys_acl_delete_def_file(const char *path)
52 This next one is not POSIX complient - but we *have* to have it !
53 More POSIX braindamage.
55 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
57 The generic POSIX free is the following call. We split this into
58 several different free functions as we may need to add tag info
59 to structures when emulating the POSIX interface.
61 int sys_acl_free( void *obj_p)
63 The calls we actually use are :
65 int sys_acl_free_text(char *text) - free acl_to_text
66 int sys_acl_free_acl(SMB_ACL_T posix_acl)
67 int sys_acl_free_qualifier(void *qualifier, SMB_ACL_TAG_T tagtype)
71 #if defined(HAVE_POSIX_ACLS)
73 /* Identity mapping - easy. */
75 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
77 return acl_get_entry( the_acl, entry_id, entry_p);
80 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
82 return acl_get_tag_type( entry_d, tag_type_p);
85 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
87 return acl_get_permset( entry_d, permset_p);
90 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
92 return acl_get_qualifier( entry_d);
95 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
97 return acl_get_file( path_p, type);
100 SMB_ACL_T sys_acl_get_fd(int fd)
102 return acl_get_fd(fd);
105 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
107 return acl_clear_perms(permset);
110 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
112 return acl_add_perm(permset, perm);
115 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
117 #if defined(HAVE_ACL_GET_PERM_NP)
119 * Required for TrustedBSD-based ACL implementations where
120 * non-POSIX.1e functions are denoted by a _np (non-portable)
121 * suffix.
123 return acl_get_perm_np(permset, perm);
124 #else
125 return acl_get_perm(permset, perm);
126 #endif
129 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
131 return acl_to_text( the_acl, plen);
134 SMB_ACL_T sys_acl_init( int count)
136 return acl_init(count);
139 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
141 return acl_create_entry(pacl, pentry);
144 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
146 return acl_set_tag_type(entry, tagtype);
149 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
151 return acl_set_qualifier(entry, qual);
154 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
156 return acl_set_permset(entry, permset);
159 int sys_acl_valid( SMB_ACL_T theacl )
161 return acl_valid(theacl);
164 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
166 return acl_set_file(name, acltype, theacl);
169 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
171 return acl_set_fd(fd, theacl);
174 int sys_acl_delete_def_file(const char *name)
176 return acl_delete_def_file(name);
179 int sys_acl_free_text(char *text)
181 return acl_free(text);
184 int sys_acl_free_acl(SMB_ACL_T the_acl)
186 return acl_free(the_acl);
189 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
191 return acl_free(qual);
194 #elif defined(HAVE_TRU64_ACLS)
196 * The interface to DEC/Compaq Tru64 UNIX ACLs
197 * is based on Draft 13 of the POSIX spec which is
198 * slightly different from the Draft 16 interface.
200 * Also, some of the permset manipulation functions
201 * such as acl_clear_perm() and acl_add_perm() appear
202 * to be broken on Tru64 so we have to manipulate
203 * the permission bits in the permset directly.
205 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
207 SMB_ACL_ENTRY_T entry;
209 if (entry_id == SMB_ACL_FIRST_ENTRY && acl_first_entry(the_acl) != 0) {
210 return -1;
213 errno = 0;
214 if ((entry = acl_get_entry(the_acl)) != NULL) {
215 *entry_p = entry;
216 return 1;
219 return errno ? -1 : 0;
222 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
224 return acl_get_tag_type( entry_d, tag_type_p);
227 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
229 return acl_get_permset( entry_d, permset_p);
232 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
234 return acl_get_qualifier( entry_d);
237 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
239 return acl_get_file((char *)path_p, type);
242 SMB_ACL_T sys_acl_get_fd(int fd)
244 return acl_get_fd(fd, ACL_TYPE_ACCESS);
247 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
249 *permset = 0; /* acl_clear_perm() is broken on Tru64 */
251 return 0;
254 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
256 if (perm & ~(SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE)) {
257 errno = EINVAL;
258 return -1;
261 *permset |= perm; /* acl_add_perm() is broken on Tru64 */
263 return 0;
266 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
268 return *permset & perm; /* Tru64 doesn't have acl_get_perm() */
271 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
273 return acl_to_text( the_acl, plen);
276 SMB_ACL_T sys_acl_init( int count)
278 return acl_init(count);
281 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
283 SMB_ACL_ENTRY_T entry;
285 if ((entry = acl_create_entry(pacl)) == NULL) {
286 return -1;
289 *pentry = entry;
290 return 0;
293 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
295 return acl_set_tag_type(entry, tagtype);
298 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
300 return acl_set_qualifier(entry, qual);
303 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
305 return acl_set_permset(entry, permset);
308 int sys_acl_valid( SMB_ACL_T theacl )
310 acl_entry_t entry;
312 return acl_valid(theacl, &entry);
315 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
317 return acl_set_file((char *)name, acltype, theacl);
320 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
322 return acl_set_fd(fd, ACL_TYPE_ACCESS, theacl);
325 int sys_acl_delete_def_file(const char *name)
327 return acl_delete_def_file((char *)name);
330 int sys_acl_free_text(char *text)
333 * (void) cast and explicit return 0 are for DEC UNIX
334 * which just #defines acl_free_text() to be free()
336 (void) acl_free_text(text);
337 return 0;
340 int sys_acl_free_acl(SMB_ACL_T the_acl)
342 return acl_free(the_acl);
345 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
347 return acl_free_qualifier(qual, tagtype);
350 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
353 * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
354 * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
358 * Note that while this code implements sufficient functionality
359 * to support the sys_acl_* interfaces it does not provide all
360 * of the semantics of the POSIX ACL interfaces.
362 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
363 * from a call to sys_acl_get_entry() should not be assumed to be
364 * valid after calling any of the following functions, which may
365 * reorder the entries in the ACL.
367 * sys_acl_valid()
368 * sys_acl_set_file()
369 * sys_acl_set_fd()
373 * The only difference between Solaris and UnixWare / OpenUNIX is
374 * that the #defines for the ACL operations have different names
376 #if defined(HAVE_UNIXWARE_ACLS)
378 #define SETACL ACL_SET
379 #define GETACL ACL_GET
380 #define GETACLCNT ACL_CNT
382 #endif
385 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
387 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
388 errno = EINVAL;
389 return -1;
392 if (entry_p == NULL) {
393 errno = EINVAL;
394 return -1;
397 if (entry_id == SMB_ACL_FIRST_ENTRY) {
398 acl_d->next = 0;
401 if (acl_d->next < 0) {
402 errno = EINVAL;
403 return -1;
406 if (acl_d->next >= acl_d->count) {
407 return 0;
410 *entry_p = &acl_d->acl[acl_d->next++];
412 return 1;
415 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
417 *type_p = entry_d->a_type;
419 return 0;
422 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
424 *permset_p = &entry_d->a_perm;
426 return 0;
429 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
431 if (entry_d->a_type != SMB_ACL_USER
432 && entry_d->a_type != SMB_ACL_GROUP) {
433 errno = EINVAL;
434 return NULL;
437 return &entry_d->a_id;
441 * There is no way of knowing what size the ACL returned by
442 * GETACL will be unless you first call GETACLCNT which means
443 * making an additional system call.
445 * In the hope of avoiding the cost of the additional system
446 * call in most cases, we initially allocate enough space for
447 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
448 * be too small then we use GETACLCNT to find out the actual
449 * size, reallocate the ACL buffer, and then call GETACL again.
452 #define INITIAL_ACL_SIZE 16
454 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
456 SMB_ACL_T acl_d;
457 int count; /* # of ACL entries allocated */
458 int naccess; /* # of access ACL entries */
459 int ndefault; /* # of default ACL entries */
461 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
462 errno = EINVAL;
463 return NULL;
466 count = INITIAL_ACL_SIZE;
467 if ((acl_d = sys_acl_init(count)) == NULL) {
468 return NULL;
472 * If there isn't enough space for the ACL entries we use
473 * GETACLCNT to determine the actual number of ACL entries
474 * reallocate and try again. This is in a loop because it
475 * is possible that someone else could modify the ACL and
476 * increase the number of entries between the call to
477 * GETACLCNT and the call to GETACL.
479 while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0
480 && errno == ENOSPC) {
482 sys_acl_free_acl(acl_d);
484 if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) {
485 return NULL;
488 if ((acl_d = sys_acl_init(count)) == NULL) {
489 return NULL;
493 if (count < 0) {
494 sys_acl_free_acl(acl_d);
495 return NULL;
499 * calculate the number of access and default ACL entries
501 * Note: we assume that the acl() system call returned a
502 * well formed ACL which is sorted so that all of the
503 * access ACL entries preceed any default ACL entries
505 for (naccess = 0; naccess < count; naccess++) {
506 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
507 break;
509 ndefault = count - naccess;
512 * if the caller wants the default ACL we have to copy
513 * the entries down to the start of the acl[] buffer
514 * and mask out the ACL_DEFAULT flag from the type field
516 if (type == SMB_ACL_TYPE_DEFAULT) {
517 int i, j;
519 for (i = 0, j = naccess; i < ndefault; i++, j++) {
520 acl_d->acl[i] = acl_d->acl[j];
521 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
524 acl_d->count = ndefault;
525 } else {
526 acl_d->count = naccess;
529 return acl_d;
532 SMB_ACL_T sys_acl_get_fd(int fd)
534 SMB_ACL_T acl_d;
535 int count; /* # of ACL entries allocated */
536 int naccess; /* # of access ACL entries */
538 count = INITIAL_ACL_SIZE;
539 if ((acl_d = sys_acl_init(count)) == NULL) {
540 return NULL;
543 while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0
544 && errno == ENOSPC) {
546 sys_acl_free_acl(acl_d);
548 if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) {
549 return NULL;
552 if ((acl_d = sys_acl_init(count)) == NULL) {
553 return NULL;
557 if (count < 0) {
558 sys_acl_free_acl(acl_d);
559 return NULL;
563 * calculate the number of access ACL entries
565 for (naccess = 0; naccess < count; naccess++) {
566 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
567 break;
570 acl_d->count = naccess;
572 return acl_d;
575 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
577 *permset_d = 0;
579 return 0;
582 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
584 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
585 && perm != SMB_ACL_EXECUTE) {
586 errno = EINVAL;
587 return -1;
590 if (permset_d == NULL) {
591 errno = EINVAL;
592 return -1;
595 *permset_d |= perm;
597 return 0;
600 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
602 return *permset_d & perm;
605 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
607 int i;
608 int len, maxlen;
609 char *text;
612 * use an initial estimate of 20 bytes per ACL entry
613 * when allocating memory for the text representation
614 * of the ACL
616 len = 0;
617 maxlen = 20 * acl_d->count;
618 if ((text = SMB_MALLOC(maxlen)) == NULL) {
619 errno = ENOMEM;
620 return NULL;
623 for (i = 0; i < acl_d->count; i++) {
624 struct acl *ap = &acl_d->acl[i];
625 struct passwd *pw;
626 struct group *gr;
627 char tagbuf[12];
628 char idbuf[12];
629 char *tag;
630 char *id = "";
631 char perms[4];
632 int nbytes;
634 switch (ap->a_type) {
636 * for debugging purposes it's probably more
637 * useful to dump unknown tag types rather
638 * than just returning an error
640 default:
641 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
642 ap->a_type);
643 tag = tagbuf;
644 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
645 (long)ap->a_id);
646 id = idbuf;
647 break;
649 case SMB_ACL_USER:
650 id = uidtoname(ap->a_id);
651 case SMB_ACL_USER_OBJ:
652 tag = "user";
653 break;
655 case SMB_ACL_GROUP:
656 if ((gr = getgrgid(ap->a_id)) == NULL) {
657 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
658 (long)ap->a_id);
659 id = idbuf;
660 } else {
661 id = gr->gr_name;
663 case SMB_ACL_GROUP_OBJ:
664 tag = "group";
665 break;
667 case SMB_ACL_OTHER:
668 tag = "other";
669 break;
671 case SMB_ACL_MASK:
672 tag = "mask";
673 break;
677 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
678 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
679 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
680 perms[3] = '\0';
682 /* <tag> : <qualifier> : rwx \n \0 */
683 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
686 * If this entry would overflow the buffer
687 * allocate enough additional memory for this
688 * entry and an estimate of another 20 bytes
689 * for each entry still to be processed
691 if ((len + nbytes) > maxlen) {
692 maxlen += nbytes + 20 * (acl_d->count - i);
693 if ((text = SMB_REALLOC(text, maxlen)) == NULL) {
694 errno = ENOMEM;
695 return NULL;
699 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
700 len += nbytes - 1;
703 if (len_p)
704 *len_p = len;
706 return text;
709 SMB_ACL_T sys_acl_init(int count)
711 SMB_ACL_T a;
713 if (count < 0) {
714 errno = EINVAL;
715 return NULL;
719 * note that since the definition of the structure pointed
720 * to by the SMB_ACL_T includes the first element of the
721 * acl[] array, this actually allocates an ACL with room
722 * for (count+1) entries
724 if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
725 errno = ENOMEM;
726 return NULL;
729 a->size = count + 1;
730 a->count = 0;
731 a->next = -1;
733 return a;
737 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
739 SMB_ACL_T acl_d;
740 SMB_ACL_ENTRY_T entry_d;
742 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
743 errno = EINVAL;
744 return -1;
747 if (acl_d->count >= acl_d->size) {
748 errno = ENOSPC;
749 return -1;
752 entry_d = &acl_d->acl[acl_d->count++];
753 entry_d->a_type = 0;
754 entry_d->a_id = -1;
755 entry_d->a_perm = 0;
756 *entry_p = entry_d;
758 return 0;
761 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
763 switch (tag_type) {
764 case SMB_ACL_USER:
765 case SMB_ACL_USER_OBJ:
766 case SMB_ACL_GROUP:
767 case SMB_ACL_GROUP_OBJ:
768 case SMB_ACL_OTHER:
769 case SMB_ACL_MASK:
770 entry_d->a_type = tag_type;
771 break;
772 default:
773 errno = EINVAL;
774 return -1;
777 return 0;
780 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
782 if (entry_d->a_type != SMB_ACL_GROUP
783 && entry_d->a_type != SMB_ACL_USER) {
784 errno = EINVAL;
785 return -1;
788 entry_d->a_id = *((id_t *)qual_p);
790 return 0;
793 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
795 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
796 return EINVAL;
799 entry_d->a_perm = *permset_d;
801 return 0;
805 * sort the ACL and check it for validity
807 * if it's a minimal ACL with only 4 entries then we
808 * need to recalculate the mask permissions to make
809 * sure that they are the same as the GROUP_OBJ
810 * permissions as required by the UnixWare acl() system call.
812 * (note: since POSIX allows minimal ACLs which only contain
813 * 3 entries - ie there is no mask entry - we should, in theory,
814 * check for this and add a mask entry if necessary - however
815 * we "know" that the caller of this interface always specifies
816 * a mask so, in practice "this never happens" (tm) - if it *does*
817 * happen aclsort() will fail and return an error and someone will
818 * have to fix it ...)
821 static int acl_sort(SMB_ACL_T acl_d)
823 int fixmask = (acl_d->count <= 4);
825 if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {
826 errno = EINVAL;
827 return -1;
829 return 0;
832 int sys_acl_valid(SMB_ACL_T acl_d)
834 return acl_sort(acl_d);
837 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
839 struct stat s;
840 struct acl *acl_p;
841 int acl_count;
842 struct acl *acl_buf = NULL;
843 int ret;
845 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
846 errno = EINVAL;
847 return -1;
850 if (acl_sort(acl_d) != 0) {
851 return -1;
854 acl_p = &acl_d->acl[0];
855 acl_count = acl_d->count;
858 * if it's a directory there is extra work to do
859 * since the acl() system call will replace both
860 * the access ACLs and the default ACLs (if any)
862 if (stat(name, &s) != 0) {
863 return -1;
865 if (S_ISDIR(s.st_mode)) {
866 SMB_ACL_T acc_acl;
867 SMB_ACL_T def_acl;
868 SMB_ACL_T tmp_acl;
869 int i;
871 if (type == SMB_ACL_TYPE_ACCESS) {
872 acc_acl = acl_d;
873 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
875 } else {
876 def_acl = acl_d;
877 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
880 if (tmp_acl == NULL) {
881 return -1;
885 * allocate a temporary buffer for the complete ACL
887 acl_count = acc_acl->count + def_acl->count;
888 acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
890 if (acl_buf == NULL) {
891 sys_acl_free_acl(tmp_acl);
892 errno = ENOMEM;
893 return -1;
897 * copy the access control and default entries into the buffer
899 memcpy(&acl_buf[0], &acc_acl->acl[0],
900 acc_acl->count * sizeof(acl_buf[0]));
902 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
903 def_acl->count * sizeof(acl_buf[0]));
906 * set the ACL_DEFAULT flag on the default entries
908 for (i = acc_acl->count; i < acl_count; i++) {
909 acl_buf[i].a_type |= ACL_DEFAULT;
912 sys_acl_free_acl(tmp_acl);
914 } else if (type != SMB_ACL_TYPE_ACCESS) {
915 errno = EINVAL;
916 return -1;
919 ret = acl(name, SETACL, acl_count, acl_p);
921 SAFE_FREE(acl_buf);
923 return ret;
926 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
928 if (acl_sort(acl_d) != 0) {
929 return -1;
932 return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
935 int sys_acl_delete_def_file(const char *path)
937 SMB_ACL_T acl_d;
938 int ret;
941 * fetching the access ACL and rewriting it has
942 * the effect of deleting the default ACL
944 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
945 return -1;
948 ret = acl(path, SETACL, acl_d->count, acl_d->acl);
950 sys_acl_free_acl(acl_d);
952 return ret;
955 int sys_acl_free_text(char *text)
957 SAFE_FREE(text);
958 return 0;
961 int sys_acl_free_acl(SMB_ACL_T acl_d)
963 SAFE_FREE(acl_d);
964 return 0;
967 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
969 return 0;
972 #elif defined(HAVE_HPUX_ACLS)
973 #include <dl.h>
976 * Based on the Solaris/SCO code - with modifications.
980 * Note that while this code implements sufficient functionality
981 * to support the sys_acl_* interfaces it does not provide all
982 * of the semantics of the POSIX ACL interfaces.
984 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
985 * from a call to sys_acl_get_entry() should not be assumed to be
986 * valid after calling any of the following functions, which may
987 * reorder the entries in the ACL.
989 * sys_acl_valid()
990 * sys_acl_set_file()
991 * sys_acl_set_fd()
994 /* This checks if the POSIX ACL system call is defined */
995 /* which basically corresponds to whether JFS 3.3 or */
996 /* higher is installed. If acl() was called when it */
997 /* isn't defined, it causes the process to core dump */
998 /* so it is important to check this and avoid acl() */
999 /* calls if it isn't there. */
1001 static BOOL hpux_acl_call_presence(void)
1004 shl_t handle = NULL;
1005 void *value;
1006 int ret_val=0;
1007 static BOOL already_checked=0;
1009 if(already_checked)
1010 return True;
1013 ret_val = shl_findsym(&handle, "acl", TYPE_PROCEDURE, &value);
1015 if(ret_val != 0) {
1016 DEBUG(5, ("hpux_acl_call_presence: shl_findsym() returned %d, errno = %d, error %s\n",
1017 ret_val, errno, strerror(errno)));
1018 DEBUG(5,("hpux_acl_call_presence: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
1019 return False;
1022 DEBUG(10,("hpux_acl_call_presence: acl() system call is present. We have JFS 3.3 or above \n"));
1024 already_checked = True;
1025 return True;
1028 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1030 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
1031 errno = EINVAL;
1032 return -1;
1035 if (entry_p == NULL) {
1036 errno = EINVAL;
1037 return -1;
1040 if (entry_id == SMB_ACL_FIRST_ENTRY) {
1041 acl_d->next = 0;
1044 if (acl_d->next < 0) {
1045 errno = EINVAL;
1046 return -1;
1049 if (acl_d->next >= acl_d->count) {
1050 return 0;
1053 *entry_p = &acl_d->acl[acl_d->next++];
1055 return 1;
1058 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
1060 *type_p = entry_d->a_type;
1062 return 0;
1065 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1067 *permset_p = &entry_d->a_perm;
1069 return 0;
1072 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
1074 if (entry_d->a_type != SMB_ACL_USER
1075 && entry_d->a_type != SMB_ACL_GROUP) {
1076 errno = EINVAL;
1077 return NULL;
1080 return &entry_d->a_id;
1084 * There is no way of knowing what size the ACL returned by
1085 * ACL_GET will be unless you first call ACL_CNT which means
1086 * making an additional system call.
1088 * In the hope of avoiding the cost of the additional system
1089 * call in most cases, we initially allocate enough space for
1090 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
1091 * be too small then we use ACL_CNT to find out the actual
1092 * size, reallocate the ACL buffer, and then call ACL_GET again.
1095 #define INITIAL_ACL_SIZE 16
1097 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
1099 SMB_ACL_T acl_d;
1100 int count; /* # of ACL entries allocated */
1101 int naccess; /* # of access ACL entries */
1102 int ndefault; /* # of default ACL entries */
1104 if(hpux_acl_call_presence() == False) {
1105 /* Looks like we don't have the acl() system call on HPUX.
1106 * May be the system doesn't have the latest version of JFS.
1108 return NULL;
1111 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
1112 errno = EINVAL;
1113 return NULL;
1116 count = INITIAL_ACL_SIZE;
1117 if ((acl_d = sys_acl_init(count)) == NULL) {
1118 return NULL;
1122 * If there isn't enough space for the ACL entries we use
1123 * ACL_CNT to determine the actual number of ACL entries
1124 * reallocate and try again. This is in a loop because it
1125 * is possible that someone else could modify the ACL and
1126 * increase the number of entries between the call to
1127 * ACL_CNT and the call to ACL_GET.
1129 while ((count = acl(path_p, ACL_GET, count, &acl_d->acl[0])) < 0 && errno == ENOSPC) {
1131 sys_acl_free_acl(acl_d);
1133 if ((count = acl(path_p, ACL_CNT, 0, NULL)) < 0) {
1134 return NULL;
1137 if ((acl_d = sys_acl_init(count)) == NULL) {
1138 return NULL;
1142 if (count < 0) {
1143 sys_acl_free_acl(acl_d);
1144 return NULL;
1148 * calculate the number of access and default ACL entries
1150 * Note: we assume that the acl() system call returned a
1151 * well formed ACL which is sorted so that all of the
1152 * access ACL entries preceed any default ACL entries
1154 for (naccess = 0; naccess < count; naccess++) {
1155 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
1156 break;
1158 ndefault = count - naccess;
1161 * if the caller wants the default ACL we have to copy
1162 * the entries down to the start of the acl[] buffer
1163 * and mask out the ACL_DEFAULT flag from the type field
1165 if (type == SMB_ACL_TYPE_DEFAULT) {
1166 int i, j;
1168 for (i = 0, j = naccess; i < ndefault; i++, j++) {
1169 acl_d->acl[i] = acl_d->acl[j];
1170 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
1173 acl_d->count = ndefault;
1174 } else {
1175 acl_d->count = naccess;
1178 return acl_d;
1181 SMB_ACL_T sys_acl_get_fd(int fd)
1184 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1187 files_struct *fsp = file_find_fd(fd);
1189 if (fsp == NULL) {
1190 errno = EBADF;
1191 return NULL;
1195 * We know we're in the same conn context. So we
1196 * can use the relative path.
1199 return sys_acl_get_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
1202 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
1204 *permset_d = 0;
1206 return 0;
1209 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1211 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
1212 && perm != SMB_ACL_EXECUTE) {
1213 errno = EINVAL;
1214 return -1;
1217 if (permset_d == NULL) {
1218 errno = EINVAL;
1219 return -1;
1222 *permset_d |= perm;
1224 return 0;
1227 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1229 return *permset_d & perm;
1232 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
1234 int i;
1235 int len, maxlen;
1236 char *text;
1239 * use an initial estimate of 20 bytes per ACL entry
1240 * when allocating memory for the text representation
1241 * of the ACL
1243 len = 0;
1244 maxlen = 20 * acl_d->count;
1245 if ((text = SMB_MALLOC(maxlen)) == NULL) {
1246 errno = ENOMEM;
1247 return NULL;
1250 for (i = 0; i < acl_d->count; i++) {
1251 struct acl *ap = &acl_d->acl[i];
1252 struct passwd *pw;
1253 struct group *gr;
1254 char tagbuf[12];
1255 char idbuf[12];
1256 char *tag;
1257 char *id = "";
1258 char perms[4];
1259 int nbytes;
1261 switch (ap->a_type) {
1263 * for debugging purposes it's probably more
1264 * useful to dump unknown tag types rather
1265 * than just returning an error
1267 default:
1268 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
1269 ap->a_type);
1270 tag = tagbuf;
1271 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
1272 (long)ap->a_id);
1273 id = idbuf;
1274 break;
1276 case SMB_ACL_USER:
1277 id = uidtoname(ap->a_id);
1278 case SMB_ACL_USER_OBJ:
1279 tag = "user";
1280 break;
1282 case SMB_ACL_GROUP:
1283 if ((gr = getgrgid(ap->a_id)) == NULL) {
1284 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
1285 (long)ap->a_id);
1286 id = idbuf;
1287 } else {
1288 id = gr->gr_name;
1290 case SMB_ACL_GROUP_OBJ:
1291 tag = "group";
1292 break;
1294 case SMB_ACL_OTHER:
1295 tag = "other";
1296 break;
1298 case SMB_ACL_MASK:
1299 tag = "mask";
1300 break;
1304 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
1305 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
1306 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
1307 perms[3] = '\0';
1309 /* <tag> : <qualifier> : rwx \n \0 */
1310 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
1313 * If this entry would overflow the buffer
1314 * allocate enough additional memory for this
1315 * entry and an estimate of another 20 bytes
1316 * for each entry still to be processed
1318 if ((len + nbytes) > maxlen) {
1319 maxlen += nbytes + 20 * (acl_d->count - i);
1320 if ((text = SMB_REALLOC(text, maxlen)) == NULL) {
1321 errno = ENOMEM;
1322 return NULL;
1326 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
1327 len += nbytes - 1;
1330 if (len_p)
1331 *len_p = len;
1333 return text;
1336 SMB_ACL_T sys_acl_init(int count)
1338 SMB_ACL_T a;
1340 if (count < 0) {
1341 errno = EINVAL;
1342 return NULL;
1346 * note that since the definition of the structure pointed
1347 * to by the SMB_ACL_T includes the first element of the
1348 * acl[] array, this actually allocates an ACL with room
1349 * for (count+1) entries
1351 if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
1352 errno = ENOMEM;
1353 return NULL;
1356 a->size = count + 1;
1357 a->count = 0;
1358 a->next = -1;
1360 return a;
1364 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1366 SMB_ACL_T acl_d;
1367 SMB_ACL_ENTRY_T entry_d;
1369 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
1370 errno = EINVAL;
1371 return -1;
1374 if (acl_d->count >= acl_d->size) {
1375 errno = ENOSPC;
1376 return -1;
1379 entry_d = &acl_d->acl[acl_d->count++];
1380 entry_d->a_type = 0;
1381 entry_d->a_id = -1;
1382 entry_d->a_perm = 0;
1383 *entry_p = entry_d;
1385 return 0;
1388 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1390 switch (tag_type) {
1391 case SMB_ACL_USER:
1392 case SMB_ACL_USER_OBJ:
1393 case SMB_ACL_GROUP:
1394 case SMB_ACL_GROUP_OBJ:
1395 case SMB_ACL_OTHER:
1396 case SMB_ACL_MASK:
1397 entry_d->a_type = tag_type;
1398 break;
1399 default:
1400 errno = EINVAL;
1401 return -1;
1404 return 0;
1407 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
1409 if (entry_d->a_type != SMB_ACL_GROUP
1410 && entry_d->a_type != SMB_ACL_USER) {
1411 errno = EINVAL;
1412 return -1;
1415 entry_d->a_id = *((id_t *)qual_p);
1417 return 0;
1420 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1422 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1423 return EINVAL;
1426 entry_d->a_perm = *permset_d;
1428 return 0;
1431 /* Structure to capture the count for each type of ACE. */
1433 struct hpux_acl_types {
1434 int n_user;
1435 int n_def_user;
1436 int n_user_obj;
1437 int n_def_user_obj;
1439 int n_group;
1440 int n_def_group;
1441 int n_group_obj;
1442 int n_def_group_obj;
1444 int n_other;
1445 int n_other_obj;
1446 int n_def_other_obj;
1448 int n_class_obj;
1449 int n_def_class_obj;
1451 int n_illegal_obj;
1454 /* count_obj:
1455 * Counts the different number of objects in a given array of ACL
1456 * structures.
1457 * Inputs:
1459 * acl_count - Count of ACLs in the array of ACL strucutres.
1460 * aclp - Array of ACL structures.
1461 * acl_type_count - Pointer to acl_types structure. Should already be
1462 * allocated.
1463 * Output:
1465 * acl_type_count - This structure is filled up with counts of various
1466 * acl types.
1469 static int hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_types *acl_type_count)
1471 int i;
1473 memset(acl_type_count, 0, sizeof(struct hpux_acl_types));
1475 for(i=0;i<acl_count;i++) {
1476 switch(aclp[i].a_type) {
1477 case USER:
1478 acl_type_count->n_user++;
1479 break;
1480 case USER_OBJ:
1481 acl_type_count->n_user_obj++;
1482 break;
1483 case DEF_USER_OBJ:
1484 acl_type_count->n_def_user_obj++;
1485 break;
1486 case GROUP:
1487 acl_type_count->n_group++;
1488 break;
1489 case GROUP_OBJ:
1490 acl_type_count->n_group_obj++;
1491 break;
1492 case DEF_GROUP_OBJ:
1493 acl_type_count->n_def_group_obj++;
1494 break;
1495 case OTHER_OBJ:
1496 acl_type_count->n_other_obj++;
1497 break;
1498 case DEF_OTHER_OBJ:
1499 acl_type_count->n_def_other_obj++;
1500 break;
1501 case CLASS_OBJ:
1502 acl_type_count->n_class_obj++;
1503 break;
1504 case DEF_CLASS_OBJ:
1505 acl_type_count->n_def_class_obj++;
1506 break;
1507 case DEF_USER:
1508 acl_type_count->n_def_user++;
1509 break;
1510 case DEF_GROUP:
1511 acl_type_count->n_def_group++;
1512 break;
1513 default:
1514 acl_type_count->n_illegal_obj++;
1515 break;
1520 /* swap_acl_entries: Swaps two ACL entries.
1522 * Inputs: aclp0, aclp1 - ACL entries to be swapped.
1525 static void hpux_swap_acl_entries(struct acl *aclp0, struct acl *aclp1)
1527 struct acl temp_acl;
1529 temp_acl.a_type = aclp0->a_type;
1530 temp_acl.a_id = aclp0->a_id;
1531 temp_acl.a_perm = aclp0->a_perm;
1533 aclp0->a_type = aclp1->a_type;
1534 aclp0->a_id = aclp1->a_id;
1535 aclp0->a_perm = aclp1->a_perm;
1537 aclp1->a_type = temp_acl.a_type;
1538 aclp1->a_id = temp_acl.a_id;
1539 aclp1->a_perm = temp_acl.a_perm;
1542 /* prohibited_duplicate_type
1543 * Identifies if given ACL type can have duplicate entries or
1544 * not.
1546 * Inputs: acl_type - ACL Type.
1548 * Outputs:
1550 * Return..
1552 * True - If the ACL type matches any of the prohibited types.
1553 * False - If the ACL type doesn't match any of the prohibited types.
1556 static BOOL hpux_prohibited_duplicate_type(int acl_type)
1558 switch(acl_type) {
1559 case USER:
1560 case GROUP:
1561 case DEF_USER:
1562 case DEF_GROUP:
1563 return True;
1564 default:
1565 return False;
1569 /* get_needed_class_perm
1570 * Returns the permissions of a ACL structure only if the ACL
1571 * type matches one of the pre-determined types for computing
1572 * CLASS_OBJ permissions.
1574 * Inputs: aclp - Pointer to ACL structure.
1577 static int hpux_get_needed_class_perm(struct acl *aclp)
1579 switch(aclp->a_type) {
1580 case USER:
1581 case GROUP_OBJ:
1582 case GROUP:
1583 case DEF_USER_OBJ:
1584 case DEF_USER:
1585 case DEF_GROUP_OBJ:
1586 case DEF_GROUP:
1587 case DEF_CLASS_OBJ:
1588 case DEF_OTHER_OBJ:
1589 return aclp->a_perm;
1590 default:
1591 return 0;
1595 /* acl_sort for HPUX.
1596 * Sorts the array of ACL structures as per the description in
1597 * aclsort man page. Refer to aclsort man page for more details
1599 * Inputs:
1601 * acl_count - Count of ACLs in the array of ACL structures.
1602 * calclass - If this is not zero, then we compute the CLASS_OBJ
1603 * permissions.
1604 * aclp - Array of ACL structures.
1606 * Outputs:
1608 * aclp - Sorted array of ACL structures.
1610 * Outputs:
1612 * Returns 0 for success -1 for failure. Prints a message to the Samba
1613 * debug log in case of failure.
1616 static int hpux_acl_sort(int acl_count, int calclass, struct acl *aclp)
1618 #if !defined(HAVE_HPUX_ACLSORT)
1620 * The aclsort() system call is availabe on the latest HPUX General
1621 * Patch Bundles. So for HPUX, we developed our version of acl_sort
1622 * function. Because, we don't want to update to a new
1623 * HPUX GR bundle just for aclsort() call.
1626 struct hpux_acl_types acl_obj_count;
1627 int n_class_obj_perm = 0;
1628 int i, j;
1630 if(!acl_count) {
1631 DEBUG(10,("Zero acl count passed. Returning Success\n"));
1632 return 0;
1635 if(aclp == NULL) {
1636 DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
1637 return -1;
1640 /* Count different types of ACLs in the ACLs array */
1642 hpux_count_obj(acl_count, aclp, &acl_obj_count);
1644 /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
1645 * CLASS_OBJ and OTHER_OBJ
1648 if( (acl_obj_count.n_user_obj != 1) ||
1649 (acl_obj_count.n_group_obj != 1) ||
1650 (acl_obj_count.n_class_obj != 1) ||
1651 (acl_obj_count.n_other_obj != 1)
1653 DEBUG(0,("hpux_acl_sort: More than one entry or no entries for \
1654 USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
1655 return -1;
1658 /* If any of the default objects are present, there should be only
1659 * one of them each.
1662 if( (acl_obj_count.n_def_user_obj > 1) || (acl_obj_count.n_def_group_obj > 1) ||
1663 (acl_obj_count.n_def_other_obj > 1) || (acl_obj_count.n_def_class_obj > 1) ) {
1664 DEBUG(0,("hpux_acl_sort: More than one entry for DEF_CLASS_OBJ \
1665 or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
1666 return -1;
1669 /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
1670 * structures.
1672 * Sorting crieteria - First sort by ACL type. If there are multiple entries of
1673 * same ACL type, sort by ACL id.
1675 * I am using the trival kind of sorting method here because, performance isn't
1676 * really effected by the ACLs feature. More over there aren't going to be more
1677 * than 17 entries on HPUX.
1680 for(i=0; i<acl_count;i++) {
1681 for (j=i+1; j<acl_count; j++) {
1682 if( aclp[i].a_type > aclp[j].a_type ) {
1683 /* ACL entries out of order, swap them */
1685 hpux_swap_acl_entries((aclp+i), (aclp+j));
1687 } else if ( aclp[i].a_type == aclp[j].a_type ) {
1689 /* ACL entries of same type, sort by id */
1691 if(aclp[i].a_id > aclp[j].a_id) {
1692 hpux_swap_acl_entries((aclp+i), (aclp+j));
1693 } else if (aclp[i].a_id == aclp[j].a_id) {
1694 /* We have a duplicate entry. */
1695 if(hpux_prohibited_duplicate_type(aclp[i].a_type)) {
1696 DEBUG(0, ("hpux_acl_sort: Duplicate entry: Type(hex): %x Id: %d\n",
1697 aclp[i].a_type, aclp[i].a_id));
1698 return -1;
1706 /* set the class obj permissions to the computed one. */
1707 if(calclass) {
1708 int n_class_obj_index = -1;
1710 for(i=0;i<acl_count;i++) {
1711 n_class_obj_perm |= hpux_get_needed_class_perm((aclp+i));
1713 if(aclp[i].a_type == CLASS_OBJ)
1714 n_class_obj_index = i;
1716 aclp[n_class_obj_index].a_perm = n_class_obj_perm;
1719 return 0;
1720 #else
1721 return aclsort(acl_count, calclass, aclp);
1722 #endif
1726 * sort the ACL and check it for validity
1728 * if it's a minimal ACL with only 4 entries then we
1729 * need to recalculate the mask permissions to make
1730 * sure that they are the same as the GROUP_OBJ
1731 * permissions as required by the UnixWare acl() system call.
1733 * (note: since POSIX allows minimal ACLs which only contain
1734 * 3 entries - ie there is no mask entry - we should, in theory,
1735 * check for this and add a mask entry if necessary - however
1736 * we "know" that the caller of this interface always specifies
1737 * a mask so, in practice "this never happens" (tm) - if it *does*
1738 * happen aclsort() will fail and return an error and someone will
1739 * have to fix it ...)
1742 static int acl_sort(SMB_ACL_T acl_d)
1744 int fixmask = (acl_d->count <= 4);
1746 if (hpux_acl_sort(acl_d->count, fixmask, acl_d->acl) != 0) {
1747 errno = EINVAL;
1748 return -1;
1750 return 0;
1753 int sys_acl_valid(SMB_ACL_T acl_d)
1755 return acl_sort(acl_d);
1758 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
1760 struct stat s;
1761 struct acl *acl_p;
1762 int acl_count;
1763 struct acl *acl_buf = NULL;
1764 int ret;
1766 if(hpux_acl_call_presence() == False) {
1767 /* Looks like we don't have the acl() system call on HPUX.
1768 * May be the system doesn't have the latest version of JFS.
1770 errno=ENOSYS;
1771 return -1;
1774 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
1775 errno = EINVAL;
1776 return -1;
1779 if (acl_sort(acl_d) != 0) {
1780 return -1;
1783 acl_p = &acl_d->acl[0];
1784 acl_count = acl_d->count;
1787 * if it's a directory there is extra work to do
1788 * since the acl() system call will replace both
1789 * the access ACLs and the default ACLs (if any)
1791 if (stat(name, &s) != 0) {
1792 return -1;
1794 if (S_ISDIR(s.st_mode)) {
1795 SMB_ACL_T acc_acl;
1796 SMB_ACL_T def_acl;
1797 SMB_ACL_T tmp_acl;
1798 int i;
1800 if (type == SMB_ACL_TYPE_ACCESS) {
1801 acc_acl = acl_d;
1802 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
1804 } else {
1805 def_acl = acl_d;
1806 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
1809 if (tmp_acl == NULL) {
1810 return -1;
1814 * allocate a temporary buffer for the complete ACL
1816 acl_count = acc_acl->count + def_acl->count;
1817 acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
1819 if (acl_buf == NULL) {
1820 sys_acl_free_acl(tmp_acl);
1821 errno = ENOMEM;
1822 return -1;
1826 * copy the access control and default entries into the buffer
1828 memcpy(&acl_buf[0], &acc_acl->acl[0],
1829 acc_acl->count * sizeof(acl_buf[0]));
1831 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
1832 def_acl->count * sizeof(acl_buf[0]));
1835 * set the ACL_DEFAULT flag on the default entries
1837 for (i = acc_acl->count; i < acl_count; i++) {
1838 acl_buf[i].a_type |= ACL_DEFAULT;
1841 sys_acl_free_acl(tmp_acl);
1843 } else if (type != SMB_ACL_TYPE_ACCESS) {
1844 errno = EINVAL;
1845 return -1;
1848 ret = acl(name, ACL_SET, acl_count, acl_p);
1850 if (acl_buf) {
1851 free(acl_buf);
1854 return ret;
1857 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
1860 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1863 files_struct *fsp = file_find_fd(fd);
1865 if (fsp == NULL) {
1866 errno = EBADF;
1867 return NULL;
1870 if (acl_sort(acl_d) != 0) {
1871 return -1;
1875 * We know we're in the same conn context. So we
1876 * can use the relative path.
1879 return sys_acl_set_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS, acl_d);
1882 int sys_acl_delete_def_file(const char *path)
1884 SMB_ACL_T acl_d;
1885 int ret;
1888 * fetching the access ACL and rewriting it has
1889 * the effect of deleting the default ACL
1891 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
1892 return -1;
1895 ret = acl(path, ACL_SET, acl_d->count, acl_d->acl);
1897 sys_acl_free_acl(acl_d);
1899 return ret;
1902 int sys_acl_free_text(char *text)
1904 free(text);
1905 return 0;
1908 int sys_acl_free_acl(SMB_ACL_T acl_d)
1910 free(acl_d);
1911 return 0;
1914 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
1916 return 0;
1919 #elif defined(HAVE_IRIX_ACLS)
1921 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1923 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
1924 errno = EINVAL;
1925 return -1;
1928 if (entry_p == NULL) {
1929 errno = EINVAL;
1930 return -1;
1933 if (entry_id == SMB_ACL_FIRST_ENTRY) {
1934 acl_d->next = 0;
1937 if (acl_d->next < 0) {
1938 errno = EINVAL;
1939 return -1;
1942 if (acl_d->next >= acl_d->aclp->acl_cnt) {
1943 return 0;
1946 *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
1948 return 1;
1951 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
1953 *type_p = entry_d->ae_tag;
1955 return 0;
1958 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1960 *permset_p = entry_d;
1962 return 0;
1965 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
1967 if (entry_d->ae_tag != SMB_ACL_USER
1968 && entry_d->ae_tag != SMB_ACL_GROUP) {
1969 errno = EINVAL;
1970 return NULL;
1973 return &entry_d->ae_id;
1976 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
1978 SMB_ACL_T a;
1980 if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
1981 errno = ENOMEM;
1982 return NULL;
1984 if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
1985 SAFE_FREE(a);
1986 return NULL;
1988 a->next = -1;
1989 a->freeaclp = True;
1990 return a;
1993 SMB_ACL_T sys_acl_get_fd(int fd)
1995 SMB_ACL_T a;
1997 if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
1998 errno = ENOMEM;
1999 return NULL;
2001 if ((a->aclp = acl_get_fd(fd)) == NULL) {
2002 SAFE_FREE(a);
2003 return NULL;
2005 a->next = -1;
2006 a->freeaclp = True;
2007 return a;
2010 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
2012 permset_d->ae_perm = 0;
2014 return 0;
2017 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
2019 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
2020 && perm != SMB_ACL_EXECUTE) {
2021 errno = EINVAL;
2022 return -1;
2025 if (permset_d == NULL) {
2026 errno = EINVAL;
2027 return -1;
2030 permset_d->ae_perm |= perm;
2032 return 0;
2035 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
2037 return permset_d->ae_perm & perm;
2040 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
2042 return acl_to_text(acl_d->aclp, len_p);
2045 SMB_ACL_T sys_acl_init(int count)
2047 SMB_ACL_T a;
2049 if (count < 0) {
2050 errno = EINVAL;
2051 return NULL;
2054 if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + sizeof(struct acl))) == NULL) {
2055 errno = ENOMEM;
2056 return NULL;
2059 a->next = -1;
2060 a->freeaclp = False;
2061 a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
2062 a->aclp->acl_cnt = 0;
2064 return a;
2068 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
2070 SMB_ACL_T acl_d;
2071 SMB_ACL_ENTRY_T entry_d;
2073 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
2074 errno = EINVAL;
2075 return -1;
2078 if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
2079 errno = ENOSPC;
2080 return -1;
2083 entry_d = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
2084 entry_d->ae_tag = 0;
2085 entry_d->ae_id = 0;
2086 entry_d->ae_perm = 0;
2087 *entry_p = entry_d;
2089 return 0;
2092 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
2094 switch (tag_type) {
2095 case SMB_ACL_USER:
2096 case SMB_ACL_USER_OBJ:
2097 case SMB_ACL_GROUP:
2098 case SMB_ACL_GROUP_OBJ:
2099 case SMB_ACL_OTHER:
2100 case SMB_ACL_MASK:
2101 entry_d->ae_tag = tag_type;
2102 break;
2103 default:
2104 errno = EINVAL;
2105 return -1;
2108 return 0;
2111 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
2113 if (entry_d->ae_tag != SMB_ACL_GROUP
2114 && entry_d->ae_tag != SMB_ACL_USER) {
2115 errno = EINVAL;
2116 return -1;
2119 entry_d->ae_id = *((id_t *)qual_p);
2121 return 0;
2124 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
2126 if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
2127 return EINVAL;
2130 entry_d->ae_perm = permset_d->ae_perm;
2132 return 0;
2135 int sys_acl_valid(SMB_ACL_T acl_d)
2137 return acl_valid(acl_d->aclp);
2140 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
2142 return acl_set_file(name, type, acl_d->aclp);
2145 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
2147 return acl_set_fd(fd, acl_d->aclp);
2150 int sys_acl_delete_def_file(const char *name)
2152 return acl_delete_def_file(name);
2155 int sys_acl_free_text(char *text)
2157 return acl_free(text);
2160 int sys_acl_free_acl(SMB_ACL_T acl_d)
2162 if (acl_d->freeaclp) {
2163 acl_free(acl_d->aclp);
2165 acl_free(acl_d);
2166 return 0;
2169 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
2171 return 0;
2174 #elif defined(HAVE_AIX_ACLS)
2176 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
2178 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
2180 struct acl_entry_link *link;
2181 struct new_acl_entry *entry;
2182 int keep_going;
2184 DEBUG(10,("This is the count: %d\n",theacl->count));
2186 /* Check if count was previously set to -1. *
2187 * If it was, that means we reached the end *
2188 * of the acl last time. */
2189 if(theacl->count == -1)
2190 return(0);
2192 link = theacl;
2193 /* To get to the next acl, traverse linked list until index *
2194 * of acl matches the count we are keeping. This count is *
2195 * incremented each time we return an acl entry. */
2197 for(keep_going = 0; keep_going < theacl->count; keep_going++)
2198 link = link->nextp;
2200 entry = *entry_p = link->entryp;
2202 DEBUG(10,("*entry_p is %d\n",entry_p));
2203 DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
2205 /* Increment count */
2206 theacl->count++;
2207 if(link->nextp == NULL)
2208 theacl->count = -1;
2210 return(1);
2213 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
2215 /* Initialize tag type */
2217 *tag_type_p = -1;
2218 DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
2220 /* Depending on what type of entry we have, *
2221 * return tag type. */
2222 switch(entry_d->ace_id->id_type) {
2223 case ACEID_USER:
2224 *tag_type_p = SMB_ACL_USER;
2225 break;
2226 case ACEID_GROUP:
2227 *tag_type_p = SMB_ACL_GROUP;
2228 break;
2230 case SMB_ACL_USER_OBJ:
2231 case SMB_ACL_GROUP_OBJ:
2232 case SMB_ACL_OTHER:
2233 *tag_type_p = entry_d->ace_id->id_type;
2234 break;
2236 default:
2237 return(-1);
2240 return(0);
2243 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
2245 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
2246 *permset_p = &entry_d->ace_access;
2247 DEBUG(10,("**permset_p is %d\n",**permset_p));
2248 if(!(**permset_p & S_IXUSR) &&
2249 !(**permset_p & S_IWUSR) &&
2250 !(**permset_p & S_IRUSR) &&
2251 (**permset_p != 0))
2252 return(-1);
2254 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
2255 return(0);
2258 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
2260 return(entry_d->ace_id->id_data);
2263 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
2265 struct acl *file_acl = (struct acl *)NULL;
2266 struct acl_entry *acl_entry;
2267 struct new_acl_entry *new_acl_entry;
2268 struct ace_id *idp;
2269 struct acl_entry_link *acl_entry_link;
2270 struct acl_entry_link *acl_entry_link_head;
2271 int i;
2272 int rc = 0;
2273 uid_t user_id;
2275 /* AIX has no DEFAULT */
2276 if ( type == SMB_ACL_TYPE_DEFAULT )
2277 return NULL;
2279 /* Get the acl using statacl */
2281 DEBUG(10,("Entering sys_acl_get_file\n"));
2282 DEBUG(10,("path_p is %s\n",path_p));
2284 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2286 if(file_acl == NULL) {
2287 errno=ENOMEM;
2288 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
2289 return(NULL);
2292 memset(file_acl,0,BUFSIZ);
2294 rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
2295 if(rc == -1) {
2296 DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
2297 SAFE_FREE(file_acl);
2298 return(NULL);
2301 DEBUG(10,("Got facl and returned it\n"));
2303 /* Point to the first acl entry in the acl */
2304 acl_entry = file_acl->acl_ext;
2306 /* Begin setting up the head of the linked list *
2307 * that will be used for the storing the acl *
2308 * in a way that is useful for the posix_acls.c *
2309 * code. */
2311 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
2312 if(acl_entry_link_head == NULL)
2313 return(NULL);
2315 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2316 if(acl_entry_link->entryp == NULL) {
2317 SAFE_FREE(file_acl);
2318 errno = ENOMEM;
2319 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2320 return(NULL);
2323 DEBUG(10,("acl_entry is %d\n",acl_entry));
2324 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
2326 /* Check if the extended acl bit is on. *
2327 * If it isn't, do not show the *
2328 * contents of the acl since AIX intends *
2329 * the extended info to remain unused */
2331 if(file_acl->acl_mode & S_IXACL){
2332 /* while we are not pointing to the very end */
2333 while(acl_entry < acl_last(file_acl)) {
2334 /* before we malloc anything, make sure this is */
2335 /* a valid acl entry and one that we want to map */
2336 idp = id_nxt(acl_entry->ace_id);
2337 if((acl_entry->ace_type == ACC_SPECIFY ||
2338 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
2339 acl_entry = acl_nxt(acl_entry);
2340 continue;
2343 idp = acl_entry->ace_id;
2345 /* Check if this is the first entry in the linked list. *
2346 * The first entry needs to keep prevp pointing to NULL *
2347 * and already has entryp allocated. */
2349 if(acl_entry_link_head->count != 0) {
2350 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2352 if(acl_entry_link->nextp == NULL) {
2353 SAFE_FREE(file_acl);
2354 errno = ENOMEM;
2355 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2356 return(NULL);
2359 acl_entry_link->nextp->prevp = acl_entry_link;
2360 acl_entry_link = acl_entry_link->nextp;
2361 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2362 if(acl_entry_link->entryp == NULL) {
2363 SAFE_FREE(file_acl);
2364 errno = ENOMEM;
2365 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2366 return(NULL);
2368 acl_entry_link->nextp = NULL;
2371 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
2373 /* Don't really need this since all types are going *
2374 * to be specified but, it's better than leaving it 0 */
2376 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
2378 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2380 memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
2382 /* The access in the acl entries must be left shifted by *
2383 * three bites, because they will ultimately be compared *
2384 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2386 switch(acl_entry->ace_type){
2387 case ACC_PERMIT:
2388 case ACC_SPECIFY:
2389 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2390 acl_entry_link->entryp->ace_access <<= 6;
2391 acl_entry_link_head->count++;
2392 break;
2393 case ACC_DENY:
2394 /* Since there is no way to return a DENY acl entry *
2395 * change to PERMIT and then shift. */
2396 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
2397 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
2398 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
2399 acl_entry_link->entryp->ace_access <<= 6;
2400 acl_entry_link_head->count++;
2401 break;
2402 default:
2403 return(0);
2406 DEBUG(10,("acl_entry = %d\n",acl_entry));
2407 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
2409 acl_entry = acl_nxt(acl_entry);
2411 } /* end of if enabled */
2413 /* Since owner, group, other acl entries are not *
2414 * part of the acl entries in an acl, they must *
2415 * be dummied up to become part of the list. */
2417 for( i = 1; i < 4; i++) {
2418 DEBUG(10,("i is %d\n",i));
2419 if(acl_entry_link_head->count != 0) {
2420 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2421 if(acl_entry_link->nextp == NULL) {
2422 SAFE_FREE(file_acl);
2423 errno = ENOMEM;
2424 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2425 return(NULL);
2428 acl_entry_link->nextp->prevp = acl_entry_link;
2429 acl_entry_link = acl_entry_link->nextp;
2430 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2431 if(acl_entry_link->entryp == NULL) {
2432 SAFE_FREE(file_acl);
2433 errno = ENOMEM;
2434 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2435 return(NULL);
2439 acl_entry_link->nextp = NULL;
2441 new_acl_entry = acl_entry_link->entryp;
2442 idp = new_acl_entry->ace_id;
2444 new_acl_entry->ace_len = sizeof(struct acl_entry);
2445 new_acl_entry->ace_type = ACC_PERMIT;
2446 idp->id_len = sizeof(struct ace_id);
2447 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
2448 memset(idp->id_data,0,sizeof(uid_t));
2450 switch(i) {
2451 case 2:
2452 new_acl_entry->ace_access = file_acl->g_access << 6;
2453 idp->id_type = SMB_ACL_GROUP_OBJ;
2454 break;
2456 case 3:
2457 new_acl_entry->ace_access = file_acl->o_access << 6;
2458 idp->id_type = SMB_ACL_OTHER;
2459 break;
2461 case 1:
2462 new_acl_entry->ace_access = file_acl->u_access << 6;
2463 idp->id_type = SMB_ACL_USER_OBJ;
2464 break;
2466 default:
2467 return(NULL);
2471 acl_entry_link_head->count++;
2472 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
2475 acl_entry_link_head->count = 0;
2476 SAFE_FREE(file_acl);
2478 return(acl_entry_link_head);
2481 SMB_ACL_T sys_acl_get_fd(int fd)
2483 struct acl *file_acl = (struct acl *)NULL;
2484 struct acl_entry *acl_entry;
2485 struct new_acl_entry *new_acl_entry;
2486 struct ace_id *idp;
2487 struct acl_entry_link *acl_entry_link;
2488 struct acl_entry_link *acl_entry_link_head;
2489 int i;
2490 int rc = 0;
2491 uid_t user_id;
2493 /* Get the acl using fstatacl */
2495 DEBUG(10,("Entering sys_acl_get_fd\n"));
2496 DEBUG(10,("fd is %d\n",fd));
2497 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2499 if(file_acl == NULL) {
2500 errno=ENOMEM;
2501 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2502 return(NULL);
2505 memset(file_acl,0,BUFSIZ);
2507 rc = fstatacl(fd,0,file_acl,BUFSIZ);
2508 if(rc == -1) {
2509 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
2510 SAFE_FREE(file_acl);
2511 return(NULL);
2514 DEBUG(10,("Got facl and returned it\n"));
2516 /* Point to the first acl entry in the acl */
2518 acl_entry = file_acl->acl_ext;
2519 /* Begin setting up the head of the linked list *
2520 * that will be used for the storing the acl *
2521 * in a way that is useful for the posix_acls.c *
2522 * code. */
2524 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
2525 if(acl_entry_link_head == NULL){
2526 SAFE_FREE(file_acl);
2527 return(NULL);
2530 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2532 if(acl_entry_link->entryp == NULL) {
2533 errno = ENOMEM;
2534 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2535 SAFE_FREE(file_acl);
2536 return(NULL);
2539 DEBUG(10,("acl_entry is %d\n",acl_entry));
2540 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
2542 /* Check if the extended acl bit is on. *
2543 * If it isn't, do not show the *
2544 * contents of the acl since AIX intends *
2545 * the extended info to remain unused */
2547 if(file_acl->acl_mode & S_IXACL){
2548 /* while we are not pointing to the very end */
2549 while(acl_entry < acl_last(file_acl)) {
2550 /* before we malloc anything, make sure this is */
2551 /* a valid acl entry and one that we want to map */
2553 idp = id_nxt(acl_entry->ace_id);
2554 if((acl_entry->ace_type == ACC_SPECIFY ||
2555 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
2556 acl_entry = acl_nxt(acl_entry);
2557 continue;
2560 idp = acl_entry->ace_id;
2562 /* Check if this is the first entry in the linked list. *
2563 * The first entry needs to keep prevp pointing to NULL *
2564 * and already has entryp allocated. */
2566 if(acl_entry_link_head->count != 0) {
2567 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2568 if(acl_entry_link->nextp == NULL) {
2569 errno = ENOMEM;
2570 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2571 SAFE_FREE(file_acl);
2572 return(NULL);
2574 acl_entry_link->nextp->prevp = acl_entry_link;
2575 acl_entry_link = acl_entry_link->nextp;
2576 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2577 if(acl_entry_link->entryp == NULL) {
2578 errno = ENOMEM;
2579 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2580 SAFE_FREE(file_acl);
2581 return(NULL);
2584 acl_entry_link->nextp = NULL;
2587 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
2589 /* Don't really need this since all types are going *
2590 * to be specified but, it's better than leaving it 0 */
2592 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
2593 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2595 memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
2597 /* The access in the acl entries must be left shifted by *
2598 * three bites, because they will ultimately be compared *
2599 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2601 switch(acl_entry->ace_type){
2602 case ACC_PERMIT:
2603 case ACC_SPECIFY:
2604 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2605 acl_entry_link->entryp->ace_access <<= 6;
2606 acl_entry_link_head->count++;
2607 break;
2608 case ACC_DENY:
2609 /* Since there is no way to return a DENY acl entry *
2610 * change to PERMIT and then shift. */
2611 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
2612 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
2613 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
2614 acl_entry_link->entryp->ace_access <<= 6;
2615 acl_entry_link_head->count++;
2616 break;
2617 default:
2618 return(0);
2621 DEBUG(10,("acl_entry = %d\n",acl_entry));
2622 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
2624 acl_entry = acl_nxt(acl_entry);
2626 } /* end of if enabled */
2628 /* Since owner, group, other acl entries are not *
2629 * part of the acl entries in an acl, they must *
2630 * be dummied up to become part of the list. */
2632 for( i = 1; i < 4; i++) {
2633 DEBUG(10,("i is %d\n",i));
2634 if(acl_entry_link_head->count != 0){
2635 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2636 if(acl_entry_link->nextp == NULL) {
2637 errno = ENOMEM;
2638 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2639 SAFE_FREE(file_acl);
2640 return(NULL);
2643 acl_entry_link->nextp->prevp = acl_entry_link;
2644 acl_entry_link = acl_entry_link->nextp;
2645 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2647 if(acl_entry_link->entryp == NULL) {
2648 SAFE_FREE(file_acl);
2649 errno = ENOMEM;
2650 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2651 return(NULL);
2655 acl_entry_link->nextp = NULL;
2657 new_acl_entry = acl_entry_link->entryp;
2658 idp = new_acl_entry->ace_id;
2660 new_acl_entry->ace_len = sizeof(struct acl_entry);
2661 new_acl_entry->ace_type = ACC_PERMIT;
2662 idp->id_len = sizeof(struct ace_id);
2663 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
2664 memset(idp->id_data,0,sizeof(uid_t));
2666 switch(i) {
2667 case 2:
2668 new_acl_entry->ace_access = file_acl->g_access << 6;
2669 idp->id_type = SMB_ACL_GROUP_OBJ;
2670 break;
2672 case 3:
2673 new_acl_entry->ace_access = file_acl->o_access << 6;
2674 idp->id_type = SMB_ACL_OTHER;
2675 break;
2677 case 1:
2678 new_acl_entry->ace_access = file_acl->u_access << 6;
2679 idp->id_type = SMB_ACL_USER_OBJ;
2680 break;
2682 default:
2683 return(NULL);
2686 acl_entry_link_head->count++;
2687 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
2690 acl_entry_link_head->count = 0;
2691 SAFE_FREE(file_acl);
2693 return(acl_entry_link_head);
2696 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
2698 *permset = *permset & ~0777;
2699 return(0);
2702 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2704 if((perm != 0) &&
2705 (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0)
2706 return(-1);
2708 *permset |= perm;
2709 DEBUG(10,("This is the permset now: %d\n",*permset));
2710 return(0);
2713 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
2715 return(NULL);
2718 SMB_ACL_T sys_acl_init( int count)
2720 struct acl_entry_link *theacl = NULL;
2722 DEBUG(10,("Entering sys_acl_init\n"));
2724 theacl = SMB_MALLOC_P(struct acl_entry_link);
2725 if(theacl == NULL) {
2726 errno = ENOMEM;
2727 DEBUG(0,("Error in sys_acl_init is %d\n",errno));
2728 return(NULL);
2731 theacl->count = 0;
2732 theacl->nextp = NULL;
2733 theacl->prevp = NULL;
2734 theacl->entryp = NULL;
2735 DEBUG(10,("Exiting sys_acl_init\n"));
2736 return(theacl);
2739 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2741 struct acl_entry_link *theacl;
2742 struct acl_entry_link *acl_entryp;
2743 struct acl_entry_link *temp_entry;
2744 int counting;
2746 DEBUG(10,("Entering the sys_acl_create_entry\n"));
2748 theacl = acl_entryp = *pacl;
2750 /* Get to the end of the acl before adding entry */
2752 for(counting=0; counting < theacl->count; counting++){
2753 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
2754 temp_entry = acl_entryp;
2755 acl_entryp = acl_entryp->nextp;
2758 if(theacl->count != 0){
2759 temp_entry->nextp = acl_entryp = SMB_MALLOC_P(struct acl_entry_link);
2760 if(acl_entryp == NULL) {
2761 errno = ENOMEM;
2762 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
2763 return(-1);
2766 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
2767 acl_entryp->prevp = temp_entry;
2768 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
2771 *pentry = acl_entryp->entryp = SMB_MALLOC_P(struct new_acl_entry);
2772 if(*pentry == NULL) {
2773 errno = ENOMEM;
2774 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
2775 return(-1);
2778 memset(*pentry,0,sizeof(struct new_acl_entry));
2779 acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
2780 acl_entryp->entryp->ace_type = ACC_PERMIT;
2781 acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
2782 acl_entryp->nextp = NULL;
2783 theacl->count++;
2784 DEBUG(10,("Exiting sys_acl_create_entry\n"));
2785 return(0);
2788 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2790 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
2791 entry->ace_id->id_type = tagtype;
2792 DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
2793 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
2796 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
2798 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
2799 memcpy(entry->ace_id->id_data,qual,sizeof(uid_t));
2800 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
2801 return(0);
2804 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2806 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
2807 if(!(*permset & S_IXUSR) &&
2808 !(*permset & S_IWUSR) &&
2809 !(*permset & S_IRUSR) &&
2810 (*permset != 0))
2811 return(-1);
2813 entry->ace_access = *permset;
2814 DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
2815 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
2816 return(0);
2819 int sys_acl_valid( SMB_ACL_T theacl )
2821 int user_obj = 0;
2822 int group_obj = 0;
2823 int other_obj = 0;
2824 struct acl_entry_link *acl_entry;
2826 for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
2827 user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
2828 group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
2829 other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
2832 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
2834 if(user_obj != 1 || group_obj != 1 || other_obj != 1)
2835 return(-1);
2837 return(0);
2840 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2842 struct acl_entry_link *acl_entry_link = NULL;
2843 struct acl *file_acl = NULL;
2844 struct acl *file_acl_temp = NULL;
2845 struct acl_entry *acl_entry = NULL;
2846 struct ace_id *ace_id = NULL;
2847 uint id_type;
2848 uint ace_access;
2849 uint user_id;
2850 uint acl_length;
2851 uint rc;
2853 DEBUG(10,("Entering sys_acl_set_file\n"));
2854 DEBUG(10,("File name is %s\n",name));
2856 /* AIX has no default ACL */
2857 if(acltype == SMB_ACL_TYPE_DEFAULT)
2858 return(0);
2860 acl_length = BUFSIZ;
2861 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2863 if(file_acl == NULL) {
2864 errno = ENOMEM;
2865 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2866 return(-1);
2869 memset(file_acl,0,BUFSIZ);
2871 file_acl->acl_len = ACL_SIZ;
2872 file_acl->acl_mode = S_IXACL;
2874 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2875 acl_entry_link->entryp->ace_access >>= 6;
2876 id_type = acl_entry_link->entryp->ace_id->id_type;
2878 switch(id_type) {
2879 case SMB_ACL_USER_OBJ:
2880 file_acl->u_access = acl_entry_link->entryp->ace_access;
2881 continue;
2882 case SMB_ACL_GROUP_OBJ:
2883 file_acl->g_access = acl_entry_link->entryp->ace_access;
2884 continue;
2885 case SMB_ACL_OTHER:
2886 file_acl->o_access = acl_entry_link->entryp->ace_access;
2887 continue;
2888 case SMB_ACL_MASK:
2889 continue;
2892 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2893 acl_length += sizeof(struct acl_entry);
2894 file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
2895 if(file_acl_temp == NULL) {
2896 SAFE_FREE(file_acl);
2897 errno = ENOMEM;
2898 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2899 return(-1);
2902 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2903 SAFE_FREE(file_acl);
2904 file_acl = file_acl_temp;
2907 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2908 file_acl->acl_len += sizeof(struct acl_entry);
2909 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2910 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2912 /* In order to use this, we'll need to wait until we can get denies */
2913 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2914 acl_entry->ace_type = ACC_SPECIFY; */
2916 acl_entry->ace_type = ACC_SPECIFY;
2918 ace_id = acl_entry->ace_id;
2920 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2921 DEBUG(10,("The id type is %d\n",ace_id->id_type));
2922 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2923 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2924 memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
2927 rc = chacl(name,file_acl,file_acl->acl_len);
2928 DEBUG(10,("errno is %d\n",errno));
2929 DEBUG(10,("return code is %d\n",rc));
2930 SAFE_FREE(file_acl);
2931 DEBUG(10,("Exiting the sys_acl_set_file\n"));
2932 return(rc);
2935 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2937 struct acl_entry_link *acl_entry_link = NULL;
2938 struct acl *file_acl = NULL;
2939 struct acl *file_acl_temp = NULL;
2940 struct acl_entry *acl_entry = NULL;
2941 struct ace_id *ace_id = NULL;
2942 uint id_type;
2943 uint user_id;
2944 uint acl_length;
2945 uint rc;
2947 DEBUG(10,("Entering sys_acl_set_fd\n"));
2948 acl_length = BUFSIZ;
2949 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2951 if(file_acl == NULL) {
2952 errno = ENOMEM;
2953 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2954 return(-1);
2957 memset(file_acl,0,BUFSIZ);
2959 file_acl->acl_len = ACL_SIZ;
2960 file_acl->acl_mode = S_IXACL;
2962 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2963 acl_entry_link->entryp->ace_access >>= 6;
2964 id_type = acl_entry_link->entryp->ace_id->id_type;
2965 DEBUG(10,("The id_type is %d\n",id_type));
2967 switch(id_type) {
2968 case SMB_ACL_USER_OBJ:
2969 file_acl->u_access = acl_entry_link->entryp->ace_access;
2970 continue;
2971 case SMB_ACL_GROUP_OBJ:
2972 file_acl->g_access = acl_entry_link->entryp->ace_access;
2973 continue;
2974 case SMB_ACL_OTHER:
2975 file_acl->o_access = acl_entry_link->entryp->ace_access;
2976 continue;
2977 case SMB_ACL_MASK:
2978 continue;
2981 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2982 acl_length += sizeof(struct acl_entry);
2983 file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
2984 if(file_acl_temp == NULL) {
2985 SAFE_FREE(file_acl);
2986 errno = ENOMEM;
2987 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2988 return(-1);
2991 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2992 SAFE_FREE(file_acl);
2993 file_acl = file_acl_temp;
2996 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2997 file_acl->acl_len += sizeof(struct acl_entry);
2998 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2999 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
3001 /* In order to use this, we'll need to wait until we can get denies */
3002 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
3003 acl_entry->ace_type = ACC_SPECIFY; */
3005 acl_entry->ace_type = ACC_SPECIFY;
3007 ace_id = acl_entry->ace_id;
3009 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
3010 DEBUG(10,("The id type is %d\n",ace_id->id_type));
3011 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
3012 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
3013 memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
3016 rc = fchacl(fd,file_acl,file_acl->acl_len);
3017 DEBUG(10,("errno is %d\n",errno));
3018 DEBUG(10,("return code is %d\n",rc));
3019 SAFE_FREE(file_acl);
3020 DEBUG(10,("Exiting sys_acl_set_fd\n"));
3021 return(rc);
3024 int sys_acl_delete_def_file(const char *name)
3026 /* AIX has no default ACL */
3027 return 0;
3030 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
3032 return(*permset & perm);
3035 int sys_acl_free_text(char *text)
3037 return(0);
3040 int sys_acl_free_acl(SMB_ACL_T posix_acl)
3042 struct acl_entry_link *acl_entry_link;
3044 for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
3045 SAFE_FREE(acl_entry_link->prevp->entryp);
3046 SAFE_FREE(acl_entry_link->prevp);
3049 SAFE_FREE(acl_entry_link->prevp->entryp);
3050 SAFE_FREE(acl_entry_link->prevp);
3051 SAFE_FREE(acl_entry_link->entryp);
3052 SAFE_FREE(acl_entry_link);
3054 return(0);
3057 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
3059 return(0);
3062 #else /* No ACLs. */
3064 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
3066 errno = ENOSYS;
3067 return -1;
3070 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
3072 errno = ENOSYS;
3073 return -1;
3076 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
3078 errno = ENOSYS;
3079 return -1;
3082 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
3084 errno = ENOSYS;
3085 return NULL;
3088 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
3090 errno = ENOSYS;
3091 return (SMB_ACL_T)NULL;
3094 SMB_ACL_T sys_acl_get_fd(int fd)
3096 errno = ENOSYS;
3097 return (SMB_ACL_T)NULL;
3100 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
3102 errno = ENOSYS;
3103 return -1;
3106 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
3108 errno = ENOSYS;
3109 return -1;
3112 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
3114 errno = ENOSYS;
3115 return (permset & perm) ? 1 : 0;
3118 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
3120 errno = ENOSYS;
3121 return NULL;
3124 int sys_acl_free_text(char *text)
3126 errno = ENOSYS;
3127 return -1;
3130 SMB_ACL_T sys_acl_init( int count)
3132 errno = ENOSYS;
3133 return NULL;
3136 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
3138 errno = ENOSYS;
3139 return -1;
3142 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
3144 errno = ENOSYS;
3145 return -1;
3148 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
3150 errno = ENOSYS;
3151 return -1;
3154 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
3156 errno = ENOSYS;
3157 return -1;
3160 int sys_acl_valid( SMB_ACL_T theacl )
3162 errno = ENOSYS;
3163 return -1;
3166 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
3168 errno = ENOSYS;
3169 return -1;
3172 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
3174 errno = ENOSYS;
3175 return -1;
3178 int sys_acl_delete_def_file(const char *name)
3180 errno = ENOSYS;
3181 return -1;
3184 int sys_acl_free_acl(SMB_ACL_T the_acl)
3186 errno = ENOSYS;
3187 return -1;
3190 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
3192 errno = ENOSYS;
3193 return -1;
3196 #endif /* No ACLs. */
3198 /************************************************************************
3199 Deliberately outside the ACL defines. Return 1 if this is a "no acls"
3200 errno, 0 if not.
3201 ************************************************************************/
3203 int no_acl_syscall_error(int err)
3205 #if defined(ENOSYS)
3206 if (err == ENOSYS) {
3207 return 1;
3209 #endif
3210 #if defined(ENOTSUP)
3211 if (err == ENOTSUP) {
3212 return 1;
3214 #endif
3215 return 0;