Added patches to remove Linux specific XFS ACLs. These are now handled by the
[ira/wip.git] / source3 / lib / sysacls.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.2.
4    Samba system utilities for ACL support.
5    Copyright (C) Jeremy Allison 2000.
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 /*
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.
30
31  The interfaces that each ACL implementation must support are as follows :
32
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)
51
52  This next one is not POSIX complient - but we *have* to have it !
53  More POSIX braindamage.
54
55  int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
56
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.
60
61  int sys_acl_free( void *obj_p)
62
63  The calls we actually use are :
64
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(SMB_ACL_T posix_acl)
68
69 */
70
71 #if defined(HAVE_POSIX_ACLS)
72
73 /* Identity mapping - easy. */
74
75 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
76 {
77         return acl_get_entry( the_acl, entry_id, entry_p);
78 }
79
80 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
81 {
82         return acl_get_tag_type( entry_d, tag_type_p);
83 }
84
85 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
86 {
87         return acl_get_permset( entry_d, permset_p);
88 }
89
90 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
91 {
92         return acl_get_qualifier( entry_d);
93 }
94
95 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
96 {
97         return acl_get_file( path_p, type);
98 }
99
100 SMB_ACL_T sys_acl_get_fd(int fd)
101 {
102         return acl_get_fd(fd);
103 }
104
105 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
106 {
107         return acl_clear_perms(permset);
108 }
109
110 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
111 {
112         return acl_add_perm(permset, perm);
113 }
114
115 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
116 {
117 #if defined(HAVE_ACL_GET_PERM_NP)
118         /*
119          * Required for TrustedBSD-based ACL implementations where
120          * non-POSIX.1e functions are denoted by a _np (non-portable)
121          * suffix.
122          */
123         return acl_get_perm_np(permset, perm);
124 #else
125         return acl_get_perm(permset, perm);
126 #endif
127 }
128
129 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
130 {
131         return acl_to_text( the_acl, plen);
132 }
133
134 SMB_ACL_T sys_acl_init( int count)
135 {
136         return acl_init(count);
137 }
138
139 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
140 {
141         return acl_create_entry(pacl, pentry);
142 }
143
144 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
145 {
146         return acl_set_tag_type(entry, tagtype);
147 }
148
149 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
150 {
151         return acl_set_qualifier(entry, qual);
152 }
153
154 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
155 {
156         return acl_set_permset(entry, permset);
157 }
158
159 int sys_acl_valid( SMB_ACL_T theacl )
160 {
161         return acl_valid(theacl);
162 }
163
164 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
165 {
166         return acl_set_file(name, acltype, theacl);
167 }
168
169 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
170 {
171         return acl_set_fd(fd, theacl);
172 }
173
174 int sys_acl_delete_def_file(const char *name)
175 {
176         return acl_delete_def_file(name);
177 }
178
179 int sys_acl_free_text(char *text)
180 {
181         return acl_free(text);
182 }
183
184 int sys_acl_free_acl(SMB_ACL_T the_acl) 
185 {
186         return acl_free(the_acl);
187 }
188
189 int sys_acl_free_qualifier(void *qual) 
190 {
191         return acl_free(qual);
192 }
193
194 #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
195
196 /*
197  * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
198  * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
199  */
200
201 /*
202  * Note that while this code implements sufficient functionality
203  * to support the sys_acl_* interfaces it does not provide all
204  * of the semantics of the POSIX ACL interfaces.
205  *
206  * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
207  * from a call to sys_acl_get_entry() should not be assumed to be
208  * valid after calling any of the following functions, which may
209  * reorder the entries in the ACL.
210  *
211  *      sys_acl_valid()
212  *      sys_acl_set_file()
213  *      sys_acl_set_fd()
214  */
215
216 /*
217  * The only difference between Solaris and UnixWare / OpenUNIX is
218  * that the #defines for the ACL operations have different names
219  */
220 #if defined(HAVE_UNIXWARE_ACLS)
221
222 #define SETACL          ACL_SET
223 #define GETACL          ACL_GET
224 #define GETACLCNT       ACL_CNT
225
226 #endif
227
228
229 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
230 {
231         if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
232                 errno = EINVAL;
233                 return -1;
234         }
235
236         if (entry_p == NULL) {
237                 errno = EINVAL;
238                 return -1;
239         }
240
241         if (entry_id == SMB_ACL_FIRST_ENTRY) {
242                 acl_d->next = 0;
243         }
244
245         if (acl_d->next < 0) {
246                 errno = EINVAL;
247                 return -1;
248         }
249
250         if (acl_d->next >= acl_d->count) {
251                 return 0;
252         }
253
254         *entry_p = &acl_d->acl[acl_d->next++];
255
256         return 1;
257 }
258
259 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
260 {
261         *type_p = entry_d->a_type;
262
263         return 0;
264 }
265
266 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
267 {
268         *permset_p = &entry_d->a_perm;
269
270         return 0;
271 }
272
273 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
274 {
275         if (entry_d->a_type != SMB_ACL_USER
276             && entry_d->a_type != SMB_ACL_GROUP) {
277                 errno = EINVAL;
278                 return NULL;
279         }
280
281         return &entry_d->a_id;
282 }
283
284 /*
285  * There is no way of knowing what size the ACL returned by
286  * GETACL will be unless you first call GETACLCNT which means
287  * making an additional system call.
288  *
289  * In the hope of avoiding the cost of the additional system
290  * call in most cases, we initially allocate enough space for
291  * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
292  * be too small then we use GETACLCNT to find out the actual
293  * size, reallocate the ACL buffer, and then call GETACL again.
294  */
295
296 #define INITIAL_ACL_SIZE        16
297
298 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
299 {
300         SMB_ACL_T       acl_d;
301         int             count;          /* # of ACL entries allocated   */
302         int             naccess;        /* # of access ACL entries      */
303         int             ndefault;       /* # of default ACL entries     */
304
305         if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
306                 errno = EINVAL;
307                 return NULL;
308         }
309
310         count = INITIAL_ACL_SIZE;
311         if ((acl_d = sys_acl_init(count)) == NULL) {
312                 return NULL;
313         }
314
315         /*
316          * If there isn't enough space for the ACL entries we use
317          * GETACLCNT to determine the actual number of ACL entries
318          * reallocate and try again. This is in a loop because it
319          * is possible that someone else could modify the ACL and
320          * increase the number of entries between the call to
321          * GETACLCNT and the call to GETACL.
322          */
323         while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0
324             && errno == ENOSPC) {
325
326                 sys_acl_free_acl(acl_d);
327
328                 if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) {
329                         return NULL;
330                 }
331
332                 if ((acl_d = sys_acl_init(count)) == NULL) {
333                         return NULL;
334                 }
335         }
336
337         if (count < 0) {
338                 sys_acl_free_acl(acl_d);
339                 return NULL;
340         }
341
342         /*
343          * calculate the number of access and default ACL entries
344          *
345          * Note: we assume that the acl() system call returned a
346          * well formed ACL which is sorted so that all of the
347          * access ACL entries preceed any default ACL entries
348          */
349         for (naccess = 0; naccess < count; naccess++) {
350                 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
351                         break;
352         }
353         ndefault = count - naccess;
354         
355         /*
356          * if the caller wants the default ACL we have to copy
357          * the entries down to the start of the acl[] buffer
358          * and mask out the ACL_DEFAULT flag from the type field
359          */
360         if (type == SMB_ACL_TYPE_DEFAULT) {
361                 int     i, j;
362
363                 for (i = 0, j = naccess; i < ndefault; i++, j++) {
364                         acl_d->acl[i] = acl_d->acl[j];
365                         acl_d->acl[i].a_type &= ~ACL_DEFAULT;
366                 }
367
368                 acl_d->count = ndefault;
369         } else {
370                 acl_d->count = naccess;
371         }
372
373         return acl_d;
374 }
375
376 SMB_ACL_T sys_acl_get_fd(int fd)
377 {
378         SMB_ACL_T       acl_d;
379         int             count;          /* # of ACL entries allocated   */
380         int             naccess;        /* # of access ACL entries      */
381
382         count = INITIAL_ACL_SIZE;
383         if ((acl_d = sys_acl_init(count)) == NULL) {
384                 return NULL;
385         }
386
387         while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0
388             && errno == ENOSPC) {
389
390                 sys_acl_free_acl(acl_d);
391
392                 if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) {
393                         return NULL;
394                 }
395
396                 if ((acl_d = sys_acl_init(count)) == NULL) {
397                         return NULL;
398                 }
399         }
400
401         if (count < 0) {
402                 sys_acl_free_acl(acl_d);
403                 return NULL;
404         }
405
406         /*
407          * calculate the number of access ACL entries
408          */
409         for (naccess = 0; naccess < count; naccess++) {
410                 if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
411                         break;
412         }
413         
414         acl_d->count = naccess;
415
416         return acl_d;
417 }
418
419 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
420 {
421         *permset_d = 0;
422
423         return 0;
424 }
425
426 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
427 {
428         if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
429             && perm != SMB_ACL_EXECUTE) {
430                 errno = EINVAL;
431                 return -1;
432         }
433
434         if (permset_d == NULL) {
435                 errno = EINVAL;
436                 return -1;
437         }
438
439         *permset_d |= perm;
440
441         return 0;
442 }
443
444 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
445 {
446         return *permset_d & perm;
447 }
448
449 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
450 {
451         int     i;
452         int     len, maxlen;
453         char    *text;
454
455         /*
456          * use an initial estimate of 20 bytes per ACL entry
457          * when allocating memory for the text representation
458          * of the ACL
459          */
460         len     = 0;
461         maxlen  = 20 * acl_d->count;
462         if ((text = malloc(maxlen)) == NULL) {
463                 errno = ENOMEM;
464                 return NULL;
465         }
466
467         for (i = 0; i < acl_d->count; i++) {
468                 struct acl      *ap     = &acl_d->acl[i];
469                 struct passwd   *pw;
470                 struct group    *gr;
471                 char            tagbuf[12];
472                 char            idbuf[12];
473                 char            *tag;
474                 char            *id     = "";
475                 char            perms[4];
476                 int             nbytes;
477
478                 switch (ap->a_type) {
479                         /*
480                          * for debugging purposes it's probably more
481                          * useful to dump unknown tag types rather
482                          * than just returning an error
483                          */
484                         default:
485                                 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
486                                         ap->a_type);
487                                 tag = tagbuf;
488                                 slprintf(idbuf, sizeof(idbuf)-1, "%ld",
489                                         (long)ap->a_id);
490                                 id = idbuf;
491                                 break;
492
493                         case SMB_ACL_USER:
494                                 if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
495                                         slprintf(idbuf, sizeof(idbuf)-1, "%ld",
496                                                 (long)ap->a_id);
497                                         id = idbuf;
498                                 } else {
499                                         id = pw->pw_name;
500                                 }
501                         case SMB_ACL_USER_OBJ:
502                                 tag = "user";
503                                 break;
504
505                         case SMB_ACL_GROUP:
506                                 if ((gr = getgrgid(ap->a_id)) == NULL) {
507                                         slprintf(idbuf, sizeof(idbuf)-1, "%ld",
508                                                 (long)ap->a_id);
509                                         id = idbuf;
510                                 } else {
511                                         id = gr->gr_name;
512                                 }
513                         case SMB_ACL_GROUP_OBJ:
514                                 tag = "group";
515                                 break;
516
517                         case SMB_ACL_OTHER:
518                                 tag = "other";
519                                 break;
520
521                         case SMB_ACL_MASK:
522                                 tag = "mask";
523                                 break;
524
525                 }
526
527                 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
528                 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
529                 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
530                 perms[3] = '\0';
531
532                 /*          <tag>      :  <qualifier>   :  rwx \n  \0 */
533                 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
534
535                 /*
536                  * If this entry would overflow the buffer
537                  * allocate enough additional memory for this
538                  * entry and an estimate of another 20 bytes
539                  * for each entry still to be processed
540                  */
541                 if ((len + nbytes) > maxlen) {
542                         char *oldtext = text;
543
544                         maxlen += nbytes + 20 * (acl_d->count - i);
545
546                         if ((text = realloc(oldtext, maxlen)) == NULL) {
547                                 free(oldtext);
548                                 errno = ENOMEM;
549                                 return NULL;
550                         }
551                 }
552
553                 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
554                 len += nbytes - 1;
555         }
556
557         if (len_p)
558                 *len_p = len;
559
560         return text;
561 }
562
563 SMB_ACL_T sys_acl_init(int count)
564 {
565         SMB_ACL_T       a;
566
567         if (count < 0) {
568                 errno = EINVAL;
569                 return NULL;
570         }
571
572         /*
573          * note that since the definition of the structure pointed
574          * to by the SMB_ACL_T includes the first element of the
575          * acl[] array, this actually allocates an ACL with room
576          * for (count+1) entries
577          */
578         if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
579                 errno = ENOMEM;
580                 return NULL;
581         }
582
583         a->size = count + 1;
584         a->count = 0;
585         a->next = -1;
586
587         return a;
588 }
589
590
591 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
592 {
593         SMB_ACL_T       acl_d;
594         SMB_ACL_ENTRY_T entry_d;
595
596         if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
597                 errno = EINVAL;
598                 return -1;
599         }
600
601         if (acl_d->count >= acl_d->size) {
602                 errno = ENOSPC;
603                 return -1;
604         }
605
606         entry_d         = &acl_d->acl[acl_d->count++];
607         entry_d->a_type = 0;
608         entry_d->a_id   = -1;
609         entry_d->a_perm = 0;
610         *entry_p        = entry_d;
611
612         return 0;
613 }
614
615 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
616 {
617         switch (tag_type) {
618                 case SMB_ACL_USER:
619                 case SMB_ACL_USER_OBJ:
620                 case SMB_ACL_GROUP:
621                 case SMB_ACL_GROUP_OBJ:
622                 case SMB_ACL_OTHER:
623                 case SMB_ACL_MASK:
624                         entry_d->a_type = tag_type;
625                         break;
626                 default:
627                         errno = EINVAL;
628                         return -1;
629         }
630
631         return 0;
632 }
633
634 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
635 {
636         if (entry_d->a_type != SMB_ACL_GROUP
637             && entry_d->a_type != SMB_ACL_USER) {
638                 errno = EINVAL;
639                 return -1;
640         }
641
642         entry_d->a_id = *((id_t *)qual_p);
643
644         return 0;
645 }
646
647 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
648 {
649         if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
650                 return EINVAL;
651         }
652
653         entry_d->a_perm = *permset_d;
654
655         return 0;
656 }
657
658 /*
659  * sort the ACL and check it for validity
660  *
661  * if it's a minimal ACL with only 4 entries then we
662  * need to recalculate the mask permissions to make
663  * sure that they are the same as the GROUP_OBJ
664  * permissions as required by the UnixWare acl() system call.
665  *
666  * (note: since POSIX allows minimal ACLs which only contain
667  * 3 entries - ie there is no mask entry - we should, in theory,
668  * check for this and add a mask entry if necessary - however
669  * we "know" that the caller of this interface always specifies
670  * a mask so, in practice "this never happens" (tm) - if it *does*
671  * happen aclsort() will fail and return an error and someone will
672  * have to fix it ...)
673  */
674
675 static int acl_sort(SMB_ACL_T acl_d)
676 {
677         int     fixmask = (acl_d->count <= 4);
678
679         if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {
680                 errno = EINVAL;
681                 return -1;
682         }
683         return 0;
684 }
685  
686 int sys_acl_valid(SMB_ACL_T acl_d)
687 {
688         return acl_sort(acl_d);
689 }
690
691 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
692 {
693         struct stat     s;
694         struct acl      *acl_p;
695         int             acl_count;
696         struct acl      *acl_buf        = NULL;
697         int             ret;
698
699         if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
700                 errno = EINVAL;
701                 return -1;
702         }
703
704         if (acl_sort(acl_d) != 0) {
705                 return -1;
706         }
707
708         acl_p           = &acl_d->acl[0];
709         acl_count       = acl_d->count;
710
711         /*
712          * if it's a directory there is extra work to do
713          * since the acl() system call will replace both
714          * the access ACLs and the default ACLs (if any)
715          */
716         if (stat(name, &s) != 0) {
717                 return -1;
718         }
719         if (S_ISDIR(s.st_mode)) {
720                 SMB_ACL_T       acc_acl;
721                 SMB_ACL_T       def_acl;
722                 SMB_ACL_T       tmp_acl;
723                 int             i;
724
725                 if (type == SMB_ACL_TYPE_ACCESS) {
726                         acc_acl = acl_d;
727                         def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
728
729                 } else {
730                         def_acl = acl_d;
731                         acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
732                 }
733
734                 if (tmp_acl == NULL) {
735                         return -1;
736                 }
737
738                 /*
739                  * allocate a temporary buffer for the complete ACL
740                  */
741                 acl_count = acc_acl->count + def_acl->count;
742                 acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
743
744                 if (acl_buf == NULL) {
745                         sys_acl_free_acl(tmp_acl);
746                         errno = ENOMEM;
747                         return -1;
748                 }
749
750                 /*
751                  * copy the access control and default entries into the buffer
752                  */
753                 memcpy(&acl_buf[0], &acc_acl->acl[0],
754                         acc_acl->count * sizeof(acl_buf[0]));
755
756                 memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
757                         def_acl->count * sizeof(acl_buf[0]));
758
759                 /*
760                  * set the ACL_DEFAULT flag on the default entries
761                  */
762                 for (i = acc_acl->count; i < acl_count; i++) {
763                         acl_buf[i].a_type |= ACL_DEFAULT;
764                 }
765
766                 sys_acl_free_acl(tmp_acl);
767
768         } else if (type != SMB_ACL_TYPE_ACCESS) {
769                 errno = EINVAL;
770                 return -1;
771         }
772
773         ret = acl(name, SETACL, acl_count, acl_p);
774
775         if (acl_buf) {
776                 free(acl_buf);
777         }
778
779         return ret;
780 }
781
782 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
783 {
784         if (acl_sort(acl_d) != 0) {
785                 return -1;
786         }
787
788         return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
789 }
790
791 int sys_acl_delete_def_file(const char *path)
792 {
793         SMB_ACL_T       acl_d;
794         int             ret;
795
796         /*
797          * fetching the access ACL and rewriting it has
798          * the effect of deleting the default ACL
799          */
800         if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
801                 return -1;
802         }
803
804         ret = acl(path, SETACL, acl_d->count, acl_d->acl);
805
806         sys_acl_free_acl(acl_d);
807         
808         return ret;
809 }
810
811 int sys_acl_free_text(char *text)
812 {
813         free(text);
814         return 0;
815 }
816
817 int sys_acl_free_acl(SMB_ACL_T acl_d) 
818 {
819         free(acl_d);
820         return 0;
821 }
822
823 int sys_acl_free_qualifier(void *qual) 
824 {
825         return 0;
826 }
827
828 #elif defined(HAVE_IRIX_ACLS)
829
830 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
831 {
832         if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
833                 errno = EINVAL;
834                 return -1;
835         }
836
837         if (entry_p == NULL) {
838                 errno = EINVAL;
839                 return -1;
840         }
841
842         if (entry_id == SMB_ACL_FIRST_ENTRY) {
843                 acl_d->next = 0;
844         }
845
846         if (acl_d->next < 0) {
847                 errno = EINVAL;
848                 return -1;
849         }
850
851         if (acl_d->next >= acl_d->aclp->acl_cnt) {
852                 return 0;
853         }
854
855         *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
856
857         return 1;
858 }
859
860 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
861 {
862         *type_p = entry_d->ae_tag;
863
864         return 0;
865 }
866
867 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
868 {
869         *permset_p = entry_d;
870
871         return 0;
872 }
873
874 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
875 {
876         if (entry_d->ae_tag != SMB_ACL_USER
877             && entry_d->ae_tag != SMB_ACL_GROUP) {
878                 errno = EINVAL;
879                 return NULL;
880         }
881
882         return &entry_d->ae_id;
883 }
884
885 SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
886 {
887         SMB_ACL_T       a;
888
889         if ((a = malloc(sizeof(*a))) == NULL) {
890                 errno = ENOMEM;
891                 return NULL;
892         }
893         if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
894                 free(a);
895                 return NULL;
896         }
897         a->next = -1;
898         a->freeaclp = True;
899         return a;
900 }
901
902 SMB_ACL_T sys_acl_get_fd(int fd)
903 {
904         SMB_ACL_T       a;
905
906         if ((a = malloc(sizeof(*a))) == NULL) {
907                 errno = ENOMEM;
908                 return NULL;
909         }
910         if ((a->aclp = acl_get_fd(fd)) == NULL) {
911                 free(a);
912                 return NULL;
913         }
914         a->next = -1;
915         a->freeaclp = True;
916         return a;
917 }
918
919 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
920 {
921         permset_d->ae_perm = 0;
922
923         return 0;
924 }
925
926 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
927 {
928         if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
929             && perm != SMB_ACL_EXECUTE) {
930                 errno = EINVAL;
931                 return -1;
932         }
933
934         if (permset_d == NULL) {
935                 errno = EINVAL;
936                 return -1;
937         }
938
939         permset_d->ae_perm |= perm;
940
941         return 0;
942 }
943
944 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
945 {
946         return permset_d->ae_perm & perm;
947 }
948
949 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
950 {
951         return acl_to_text(acl_d->aclp, len_p);
952 }
953
954 SMB_ACL_T sys_acl_init(int count)
955 {
956         SMB_ACL_T       a;
957
958         if (count < 0) {
959                 errno = EINVAL;
960                 return NULL;
961         }
962
963         if ((a = malloc(sizeof(*a) + sizeof(struct acl))) == NULL) {
964                 errno = ENOMEM;
965                 return NULL;
966         }
967
968         a->next = -1;
969         a->freeaclp = False;
970         a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
971         a->aclp->acl_cnt = 0;
972
973         return a;
974 }
975
976
977 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
978 {
979         SMB_ACL_T       acl_d;
980         SMB_ACL_ENTRY_T entry_d;
981
982         if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
983                 errno = EINVAL;
984                 return -1;
985         }
986
987         if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
988                 errno = ENOSPC;
989                 return -1;
990         }
991
992         entry_d         = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
993         entry_d->ae_tag = 0;
994         entry_d->ae_id  = 0;
995         entry_d->ae_perm        = 0;
996         *entry_p        = entry_d;
997
998         return 0;
999 }
1000
1001 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
1002 {
1003         switch (tag_type) {
1004                 case SMB_ACL_USER:
1005                 case SMB_ACL_USER_OBJ:
1006                 case SMB_ACL_GROUP:
1007                 case SMB_ACL_GROUP_OBJ:
1008                 case SMB_ACL_OTHER:
1009                 case SMB_ACL_MASK:
1010                         entry_d->ae_tag = tag_type;
1011                         break;
1012                 default:
1013                         errno = EINVAL;
1014                         return -1;
1015         }
1016
1017         return 0;
1018 }
1019
1020 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
1021 {
1022         if (entry_d->ae_tag != SMB_ACL_GROUP
1023             && entry_d->ae_tag != SMB_ACL_USER) {
1024                 errno = EINVAL;
1025                 return -1;
1026         }
1027
1028         entry_d->ae_id = *((id_t *)qual_p);
1029
1030         return 0;
1031 }
1032
1033 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
1034 {
1035         if (permset_d->ae_perm & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
1036                 return EINVAL;
1037         }
1038
1039         entry_d->ae_perm = permset_d->ae_perm;
1040
1041         return 0;
1042 }
1043
1044 int sys_acl_valid(SMB_ACL_T acl_d)
1045 {
1046         return acl_valid(acl_d->aclp);
1047 }
1048
1049 int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
1050 {
1051         return acl_set_file(name, type, acl_d->aclp);
1052 }
1053
1054 int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
1055 {
1056         return acl_set_fd(fd, acl_d->aclp);
1057 }
1058
1059 int sys_acl_delete_def_file(const char *name)
1060 {
1061         return acl_delete_def_file(name);
1062 }
1063
1064 int sys_acl_free_text(char *text)
1065 {
1066         return acl_free(text);
1067 }
1068
1069 int sys_acl_free_acl(SMB_ACL_T acl_d) 
1070 {
1071         if (acl_d->freeaclp) {
1072                 acl_free(acl_d->aclp);
1073         }
1074         acl_free(acl_d);
1075         return 0;
1076 }
1077
1078 int sys_acl_free_qualifier(void *qual) 
1079 {
1080         return 0;
1081 }
1082
1083 #elif defined(HAVE_AIX_ACLS)
1084
1085 /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
1086
1087 int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1088 {
1089         struct acl_entry_link *link;
1090         struct new_acl_entry *entry;
1091         int keep_going;
1092
1093         DEBUG(10,("This is the count: %d\n",theacl->count));
1094
1095         /* Check if count was previously set to -1. *
1096          * If it was, that means we reached the end *
1097          * of the acl last time.                    */
1098         if(theacl->count == -1)
1099                 return(0);
1100
1101         link = theacl;
1102         /* To get to the next acl, traverse linked list until index *
1103          * of acl matches the count we are keeping.  This count is  *
1104          * incremented each time we return an acl entry.            */
1105
1106         for(keep_going = 0; keep_going < theacl->count; keep_going++)
1107                 link = link->nextp;
1108
1109         entry = *entry_p =  link->entryp;
1110
1111         DEBUG(10,("*entry_p is %d\n",entry_p));
1112         DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
1113
1114         /* Increment count */
1115         theacl->count++;
1116         if(link->nextp == NULL)
1117                 theacl->count = -1;
1118
1119         return(1);
1120 }
1121
1122 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1123 {
1124         /* Initialize tag type */
1125
1126         *tag_type_p = -1;
1127         DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
1128
1129         /* Depending on what type of entry we have, *
1130          * return tag type.                         */
1131         switch(entry_d->ace_id->id_type) {
1132         case ACEID_USER:
1133                 *tag_type_p = SMB_ACL_USER;
1134                 break;
1135         case ACEID_GROUP:
1136                 *tag_type_p = SMB_ACL_GROUP;
1137                 break;
1138
1139         case SMB_ACL_USER_OBJ:
1140         case SMB_ACL_GROUP_OBJ:
1141         case SMB_ACL_OTHER:
1142                 *tag_type_p = entry_d->ace_id->id_type;
1143                 break;
1144  
1145         default:
1146                 return(-1);
1147         }
1148
1149         return(0);
1150 }
1151
1152 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1153 {
1154         DEBUG(10,("Starting AIX sys_acl_get_permset\n"));
1155         *permset_p = &entry_d->ace_access;
1156         DEBUG(10,("**permset_p is %d\n",**permset_p));
1157         if(!(**permset_p & S_IXUSR) &&
1158                 !(**permset_p & S_IWUSR) &&
1159                 !(**permset_p & S_IRUSR) &&
1160                 (**permset_p != 0))
1161                         return(-1);
1162
1163         DEBUG(10,("Ending AIX sys_acl_get_permset\n"));
1164         return(0);
1165 }
1166
1167 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1168 {
1169         return(entry_d->ace_id->id_data);
1170 }
1171
1172 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1173 {
1174         struct acl *file_acl = (struct acl *)NULL;
1175         struct acl_entry *acl_entry;
1176         struct new_acl_entry *new_acl_entry;
1177         struct ace_id *idp;
1178         struct acl_entry_link *acl_entry_link;
1179         struct acl_entry_link *acl_entry_link_head;
1180         int i;
1181         int rc = 0;
1182         uid_t user_id;
1183
1184         /* Get the acl using statacl */
1185  
1186         DEBUG(10,("Entering sys_acl_get_file\n"));
1187         DEBUG(10,("path_p is %s\n",path_p));
1188
1189         file_acl = (struct acl *)malloc(BUFSIZ);
1190  
1191         if(file_acl == NULL) {
1192                 errno=ENOMEM;
1193                 DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
1194                 return(NULL);
1195         }
1196
1197         memset(file_acl,0,BUFSIZ);
1198
1199         rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
1200         if(rc == -1) {
1201                 DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
1202                 free(file_acl);
1203                 return(NULL);
1204         }
1205
1206         DEBUG(10,("Got facl and returned it\n"));
1207
1208         /* Point to the first acl entry in the acl */
1209         acl_entry =  file_acl->acl_ext;
1210
1211         /* Begin setting up the head of the linked list *
1212          * that will be used for the storing the acl    *
1213          * in a way that is useful for the posix_acls.c *
1214          * code.                                          */
1215
1216         acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1217         if(acl_entry_link_head == NULL)
1218                 return(NULL);
1219
1220         acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1221         if(acl_entry_link->entryp == NULL) {
1222                 free(file_acl);
1223                 errno = ENOMEM;
1224                 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1225                 return(NULL);
1226         }
1227
1228         DEBUG(10,("acl_entry is %d\n",acl_entry));
1229         DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1230
1231         /* Check if the extended acl bit is on.   *
1232          * If it isn't, do not show the           *
1233          * contents of the acl since AIX intends *
1234          * the extended info to remain unused     */
1235
1236         if(file_acl->acl_mode & S_IXACL){
1237                 /* while we are not pointing to the very end */
1238                 while(acl_entry < acl_last(file_acl)) {
1239                         /* before we malloc anything, make sure this is  */
1240                         /* a valid acl entry and one that we want to map */
1241                         idp = id_nxt(acl_entry->ace_id);
1242                         if((acl_entry->ace_type == ACC_SPECIFY ||
1243                                 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1244                                         acl_entry = acl_nxt(acl_entry);
1245                                         continue;
1246                         }
1247
1248                         idp = acl_entry->ace_id;
1249
1250                         /* Check if this is the first entry in the linked list. *
1251                          * The first entry needs to keep prevp pointing to NULL *
1252                          * and already has entryp allocated.                  */
1253
1254                         if(acl_entry_link_head->count != 0) {
1255                                 acl_entry_link->nextp = (struct acl_entry_link *)
1256                                                                                         malloc(sizeof(struct acl_entry_link));
1257
1258                                 if(acl_entry_link->nextp == NULL) {
1259                                         free(file_acl);
1260                                         errno = ENOMEM;
1261                                         DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1262                                         return(NULL);
1263                                 }
1264
1265                                 acl_entry_link->nextp->prevp = acl_entry_link;
1266                                 acl_entry_link = acl_entry_link->nextp;
1267                                 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1268                                 if(acl_entry_link->entryp == NULL) {
1269                                         free(file_acl);
1270                                         errno = ENOMEM;
1271                                         DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1272                                         return(NULL);
1273                                 }
1274                                 acl_entry_link->nextp = NULL;
1275                         }
1276
1277                         acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1278
1279                         /* Don't really need this since all types are going *
1280                          * to be specified but, it's better than leaving it 0 */
1281
1282                         acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1283  
1284                         acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1285  
1286                         memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
1287
1288                         /* The access in the acl entries must be left shifted by *
1289                          * three bites, because they will ultimately be compared *
1290                          * to S_IRUSR, S_IWUSR, and S_IXUSR.                  */
1291
1292                         switch(acl_entry->ace_type){
1293                         case ACC_PERMIT:
1294                         case ACC_SPECIFY:
1295                                 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1296                                 acl_entry_link->entryp->ace_access <<= 6;
1297                                 acl_entry_link_head->count++;
1298                                 break;
1299                         case ACC_DENY:
1300                                 /* Since there is no way to return a DENY acl entry *
1301                                  * change to PERMIT and then shift.                 */
1302                                 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1303                                 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1304                                 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1305                                 acl_entry_link->entryp->ace_access <<= 6;
1306                                 acl_entry_link_head->count++;
1307                                 break;
1308                         default:
1309                                 return(0);
1310                         }
1311
1312                         DEBUG(10,("acl_entry = %d\n",acl_entry));
1313                         DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1314  
1315                         acl_entry = acl_nxt(acl_entry);
1316                 }
1317         } /* end of if enabled */
1318
1319         /* Since owner, group, other acl entries are not *
1320          * part of the acl entries in an acl, they must  *
1321          * be dummied up to become part of the list.     */
1322
1323         for( i = 1; i < 4; i++) {
1324                 DEBUG(10,("i is %d\n",i));
1325                 if(acl_entry_link_head->count != 0) {
1326                         acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1327                         if(acl_entry_link->nextp == NULL) {
1328                                 free(file_acl);
1329                                 errno = ENOMEM;
1330                                 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1331                                 return(NULL);
1332                         }
1333
1334                         acl_entry_link->nextp->prevp = acl_entry_link;
1335                         acl_entry_link = acl_entry_link->nextp;
1336                         acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1337                         if(acl_entry_link->entryp == NULL) {
1338                                 free(file_acl);
1339                                 errno = ENOMEM;
1340                                 DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1341                                 return(NULL);
1342                         }
1343                 }
1344
1345                 acl_entry_link->nextp = NULL;
1346
1347                 new_acl_entry = acl_entry_link->entryp;
1348                 idp = new_acl_entry->ace_id;
1349
1350                 new_acl_entry->ace_len = sizeof(struct acl_entry);
1351                 new_acl_entry->ace_type = ACC_PERMIT;
1352                 idp->id_len = sizeof(struct ace_id);
1353                 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1354                 memset(idp->id_data,0,sizeof(uid_t));
1355
1356                 switch(i) {
1357                 case 2:
1358                         new_acl_entry->ace_access = file_acl->g_access << 6;
1359                         idp->id_type = SMB_ACL_GROUP_OBJ;
1360                         break;
1361
1362                 case 3:
1363                         new_acl_entry->ace_access = file_acl->o_access << 6;
1364                         idp->id_type = SMB_ACL_OTHER;
1365                         break;
1366  
1367                 case 1:
1368                         new_acl_entry->ace_access = file_acl->u_access << 6;
1369                         idp->id_type = SMB_ACL_USER_OBJ;
1370                         break;
1371  
1372                 default:
1373                         return(NULL);
1374
1375                 }
1376
1377                 acl_entry_link_head->count++;
1378                 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1379         }
1380
1381         acl_entry_link_head->count = 0;
1382         free(file_acl);
1383
1384         return(acl_entry_link_head);
1385 }
1386
1387 SMB_ACL_T sys_acl_get_fd(int fd)
1388 {
1389         struct acl *file_acl = (struct acl *)NULL;
1390         struct acl_entry *acl_entry;
1391         struct new_acl_entry *new_acl_entry;
1392         struct ace_id *idp;
1393         struct acl_entry_link *acl_entry_link;
1394         struct acl_entry_link *acl_entry_link_head;
1395         int i;
1396         int rc = 0;
1397         uid_t user_id;
1398
1399         /* Get the acl using fstatacl */
1400    
1401         DEBUG(10,("Entering sys_acl_get_fd\n"));
1402         DEBUG(10,("fd is %d\n",fd));
1403         file_acl = (struct acl *)malloc(BUFSIZ);
1404
1405         if(file_acl == NULL) {
1406                 errno=ENOMEM;
1407                 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1408                 return(NULL);
1409         }
1410
1411         memset(file_acl,0,BUFSIZ);
1412
1413         rc = fstatacl(fd,0,file_acl,BUFSIZ);
1414         if(rc == -1) {
1415                 DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
1416                 free(file_acl);
1417                 return(NULL);
1418         }
1419
1420         DEBUG(10,("Got facl and returned it\n"));
1421
1422         /* Point to the first acl entry in the acl */
1423
1424         acl_entry =  file_acl->acl_ext;
1425         /* Begin setting up the head of the linked list *
1426          * that will be used for the storing the acl    *
1427          * in a way that is useful for the posix_acls.c *
1428          * code.                                        */
1429
1430         acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1431         if(acl_entry_link_head == NULL){
1432                 free(file_acl);
1433                 return(NULL);
1434         }
1435
1436         acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1437
1438         if(acl_entry_link->entryp == NULL) {
1439                 errno = ENOMEM;
1440                 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1441                 free(file_acl);
1442                 return(NULL);
1443         }
1444
1445         DEBUG(10,("acl_entry is %d\n",acl_entry));
1446         DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1447  
1448         /* Check if the extended acl bit is on.   *
1449          * If it isn't, do not show the           *
1450          * contents of the acl since AIX intends  *
1451          * the extended info to remain unused     */
1452  
1453         if(file_acl->acl_mode & S_IXACL){
1454                 /* while we are not pointing to the very end */
1455                 while(acl_entry < acl_last(file_acl)) {
1456                         /* before we malloc anything, make sure this is  */
1457                         /* a valid acl entry and one that we want to map */
1458
1459                         idp = id_nxt(acl_entry->ace_id);
1460                         if((acl_entry->ace_type == ACC_SPECIFY ||
1461                                 (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1462                                         acl_entry = acl_nxt(acl_entry);
1463                                         continue;
1464                         }
1465
1466                         idp = acl_entry->ace_id;
1467  
1468                         /* Check if this is the first entry in the linked list. *
1469                          * The first entry needs to keep prevp pointing to NULL *
1470                          * and already has entryp allocated.                 */
1471
1472                         if(acl_entry_link_head->count != 0) {
1473                                 acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1474                                 if(acl_entry_link->nextp == NULL) {
1475                                         errno = ENOMEM;
1476                                         DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1477                                         free(file_acl);
1478                                         return(NULL);
1479                                 }
1480                                 acl_entry_link->nextp->prevp = acl_entry_link;
1481                                 acl_entry_link = acl_entry_link->nextp;
1482                                 acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1483                                 if(acl_entry_link->entryp == NULL) {
1484                                         errno = ENOMEM;
1485                                         DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1486                                         free(file_acl);
1487                                         return(NULL);
1488                                 }
1489
1490                                 acl_entry_link->nextp = NULL;
1491                         }
1492
1493                         acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1494
1495                         /* Don't really need this since all types are going *
1496                          * to be specified but, it's better than leaving it 0 */
1497
1498                         acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1499                         acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1500
1501                         memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
1502
1503                         /* The access in the acl entries must be left shifted by *
1504                          * three bites, because they will ultimately be compared *
1505                          * to S_IRUSR, S_IWUSR, and S_IXUSR.                  */
1506
1507                         switch(acl_entry->ace_type){
1508                         case ACC_PERMIT:
1509                         case ACC_SPECIFY:
1510                                 acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1511                                 acl_entry_link->entryp->ace_access <<= 6;
1512                                 acl_entry_link_head->count++;
1513                                 break;
1514                         case ACC_DENY:
1515                                 /* Since there is no way to return a DENY acl entry *
1516                                  * change to PERMIT and then shift.                 */
1517                                 DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1518                                 acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1519                                 DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1520                                 acl_entry_link->entryp->ace_access <<= 6;
1521                                 acl_entry_link_head->count++;
1522                                 break;
1523                         default:
1524                                 return(0);
1525                         }
1526
1527                         DEBUG(10,("acl_entry = %d\n",acl_entry));
1528                         DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1529  
1530                         acl_entry = acl_nxt(acl_entry);
1531                 }
1532         } /* end of if enabled */
1533
1534         /* Since owner, group, other acl entries are not *
1535          * part of the acl entries in an acl, they must  *
1536          * be dummied up to become part of the list.     */
1537
1538         for( i = 1; i < 4; i++) {
1539                 DEBUG(10,("i is %d\n",i));
1540                 if(acl_entry_link_head->count != 0){
1541                         acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1542                         if(acl_entry_link->nextp == NULL) {
1543                                 errno = ENOMEM;
1544                                 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1545                                 free(file_acl);
1546                                 return(NULL);
1547                         }
1548
1549                         acl_entry_link->nextp->prevp = acl_entry_link;
1550                         acl_entry_link = acl_entry_link->nextp;
1551                         acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1552
1553                         if(acl_entry_link->entryp == NULL) {
1554                                 free(file_acl);
1555                                 errno = ENOMEM;
1556                                 DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
1557                                 return(NULL);
1558                         }
1559                 }
1560
1561                 acl_entry_link->nextp = NULL;
1562  
1563                 new_acl_entry = acl_entry_link->entryp;
1564                 idp = new_acl_entry->ace_id;
1565  
1566                 new_acl_entry->ace_len = sizeof(struct acl_entry);
1567                 new_acl_entry->ace_type = ACC_PERMIT;
1568                 idp->id_len = sizeof(struct ace_id);
1569                 DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1570                 memset(idp->id_data,0,sizeof(uid_t));
1571  
1572                 switch(i) {
1573                 case 2:
1574                         new_acl_entry->ace_access = file_acl->g_access << 6;
1575                         idp->id_type = SMB_ACL_GROUP_OBJ;
1576                         break;
1577  
1578                 case 3:
1579                         new_acl_entry->ace_access = file_acl->o_access << 6;
1580                         idp->id_type = SMB_ACL_OTHER;
1581                         break;
1582  
1583                 case 1:
1584                         new_acl_entry->ace_access = file_acl->u_access << 6;
1585                         idp->id_type = SMB_ACL_USER_OBJ;
1586                         break;
1587  
1588                 default:
1589                         return(NULL);
1590                 }
1591  
1592                 acl_entry_link_head->count++;
1593                 DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
1594         }
1595
1596         acl_entry_link_head->count = 0;
1597         free(file_acl);
1598  
1599         return(acl_entry_link_head);
1600 }
1601
1602 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
1603 {
1604         *permset = *permset & ~0777;
1605         return(0);
1606 }
1607
1608 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1609 {
1610         if((perm != 0) &&
1611                         (perm & (S_IXUSR | S_IWUSR | S_IRUSR)) == 0)
1612                 return(-1);
1613
1614         *permset |= perm;
1615         DEBUG(10,("This is the permset now: %d\n",*permset));
1616         return(0);
1617 }
1618
1619 char *sys_acl_to_text( SMB_ACL_T theacl, ssize_t *plen)
1620 {
1621         return(NULL);
1622 }
1623
1624 SMB_ACL_T sys_acl_init( int count)
1625 {
1626         struct acl_entry_link *theacl = NULL;
1627  
1628         DEBUG(10,("Entering sys_acl_init\n"));
1629
1630         theacl = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1631         if(theacl == NULL) {
1632                 errno = ENOMEM;
1633                 DEBUG(0,("Error in sys_acl_init is %d\n",errno));
1634                 return(NULL);
1635         }
1636
1637         theacl->count = 0;
1638         theacl->nextp = NULL;
1639         theacl->prevp = NULL;
1640         theacl->entryp = NULL;
1641         DEBUG(10,("Exiting sys_acl_init\n"));
1642         return(theacl);
1643 }
1644
1645 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1646 {
1647         struct acl_entry_link *theacl;
1648         struct acl_entry_link *acl_entryp;
1649         struct acl_entry_link *temp_entry;
1650         int counting;
1651
1652         DEBUG(10,("Entering the sys_acl_create_entry\n"));
1653
1654         theacl = acl_entryp = *pacl;
1655
1656         /* Get to the end of the acl before adding entry */
1657
1658         for(counting=0; counting < theacl->count; counting++){
1659                 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1660                 temp_entry = acl_entryp;
1661                 acl_entryp = acl_entryp->nextp;
1662         }
1663
1664         if(theacl->count != 0){
1665                 temp_entry->nextp = acl_entryp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
1666                 if(acl_entryp == NULL) {
1667                         errno = ENOMEM;
1668                         DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1669                         return(-1);
1670                 }
1671
1672                 DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
1673                 acl_entryp->prevp = temp_entry;
1674                 DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
1675         }
1676
1677         *pentry = acl_entryp->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
1678         if(*pentry == NULL) {
1679                 errno = ENOMEM;
1680                 DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
1681                 return(-1);
1682         }
1683
1684         memset(*pentry,0,sizeof(struct new_acl_entry));
1685         acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
1686         acl_entryp->entryp->ace_type = ACC_PERMIT;
1687         acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
1688         acl_entryp->nextp = NULL;
1689         theacl->count++;
1690         DEBUG(10,("Exiting sys_acl_create_entry\n"));
1691         return(0);
1692 }
1693
1694 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1695 {
1696         DEBUG(10,("Starting AIX sys_acl_set_tag_type\n"));
1697         entry->ace_id->id_type = tagtype;
1698         DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
1699         DEBUG(10,("Ending AIX sys_acl_set_tag_type\n"));
1700 }
1701
1702 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
1703 {
1704         DEBUG(10,("Starting AIX sys_acl_set_qualifier\n"));
1705         memcpy(entry->ace_id->id_data,qual,sizeof(uid_t));
1706         DEBUG(10,("Ending AIX sys_acl_set_qualifier\n"));
1707         return(0);
1708 }
1709
1710 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1711 {
1712         DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
1713         if(!(*permset & S_IXUSR) &&
1714                 !(*permset & S_IWUSR) &&
1715                 !(*permset & S_IRUSR) &&
1716                 (*permset != 0))
1717                         return(-1);
1718
1719         entry->ace_access = *permset;
1720         DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
1721         DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
1722         return(0);
1723 }
1724
1725 int sys_acl_valid( SMB_ACL_T theacl )
1726 {
1727         int user_obj = 0;
1728         int group_obj = 0;
1729         int other_obj = 0;
1730         struct acl_entry_link *acl_entry;
1731
1732         for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
1733                 user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
1734                 group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
1735                 other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
1736         }
1737
1738         DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
1739  
1740         if(user_obj != 1 || group_obj != 1 || other_obj != 1)
1741                 return(-1); 
1742
1743         return(0);
1744 }
1745
1746 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1747 {
1748         struct acl_entry_link *acl_entry_link = NULL;
1749         struct acl *file_acl = NULL;
1750         struct acl *file_acl_temp = NULL;
1751         struct acl_entry *acl_entry = NULL;
1752         struct ace_id *ace_id = NULL;
1753         uint id_type;
1754         uint ace_access;
1755         uint user_id;
1756         uint acl_length;
1757         uint rc;
1758
1759         DEBUG(10,("Entering sys_acl_set_file\n"));
1760         DEBUG(10,("File name is %s\n",name));
1761  
1762         /* AIX has no default ACL */
1763         if(acltype == SMB_ACL_TYPE_DEFAULT)
1764                 return(0);
1765
1766         acl_length = BUFSIZ;
1767         file_acl = (struct acl *)malloc(BUFSIZ);
1768
1769         if(file_acl == NULL) {
1770                 errno = ENOMEM;
1771                 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
1772                 return(-1);
1773         }
1774
1775         memset(file_acl,0,BUFSIZ);
1776
1777         file_acl->acl_len = ACL_SIZ;
1778         file_acl->acl_mode = S_IXACL;
1779
1780         for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
1781                 acl_entry_link->entryp->ace_access >>= 6;
1782                 id_type = acl_entry_link->entryp->ace_id->id_type;
1783
1784                 switch(id_type) {
1785                 case SMB_ACL_USER_OBJ:
1786                         file_acl->u_access = acl_entry_link->entryp->ace_access;
1787                         continue;
1788                 case SMB_ACL_GROUP_OBJ:
1789                         file_acl->g_access = acl_entry_link->entryp->ace_access;
1790                         continue;
1791                 case SMB_ACL_OTHER:
1792                         file_acl->o_access = acl_entry_link->entryp->ace_access;
1793                         continue;
1794                 case SMB_ACL_MASK:
1795                         continue;
1796                 }
1797
1798                 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
1799                         acl_length += sizeof(struct acl_entry);
1800                         file_acl_temp = (struct acl *)malloc(acl_length);
1801                         if(file_acl_temp == NULL) {
1802                                 free(file_acl);
1803                                 errno = ENOMEM;
1804                                 DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
1805                                 return(-1);
1806                         }  
1807
1808                         memcpy(file_acl_temp,file_acl,file_acl->acl_len);
1809                         free(file_acl);
1810                         file_acl = file_acl_temp;
1811                 }
1812
1813                 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
1814                 file_acl->acl_len += sizeof(struct acl_entry);
1815                 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
1816                 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
1817  
1818                 /* In order to use this, we'll need to wait until we can get denies */
1819                 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
1820                 acl_entry->ace_type = ACC_SPECIFY; */
1821
1822                 acl_entry->ace_type = ACC_SPECIFY;
1823  
1824                 ace_id = acl_entry->ace_id;
1825  
1826                 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
1827                 DEBUG(10,("The id type is %d\n",ace_id->id_type));
1828                 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
1829                 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
1830                 memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
1831         }
1832
1833         rc = chacl(name,file_acl,file_acl->acl_len);
1834         DEBUG(10,("errno is %d\n",errno));
1835         DEBUG(10,("return code is %d\n",rc));
1836         free(file_acl);
1837         DEBUG(10,("Exiting the sys_acl_set_file\n"));
1838         return(rc);
1839 }
1840
1841 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
1842 {
1843         struct acl_entry_link *acl_entry_link = NULL;
1844         struct acl *file_acl = NULL;
1845         struct acl *file_acl_temp = NULL;
1846         struct acl_entry *acl_entry = NULL;
1847         struct ace_id *ace_id = NULL;
1848         uint id_type;
1849         uint user_id;
1850         uint acl_length;
1851         uint rc;
1852  
1853         DEBUG(10,("Entering sys_acl_set_fd\n"));
1854         acl_length = BUFSIZ;
1855         file_acl = (struct acl *)malloc(BUFSIZ);
1856
1857         if(file_acl == NULL) {
1858                 errno = ENOMEM;
1859                 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
1860                 return(-1);
1861         }
1862
1863         memset(file_acl,0,BUFSIZ);
1864  
1865         file_acl->acl_len = ACL_SIZ;
1866         file_acl->acl_mode = S_IXACL;
1867
1868         for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
1869                 acl_entry_link->entryp->ace_access >>= 6;
1870                 id_type = acl_entry_link->entryp->ace_id->id_type;
1871                 DEBUG(10,("The id_type is %d\n",id_type));
1872
1873                 switch(id_type) {
1874                 case SMB_ACL_USER_OBJ:
1875                         file_acl->u_access = acl_entry_link->entryp->ace_access;
1876                         continue;
1877                 case SMB_ACL_GROUP_OBJ:
1878                         file_acl->g_access = acl_entry_link->entryp->ace_access;
1879                         continue;
1880                 case SMB_ACL_OTHER:
1881                         file_acl->o_access = acl_entry_link->entryp->ace_access;
1882                         continue;
1883                 case SMB_ACL_MASK:
1884                         continue;
1885                 }
1886
1887                 if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
1888                         acl_length += sizeof(struct acl_entry);
1889                         file_acl_temp = (struct acl *)malloc(acl_length);
1890                         if(file_acl_temp == NULL) {
1891                                 free(file_acl);
1892                                 errno = ENOMEM;
1893                                 DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
1894                                 return(-1);
1895                         }
1896
1897                         memcpy(file_acl_temp,file_acl,file_acl->acl_len);
1898                         free(file_acl);
1899                         file_acl = file_acl_temp;
1900                 }
1901
1902                 acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
1903                 file_acl->acl_len += sizeof(struct acl_entry);
1904                 acl_entry->ace_len = acl_entry_link->entryp->ace_len;
1905                 acl_entry->ace_access = acl_entry_link->entryp->ace_access;
1906  
1907                 /* In order to use this, we'll need to wait until we can get denies */
1908                 /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
1909                         acl_entry->ace_type = ACC_SPECIFY; */
1910  
1911                 acl_entry->ace_type = ACC_SPECIFY;
1912  
1913                 ace_id = acl_entry->ace_id;
1914  
1915                 ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
1916                 DEBUG(10,("The id type is %d\n",ace_id->id_type));
1917                 ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
1918                 memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
1919                 memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
1920         }
1921  
1922         rc = fchacl(fd,file_acl,file_acl->acl_len);
1923         DEBUG(10,("errno is %d\n",errno));
1924         DEBUG(10,("return code is %d\n",rc));
1925         free(file_acl);
1926         DEBUG(10,("Exiting sys_acl_set_fd\n"));
1927         return(rc);
1928 }
1929
1930 int sys_acl_delete_def_file(const char *name)
1931 {
1932         /* AIX has no default ACL */
1933         return 0;
1934 }
1935
1936 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1937 {
1938         return(*permset & perm);
1939 }
1940
1941 int sys_acl_free_text(char *text)
1942 {
1943         return(0);
1944 }
1945
1946 int sys_acl_free_acl(SMB_ACL_T posix_acl)
1947 {
1948         struct acl_entry_link *acl_entry_link;
1949
1950         for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
1951                 free(acl_entry_link->prevp->entryp);
1952                 free(acl_entry_link->prevp);
1953         }
1954
1955         free(acl_entry_link->prevp->entryp);
1956         free(acl_entry_link->prevp);
1957         free(acl_entry_link->entryp);
1958         free(acl_entry_link);
1959  
1960         return(0);
1961 }
1962
1963 int sys_acl_free_qualifier(void *qual)
1964 {
1965         return(0);
1966 }
1967
1968 #else /* No ACLs. */
1969
1970 int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1971 {
1972         errno = ENOSYS;
1973         return -1;
1974 }
1975
1976 int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1977 {
1978         errno = ENOSYS;
1979         return -1;
1980 }
1981
1982 int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1983 {
1984         errno = ENOSYS;
1985         return -1;
1986 }
1987
1988 void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
1989 {
1990         errno = ENOSYS;
1991         return NULL;
1992 }
1993
1994 SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1995 {
1996         errno = ENOSYS;
1997         return (SMB_ACL_T)NULL;
1998 }
1999
2000 SMB_ACL_T sys_acl_get_fd(int fd)
2001 {
2002         errno = ENOSYS;
2003         return (SMB_ACL_T)NULL;
2004 }
2005
2006 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
2007 {
2008         errno = ENOSYS;
2009         return -1;
2010 }
2011
2012 int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2013 {
2014         errno = ENOSYS;
2015         return -1;
2016 }
2017
2018 int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2019 {
2020         errno = ENOSYS;
2021         return (permset & perm) ? 1 : 0;
2022 }
2023
2024 char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
2025 {
2026         errno = ENOSYS;
2027         return NULL;
2028 }
2029
2030 int sys_acl_free_text(char *text)
2031 {
2032         errno = ENOSYS;
2033         return -1;
2034 }
2035
2036 SMB_ACL_T sys_acl_init( int count)
2037 {
2038         errno = ENOSYS;
2039         return NULL;
2040 }
2041
2042 int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2043 {
2044         errno = ENOSYS;
2045         return -1;
2046 }
2047
2048 int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2049 {
2050         errno = ENOSYS;
2051         return -1;
2052 }
2053
2054 int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
2055 {
2056         errno = ENOSYS;
2057         return -1;
2058 }
2059
2060 int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2061 {
2062         errno = ENOSYS;
2063         return -1;
2064 }
2065
2066 int sys_acl_valid( SMB_ACL_T theacl )
2067 {
2068         errno = ENOSYS;
2069         return -1;
2070 }
2071
2072 int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2073 {
2074         errno = ENOSYS;
2075         return -1;
2076 }
2077
2078 int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2079 {
2080         errno = ENOSYS;
2081         return -1;
2082 }
2083
2084 int sys_acl_delete_def_file(const char *name)
2085 {
2086         errno = ENOSYS;
2087         return -1;
2088 }
2089
2090 int sys_acl_free_acl(SMB_ACL_T the_acl) 
2091 {
2092         errno = ENOSYS;
2093         return -1;
2094 }
2095
2096 int sys_acl_free_qualifier(void *qual) 
2097 {
2098         errno = ENOSYS;
2099         return -1;
2100 }
2101
2102 #endif /* No ACLs. */