r7372: abartet's patch for BUG 2391 (segv caused by free a static pointer)
[Samba/gbeck.git] / source / lib / sysacls.c
blobe7bd288f6e881863cb04a7d51cec77b5ae4108a3
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 char *oldtext = text;
694 maxlen += nbytes + 20 * (acl_d->count - i);
696 if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) {
697 SAFE_FREE(oldtext);
698 errno = ENOMEM;
699 return NULL;
703 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
704 len += nbytes - 1;
707 if (len_p)
708 *len_p = len;
710 return text;
713 SMB_ACL_T sys_acl_init(int count)
715 SMB_ACL_T a;
717 if (count < 0) {
718 errno = EINVAL;
719 return NULL;
723 * note that since the definition of the structure pointed
724 * to by the SMB_ACL_T includes the first element of the
725 * acl[] array, this actually allocates an ACL with room
726 * for (count+1) entries
728 if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
729 errno = ENOMEM;
730 return NULL;
733 a->size = count + 1;
734 a->count = 0;
735 a->next = -1;
737 return a;
741 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
743 SMB_ACL_T acl_d;
744 SMB_ACL_ENTRY_T entry_d;
746 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
747 errno = EINVAL;
748 return -1;
751 if (acl_d->count >= acl_d->size) {
752 errno = ENOSPC;
753 return -1;
756 entry_d = &acl_d->acl[acl_d->count++];
757 entry_d->a_type = 0;
758 entry_d->a_id = -1;
759 entry_d->a_perm = 0;
760 *entry_p = entry_d;
762 return 0;
765 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
767 switch (tag_type) {
768 case SMB_ACL_USER:
769 case SMB_ACL_USER_OBJ:
770 case SMB_ACL_GROUP:
771 case SMB_ACL_GROUP_OBJ:
772 case SMB_ACL_OTHER:
773 case SMB_ACL_MASK:
774 entry_d->a_type = tag_type;
775 break;
776 default:
777 errno = EINVAL;
778 return -1;
781 return 0;
784 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
786 if (entry_d->a_type != SMB_ACL_GROUP
787 && entry_d->a_type != SMB_ACL_USER) {
788 errno = EINVAL;
789 return -1;
792 entry_d->a_id = *((id_t *)qual_p);
794 return 0;
797 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
799 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
800 return EINVAL;
803 entry_d->a_perm = *permset_d;
805 return 0;
809 * sort the ACL and check it for validity
811 * if it's a minimal ACL with only 4 entries then we
812 * need to recalculate the mask permissions to make
813 * sure that they are the same as the GROUP_OBJ
814 * permissions as required by the UnixWare acl() system call.
816 * (note: since POSIX allows minimal ACLs which only contain
817 * 3 entries - ie there is no mask entry - we should, in theory,
818 * check for this and add a mask entry if necessary - however
819 * we "know" that the caller of this interface always specifies
820 * a mask so, in practice "this never happens" (tm) - if it *does*
821 * happen aclsort() will fail and return an error and someone will
822 * have to fix it ...)
825 static int acl_sort(SMB_ACL_T acl_d)
827 int fixmask = (acl_d->count <= 4);
829 if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {
830 errno = EINVAL;
831 return -1;
833 return 0;
836 int sys_acl_valid(SMB_ACL_T acl_d)
838 return acl_sort(acl_d);
841 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
843 struct stat s;
844 struct acl *acl_p;
845 int acl_count;
846 struct acl *acl_buf = NULL;
847 int ret;
849 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
850 errno = EINVAL;
851 return -1;
854 if (acl_sort(acl_d) != 0) {
855 return -1;
858 acl_p = &acl_d->acl[0];
859 acl_count = acl_d->count;
862 * if it's a directory there is extra work to do
863 * since the acl() system call will replace both
864 * the access ACLs and the default ACLs (if any)
866 if (stat(name, &s) != 0) {
867 return -1;
869 if (S_ISDIR(s.st_mode)) {
870 SMB_ACL_T acc_acl;
871 SMB_ACL_T def_acl;
872 SMB_ACL_T tmp_acl;
873 int i;
875 if (type == SMB_ACL_TYPE_ACCESS) {
876 acc_acl = acl_d;
877 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
879 } else {
880 def_acl = acl_d;
881 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
884 if (tmp_acl == NULL) {
885 return -1;
889 * allocate a temporary buffer for the complete ACL
891 acl_count = acc_acl->count + def_acl->count;
892 acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
894 if (acl_buf == NULL) {
895 sys_acl_free_acl(tmp_acl);
896 errno = ENOMEM;
897 return -1;
901 * copy the access control and default entries into the buffer
903 memcpy(&acl_buf[0], &acc_acl->acl[0],
904 acc_acl->count * sizeof(acl_buf[0]));
906 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
907 def_acl->count * sizeof(acl_buf[0]));
910 * set the ACL_DEFAULT flag on the default entries
912 for (i = acc_acl->count; i < acl_count; i++) {
913 acl_buf[i].a_type |= ACL_DEFAULT;
916 sys_acl_free_acl(tmp_acl);
918 } else if (type != SMB_ACL_TYPE_ACCESS) {
919 errno = EINVAL;
920 return -1;
923 ret = acl(name, SETACL, acl_count, acl_p);
925 SAFE_FREE(acl_buf);
927 return ret;
930 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
932 if (acl_sort(acl_d) != 0) {
933 return -1;
936 return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
939 int sys_acl_delete_def_file(const char *path)
941 SMB_ACL_T acl_d;
942 int ret;
945 * fetching the access ACL and rewriting it has
946 * the effect of deleting the default ACL
948 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
949 return -1;
952 ret = acl(path, SETACL, acl_d->count, acl_d->acl);
954 sys_acl_free_acl(acl_d);
956 return ret;
959 int sys_acl_free_text(char *text)
961 SAFE_FREE(text);
962 return 0;
965 int sys_acl_free_acl(SMB_ACL_T acl_d)
967 SAFE_FREE(acl_d);
968 return 0;
971 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
973 return 0;
976 #elif defined(HAVE_HPUX_ACLS)
977 #include <dl.h>
980 * Based on the Solaris/SCO code - with modifications.
984 * Note that while this code implements sufficient functionality
985 * to support the sys_acl_* interfaces it does not provide all
986 * of the semantics of the POSIX ACL interfaces.
988 * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
989 * from a call to sys_acl_get_entry() should not be assumed to be
990 * valid after calling any of the following functions, which may
991 * reorder the entries in the ACL.
993 * sys_acl_valid()
994 * sys_acl_set_file()
995 * sys_acl_set_fd()
998 /* This checks if the POSIX ACL system call is defined */
999 /* which basically corresponds to whether JFS 3.3 or */
1000 /* higher is installed. If acl() was called when it */
1001 /* isn't defined, it causes the process to core dump */
1002 /* so it is important to check this and avoid acl() */
1003 /* calls if it isn't there. */
1005 static BOOL hpux_acl_call_presence(void)
1008 shl_t handle = NULL;
1009 void *value;
1010 int ret_val=0;
1011 static BOOL already_checked=0;
1013 if(already_checked)
1014 return True;
1017 ret_val = shl_findsym(&handle, "acl", TYPE_PROCEDURE, &value);
1019 if(ret_val != 0) {
1020 DEBUG(5, ("hpux_acl_call_presence: shl_findsym() returned %d, errno = %d, error %s\n",
1021 ret_val, errno, strerror(errno)));
1022 DEBUG(5,("hpux_acl_call_presence: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
1023 return False;
1026 DEBUG(10,("hpux_acl_call_presence: acl() system call is present. We have JFS 3.3 or above \n"));
1028 already_checked = True;
1029 return True;
1032 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1034 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
1035 errno = EINVAL;
1036 return -1;
1039 if (entry_p == NULL) {
1040 errno = EINVAL;
1041 return -1;
1044 if (entry_id == SMB_ACL_FIRST_ENTRY) {
1045 acl_d->next = 0;
1048 if (acl_d->next < 0) {
1049 errno = EINVAL;
1050 return -1;
1053 if (acl_d->next >= acl_d->count) {
1054 return 0;
1057 *entry_p = &acl_d->acl[acl_d->next++];
1059 return 1;
1062 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
1064 *type_p = entry_d->a_type;
1066 return 0;
1069 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1071 *permset_p = &entry_d->a_perm;
1073 return 0;
1076 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
1078 if (entry_d->a_type != SMB_ACL_USER
1079 && entry_d->a_type != SMB_ACL_GROUP) {
1080 errno = EINVAL;
1081 return NULL;
1084 return &entry_d->a_id;
1088 * There is no way of knowing what size the ACL returned by
1089 * ACL_GET will be unless you first call ACL_CNT which means
1090 * making an additional system call.
1092 * In the hope of avoiding the cost of the additional system
1093 * call in most cases, we initially allocate enough space for
1094 * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
1095 * be too small then we use ACL_CNT to find out the actual
1096 * size, reallocate the ACL buffer, and then call ACL_GET again.
1099 #define INITIAL_ACL_SIZE 16
1101 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
1103 SMB_ACL_T acl_d;
1104 int count; /* # of ACL entries allocated */
1105 int naccess; /* # of access ACL entries */
1106 int ndefault; /* # of default ACL entries */
1108 if(hpux_acl_call_presence() == False) {
1109 /* Looks like we don't have the acl() system call on HPUX.
1110 * May be the system doesn't have the latest version of JFS.
1112 return NULL;
1115 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
1116 errno = EINVAL;
1117 return NULL;
1120 count = INITIAL_ACL_SIZE;
1121 if ((acl_d = sys_acl_init(count)) == NULL) {
1122 return NULL;
1126 * If there isn't enough space for the ACL entries we use
1127 * ACL_CNT to determine the actual number of ACL entries
1128 * reallocate and try again. This is in a loop because it
1129 * is possible that someone else could modify the ACL and
1130 * increase the number of entries between the call to
1131 * ACL_CNT and the call to ACL_GET.
1133 while ((count = acl(path_p, ACL_GET, count, &acl_d->acl[0])) < 0 && errno == ENOSPC) {
1135 sys_acl_free_acl(acl_d);
1137 if ((count = acl(path_p, ACL_CNT, 0, NULL)) < 0) {
1138 return NULL;
1141 if ((acl_d = sys_acl_init(count)) == NULL) {
1142 return NULL;
1146 if (count < 0) {
1147 sys_acl_free_acl(acl_d);
1148 return NULL;
1152 * calculate the number of access and default ACL entries
1154 * Note: we assume that the acl() system call returned a
1155 * well formed ACL which is sorted so that all of the
1156 * access ACL entries preceed any default ACL entries
1158 for (naccess = 0; naccess < count; naccess++) {
1159 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
1160 break;
1162 ndefault = count - naccess;
1165 * if the caller wants the default ACL we have to copy
1166 * the entries down to the start of the acl[] buffer
1167 * and mask out the ACL_DEFAULT flag from the type field
1169 if (type == SMB_ACL_TYPE_DEFAULT) {
1170 int i, j;
1172 for (i = 0, j = naccess; i < ndefault; i++, j++) {
1173 acl_d->acl[i] = acl_d->acl[j];
1174 acl_d->acl[i].a_type &= ~ACL_DEFAULT;
1177 acl_d->count = ndefault;
1178 } else {
1179 acl_d->count = naccess;
1182 return acl_d;
1185 SMB_ACL_T sys_acl_get_fd(int fd)
1188 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1191 files_struct *fsp = file_find_fd(fd);
1193 if (fsp == NULL) {
1194 errno = EBADF;
1195 return NULL;
1199 * We know we're in the same conn context. So we
1200 * can use the relative path.
1203 return sys_acl_get_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
1206 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
1208 *permset_d = 0;
1210 return 0;
1213 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1215 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
1216 && perm != SMB_ACL_EXECUTE) {
1217 errno = EINVAL;
1218 return -1;
1221 if (permset_d == NULL) {
1222 errno = EINVAL;
1223 return -1;
1226 *permset_d |= perm;
1228 return 0;
1231 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
1233 return *permset_d & perm;
1236 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
1238 int i;
1239 int len, maxlen;
1240 char *text;
1243 * use an initial estimate of 20 bytes per ACL entry
1244 * when allocating memory for the text representation
1245 * of the ACL
1247 len = 0;
1248 maxlen = 20 * acl_d->count;
1249 if ((text = SMB_MALLOC(maxlen)) == NULL) {
1250 errno = ENOMEM;
1251 return NULL;
1254 for (i = 0; i < acl_d->count; i++) {
1255 struct acl *ap = &acl_d->acl[i];
1256 struct passwd *pw;
1257 struct group *gr;
1258 char tagbuf[12];
1259 char idbuf[12];
1260 char *tag;
1261 char *id = "";
1262 char perms[4];
1263 int nbytes;
1265 switch (ap->a_type) {
1267 * for debugging purposes it's probably more
1268 * useful to dump unknown tag types rather
1269 * than just returning an error
1271 default:
1272 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
1273 ap->a_type);
1274 tag = tagbuf;
1275 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
1276 (long)ap->a_id);
1277 id = idbuf;
1278 break;
1280 case SMB_ACL_USER:
1281 id = uidtoname(ap->a_id);
1282 case SMB_ACL_USER_OBJ:
1283 tag = "user";
1284 break;
1286 case SMB_ACL_GROUP:
1287 if ((gr = getgrgid(ap->a_id)) == NULL) {
1288 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
1289 (long)ap->a_id);
1290 id = idbuf;
1291 } else {
1292 id = gr->gr_name;
1294 case SMB_ACL_GROUP_OBJ:
1295 tag = "group";
1296 break;
1298 case SMB_ACL_OTHER:
1299 tag = "other";
1300 break;
1302 case SMB_ACL_MASK:
1303 tag = "mask";
1304 break;
1308 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
1309 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
1310 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
1311 perms[3] = '\0';
1313 /* <tag> : <qualifier> : rwx \n \0 */
1314 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
1317 * If this entry would overflow the buffer
1318 * allocate enough additional memory for this
1319 * entry and an estimate of another 20 bytes
1320 * for each entry still to be processed
1322 if ((len + nbytes) > maxlen) {
1323 char *oldtext = text;
1325 maxlen += nbytes + 20 * (acl_d->count - i);
1327 if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) {
1328 free(oldtext);
1329 errno = ENOMEM;
1330 return NULL;
1334 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
1335 len += nbytes - 1;
1338 if (len_p)
1339 *len_p = len;
1341 return text;
1344 SMB_ACL_T sys_acl_init(int count)
1346 SMB_ACL_T a;
1348 if (count < 0) {
1349 errno = EINVAL;
1350 return NULL;
1354 * note that since the definition of the structure pointed
1355 * to by the SMB_ACL_T includes the first element of the
1356 * acl[] array, this actually allocates an ACL with room
1357 * for (count+1) entries
1359 if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
1360 errno = ENOMEM;
1361 return NULL;
1364 a->size = count + 1;
1365 a->count = 0;
1366 a->next = -1;
1368 return a;
1372 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1374 SMB_ACL_T acl_d;
1375 SMB_ACL_ENTRY_T entry_d;
1377 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
1378 errno = EINVAL;
1379 return -1;
1382 if (acl_d->count >= acl_d->size) {
1383 errno = ENOSPC;
1384 return -1;
1387 entry_d = &acl_d->acl[acl_d->count++];
1388 entry_d->a_type = 0;
1389 entry_d->a_id = -1;
1390 entry_d->a_perm = 0;
1391 *entry_p = entry_d;
1393 return 0;
1396 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1398 switch (tag_type) {
1399 case SMB_ACL_USER:
1400 case SMB_ACL_USER_OBJ:
1401 case SMB_ACL_GROUP:
1402 case SMB_ACL_GROUP_OBJ:
1403 case SMB_ACL_OTHER:
1404 case SMB_ACL_MASK:
1405 entry_d->a_type = tag_type;
1406 break;
1407 default:
1408 errno = EINVAL;
1409 return -1;
1412 return 0;
1415 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
1417 if (entry_d->a_type != SMB_ACL_GROUP
1418 && entry_d->a_type != SMB_ACL_USER) {
1419 errno = EINVAL;
1420 return -1;
1423 entry_d->a_id = *((id_t *)qual_p);
1425 return 0;
1428 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1430 if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1431 return EINVAL;
1434 entry_d->a_perm = *permset_d;
1436 return 0;
1439 /* Structure to capture the count for each type of ACE. */
1441 struct hpux_acl_types {
1442 int n_user;
1443 int n_def_user;
1444 int n_user_obj;
1445 int n_def_user_obj;
1447 int n_group;
1448 int n_def_group;
1449 int n_group_obj;
1450 int n_def_group_obj;
1452 int n_other;
1453 int n_other_obj;
1454 int n_def_other_obj;
1456 int n_class_obj;
1457 int n_def_class_obj;
1459 int n_illegal_obj;
1462 /* count_obj:
1463 * Counts the different number of objects in a given array of ACL
1464 * structures.
1465 * Inputs:
1467 * acl_count - Count of ACLs in the array of ACL strucutres.
1468 * aclp - Array of ACL structures.
1469 * acl_type_count - Pointer to acl_types structure. Should already be
1470 * allocated.
1471 * Output:
1473 * acl_type_count - This structure is filled up with counts of various
1474 * acl types.
1477 static int hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_types *acl_type_count)
1479 int i;
1481 memset(acl_type_count, 0, sizeof(struct hpux_acl_types));
1483 for(i=0;i<acl_count;i++) {
1484 switch(aclp[i].a_type) {
1485 case USER:
1486 acl_type_count->n_user++;
1487 break;
1488 case USER_OBJ:
1489 acl_type_count->n_user_obj++;
1490 break;
1491 case DEF_USER_OBJ:
1492 acl_type_count->n_def_user_obj++;
1493 break;
1494 case GROUP:
1495 acl_type_count->n_group++;
1496 break;
1497 case GROUP_OBJ:
1498 acl_type_count->n_group_obj++;
1499 break;
1500 case DEF_GROUP_OBJ:
1501 acl_type_count->n_def_group_obj++;
1502 break;
1503 case OTHER_OBJ:
1504 acl_type_count->n_other_obj++;
1505 break;
1506 case DEF_OTHER_OBJ:
1507 acl_type_count->n_def_other_obj++;
1508 break;
1509 case CLASS_OBJ:
1510 acl_type_count->n_class_obj++;
1511 break;
1512 case DEF_CLASS_OBJ:
1513 acl_type_count->n_def_class_obj++;
1514 break;
1515 case DEF_USER:
1516 acl_type_count->n_def_user++;
1517 break;
1518 case DEF_GROUP:
1519 acl_type_count->n_def_group++;
1520 break;
1521 default:
1522 acl_type_count->n_illegal_obj++;
1523 break;
1528 /* swap_acl_entries: Swaps two ACL entries.
1530 * Inputs: aclp0, aclp1 - ACL entries to be swapped.
1533 static void hpux_swap_acl_entries(struct acl *aclp0, struct acl *aclp1)
1535 struct acl temp_acl;
1537 temp_acl.a_type = aclp0->a_type;
1538 temp_acl.a_id = aclp0->a_id;
1539 temp_acl.a_perm = aclp0->a_perm;
1541 aclp0->a_type = aclp1->a_type;
1542 aclp0->a_id = aclp1->a_id;
1543 aclp0->a_perm = aclp1->a_perm;
1545 aclp1->a_type = temp_acl.a_type;
1546 aclp1->a_id = temp_acl.a_id;
1547 aclp1->a_perm = temp_acl.a_perm;
1550 /* prohibited_duplicate_type
1551 * Identifies if given ACL type can have duplicate entries or
1552 * not.
1554 * Inputs: acl_type - ACL Type.
1556 * Outputs:
1558 * Return..
1560 * True - If the ACL type matches any of the prohibited types.
1561 * False - If the ACL type doesn't match any of the prohibited types.
1564 static BOOL hpux_prohibited_duplicate_type(int acl_type)
1566 switch(acl_type) {
1567 case USER:
1568 case GROUP:
1569 case DEF_USER:
1570 case DEF_GROUP:
1571 return True;
1572 default:
1573 return False;
1577 /* get_needed_class_perm
1578 * Returns the permissions of a ACL structure only if the ACL
1579 * type matches one of the pre-determined types for computing
1580 * CLASS_OBJ permissions.
1582 * Inputs: aclp - Pointer to ACL structure.
1585 static int hpux_get_needed_class_perm(struct acl *aclp)
1587 switch(aclp->a_type) {
1588 case USER:
1589 case GROUP_OBJ:
1590 case GROUP:
1591 case DEF_USER_OBJ:
1592 case DEF_USER:
1593 case DEF_GROUP_OBJ:
1594 case DEF_GROUP:
1595 case DEF_CLASS_OBJ:
1596 case DEF_OTHER_OBJ:
1597 return aclp->a_perm;
1598 default:
1599 return 0;
1603 /* acl_sort for HPUX.
1604 * Sorts the array of ACL structures as per the description in
1605 * aclsort man page. Refer to aclsort man page for more details
1607 * Inputs:
1609 * acl_count - Count of ACLs in the array of ACL structures.
1610 * calclass - If this is not zero, then we compute the CLASS_OBJ
1611 * permissions.
1612 * aclp - Array of ACL structures.
1614 * Outputs:
1616 * aclp - Sorted array of ACL structures.
1618 * Outputs:
1620 * Returns 0 for success -1 for failure. Prints a message to the Samba
1621 * debug log in case of failure.
1624 static int hpux_acl_sort(int acl_count, int calclass, struct acl *aclp)
1626 #if !defined(HAVE_HPUX_ACLSORT)
1628 * The aclsort() system call is availabe on the latest HPUX General
1629 * Patch Bundles. So for HPUX, we developed our version of acl_sort
1630 * function. Because, we don't want to update to a new
1631 * HPUX GR bundle just for aclsort() call.
1634 struct hpux_acl_types acl_obj_count;
1635 int n_class_obj_perm = 0;
1636 int i, j;
1638 if(!acl_count) {
1639 DEBUG(10,("Zero acl count passed. Returning Success\n"));
1640 return 0;
1643 if(aclp == NULL) {
1644 DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
1645 return -1;
1648 /* Count different types of ACLs in the ACLs array */
1650 hpux_count_obj(acl_count, aclp, &acl_obj_count);
1652 /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
1653 * CLASS_OBJ and OTHER_OBJ
1656 if( (acl_obj_count.n_user_obj != 1) ||
1657 (acl_obj_count.n_group_obj != 1) ||
1658 (acl_obj_count.n_class_obj != 1) ||
1659 (acl_obj_count.n_other_obj != 1)
1661 DEBUG(0,("hpux_acl_sort: More than one entry or no entries for \
1662 USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
1663 return -1;
1666 /* If any of the default objects are present, there should be only
1667 * one of them each.
1670 if( (acl_obj_count.n_def_user_obj > 1) || (acl_obj_count.n_def_group_obj > 1) ||
1671 (acl_obj_count.n_def_other_obj > 1) || (acl_obj_count.n_def_class_obj > 1) ) {
1672 DEBUG(0,("hpux_acl_sort: More than one entry for DEF_CLASS_OBJ \
1673 or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
1674 return -1;
1677 /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
1678 * structures.
1680 * Sorting crieteria - First sort by ACL type. If there are multiple entries of
1681 * same ACL type, sort by ACL id.
1683 * I am using the trival kind of sorting method here because, performance isn't
1684 * really effected by the ACLs feature. More over there aren't going to be more
1685 * than 17 entries on HPUX.
1688 for(i=0; i<acl_count;i++) {
1689 for (j=i+1; j<acl_count; j++) {
1690 if( aclp[i].a_type > aclp[j].a_type ) {
1691 /* ACL entries out of order, swap them */
1693 hpux_swap_acl_entries((aclp+i), (aclp+j));
1695 } else if ( aclp[i].a_type == aclp[j].a_type ) {
1697 /* ACL entries of same type, sort by id */
1699 if(aclp[i].a_id > aclp[j].a_id) {
1700 hpux_swap_acl_entries((aclp+i), (aclp+j));
1701 } else if (aclp[i].a_id == aclp[j].a_id) {
1702 /* We have a duplicate entry. */
1703 if(hpux_prohibited_duplicate_type(aclp[i].a_type)) {
1704 DEBUG(0, ("hpux_acl_sort: Duplicate entry: Type(hex): %x Id: %d\n",
1705 aclp[i].a_type, aclp[i].a_id));
1706 return -1;
1714 /* set the class obj permissions to the computed one. */
1715 if(calclass) {
1716 int n_class_obj_index = -1;
1718 for(i=0;i<acl_count;i++) {
1719 n_class_obj_perm |= hpux_get_needed_class_perm((aclp+i));
1721 if(aclp[i].a_type == CLASS_OBJ)
1722 n_class_obj_index = i;
1724 aclp[n_class_obj_index].a_perm = n_class_obj_perm;
1727 return 0;
1728 #else
1729 return aclsort(acl_count, calclass, aclp);
1730 #endif
1734 * sort the ACL and check it for validity
1736 * if it's a minimal ACL with only 4 entries then we
1737 * need to recalculate the mask permissions to make
1738 * sure that they are the same as the GROUP_OBJ
1739 * permissions as required by the UnixWare acl() system call.
1741 * (note: since POSIX allows minimal ACLs which only contain
1742 * 3 entries - ie there is no mask entry - we should, in theory,
1743 * check for this and add a mask entry if necessary - however
1744 * we "know" that the caller of this interface always specifies
1745 * a mask so, in practice "this never happens" (tm) - if it *does*
1746 * happen aclsort() will fail and return an error and someone will
1747 * have to fix it ...)
1750 static int acl_sort(SMB_ACL_T acl_d)
1752 int fixmask = (acl_d->count <= 4);
1754 if (hpux_acl_sort(acl_d->count, fixmask, acl_d->acl) != 0) {
1755 errno = EINVAL;
1756 return -1;
1758 return 0;
1761 int sys_acl_valid(SMB_ACL_T acl_d)
1763 return acl_sort(acl_d);
1766 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
1768 struct stat s;
1769 struct acl *acl_p;
1770 int acl_count;
1771 struct acl *acl_buf = NULL;
1772 int ret;
1774 if(hpux_acl_call_presence() == False) {
1775 /* Looks like we don't have the acl() system call on HPUX.
1776 * May be the system doesn't have the latest version of JFS.
1778 errno=ENOSYS;
1779 return -1;
1782 if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
1783 errno = EINVAL;
1784 return -1;
1787 if (acl_sort(acl_d) != 0) {
1788 return -1;
1791 acl_p = &acl_d->acl[0];
1792 acl_count = acl_d->count;
1795 * if it's a directory there is extra work to do
1796 * since the acl() system call will replace both
1797 * the access ACLs and the default ACLs (if any)
1799 if (stat(name, &s) != 0) {
1800 return -1;
1802 if (S_ISDIR(s.st_mode)) {
1803 SMB_ACL_T acc_acl;
1804 SMB_ACL_T def_acl;
1805 SMB_ACL_T tmp_acl;
1806 int i;
1808 if (type == SMB_ACL_TYPE_ACCESS) {
1809 acc_acl = acl_d;
1810 def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
1812 } else {
1813 def_acl = acl_d;
1814 acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
1817 if (tmp_acl == NULL) {
1818 return -1;
1822 * allocate a temporary buffer for the complete ACL
1824 acl_count = acc_acl->count + def_acl->count;
1825 acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
1827 if (acl_buf == NULL) {
1828 sys_acl_free_acl(tmp_acl);
1829 errno = ENOMEM;
1830 return -1;
1834 * copy the access control and default entries into the buffer
1836 memcpy(&acl_buf[0], &acc_acl->acl[0],
1837 acc_acl->count * sizeof(acl_buf[0]));
1839 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
1840 def_acl->count * sizeof(acl_buf[0]));
1843 * set the ACL_DEFAULT flag on the default entries
1845 for (i = acc_acl->count; i < acl_count; i++) {
1846 acl_buf[i].a_type |= ACL_DEFAULT;
1849 sys_acl_free_acl(tmp_acl);
1851 } else if (type != SMB_ACL_TYPE_ACCESS) {
1852 errno = EINVAL;
1853 return -1;
1856 ret = acl(name, ACL_SET, acl_count, acl_p);
1858 if (acl_buf) {
1859 free(acl_buf);
1862 return ret;
1865 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
1868 * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1871 files_struct *fsp = file_find_fd(fd);
1873 if (fsp == NULL) {
1874 errno = EBADF;
1875 return NULL;
1878 if (acl_sort(acl_d) != 0) {
1879 return -1;
1883 * We know we're in the same conn context. So we
1884 * can use the relative path.
1887 return sys_acl_set_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS, acl_d);
1890 int sys_acl_delete_def_file(const char *path)
1892 SMB_ACL_T acl_d;
1893 int ret;
1896 * fetching the access ACL and rewriting it has
1897 * the effect of deleting the default ACL
1899 if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
1900 return -1;
1903 ret = acl(path, ACL_SET, acl_d->count, acl_d->acl);
1905 sys_acl_free_acl(acl_d);
1907 return ret;
1910 int sys_acl_free_text(char *text)
1912 free(text);
1913 return 0;
1916 int sys_acl_free_acl(SMB_ACL_T acl_d)
1918 free(acl_d);
1919 return 0;
1922 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
1924 return 0;
1927 #elif defined(HAVE_IRIX_ACLS)
1929 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1931 if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
1932 errno = EINVAL;
1933 return -1;
1936 if (entry_p == NULL) {
1937 errno = EINVAL;
1938 return -1;
1941 if (entry_id == SMB_ACL_FIRST_ENTRY) {
1942 acl_d->next = 0;
1945 if (acl_d->next < 0) {
1946 errno = EINVAL;
1947 return -1;
1950 if (acl_d->next >= acl_d->aclp->acl_cnt) {
1951 return 0;
1954 *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
1956 return 1;
1959 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
1961 *type_p = entry_d->ae_tag;
1963 return 0;
1966 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1968 *permset_p = entry_d;
1970 return 0;
1973 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
1975 if (entry_d->ae_tag != SMB_ACL_USER
1976 && entry_d->ae_tag != SMB_ACL_GROUP) {
1977 errno = EINVAL;
1978 return NULL;
1981 return &entry_d->ae_id;
1984 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
1986 SMB_ACL_T a;
1988 if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
1989 errno = ENOMEM;
1990 return NULL;
1992 if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
1993 SAFE_FREE(a);
1994 return NULL;
1996 a->next = -1;
1997 a->freeaclp = True;
1998 return a;
2001 SMB_ACL_T sys_acl_get_fd(int fd)
2003 SMB_ACL_T a;
2005 if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
2006 errno = ENOMEM;
2007 return NULL;
2009 if ((a->aclp = acl_get_fd(fd)) == NULL) {
2010 SAFE_FREE(a);
2011 return NULL;
2013 a->next = -1;
2014 a->freeaclp = True;
2015 return a;
2018 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
2020 permset_d->ae_perm = 0;
2022 return 0;
2025 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
2027 if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
2028 && perm != SMB_ACL_EXECUTE) {
2029 errno = EINVAL;
2030 return -1;
2033 if (permset_d == NULL) {
2034 errno = EINVAL;
2035 return -1;
2038 permset_d->ae_perm |= perm;
2040 return 0;
2043 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
2045 return permset_d->ae_perm & perm;
2048 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
2050 return acl_to_text(acl_d->aclp, len_p);
2053 SMB_ACL_T sys_acl_init(int count)
2055 SMB_ACL_T a;
2057 if (count < 0) {
2058 errno = EINVAL;
2059 return NULL;
2062 if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + sizeof(struct acl))) == NULL) {
2063 errno = ENOMEM;
2064 return NULL;
2067 a->next = -1;
2068 a->freeaclp = False;
2069 a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
2070 a->aclp->acl_cnt = 0;
2072 return a;
2076 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
2078 SMB_ACL_T acl_d;
2079 SMB_ACL_ENTRY_T entry_d;
2081 if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
2082 errno = EINVAL;
2083 return -1;
2086 if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
2087 errno = ENOSPC;
2088 return -1;
2091 entry_d = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
2092 entry_d->ae_tag = 0;
2093 entry_d->ae_id = 0;
2094 entry_d->ae_perm = 0;
2095 *entry_p = entry_d;
2097 return 0;
2100 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
2102 switch (tag_type) {
2103 case SMB_ACL_USER:
2104 case SMB_ACL_USER_OBJ:
2105 case SMB_ACL_GROUP:
2106 case SMB_ACL_GROUP_OBJ:
2107 case SMB_ACL_OTHER:
2108 case SMB_ACL_MASK:
2109 entry_d->ae_tag = tag_type;
2110 break;
2111 default:
2112 errno = EINVAL;
2113 return -1;
2116 return 0;
2119 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
2121 if (entry_d->ae_tag != SMB_ACL_GROUP
2122 && entry_d->ae_tag != SMB_ACL_USER) {
2123 errno = EINVAL;
2124 return -1;
2127 entry_d->ae_id = *((id_t *)qual_p);
2129 return 0;
2132 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
2134 if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
2135 return EINVAL;
2138 entry_d->ae_perm = permset_d->ae_perm;
2140 return 0;
2143 int sys_acl_valid(SMB_ACL_T acl_d)
2145 return acl_valid(acl_d->aclp);
2148 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
2150 return acl_set_file(name, type, acl_d->aclp);
2153 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
2155 return acl_set_fd(fd, acl_d->aclp);
2158 int sys_acl_delete_def_file(const char *name)
2160 return acl_delete_def_file(name);
2163 int sys_acl_free_text(char *text)
2165 return acl_free(text);
2168 int sys_acl_free_acl(SMB_ACL_T acl_d)
2170 if (acl_d->freeaclp) {
2171 acl_free(acl_d->aclp);
2173 acl_free(acl_d);
2174 return 0;
2177 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
2179 return 0;
2182 #elif defined(HAVE_AIX_ACLS)
2184 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
2186 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
2188 struct acl_entry_link *link;
2189 struct new_acl_entry *entry;
2190 int keep_going;
2192 DEBUG(10,("This is the count: %d\n",theacl->count));
2194 /* Check if count was previously set to -1. *
2195 * If it was, that means we reached the end *
2196 * of the acl last time. */
2197 if(theacl->count == -1)
2198 return(0);
2200 link = theacl;
2201 /* To get to the next acl, traverse linked list until index *
2202 * of acl matches the count we are keeping. This count is *
2203 * incremented each time we return an acl entry. */
2205 for(keep_going = 0; keep_going < theacl->count; keep_going++)
2206 link = link->nextp;
2208 entry = *entry_p = link->entryp;
2210 DEBUG(10,("*entry_p is %d\n",entry_p));
2211 DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
2213 /* Increment count */
2214 theacl->count++;
2215 if(link->nextp == NULL)
2216 theacl->count = -1;
2218 return(1);
2221 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
2223 /* Initialize tag type */
2225 *tag_type_p = -1;
2226 DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
2228 /* Depending on what type of entry we have, *
2229 * return tag type. */
2230 switch(entry_d->ace_id->id_type) {
2231 case ACEID_USER:
2232 *tag_type_p = SMB_ACL_USER;
2233 break;
2234 case ACEID_GROUP:
2235 *tag_type_p = SMB_ACL_GROUP;
2236 break;
2238 case SMB_ACL_USER_OBJ:
2239 case SMB_ACL_GROUP_OBJ:
2240 case SMB_ACL_OTHER:
2241 *tag_type_p = entry_d->ace_id->id_type;
2242 break;
2244 default:
2245 return(-1);
2248 return(0);
2251 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
2253 DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
2254 *permset_p = &entry_d->ace_access;
2255 DEBUG(10,("**permset_p is %d\n",**permset_p));
2256 if(!(**permset_p & S_IXUSR) &&
2257 !(**permset_p & S_IWUSR) &&
2258 !(**permset_p & S_IRUSR) &&
2259 (**permset_p != 0))
2260 return(-1);
2262 DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
2263 return(0);
2266 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
2268 return(entry_d->ace_id->id_data);
2271 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
2273 struct acl *file_acl = (struct acl *)NULL;
2274 struct acl_entry *acl_entry;
2275 struct new_acl_entry *new_acl_entry;
2276 struct ace_id *idp;
2277 struct acl_entry_link *acl_entry_link;
2278 struct acl_entry_link *acl_entry_link_head;
2279 int i;
2280 int rc = 0;
2281 uid_t user_id;
2283 /* AIX has no DEFAULT */
2284 if ( type == SMB_ACL_TYPE_DEFAULT )
2285 return NULL;
2287 /* Get the acl using statacl */
2289 DEBUG(10,("Entering sys_acl_get_file\n"));
2290 DEBUG(10,("path_p is %s\n",path_p));
2292 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2294 if(file_acl == NULL) {
2295 errno=ENOMEM;
2296 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
2297 return(NULL);
2300 memset(file_acl,0,BUFSIZ);
2302 rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
2303 if(rc == -1) {
2304 DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
2305 SAFE_FREE(file_acl);
2306 return(NULL);
2309 DEBUG(10,("Got facl and returned it\n"));
2311 /* Point to the first acl entry in the acl */
2312 acl_entry = file_acl->acl_ext;
2314 /* Begin setting up the head of the linked list *
2315 * that will be used for the storing the acl *
2316 * in a way that is useful for the posix_acls.c *
2317 * code. */
2319 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
2320 if(acl_entry_link_head == NULL)
2321 return(NULL);
2323 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2324 if(acl_entry_link->entryp == NULL) {
2325 SAFE_FREE(file_acl);
2326 errno = ENOMEM;
2327 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2328 return(NULL);
2331 DEBUG(10,("acl_entry is %d\n",acl_entry));
2332 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
2334 /* Check if the extended acl bit is on. *
2335 * If it isn't, do not show the *
2336 * contents of the acl since AIX intends *
2337 * the extended info to remain unused */
2339 if(file_acl->acl_mode & S_IXACL){
2340 /* while we are not pointing to the very end */
2341 while(acl_entry < acl_last(file_acl)) {
2342 /* before we malloc anything, make sure this is */
2343 /* a valid acl entry and one that we want to map */
2344 idp = id_nxt(acl_entry->ace_id);
2345 if((acl_entry->ace_type == ACC_SPECIFY ||
2346 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
2347 acl_entry = acl_nxt(acl_entry);
2348 continue;
2351 idp = acl_entry->ace_id;
2353 /* Check if this is the first entry in the linked list. *
2354 * The first entry needs to keep prevp pointing to NULL *
2355 * and already has entryp allocated. */
2357 if(acl_entry_link_head->count != 0) {
2358 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2360 if(acl_entry_link->nextp == NULL) {
2361 SAFE_FREE(file_acl);
2362 errno = ENOMEM;
2363 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2364 return(NULL);
2367 acl_entry_link->nextp->prevp = acl_entry_link;
2368 acl_entry_link = acl_entry_link->nextp;
2369 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2370 if(acl_entry_link->entryp == NULL) {
2371 SAFE_FREE(file_acl);
2372 errno = ENOMEM;
2373 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2374 return(NULL);
2376 acl_entry_link->nextp = NULL;
2379 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
2381 /* Don't really need this since all types are going *
2382 * to be specified but, it's better than leaving it 0 */
2384 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
2386 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2388 memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
2390 /* The access in the acl entries must be left shifted by *
2391 * three bites, because they will ultimately be compared *
2392 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2394 switch(acl_entry->ace_type){
2395 case ACC_PERMIT:
2396 case ACC_SPECIFY:
2397 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2398 acl_entry_link->entryp->ace_access <<= 6;
2399 acl_entry_link_head->count++;
2400 break;
2401 case ACC_DENY:
2402 /* Since there is no way to return a DENY acl entry *
2403 * change to PERMIT and then shift. */
2404 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
2405 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
2406 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
2407 acl_entry_link->entryp->ace_access <<= 6;
2408 acl_entry_link_head->count++;
2409 break;
2410 default:
2411 return(0);
2414 DEBUG(10,("acl_entry = %d\n",acl_entry));
2415 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
2417 acl_entry = acl_nxt(acl_entry);
2419 } /* end of if enabled */
2421 /* Since owner, group, other acl entries are not *
2422 * part of the acl entries in an acl, they must *
2423 * be dummied up to become part of the list. */
2425 for( i = 1; i < 4; i++) {
2426 DEBUG(10,("i is %d\n",i));
2427 if(acl_entry_link_head->count != 0) {
2428 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2429 if(acl_entry_link->nextp == NULL) {
2430 SAFE_FREE(file_acl);
2431 errno = ENOMEM;
2432 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2433 return(NULL);
2436 acl_entry_link->nextp->prevp = acl_entry_link;
2437 acl_entry_link = acl_entry_link->nextp;
2438 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2439 if(acl_entry_link->entryp == NULL) {
2440 SAFE_FREE(file_acl);
2441 errno = ENOMEM;
2442 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
2443 return(NULL);
2447 acl_entry_link->nextp = NULL;
2449 new_acl_entry = acl_entry_link->entryp;
2450 idp = new_acl_entry->ace_id;
2452 new_acl_entry->ace_len = sizeof(struct acl_entry);
2453 new_acl_entry->ace_type = ACC_PERMIT;
2454 idp->id_len = sizeof(struct ace_id);
2455 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
2456 memset(idp->id_data,0,sizeof(uid_t));
2458 switch(i) {
2459 case 2:
2460 new_acl_entry->ace_access = file_acl->g_access << 6;
2461 idp->id_type = SMB_ACL_GROUP_OBJ;
2462 break;
2464 case 3:
2465 new_acl_entry->ace_access = file_acl->o_access << 6;
2466 idp->id_type = SMB_ACL_OTHER;
2467 break;
2469 case 1:
2470 new_acl_entry->ace_access = file_acl->u_access << 6;
2471 idp->id_type = SMB_ACL_USER_OBJ;
2472 break;
2474 default:
2475 return(NULL);
2479 acl_entry_link_head->count++;
2480 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
2483 acl_entry_link_head->count = 0;
2484 SAFE_FREE(file_acl);
2486 return(acl_entry_link_head);
2489 SMB_ACL_T sys_acl_get_fd(int fd)
2491 struct acl *file_acl = (struct acl *)NULL;
2492 struct acl_entry *acl_entry;
2493 struct new_acl_entry *new_acl_entry;
2494 struct ace_id *idp;
2495 struct acl_entry_link *acl_entry_link;
2496 struct acl_entry_link *acl_entry_link_head;
2497 int i;
2498 int rc = 0;
2499 uid_t user_id;
2501 /* Get the acl using fstatacl */
2503 DEBUG(10,("Entering sys_acl_get_fd\n"));
2504 DEBUG(10,("fd is %d\n",fd));
2505 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2507 if(file_acl == NULL) {
2508 errno=ENOMEM;
2509 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2510 return(NULL);
2513 memset(file_acl,0,BUFSIZ);
2515 rc = fstatacl(fd,0,file_acl,BUFSIZ);
2516 if(rc == -1) {
2517 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
2518 SAFE_FREE(file_acl);
2519 return(NULL);
2522 DEBUG(10,("Got facl and returned it\n"));
2524 /* Point to the first acl entry in the acl */
2526 acl_entry = file_acl->acl_ext;
2527 /* Begin setting up the head of the linked list *
2528 * that will be used for the storing the acl *
2529 * in a way that is useful for the posix_acls.c *
2530 * code. */
2532 acl_entry_link_head = acl_entry_link = sys_acl_init(0);
2533 if(acl_entry_link_head == NULL){
2534 SAFE_FREE(file_acl);
2535 return(NULL);
2538 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2540 if(acl_entry_link->entryp == NULL) {
2541 errno = ENOMEM;
2542 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2543 SAFE_FREE(file_acl);
2544 return(NULL);
2547 DEBUG(10,("acl_entry is %d\n",acl_entry));
2548 DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
2550 /* Check if the extended acl bit is on. *
2551 * If it isn't, do not show the *
2552 * contents of the acl since AIX intends *
2553 * the extended info to remain unused */
2555 if(file_acl->acl_mode & S_IXACL){
2556 /* while we are not pointing to the very end */
2557 while(acl_entry < acl_last(file_acl)) {
2558 /* before we malloc anything, make sure this is */
2559 /* a valid acl entry and one that we want to map */
2561 idp = id_nxt(acl_entry->ace_id);
2562 if((acl_entry->ace_type == ACC_SPECIFY ||
2563 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
2564 acl_entry = acl_nxt(acl_entry);
2565 continue;
2568 idp = acl_entry->ace_id;
2570 /* Check if this is the first entry in the linked list. *
2571 * The first entry needs to keep prevp pointing to NULL *
2572 * and already has entryp allocated. */
2574 if(acl_entry_link_head->count != 0) {
2575 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2576 if(acl_entry_link->nextp == NULL) {
2577 errno = ENOMEM;
2578 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2579 SAFE_FREE(file_acl);
2580 return(NULL);
2582 acl_entry_link->nextp->prevp = acl_entry_link;
2583 acl_entry_link = acl_entry_link->nextp;
2584 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2585 if(acl_entry_link->entryp == NULL) {
2586 errno = ENOMEM;
2587 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2588 SAFE_FREE(file_acl);
2589 return(NULL);
2592 acl_entry_link->nextp = NULL;
2595 acl_entry_link->entryp->ace_len = acl_entry->ace_len;
2597 /* Don't really need this since all types are going *
2598 * to be specified but, it's better than leaving it 0 */
2600 acl_entry_link->entryp->ace_type = acl_entry->ace_type;
2601 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2603 memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
2605 /* The access in the acl entries must be left shifted by *
2606 * three bites, because they will ultimately be compared *
2607 * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2609 switch(acl_entry->ace_type){
2610 case ACC_PERMIT:
2611 case ACC_SPECIFY:
2612 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2613 acl_entry_link->entryp->ace_access <<= 6;
2614 acl_entry_link_head->count++;
2615 break;
2616 case ACC_DENY:
2617 /* Since there is no way to return a DENY acl entry *
2618 * change to PERMIT and then shift. */
2619 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
2620 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
2621 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
2622 acl_entry_link->entryp->ace_access <<= 6;
2623 acl_entry_link_head->count++;
2624 break;
2625 default:
2626 return(0);
2629 DEBUG(10,("acl_entry = %d\n",acl_entry));
2630 DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
2632 acl_entry = acl_nxt(acl_entry);
2634 } /* end of if enabled */
2636 /* Since owner, group, other acl entries are not *
2637 * part of the acl entries in an acl, they must *
2638 * be dummied up to become part of the list. */
2640 for( i = 1; i < 4; i++) {
2641 DEBUG(10,("i is %d\n",i));
2642 if(acl_entry_link_head->count != 0){
2643 acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2644 if(acl_entry_link->nextp == NULL) {
2645 errno = ENOMEM;
2646 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2647 SAFE_FREE(file_acl);
2648 return(NULL);
2651 acl_entry_link->nextp->prevp = acl_entry_link;
2652 acl_entry_link = acl_entry_link->nextp;
2653 acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2655 if(acl_entry_link->entryp == NULL) {
2656 SAFE_FREE(file_acl);
2657 errno = ENOMEM;
2658 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2659 return(NULL);
2663 acl_entry_link->nextp = NULL;
2665 new_acl_entry = acl_entry_link->entryp;
2666 idp = new_acl_entry->ace_id;
2668 new_acl_entry->ace_len = sizeof(struct acl_entry);
2669 new_acl_entry->ace_type = ACC_PERMIT;
2670 idp->id_len = sizeof(struct ace_id);
2671 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
2672 memset(idp->id_data,0,sizeof(uid_t));
2674 switch(i) {
2675 case 2:
2676 new_acl_entry->ace_access = file_acl->g_access << 6;
2677 idp->id_type = SMB_ACL_GROUP_OBJ;
2678 break;
2680 case 3:
2681 new_acl_entry->ace_access = file_acl->o_access << 6;
2682 idp->id_type = SMB_ACL_OTHER;
2683 break;
2685 case 1:
2686 new_acl_entry->ace_access = file_acl->u_access << 6;
2687 idp->id_type = SMB_ACL_USER_OBJ;
2688 break;
2690 default:
2691 return(NULL);
2694 acl_entry_link_head->count++;
2695 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
2698 acl_entry_link_head->count = 0;
2699 SAFE_FREE(file_acl);
2701 return(acl_entry_link_head);
2704 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
2706 *permset = *permset & ~0777;
2707 return(0);
2710 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2712 if((perm != 0) &&
2713 (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0)
2714 return(-1);
2716 *permset |= perm;
2717 DEBUG(10,("This is the permset now: %d\n",*permset));
2718 return(0);
2721 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
2723 return(NULL);
2726 SMB_ACL_T sys_acl_init( int count)
2728 struct acl_entry_link *theacl = NULL;
2730 DEBUG(10,("Entering sys_acl_init\n"));
2732 theacl = SMB_MALLOC_P(struct acl_entry_link);
2733 if(theacl == NULL) {
2734 errno = ENOMEM;
2735 DEBUG(0,("Error in sys_acl_init is %d\n",errno));
2736 return(NULL);
2739 theacl->count = 0;
2740 theacl->nextp = NULL;
2741 theacl->prevp = NULL;
2742 theacl->entryp = NULL;
2743 DEBUG(10,("Exiting sys_acl_init\n"));
2744 return(theacl);
2747 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2749 struct acl_entry_link *theacl;
2750 struct acl_entry_link *acl_entryp;
2751 struct acl_entry_link *temp_entry;
2752 int counting;
2754 DEBUG(10,("Entering the sys_acl_create_entry\n"));
2756 theacl = acl_entryp = *pacl;
2758 /* Get to the end of the acl before adding entry */
2760 for(counting=0; counting < theacl->count; counting++){
2761 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
2762 temp_entry = acl_entryp;
2763 acl_entryp = acl_entryp->nextp;
2766 if(theacl->count != 0){
2767 temp_entry->nextp = acl_entryp = SMB_MALLOC_P(struct acl_entry_link);
2768 if(acl_entryp == NULL) {
2769 errno = ENOMEM;
2770 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
2771 return(-1);
2774 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
2775 acl_entryp->prevp = temp_entry;
2776 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
2779 *pentry = acl_entryp->entryp = SMB_MALLOC_P(struct new_acl_entry);
2780 if(*pentry == NULL) {
2781 errno = ENOMEM;
2782 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
2783 return(-1);
2786 memset(*pentry,0,sizeof(struct new_acl_entry));
2787 acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
2788 acl_entryp->entryp->ace_type = ACC_PERMIT;
2789 acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
2790 acl_entryp->nextp = NULL;
2791 theacl->count++;
2792 DEBUG(10,("Exiting sys_acl_create_entry\n"));
2793 return(0);
2796 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2798 DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
2799 entry->ace_id->id_type = tagtype;
2800 DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
2801 DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
2804 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
2806 DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
2807 memcpy(entry->ace_id->id_data,qual,sizeof(uid_t));
2808 DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
2809 return(0);
2812 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2814 DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
2815 if(!(*permset & S_IXUSR) &&
2816 !(*permset & S_IWUSR) &&
2817 !(*permset & S_IRUSR) &&
2818 (*permset != 0))
2819 return(-1);
2821 entry->ace_access = *permset;
2822 DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
2823 DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
2824 return(0);
2827 int sys_acl_valid( SMB_ACL_T theacl )
2829 int user_obj = 0;
2830 int group_obj = 0;
2831 int other_obj = 0;
2832 struct acl_entry_link *acl_entry;
2834 for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
2835 user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
2836 group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
2837 other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
2840 DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
2842 if(user_obj != 1 || group_obj != 1 || other_obj != 1)
2843 return(-1);
2845 return(0);
2848 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2850 struct acl_entry_link *acl_entry_link = NULL;
2851 struct acl *file_acl = NULL;
2852 struct acl *file_acl_temp = NULL;
2853 struct acl_entry *acl_entry = NULL;
2854 struct ace_id *ace_id = NULL;
2855 uint id_type;
2856 uint ace_access;
2857 uint user_id;
2858 uint acl_length;
2859 uint rc;
2861 DEBUG(10,("Entering sys_acl_set_file\n"));
2862 DEBUG(10,("File name is %s\n",name));
2864 /* AIX has no default ACL */
2865 if(acltype == SMB_ACL_TYPE_DEFAULT)
2866 return(0);
2868 acl_length = BUFSIZ;
2869 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2871 if(file_acl == NULL) {
2872 errno = ENOMEM;
2873 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2874 return(-1);
2877 memset(file_acl,0,BUFSIZ);
2879 file_acl->acl_len = ACL_SIZ;
2880 file_acl->acl_mode = S_IXACL;
2882 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2883 acl_entry_link->entryp->ace_access >>= 6;
2884 id_type = acl_entry_link->entryp->ace_id->id_type;
2886 switch(id_type) {
2887 case SMB_ACL_USER_OBJ:
2888 file_acl->u_access = acl_entry_link->entryp->ace_access;
2889 continue;
2890 case SMB_ACL_GROUP_OBJ:
2891 file_acl->g_access = acl_entry_link->entryp->ace_access;
2892 continue;
2893 case SMB_ACL_OTHER:
2894 file_acl->o_access = acl_entry_link->entryp->ace_access;
2895 continue;
2896 case SMB_ACL_MASK:
2897 continue;
2900 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2901 acl_length += sizeof(struct acl_entry);
2902 file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
2903 if(file_acl_temp == NULL) {
2904 SAFE_FREE(file_acl);
2905 errno = ENOMEM;
2906 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2907 return(-1);
2910 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2911 SAFE_FREE(file_acl);
2912 file_acl = file_acl_temp;
2915 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2916 file_acl->acl_len += sizeof(struct acl_entry);
2917 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2918 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2920 /* In order to use this, we'll need to wait until we can get denies */
2921 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2922 acl_entry->ace_type = ACC_SPECIFY; */
2924 acl_entry->ace_type = ACC_SPECIFY;
2926 ace_id = acl_entry->ace_id;
2928 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2929 DEBUG(10,("The id type is %d\n",ace_id->id_type));
2930 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2931 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2932 memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
2935 rc = chacl(name,file_acl,file_acl->acl_len);
2936 DEBUG(10,("errno is %d\n",errno));
2937 DEBUG(10,("return code is %d\n",rc));
2938 SAFE_FREE(file_acl);
2939 DEBUG(10,("Exiting the sys_acl_set_file\n"));
2940 return(rc);
2943 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2945 struct acl_entry_link *acl_entry_link = NULL;
2946 struct acl *file_acl = NULL;
2947 struct acl *file_acl_temp = NULL;
2948 struct acl_entry *acl_entry = NULL;
2949 struct ace_id *ace_id = NULL;
2950 uint id_type;
2951 uint user_id;
2952 uint acl_length;
2953 uint rc;
2955 DEBUG(10,("Entering sys_acl_set_fd\n"));
2956 acl_length = BUFSIZ;
2957 file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2959 if(file_acl == NULL) {
2960 errno = ENOMEM;
2961 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2962 return(-1);
2965 memset(file_acl,0,BUFSIZ);
2967 file_acl->acl_len = ACL_SIZ;
2968 file_acl->acl_mode = S_IXACL;
2970 for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2971 acl_entry_link->entryp->ace_access >>= 6;
2972 id_type = acl_entry_link->entryp->ace_id->id_type;
2973 DEBUG(10,("The id_type is %d\n",id_type));
2975 switch(id_type) {
2976 case SMB_ACL_USER_OBJ:
2977 file_acl->u_access = acl_entry_link->entryp->ace_access;
2978 continue;
2979 case SMB_ACL_GROUP_OBJ:
2980 file_acl->g_access = acl_entry_link->entryp->ace_access;
2981 continue;
2982 case SMB_ACL_OTHER:
2983 file_acl->o_access = acl_entry_link->entryp->ace_access;
2984 continue;
2985 case SMB_ACL_MASK:
2986 continue;
2989 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2990 acl_length += sizeof(struct acl_entry);
2991 file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
2992 if(file_acl_temp == NULL) {
2993 SAFE_FREE(file_acl);
2994 errno = ENOMEM;
2995 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2996 return(-1);
2999 memcpy(file_acl_temp,file_acl,file_acl->acl_len);
3000 SAFE_FREE(file_acl);
3001 file_acl = file_acl_temp;
3004 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
3005 file_acl->acl_len += sizeof(struct acl_entry);
3006 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
3007 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
3009 /* In order to use this, we'll need to wait until we can get denies */
3010 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
3011 acl_entry->ace_type = ACC_SPECIFY; */
3013 acl_entry->ace_type = ACC_SPECIFY;
3015 ace_id = acl_entry->ace_id;
3017 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
3018 DEBUG(10,("The id type is %d\n",ace_id->id_type));
3019 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
3020 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
3021 memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
3024 rc = fchacl(fd,file_acl,file_acl->acl_len);
3025 DEBUG(10,("errno is %d\n",errno));
3026 DEBUG(10,("return code is %d\n",rc));
3027 SAFE_FREE(file_acl);
3028 DEBUG(10,("Exiting sys_acl_set_fd\n"));
3029 return(rc);
3032 int sys_acl_delete_def_file(const char *name)
3034 /* AIX has no default ACL */
3035 return 0;
3038 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
3040 return(*permset & perm);
3043 int sys_acl_free_text(char *text)
3045 return(0);
3048 int sys_acl_free_acl(SMB_ACL_T posix_acl)
3050 struct acl_entry_link *acl_entry_link;
3052 for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
3053 SAFE_FREE(acl_entry_link->prevp->entryp);
3054 SAFE_FREE(acl_entry_link->prevp);
3057 SAFE_FREE(acl_entry_link->prevp->entryp);
3058 SAFE_FREE(acl_entry_link->prevp);
3059 SAFE_FREE(acl_entry_link->entryp);
3060 SAFE_FREE(acl_entry_link);
3062 return(0);
3065 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
3067 return(0);
3070 #else /* No ACLs. */
3072 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
3074 errno = ENOSYS;
3075 return -1;
3078 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
3080 errno = ENOSYS;
3081 return -1;
3084 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
3086 errno = ENOSYS;
3087 return -1;
3090 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
3092 errno = ENOSYS;
3093 return NULL;
3096 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
3098 errno = ENOSYS;
3099 return (SMB_ACL_T)NULL;
3102 SMB_ACL_T sys_acl_get_fd(int fd)
3104 errno = ENOSYS;
3105 return (SMB_ACL_T)NULL;
3108 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
3110 errno = ENOSYS;
3111 return -1;
3114 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
3116 errno = ENOSYS;
3117 return -1;
3120 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
3122 errno = ENOSYS;
3123 return (permset & perm) ? 1 : 0;
3126 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
3128 errno = ENOSYS;
3129 return NULL;
3132 int sys_acl_free_text(char *text)
3134 errno = ENOSYS;
3135 return -1;
3138 SMB_ACL_T sys_acl_init( int count)
3140 errno = ENOSYS;
3141 return NULL;
3144 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
3146 errno = ENOSYS;
3147 return -1;
3150 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
3152 errno = ENOSYS;
3153 return -1;
3156 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
3158 errno = ENOSYS;
3159 return -1;
3162 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
3164 errno = ENOSYS;
3165 return -1;
3168 int sys_acl_valid( SMB_ACL_T theacl )
3170 errno = ENOSYS;
3171 return -1;
3174 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
3176 errno = ENOSYS;
3177 return -1;
3180 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
3182 errno = ENOSYS;
3183 return -1;
3186 int sys_acl_delete_def_file(const char *name)
3188 errno = ENOSYS;
3189 return -1;
3192 int sys_acl_free_acl(SMB_ACL_T the_acl)
3194 errno = ENOSYS;
3195 return -1;
3198 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
3200 errno = ENOSYS;
3201 return -1;
3204 #endif /* No ACLs. */
3206 /************************************************************************
3207 Deliberately outside the ACL defines. Return 1 if this is a "no acls"
3208 errno, 0 if not.
3209 ************************************************************************/
3211 int no_acl_syscall_error(int err)
3213 #if defined(ENOSYS)
3214 if (err == ENOSYS) {
3215 return 1;
3217 #endif
3218 #if defined(ENOTSUP)
3219 if (err == ENOTSUP) {
3220 return 1;
3222 #endif
3223 return 0;