Annotation of embedaddon/rsync/lib/sysacls.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Unix SMB/CIFS implementation.
3: * Based on the Samba ACL support code.
4: * Copyright (C) Jeremy Allison 2000.
5: * Copyright (C) 2007-2008 Wayne Davison
6: *
7: * The permission functions have been changed to get/set all bits via
8: * one call. Some functions that rsync doesn't need were also removed.
9: *
10: * This program is free software; you can redistribute it and/or modify
11: * it under the terms of the GNU General Public License as published by
12: * the Free Software Foundation; either version 3 of the License, or
13: * (at your option) any later version.
14: *
15: * This program is distributed in the hope that it will be useful,
16: * but WITHOUT ANY WARRANTY; without even the implied warranty of
17: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: * GNU General Public License for more details.
19: *
20: * You should have received a copy of the GNU General Public License
21: * with this program; if not, visit the http://fsf.org website.
22: */
23:
24: #include "rsync.h"
25: #include "sysacls.h"
26:
27: #ifdef SUPPORT_ACLS
28:
29: #ifdef DEBUG
30: #undef DEBUG
31: #endif
32: #define DEBUG(x,y)
33:
34: void SAFE_FREE(void *mem)
35: {
36: if (mem)
37: free(mem);
38: }
39:
40: /*
41: This file wraps all differing system ACL interfaces into a consistent
42: one based on the POSIX interface. It also returns the correct errors
43: for older UNIX systems that don't support ACLs.
44:
45: The interfaces that each ACL implementation must support are as follows :
46:
47: int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
48: int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
49: int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p)
50: SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
51: SMB_ACL_T sys_acl_get_fd(int fd)
52: SMB_ACL_T sys_acl_init( int count)
53: int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
54: int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id)
55: int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits)
56: int sys_acl_valid( SMB_ACL_T theacl )
57: int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
58: int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
59: int sys_acl_delete_def_file(const char *path)
60: int sys_acl_free_acl(SMB_ACL_T posix_acl)
61:
62: */
63:
64: #if defined(HAVE_POSIX_ACLS) /*--------------------------------------------*/
65:
66: /* Identity mapping - easy. */
67:
68: int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
69: {
70: return acl_get_entry( the_acl, entry_id, entry_p);
71: }
72:
73: int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
74: {
75: return acl_get_tag_type( entry_d, tag_type_p);
76: }
77:
78: SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
79: {
80: return acl_get_file( path_p, type);
81: }
82:
83: #if 0
84: SMB_ACL_T sys_acl_get_fd(int fd)
85: {
86: return acl_get_fd(fd);
87: }
88: #endif
89:
90: #if defined(HAVE_ACL_GET_PERM_NP)
91: #define acl_get_perm(p, b) acl_get_perm_np(p, b)
92: #endif
93:
94: int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p)
95: {
96: acl_permset_t permset;
97:
98: if (acl_get_tag_type(entry, tag_type_p) != 0
99: || acl_get_permset(entry, &permset) != 0)
100: return -1;
101:
102: *bits_p = (acl_get_perm(permset, ACL_READ) ? 4 : 0)
103: | (acl_get_perm(permset, ACL_WRITE) ? 2 : 0)
104: | (acl_get_perm(permset, ACL_EXECUTE) ? 1 : 0);
105:
106: if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP) {
107: void *qual;
108: if ((qual = acl_get_qualifier(entry)) == NULL)
109: return -1;
110: *u_g_id_p = *(id_t*)qual;
111: acl_free(qual);
112: }
113:
114: return 0;
115: }
116:
117: SMB_ACL_T sys_acl_init( int count)
118: {
119: return acl_init(count);
120: }
121:
122: int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
123: {
124: return acl_create_entry(pacl, pentry);
125: }
126:
127: int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id)
128: {
129: if (acl_set_tag_type(entry, tag_type) != 0)
130: return -1;
131:
132: if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP) {
133: if (acl_set_qualifier(entry, (void*)&u_g_id) != 0)
134: return -1;
135: }
136:
137: return sys_acl_set_access_bits(entry, bits);
138: }
139:
140: int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits)
141: {
142: acl_permset_t permset;
143: int rc;
144: if ((rc = acl_get_permset(entry, &permset)) != 0)
145: return rc;
146: acl_clear_perms(permset);
147: if (bits & 4)
148: acl_add_perm(permset, ACL_READ);
149: if (bits & 2)
150: acl_add_perm(permset, ACL_WRITE);
151: if (bits & 1)
152: acl_add_perm(permset, ACL_EXECUTE);
153: return acl_set_permset(entry, permset);
154: }
155:
156: int sys_acl_valid( SMB_ACL_T theacl )
157: {
158: return acl_valid(theacl);
159: }
160:
161: int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
162: {
163: return acl_set_file(name, acltype, theacl);
164: }
165:
166: #if 0
167: int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
168: {
169: return acl_set_fd(fd, theacl);
170: }
171: #endif
172:
173: int sys_acl_delete_def_file(const char *name)
174: {
175: return acl_delete_def_file(name);
176: }
177:
178: int sys_acl_free_acl(SMB_ACL_T the_acl)
179: {
180: return acl_free(the_acl);
181: }
182:
183: #elif defined(HAVE_TRU64_ACLS) /*--------------------------------------------*/
184: /*
185: * The interface to DEC/Compaq Tru64 UNIX ACLs
186: * is based on Draft 13 of the POSIX spec which is
187: * slightly different from the Draft 16 interface.
188: *
189: * Also, some of the permset manipulation functions
190: * such as acl_clear_perm() and acl_add_perm() appear
191: * to be broken on Tru64 so we have to manipulate
192: * the permission bits in the permset directly.
193: */
194: int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
195: {
196: SMB_ACL_ENTRY_T entry;
197:
198: if (entry_id == SMB_ACL_FIRST_ENTRY && acl_first_entry(the_acl) != 0) {
199: return -1;
200: }
201:
202: errno = 0;
203: if ((entry = acl_get_entry(the_acl)) != NULL) {
204: *entry_p = entry;
205: return 1;
206: }
207:
208: return errno ? -1 : 0;
209: }
210:
211: int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
212: {
213: return acl_get_tag_type( entry_d, tag_type_p);
214: }
215:
216: SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
217: {
218: return acl_get_file((char *)path_p, type);
219: }
220:
221: #if 0
222: SMB_ACL_T sys_acl_get_fd(int fd)
223: {
224: return acl_get_fd(fd, ACL_TYPE_ACCESS);
225: }
226: #endif
227:
228: int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p)
229: {
230: acl_permset_t permset;
231:
232: if (acl_get_tag_type(entry, tag_type_p) != 0
233: || acl_get_permset(entry, &permset) != 0)
234: return -1;
235:
236: *bits_p = *permset & 7; /* Tru64 doesn't have acl_get_perm() */
237:
238: if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP) {
239: void *qual;
240: if ((qual = acl_get_qualifier(entry)) == NULL)
241: return -1;
242: *u_g_id_p = *(id_t*)qual;
243: acl_free_qualifier(qual, *tag_type_p);
244: }
245:
246: return 0;
247: }
248:
249: SMB_ACL_T sys_acl_init( int count)
250: {
251: return acl_init(count);
252: }
253:
254: int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
255: {
256: SMB_ACL_ENTRY_T entry;
257:
258: if ((entry = acl_create_entry(pacl)) == NULL) {
259: return -1;
260: }
261:
262: *pentry = entry;
263: return 0;
264: }
265:
266: int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id)
267: {
268: if (acl_set_tag_type(entry, tag_type) != 0)
269: return -1;
270:
271: if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP) {
272: if (acl_set_qualifier(entry, (void*)&u_g_id) != 0)
273: return -1;
274: }
275:
276: return sys_acl_set_access_bits(entry, bits);
277: }
278:
279: int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits)
280: {
281: acl_permset_t permset;
282: int rc;
283: if ((rc = acl_get_permset(entry, &permset)) != 0)
284: return rc;
285: *permset = bits & 7;
286: return acl_set_permset(entry, permset);
287: }
288:
289: int sys_acl_valid( SMB_ACL_T theacl )
290: {
291: acl_entry_t entry;
292:
293: return acl_valid(theacl, &entry);
294: }
295:
296: int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
297: {
298: return acl_set_file((char *)name, acltype, theacl);
299: }
300:
301: #if 0
302: int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
303: {
304: return acl_set_fd(fd, ACL_TYPE_ACCESS, theacl);
305: }
306: #endif
307:
308: int sys_acl_delete_def_file(const char *name)
309: {
310: return acl_delete_def_file((char *)name);
311: }
312:
313: int sys_acl_free_acl(SMB_ACL_T the_acl)
314: {
315: return acl_free(the_acl);
316: }
317:
318: #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS) /*-----------*/
319:
320: /*
321: * Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
322: * Modified by Toomas Soome <tsoome@ut.ee> for Solaris.
323: */
324:
325: /*
326: * Note that while this code implements sufficient functionality
327: * to support the sys_acl_* interfaces it does not provide all
328: * of the semantics of the POSIX ACL interfaces.
329: *
330: * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
331: * from a call to sys_acl_get_entry() should not be assumed to be
332: * valid after calling any of the following functions, which may
333: * reorder the entries in the ACL.
334: *
335: * sys_acl_valid()
336: * sys_acl_set_file()
337: * sys_acl_set_fd()
338: */
339:
340: /*
341: * The only difference between Solaris and UnixWare / OpenUNIX is
342: * that the #defines for the ACL operations have different names
343: */
344: #if defined(HAVE_UNIXWARE_ACLS)
345:
346: #define SETACL ACL_SET
347: #define GETACL ACL_GET
348: #define GETACLCNT ACL_CNT
349:
350: #endif
351:
352:
353: int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
354: {
355: if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
356: errno = EINVAL;
357: return -1;
358: }
359:
360: if (entry_p == NULL) {
361: errno = EINVAL;
362: return -1;
363: }
364:
365: if (entry_id == SMB_ACL_FIRST_ENTRY) {
366: acl_d->next = 0;
367: }
368:
369: if (acl_d->next < 0) {
370: errno = EINVAL;
371: return -1;
372: }
373:
374: if (acl_d->next >= acl_d->count) {
375: return 0;
376: }
377:
378: *entry_p = &acl_d->acl[acl_d->next++];
379:
380: return 1;
381: }
382:
383: int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
384: {
385: *type_p = entry_d->a_type;
386:
387: return 0;
388: }
389:
390: /*
391: * There is no way of knowing what size the ACL returned by
392: * GETACL will be unless you first call GETACLCNT which means
393: * making an additional system call.
394: *
395: * In the hope of avoiding the cost of the additional system
396: * call in most cases, we initially allocate enough space for
397: * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
398: * be too small then we use GETACLCNT to find out the actual
399: * size, reallocate the ACL buffer, and then call GETACL again.
400: */
401:
402: #define INITIAL_ACL_SIZE 16
403:
404: SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
405: {
406: SMB_ACL_T acl_d;
407: int count; /* # of ACL entries allocated */
408: int naccess; /* # of access ACL entries */
409: int ndefault; /* # of default ACL entries */
410:
411: if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
412: errno = EINVAL;
413: return NULL;
414: }
415:
416: count = INITIAL_ACL_SIZE;
417: if ((acl_d = sys_acl_init(count)) == NULL) {
418: return NULL;
419: }
420:
421: /*
422: * If there isn't enough space for the ACL entries we use
423: * GETACLCNT to determine the actual number of ACL entries
424: * reallocate and try again. This is in a loop because it
425: * is possible that someone else could modify the ACL and
426: * increase the number of entries between the call to
427: * GETACLCNT and the call to GETACL.
428: */
429: while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0
430: && errno == ENOSPC) {
431:
432: sys_acl_free_acl(acl_d);
433:
434: if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) {
435: return NULL;
436: }
437:
438: if ((acl_d = sys_acl_init(count)) == NULL) {
439: return NULL;
440: }
441: }
442:
443: if (count < 0) {
444: sys_acl_free_acl(acl_d);
445: return NULL;
446: }
447:
448: /*
449: * calculate the number of access and default ACL entries
450: *
451: * Note: we assume that the acl() system call returned a
452: * well formed ACL which is sorted so that all of the
453: * access ACL entries preceed any default ACL entries
454: */
455: for (naccess = 0; naccess < count; naccess++) {
456: if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
457: break;
458: }
459: ndefault = count - naccess;
460:
461: /*
462: * if the caller wants the default ACL we have to copy
463: * the entries down to the start of the acl[] buffer
464: * and mask out the ACL_DEFAULT flag from the type field
465: */
466: if (type == SMB_ACL_TYPE_DEFAULT) {
467: int i, j;
468:
469: for (i = 0, j = naccess; i < ndefault; i++, j++) {
470: acl_d->acl[i] = acl_d->acl[j];
471: acl_d->acl[i].a_type &= ~ACL_DEFAULT;
472: }
473:
474: acl_d->count = ndefault;
475: } else {
476: acl_d->count = naccess;
477: }
478:
479: return acl_d;
480: }
481:
482: #if 0
483: SMB_ACL_T sys_acl_get_fd(int fd)
484: {
485: SMB_ACL_T acl_d;
486: int count; /* # of ACL entries allocated */
487: int naccess; /* # of access ACL entries */
488:
489: count = INITIAL_ACL_SIZE;
490: if ((acl_d = sys_acl_init(count)) == NULL) {
491: return NULL;
492: }
493:
494: while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0
495: && errno == ENOSPC) {
496:
497: sys_acl_free_acl(acl_d);
498:
499: if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) {
500: return NULL;
501: }
502:
503: if ((acl_d = sys_acl_init(count)) == NULL) {
504: return NULL;
505: }
506: }
507:
508: if (count < 0) {
509: sys_acl_free_acl(acl_d);
510: return NULL;
511: }
512:
513: /*
514: * calculate the number of access ACL entries
515: */
516: for (naccess = 0; naccess < count; naccess++) {
517: if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
518: break;
519: }
520:
521: acl_d->count = naccess;
522:
523: return acl_d;
524: }
525: #endif
526:
527: int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p)
528: {
529: *tag_type_p = entry->a_type;
530:
531: *bits_p = entry->a_perm;
532:
533: if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP)
534: *u_g_id_p = entry->a_id;
535:
536: return 0;
537: }
538:
539: SMB_ACL_T sys_acl_init(int count)
540: {
541: SMB_ACL_T a;
542:
543: if (count < 0) {
544: errno = EINVAL;
545: return NULL;
546: }
547:
548: /*
549: * note that since the definition of the structure pointed
550: * to by the SMB_ACL_T includes the first element of the
551: * acl[] array, this actually allocates an ACL with room
552: * for (count+1) entries
553: */
554: if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + count * sizeof (struct acl))) == NULL) {
555: errno = ENOMEM;
556: return NULL;
557: }
558:
559: a->size = count + 1;
560: a->count = 0;
561: a->next = -1;
562:
563: return a;
564: }
565:
566:
567: int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
568: {
569: SMB_ACL_T acl_d;
570: SMB_ACL_ENTRY_T entry_d;
571:
572: if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
573: errno = EINVAL;
574: return -1;
575: }
576:
577: if (acl_d->count >= acl_d->size) {
578: errno = ENOSPC;
579: return -1;
580: }
581:
582: entry_d = &acl_d->acl[acl_d->count++];
583: entry_d->a_type = 0;
584: entry_d->a_id = -1;
585: entry_d->a_perm = 0;
586: *entry_p = entry_d;
587:
588: return 0;
589: }
590:
591: int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id)
592: {
593: entry->a_type = tag_type;
594:
595: if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP)
596: entry->a_id = u_g_id;
597:
598: entry->a_perm = bits;
599:
600: return 0;
601: }
602:
603: int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry_d, uint32 bits)
604: {
605: entry_d->a_perm = bits;
606: return 0;
607: }
608:
609: /*
610: * sort the ACL and check it for validity
611: *
612: * if it's a minimal ACL with only 4 entries then we
613: * need to recalculate the mask permissions to make
614: * sure that they are the same as the GROUP_OBJ
615: * permissions as required by the UnixWare acl() system call.
616: *
617: * (note: since POSIX allows minimal ACLs which only contain
618: * 3 entries - ie there is no mask entry - we should, in theory,
619: * check for this and add a mask entry if necessary - however
620: * we "know" that the caller of this interface always specifies
621: * a mask so, in practice "this never happens" (tm) - if it *does*
622: * happen aclsort() will fail and return an error and someone will
623: * have to fix it ...)
624: */
625:
626: static int acl_sort(SMB_ACL_T acl_d)
627: {
628: int fixmask = (acl_d->count <= 4);
629:
630: if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {
631: errno = EINVAL;
632: return -1;
633: }
634: return 0;
635: }
636:
637: int sys_acl_valid(SMB_ACL_T acl_d)
638: {
639: return acl_sort(acl_d);
640: }
641:
642: int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
643: {
644: struct stat s;
645: struct acl *acl_p;
646: int acl_count;
647: struct acl *acl_buf = NULL;
648: int ret;
649:
650: if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
651: errno = EINVAL;
652: return -1;
653: }
654:
655: if (acl_sort(acl_d) != 0) {
656: return -1;
657: }
658:
659: acl_p = &acl_d->acl[0];
660: acl_count = acl_d->count;
661:
662: /*
663: * if it's a directory there is extra work to do
664: * since the acl() system call will replace both
665: * the access ACLs and the default ACLs (if any)
666: */
667: if (stat(name, &s) != 0) {
668: return -1;
669: }
670: if (S_ISDIR(s.st_mode)) {
671: SMB_ACL_T acc_acl;
672: SMB_ACL_T def_acl;
673: SMB_ACL_T tmp_acl;
674: int i;
675:
676: if (type == SMB_ACL_TYPE_ACCESS) {
677: acc_acl = acl_d;
678: def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
679:
680: } else {
681: def_acl = acl_d;
682: acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
683: }
684:
685: if (tmp_acl == NULL) {
686: return -1;
687: }
688:
689: /*
690: * allocate a temporary buffer for the complete ACL
691: */
692: acl_count = acc_acl->count + def_acl->count;
693: acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
694:
695: if (acl_buf == NULL) {
696: sys_acl_free_acl(tmp_acl);
697: errno = ENOMEM;
698: return -1;
699: }
700:
701: /*
702: * copy the access control and default entries into the buffer
703: */
704: memcpy(&acl_buf[0], &acc_acl->acl[0],
705: acc_acl->count * sizeof(acl_buf[0]));
706:
707: memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
708: def_acl->count * sizeof(acl_buf[0]));
709:
710: /*
711: * set the ACL_DEFAULT flag on the default entries
712: */
713: for (i = acc_acl->count; i < acl_count; i++) {
714: acl_buf[i].a_type |= ACL_DEFAULT;
715: }
716:
717: sys_acl_free_acl(tmp_acl);
718:
719: } else if (type != SMB_ACL_TYPE_ACCESS) {
720: errno = EINVAL;
721: return -1;
722: }
723:
724: ret = acl(name, SETACL, acl_count, acl_p);
725:
726: SAFE_FREE(acl_buf);
727:
728: return ret;
729: }
730:
731: #if 0
732: int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
733: {
734: if (acl_sort(acl_d) != 0) {
735: return -1;
736: }
737:
738: return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);
739: }
740: #endif
741:
742: int sys_acl_delete_def_file(const char *path)
743: {
744: SMB_ACL_T acl_d;
745: int ret;
746:
747: /*
748: * fetching the access ACL and rewriting it has
749: * the effect of deleting the default ACL
750: */
751: if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
752: return -1;
753: }
754:
755: ret = acl(path, SETACL, acl_d->count, acl_d->acl);
756:
757: sys_acl_free_acl(acl_d);
758:
759: return ret;
760: }
761:
762: int sys_acl_free_acl(SMB_ACL_T acl_d)
763: {
764: SAFE_FREE(acl_d);
765: return 0;
766: }
767:
768: #elif defined(HAVE_HPUX_ACLS) /*---------------------------------------------*/
769:
770: #include <dl.h>
771:
772: /*
773: * Based on the Solaris/SCO code - with modifications.
774: */
775:
776: /*
777: * Note that while this code implements sufficient functionality
778: * to support the sys_acl_* interfaces it does not provide all
779: * of the semantics of the POSIX ACL interfaces.
780: *
781: * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
782: * from a call to sys_acl_get_entry() should not be assumed to be
783: * valid after calling any of the following functions, which may
784: * reorder the entries in the ACL.
785: *
786: * sys_acl_valid()
787: * sys_acl_set_file()
788: * sys_acl_set_fd()
789: */
790:
791: /* This checks if the POSIX ACL system call is defined */
792: /* which basically corresponds to whether JFS 3.3 or */
793: /* higher is installed. If acl() was called when it */
794: /* isn't defined, it causes the process to core dump */
795: /* so it is important to check this and avoid acl() */
796: /* calls if it isn't there. */
797:
798: static BOOL hpux_acl_call_presence(void)
799: {
800:
801: shl_t handle = NULL;
802: void *value;
803: int ret_val=0;
804: static BOOL already_checked=0;
805:
806: if(already_checked)
807: return True;
808:
809:
810: ret_val = shl_findsym(&handle, "acl", TYPE_PROCEDURE, &value);
811:
812: if(ret_val != 0) {
813: DEBUG(5, ("hpux_acl_call_presence: shl_findsym() returned %d, errno = %d, error %s\n",
814: ret_val, errno, strerror(errno)));
815: DEBUG(5,("hpux_acl_call_presence: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
816: return False;
817: }
818:
819: DEBUG(10,("hpux_acl_call_presence: acl() system call is present. We have JFS 3.3 or above \n"));
820:
821: already_checked = True;
822: return True;
823: }
824:
825: int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
826: {
827: if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
828: errno = EINVAL;
829: return -1;
830: }
831:
832: if (entry_p == NULL) {
833: errno = EINVAL;
834: return -1;
835: }
836:
837: if (entry_id == SMB_ACL_FIRST_ENTRY) {
838: acl_d->next = 0;
839: }
840:
841: if (acl_d->next < 0) {
842: errno = EINVAL;
843: return -1;
844: }
845:
846: if (acl_d->next >= acl_d->count) {
847: return 0;
848: }
849:
850: *entry_p = &acl_d->acl[acl_d->next++];
851:
852: return 1;
853: }
854:
855: int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
856: {
857: *type_p = entry_d->a_type;
858:
859: return 0;
860: }
861:
862: /*
863: * There is no way of knowing what size the ACL returned by
864: * ACL_GET will be unless you first call ACL_CNT which means
865: * making an additional system call.
866: *
867: * In the hope of avoiding the cost of the additional system
868: * call in most cases, we initially allocate enough space for
869: * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
870: * be too small then we use ACL_CNT to find out the actual
871: * size, reallocate the ACL buffer, and then call ACL_GET again.
872: */
873:
874: #define INITIAL_ACL_SIZE 16
875:
876: SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
877: {
878: SMB_ACL_T acl_d;
879: int count; /* # of ACL entries allocated */
880: int naccess; /* # of access ACL entries */
881: int ndefault; /* # of default ACL entries */
882:
883: if(hpux_acl_call_presence() == False) {
884: /* Looks like we don't have the acl() system call on HPUX.
885: * May be the system doesn't have the latest version of JFS.
886: */
887: return NULL;
888: }
889:
890: if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
891: errno = EINVAL;
892: return NULL;
893: }
894:
895: count = INITIAL_ACL_SIZE;
896: if ((acl_d = sys_acl_init(count)) == NULL) {
897: return NULL;
898: }
899:
900: /*
901: * If there isn't enough space for the ACL entries we use
902: * ACL_CNT to determine the actual number of ACL entries
903: * reallocate and try again. This is in a loop because it
904: * is possible that someone else could modify the ACL and
905: * increase the number of entries between the call to
906: * ACL_CNT and the call to ACL_GET.
907: */
908: while ((count = acl(path_p, ACL_GET, count, &acl_d->acl[0])) < 0 && errno == ENOSPC) {
909:
910: sys_acl_free_acl(acl_d);
911:
912: if ((count = acl(path_p, ACL_CNT, 0, NULL)) < 0) {
913: return NULL;
914: }
915:
916: if ((acl_d = sys_acl_init(count)) == NULL) {
917: return NULL;
918: }
919: }
920:
921: if (count < 0) {
922: sys_acl_free_acl(acl_d);
923: return NULL;
924: }
925:
926: /*
927: * calculate the number of access and default ACL entries
928: *
929: * Note: we assume that the acl() system call returned a
930: * well formed ACL which is sorted so that all of the
931: * access ACL entries preceed any default ACL entries
932: */
933: for (naccess = 0; naccess < count; naccess++) {
934: if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
935: break;
936: }
937: ndefault = count - naccess;
938:
939: /*
940: * if the caller wants the default ACL we have to copy
941: * the entries down to the start of the acl[] buffer
942: * and mask out the ACL_DEFAULT flag from the type field
943: */
944: if (type == SMB_ACL_TYPE_DEFAULT) {
945: int i, j;
946:
947: for (i = 0, j = naccess; i < ndefault; i++, j++) {
948: acl_d->acl[i] = acl_d->acl[j];
949: acl_d->acl[i].a_type &= ~ACL_DEFAULT;
950: }
951:
952: acl_d->count = ndefault;
953: } else {
954: acl_d->count = naccess;
955: }
956:
957: return acl_d;
958: }
959:
960: #if 0
961: SMB_ACL_T sys_acl_get_fd(int fd)
962: {
963: /*
964: * HPUX doesn't have the facl call. Fake it using the path.... JRA.
965: */
966:
967: files_struct *fsp = file_find_fd(fd);
968:
969: if (fsp == NULL) {
970: errno = EBADF;
971: return NULL;
972: }
973:
974: /*
975: * We know we're in the same conn context. So we
976: * can use the relative path.
977: */
978:
979: return sys_acl_get_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS);
980: }
981: #endif
982:
983: int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p)
984: {
985: *tag_type_p = entry->a_type;
986:
987: *bits_p = entry->a_perm;
988:
989: if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP)
990: *u_g_id_p = entry->a_id;
991:
992: return 0;
993: }
994:
995: SMB_ACL_T sys_acl_init(int count)
996: {
997: SMB_ACL_T a;
998:
999: if (count < 0) {
1000: errno = EINVAL;
1001: return NULL;
1002: }
1003:
1004: /*
1005: * note that since the definition of the structure pointed
1006: * to by the SMB_ACL_T includes the first element of the
1007: * acl[] array, this actually allocates an ACL with room
1008: * for (count+1) entries
1009: */
1010: if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + count * sizeof(struct acl))) == NULL) {
1011: errno = ENOMEM;
1012: return NULL;
1013: }
1014:
1015: a->size = count + 1;
1016: a->count = 0;
1017: a->next = -1;
1018:
1019: return a;
1020: }
1021:
1022:
1023: int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1024: {
1025: SMB_ACL_T acl_d;
1026: SMB_ACL_ENTRY_T entry_d;
1027:
1028: if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
1029: errno = EINVAL;
1030: return -1;
1031: }
1032:
1033: if (acl_d->count >= acl_d->size) {
1034: errno = ENOSPC;
1035: return -1;
1036: }
1037:
1038: entry_d = &acl_d->acl[acl_d->count++];
1039: entry_d->a_type = 0;
1040: entry_d->a_id = -1;
1041: entry_d->a_perm = 0;
1042: *entry_p = entry_d;
1043:
1044: return 0;
1045: }
1046:
1047: int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id)
1048: {
1049: entry->a_type = tag_type;
1050:
1051: if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP)
1052: entry->a_id = u_g_id;
1053:
1054: entry->a_perm = bits;
1055:
1056: return 0;
1057: }
1058:
1059: int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry_d, uint32 bits)
1060: {
1061: entry_d->a_perm = bits;
1062:
1063: return 0;
1064: }
1065:
1066: /* Structure to capture the count for each type of ACE. */
1067:
1068: struct hpux_acl_types {
1069: int n_user;
1070: int n_def_user;
1071: int n_user_obj;
1072: int n_def_user_obj;
1073:
1074: int n_group;
1075: int n_def_group;
1076: int n_group_obj;
1077: int n_def_group_obj;
1078:
1079: int n_other;
1080: int n_other_obj;
1081: int n_def_other_obj;
1082:
1083: int n_class_obj;
1084: int n_def_class_obj;
1085:
1086: int n_illegal_obj;
1087: };
1088:
1089: /* count_obj:
1090: * Counts the different number of objects in a given array of ACL
1091: * structures.
1092: * Inputs:
1093: *
1094: * acl_count - Count of ACLs in the array of ACL strucutres.
1095: * aclp - Array of ACL structures.
1096: * acl_type_count - Pointer to acl_types structure. Should already be
1097: * allocated.
1098: * Output:
1099: *
1100: * acl_type_count - This structure is filled up with counts of various
1101: * acl types.
1102: */
1103:
1104: static void hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_types *acl_type_count)
1105: {
1106: int i;
1107:
1108: memset(acl_type_count, 0, sizeof(struct hpux_acl_types));
1109:
1110: for(i=0;i<acl_count;i++) {
1111: switch(aclp[i].a_type) {
1112: case USER:
1113: acl_type_count->n_user++;
1114: break;
1115: case USER_OBJ:
1116: acl_type_count->n_user_obj++;
1117: break;
1118: case DEF_USER_OBJ:
1119: acl_type_count->n_def_user_obj++;
1120: break;
1121: case GROUP:
1122: acl_type_count->n_group++;
1123: break;
1124: case GROUP_OBJ:
1125: acl_type_count->n_group_obj++;
1126: break;
1127: case DEF_GROUP_OBJ:
1128: acl_type_count->n_def_group_obj++;
1129: break;
1130: case OTHER_OBJ:
1131: acl_type_count->n_other_obj++;
1132: break;
1133: case DEF_OTHER_OBJ:
1134: acl_type_count->n_def_other_obj++;
1135: break;
1136: case CLASS_OBJ:
1137: acl_type_count->n_class_obj++;
1138: break;
1139: case DEF_CLASS_OBJ:
1140: acl_type_count->n_def_class_obj++;
1141: break;
1142: case DEF_USER:
1143: acl_type_count->n_def_user++;
1144: break;
1145: case DEF_GROUP:
1146: acl_type_count->n_def_group++;
1147: break;
1148: default:
1149: acl_type_count->n_illegal_obj++;
1150: break;
1151: }
1152: }
1153: }
1154:
1155: /* swap_acl_entries: Swaps two ACL entries.
1156: *
1157: * Inputs: aclp0, aclp1 - ACL entries to be swapped.
1158: */
1159:
1160: static void hpux_swap_acl_entries(struct acl *aclp0, struct acl *aclp1)
1161: {
1162: struct acl temp_acl;
1163:
1164: temp_acl.a_type = aclp0->a_type;
1165: temp_acl.a_id = aclp0->a_id;
1166: temp_acl.a_perm = aclp0->a_perm;
1167:
1168: aclp0->a_type = aclp1->a_type;
1169: aclp0->a_id = aclp1->a_id;
1170: aclp0->a_perm = aclp1->a_perm;
1171:
1172: aclp1->a_type = temp_acl.a_type;
1173: aclp1->a_id = temp_acl.a_id;
1174: aclp1->a_perm = temp_acl.a_perm;
1175: }
1176:
1177: /* prohibited_duplicate_type
1178: * Identifies if given ACL type can have duplicate entries or
1179: * not.
1180: *
1181: * Inputs: acl_type - ACL Type.
1182: *
1183: * Outputs:
1184: *
1185: * Return..
1186: *
1187: * True - If the ACL type matches any of the prohibited types.
1188: * False - If the ACL type doesn't match any of the prohibited types.
1189: */
1190:
1191: static BOOL hpux_prohibited_duplicate_type(int acl_type)
1192: {
1193: switch(acl_type) {
1194: case USER:
1195: case GROUP:
1196: case DEF_USER:
1197: case DEF_GROUP:
1198: return True;
1199: default:
1200: return False;
1201: }
1202: }
1203:
1204: /* get_needed_class_perm
1205: * Returns the permissions of a ACL structure only if the ACL
1206: * type matches one of the pre-determined types for computing
1207: * CLASS_OBJ permissions.
1208: *
1209: * Inputs: aclp - Pointer to ACL structure.
1210: */
1211:
1212: static int hpux_get_needed_class_perm(struct acl *aclp)
1213: {
1214: switch(aclp->a_type) {
1215: case USER:
1216: case GROUP_OBJ:
1217: case GROUP:
1218: case DEF_USER_OBJ:
1219: case DEF_USER:
1220: case DEF_GROUP_OBJ:
1221: case DEF_GROUP:
1222: case DEF_CLASS_OBJ:
1223: case DEF_OTHER_OBJ:
1224: return aclp->a_perm;
1225: default:
1226: return 0;
1227: }
1228: }
1229:
1230: /* acl_sort for HPUX.
1231: * Sorts the array of ACL structures as per the description in
1232: * aclsort man page. Refer to aclsort man page for more details
1233: *
1234: * Inputs:
1235: *
1236: * acl_count - Count of ACLs in the array of ACL structures.
1237: * calclass - If this is not zero, then we compute the CLASS_OBJ
1238: * permissions.
1239: * aclp - Array of ACL structures.
1240: *
1241: * Outputs:
1242: *
1243: * aclp - Sorted array of ACL structures.
1244: *
1245: * Outputs:
1246: *
1247: * Returns 0 for success -1 for failure. Prints a message to the Samba
1248: * debug log in case of failure.
1249: */
1250:
1251: static int hpux_acl_sort(int acl_count, int calclass, struct acl *aclp)
1252: {
1253: #if !defined(HAVE_HPUX_ACLSORT)
1254: /*
1255: * The aclsort() system call is availabe on the latest HPUX General
1256: * Patch Bundles. So for HPUX, we developed our version of acl_sort
1257: * function. Because, we don't want to update to a new
1258: * HPUX GR bundle just for aclsort() call.
1259: */
1260:
1261: struct hpux_acl_types acl_obj_count;
1262: int n_class_obj_perm = 0;
1263: int i, j;
1264:
1265: if(!acl_count) {
1266: DEBUG(10,("Zero acl count passed. Returning Success\n"));
1267: return 0;
1268: }
1269:
1270: if(aclp == NULL) {
1271: DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
1272: return -1;
1273: }
1274:
1275: /* Count different types of ACLs in the ACLs array */
1276:
1277: hpux_count_obj(acl_count, aclp, &acl_obj_count);
1278:
1279: /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
1280: * CLASS_OBJ and OTHER_OBJ
1281: */
1282:
1283: if( (acl_obj_count.n_user_obj != 1) ||
1284: (acl_obj_count.n_group_obj != 1) ||
1285: (acl_obj_count.n_class_obj != 1) ||
1286: (acl_obj_count.n_other_obj != 1)
1287: ) {
1288: DEBUG(0,("hpux_acl_sort: More than one entry or no entries for \
1289: USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
1290: return -1;
1291: }
1292:
1293: /* If any of the default objects are present, there should be only
1294: * one of them each.
1295: */
1296:
1297: if( (acl_obj_count.n_def_user_obj > 1) || (acl_obj_count.n_def_group_obj > 1) ||
1298: (acl_obj_count.n_def_other_obj > 1) || (acl_obj_count.n_def_class_obj > 1) ) {
1299: DEBUG(0,("hpux_acl_sort: More than one entry for DEF_CLASS_OBJ \
1300: or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
1301: return -1;
1302: }
1303:
1304: /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
1305: * structures.
1306: *
1307: * Sorting crieteria - First sort by ACL type. If there are multiple entries of
1308: * same ACL type, sort by ACL id.
1309: *
1310: * I am using the trival kind of sorting method here because, performance isn't
1311: * really effected by the ACLs feature. More over there aren't going to be more
1312: * than 17 entries on HPUX.
1313: */
1314:
1315: for(i=0; i<acl_count;i++) {
1316: for (j=i+1; j<acl_count; j++) {
1317: if( aclp[i].a_type > aclp[j].a_type ) {
1318: /* ACL entries out of order, swap them */
1319:
1320: hpux_swap_acl_entries((aclp+i), (aclp+j));
1321:
1322: } else if ( aclp[i].a_type == aclp[j].a_type ) {
1323:
1324: /* ACL entries of same type, sort by id */
1325:
1326: if(aclp[i].a_id > aclp[j].a_id) {
1327: hpux_swap_acl_entries((aclp+i), (aclp+j));
1328: } else if (aclp[i].a_id == aclp[j].a_id) {
1329: /* We have a duplicate entry. */
1330: if(hpux_prohibited_duplicate_type(aclp[i].a_type)) {
1331: DEBUG(0, ("hpux_acl_sort: Duplicate entry: Type(hex): %x Id: %d\n",
1332: aclp[i].a_type, aclp[i].a_id));
1333: return -1;
1334: }
1335: }
1336:
1337: }
1338: }
1339: }
1340:
1341: /* set the class obj permissions to the computed one. */
1342: if(calclass) {
1343: int n_class_obj_index = -1;
1344:
1345: for(i=0;i<acl_count;i++) {
1346: n_class_obj_perm |= hpux_get_needed_class_perm((aclp+i));
1347:
1348: if(aclp[i].a_type == CLASS_OBJ)
1349: n_class_obj_index = i;
1350: }
1351: aclp[n_class_obj_index].a_perm = n_class_obj_perm;
1352: }
1353:
1354: return 0;
1355: #else
1356: return aclsort(acl_count, calclass, aclp);
1357: #endif
1358: }
1359:
1360: /*
1361: * sort the ACL and check it for validity
1362: *
1363: * if it's a minimal ACL with only 4 entries then we
1364: * need to recalculate the mask permissions to make
1365: * sure that they are the same as the GROUP_OBJ
1366: * permissions as required by the UnixWare acl() system call.
1367: *
1368: * (note: since POSIX allows minimal ACLs which only contain
1369: * 3 entries - ie there is no mask entry - we should, in theory,
1370: * check for this and add a mask entry if necessary - however
1371: * we "know" that the caller of this interface always specifies
1372: * a mask so, in practice "this never happens" (tm) - if it *does*
1373: * happen aclsort() will fail and return an error and someone will
1374: * have to fix it ...)
1375: */
1376:
1377: static int acl_sort(SMB_ACL_T acl_d)
1378: {
1379: int fixmask = (acl_d->count <= 4);
1380:
1381: if (hpux_acl_sort(acl_d->count, fixmask, acl_d->acl) != 0) {
1382: errno = EINVAL;
1383: return -1;
1384: }
1385: return 0;
1386: }
1387:
1388: int sys_acl_valid(SMB_ACL_T acl_d)
1389: {
1390: return acl_sort(acl_d);
1391: }
1392:
1393: int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
1394: {
1395: struct stat s;
1396: struct acl *acl_p;
1397: int acl_count;
1398: struct acl *acl_buf = NULL;
1399: int ret;
1400:
1401: if(hpux_acl_call_presence() == False) {
1402: /* Looks like we don't have the acl() system call on HPUX.
1403: * May be the system doesn't have the latest version of JFS.
1404: */
1405: errno=ENOSYS;
1406: return -1;
1407: }
1408:
1409: if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
1410: errno = EINVAL;
1411: return -1;
1412: }
1413:
1414: if (acl_sort(acl_d) != 0) {
1415: return -1;
1416: }
1417:
1418: acl_p = &acl_d->acl[0];
1419: acl_count = acl_d->count;
1420:
1421: /*
1422: * if it's a directory there is extra work to do
1423: * since the acl() system call will replace both
1424: * the access ACLs and the default ACLs (if any)
1425: */
1426: if (stat(name, &s) != 0) {
1427: return -1;
1428: }
1429: if (S_ISDIR(s.st_mode)) {
1430: SMB_ACL_T acc_acl;
1431: SMB_ACL_T def_acl;
1432: SMB_ACL_T tmp_acl;
1433: int i;
1434:
1435: if (type == SMB_ACL_TYPE_ACCESS) {
1436: acc_acl = acl_d;
1437: def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
1438:
1439: } else {
1440: def_acl = acl_d;
1441: acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
1442: }
1443:
1444: if (tmp_acl == NULL) {
1445: return -1;
1446: }
1447:
1448: /*
1449: * allocate a temporary buffer for the complete ACL
1450: */
1451: acl_count = acc_acl->count + def_acl->count;
1452: acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
1453:
1454: if (acl_buf == NULL) {
1455: sys_acl_free_acl(tmp_acl);
1456: errno = ENOMEM;
1457: return -1;
1458: }
1459:
1460: /*
1461: * copy the access control and default entries into the buffer
1462: */
1463: memcpy(&acl_buf[0], &acc_acl->acl[0],
1464: acc_acl->count * sizeof(acl_buf[0]));
1465:
1466: memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
1467: def_acl->count * sizeof(acl_buf[0]));
1468:
1469: /*
1470: * set the ACL_DEFAULT flag on the default entries
1471: */
1472: for (i = acc_acl->count; i < acl_count; i++) {
1473: acl_buf[i].a_type |= ACL_DEFAULT;
1474: }
1475:
1476: sys_acl_free_acl(tmp_acl);
1477:
1478: } else if (type != SMB_ACL_TYPE_ACCESS) {
1479: errno = EINVAL;
1480: return -1;
1481: }
1482:
1483: ret = acl(name, ACL_SET, acl_count, acl_p);
1484:
1485: if (acl_buf) {
1486: free(acl_buf);
1487: }
1488:
1489: return ret;
1490: }
1491:
1492: #if 0
1493: int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
1494: {
1495: /*
1496: * HPUX doesn't have the facl call. Fake it using the path.... JRA.
1497: */
1498:
1499: files_struct *fsp = file_find_fd(fd);
1500:
1501: if (fsp == NULL) {
1502: errno = EBADF;
1503: return NULL;
1504: }
1505:
1506: if (acl_sort(acl_d) != 0) {
1507: return -1;
1508: }
1509:
1510: /*
1511: * We know we're in the same conn context. So we
1512: * can use the relative path.
1513: */
1514:
1515: return sys_acl_set_file(fsp->fsp_name, SMB_ACL_TYPE_ACCESS, acl_d);
1516: }
1517: #endif
1518:
1519: int sys_acl_delete_def_file(const char *path)
1520: {
1521: SMB_ACL_T acl_d;
1522: int ret;
1523:
1524: /*
1525: * fetching the access ACL and rewriting it has
1526: * the effect of deleting the default ACL
1527: */
1528: if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
1529: return -1;
1530: }
1531:
1532: ret = acl(path, ACL_SET, acl_d->count, acl_d->acl);
1533:
1534: sys_acl_free_acl(acl_d);
1535:
1536: return ret;
1537: }
1538:
1539: int sys_acl_free_acl(SMB_ACL_T acl_d)
1540: {
1541: free(acl_d);
1542: return 0;
1543: }
1544:
1545: #elif defined(HAVE_IRIX_ACLS) /*---------------------------------------------*/
1546:
1547: int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1548: {
1549: if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
1550: errno = EINVAL;
1551: return -1;
1552: }
1553:
1554: if (entry_p == NULL) {
1555: errno = EINVAL;
1556: return -1;
1557: }
1558:
1559: if (entry_id == SMB_ACL_FIRST_ENTRY) {
1560: acl_d->next = 0;
1561: }
1562:
1563: if (acl_d->next < 0) {
1564: errno = EINVAL;
1565: return -1;
1566: }
1567:
1568: if (acl_d->next >= acl_d->aclp->acl_cnt) {
1569: return 0;
1570: }
1571:
1572: *entry_p = &acl_d->aclp->acl_entry[acl_d->next++];
1573:
1574: return 1;
1575: }
1576:
1577: int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
1578: {
1579: *type_p = entry_d->ae_tag;
1580:
1581: return 0;
1582: }
1583:
1584: SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
1585: {
1586: SMB_ACL_T a;
1587:
1588: if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
1589: errno = ENOMEM;
1590: return NULL;
1591: }
1592: if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
1593: SAFE_FREE(a);
1594: return NULL;
1595: }
1596: a->next = -1;
1597: a->freeaclp = True;
1598: return a;
1599: }
1600:
1601: #if 0
1602: SMB_ACL_T sys_acl_get_fd(int fd)
1603: {
1604: SMB_ACL_T a;
1605:
1606: if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
1607: errno = ENOMEM;
1608: return NULL;
1609: }
1610: if ((a->aclp = acl_get_fd(fd)) == NULL) {
1611: SAFE_FREE(a);
1612: return NULL;
1613: }
1614: a->next = -1;
1615: a->freeaclp = True;
1616: return a;
1617: }
1618: #endif
1619:
1620: int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p)
1621: {
1622: *tag_type_p = entry->ae_tag;
1623:
1624: *bits_p = entry->ae_perm;
1625:
1626: if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP)
1627: *u_g_id_p = entry->ae_id;
1628:
1629: return 0;
1630: }
1631:
1632: SMB_ACL_T sys_acl_init(int count)
1633: {
1634: SMB_ACL_T a;
1635:
1636: if (count < 0) {
1637: errno = EINVAL;
1638: return NULL;
1639: }
1640:
1641: if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + sizeof (struct acl))) == NULL) {
1642: errno = ENOMEM;
1643: return NULL;
1644: }
1645:
1646: a->next = -1;
1647: a->freeaclp = False;
1648: a->aclp = (struct acl *)((char *)a + sizeof a[0]);
1649: a->aclp->acl_cnt = 0;
1650:
1651: return a;
1652: }
1653:
1654:
1655: int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
1656: {
1657: SMB_ACL_T acl_d;
1658: SMB_ACL_ENTRY_T entry_d;
1659:
1660: if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
1661: errno = EINVAL;
1662: return -1;
1663: }
1664:
1665: if (acl_d->aclp->acl_cnt >= ACL_MAX_ENTRIES) {
1666: errno = ENOSPC;
1667: return -1;
1668: }
1669:
1670: entry_d = &acl_d->aclp->acl_entry[acl_d->aclp->acl_cnt++];
1671: entry_d->ae_tag = 0;
1672: entry_d->ae_id = 0;
1673: entry_d->ae_perm = 0;
1674: *entry_p = entry_d;
1675:
1676: return 0;
1677: }
1678:
1679: int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id)
1680: {
1681: entry->ae_tag = tag_type;
1682:
1683: if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP)
1684: entry->ae_id = u_g_id;
1685:
1686: entry->ae_perm = bits;
1687:
1688: return 0;
1689: }
1690:
1691: int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry_d, uint32 bits)
1692: {
1693: entry_d->ae_perm = bits;
1694:
1695: return 0;
1696: }
1697:
1698: int sys_acl_valid(SMB_ACL_T acl_d)
1699: {
1700: return acl_valid(acl_d->aclp);
1701: }
1702:
1703: int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
1704: {
1705: return acl_set_file(name, type, acl_d->aclp);
1706: }
1707:
1708: #if 0
1709: int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
1710: {
1711: return acl_set_fd(fd, acl_d->aclp);
1712: }
1713: #endif
1714:
1715: int sys_acl_delete_def_file(const char *name)
1716: {
1717: return acl_delete_def_file(name);
1718: }
1719:
1720: int sys_acl_free_acl(SMB_ACL_T acl_d)
1721: {
1722: if (acl_d->freeaclp) {
1723: acl_free(acl_d->aclp);
1724: }
1725: acl_free(acl_d);
1726: return 0;
1727: }
1728:
1729: #elif defined(HAVE_AIX_ACLS) /*----------------------------------------------*/
1730:
1731: /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
1732:
1733: int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1734: {
1735: struct acl_entry_link *link;
1736: struct new_acl_entry *entry;
1737: int keep_going;
1738:
1739: if (entry_id == SMB_ACL_FIRST_ENTRY)
1740: theacl->count = 0;
1741: else if (entry_id != SMB_ACL_NEXT_ENTRY) {
1742: errno = EINVAL;
1743: return -1;
1744: }
1745:
1746: DEBUG(10,("This is the count: %d\n",theacl->count));
1747:
1748: /* Check if count was previously set to -1. *
1749: * If it was, that means we reached the end *
1750: * of the acl last time. */
1751: if(theacl->count == -1)
1752: return(0);
1753:
1754: link = theacl;
1755: /* To get to the next acl, traverse linked list until index *
1756: * of acl matches the count we are keeping. This count is *
1757: * incremented each time we return an acl entry. */
1758:
1759: for(keep_going = 0; keep_going < theacl->count; keep_going++)
1760: link = link->nextp;
1761:
1762: entry = *entry_p = link->entryp;
1763:
1764: DEBUG(10,("*entry_p is %d\n",entry_p));
1765: DEBUG(10,("*entry_p->ace_access is %d\n",entry->ace_access));
1766:
1767: /* Increment count */
1768: theacl->count++;
1769: if(link->nextp == NULL)
1770: theacl->count = -1;
1771:
1772: return(1);
1773: }
1774:
1775: int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1776: {
1777: /* Initialize tag type */
1778:
1779: *tag_type_p = -1;
1780: DEBUG(10,("the tagtype is %d\n",entry_d->ace_id->id_type));
1781:
1782: /* Depending on what type of entry we have, *
1783: * return tag type. */
1784: switch(entry_d->ace_id->id_type) {
1785: case ACEID_USER:
1786: *tag_type_p = SMB_ACL_USER;
1787: break;
1788: case ACEID_GROUP:
1789: *tag_type_p = SMB_ACL_GROUP;
1790: break;
1791:
1792: case SMB_ACL_USER_OBJ:
1793: case SMB_ACL_GROUP_OBJ:
1794: case SMB_ACL_OTHER:
1795: *tag_type_p = entry_d->ace_id->id_type;
1796: break;
1797:
1798: default:
1799: return(-1);
1800: }
1801:
1802: return(0);
1803: }
1804:
1805: SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
1806: {
1807: struct acl *file_acl = (struct acl *)NULL;
1808: struct acl_entry *acl_entry;
1809: struct new_acl_entry *new_acl_entry;
1810: struct ace_id *idp;
1811: struct acl_entry_link *acl_entry_link;
1812: struct acl_entry_link *acl_entry_link_head;
1813: int i;
1814: int rc = 0;
1815:
1816: /* AIX has no DEFAULT */
1817: if ( type == SMB_ACL_TYPE_DEFAULT ) {
1818: #ifdef ENOTSUP
1819: errno = ENOTSUP;
1820: #else
1821: errno = ENOSYS;
1822: #endif
1823: return NULL;
1824: }
1825:
1826: /* Get the acl using statacl */
1827:
1828: DEBUG(10,("Entering sys_acl_get_file\n"));
1829: DEBUG(10,("path_p is %s\n",path_p));
1830:
1831: file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
1832:
1833: if(file_acl == NULL) {
1834: errno=ENOMEM;
1835: DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
1836: return(NULL);
1837: }
1838:
1839: memset(file_acl,0,BUFSIZ);
1840:
1841: rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
1842: if(rc == -1) {
1843: DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
1844: SAFE_FREE(file_acl);
1845: return(NULL);
1846: }
1847:
1848: DEBUG(10,("Got facl and returned it\n"));
1849:
1850: /* Point to the first acl entry in the acl */
1851: acl_entry = file_acl->acl_ext;
1852:
1853: /* Begin setting up the head of the linked list *
1854: * that will be used for the storing the acl *
1855: * in a way that is useful for the posix_acls.c *
1856: * code. */
1857:
1858: acl_entry_link_head = acl_entry_link = sys_acl_init(0);
1859: if(acl_entry_link_head == NULL)
1860: return(NULL);
1861:
1862: acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
1863: if(acl_entry_link->entryp == NULL) {
1864: SAFE_FREE(file_acl);
1865: errno = ENOMEM;
1866: DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1867: return(NULL);
1868: }
1869:
1870: DEBUG(10,("acl_entry is %d\n",acl_entry));
1871: DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
1872:
1873: /* Check if the extended acl bit is on. *
1874: * If it isn't, do not show the *
1875: * contents of the acl since AIX intends *
1876: * the extended info to remain unused */
1877:
1878: if(file_acl->acl_mode & S_IXACL){
1879: /* while we are not pointing to the very end */
1880: while(acl_entry < acl_last(file_acl)) {
1881: /* before we malloc anything, make sure this is */
1882: /* a valid acl entry and one that we want to map */
1883: idp = id_nxt(acl_entry->ace_id);
1884: if((acl_entry->ace_type == ACC_SPECIFY ||
1885: (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
1886: acl_entry = acl_nxt(acl_entry);
1887: continue;
1888: }
1889:
1890: idp = acl_entry->ace_id;
1891:
1892: /* Check if this is the first entry in the linked list. *
1893: * The first entry needs to keep prevp pointing to NULL *
1894: * and already has entryp allocated. */
1895:
1896: if(acl_entry_link_head->count != 0) {
1897: acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
1898:
1899: if(acl_entry_link->nextp == NULL) {
1900: SAFE_FREE(file_acl);
1901: errno = ENOMEM;
1902: DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1903: return(NULL);
1904: }
1905:
1906: acl_entry_link->nextp->prevp = acl_entry_link;
1907: acl_entry_link = acl_entry_link->nextp;
1908: acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
1909: if(acl_entry_link->entryp == NULL) {
1910: SAFE_FREE(file_acl);
1911: errno = ENOMEM;
1912: DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1913: return(NULL);
1914: }
1915: acl_entry_link->nextp = NULL;
1916: }
1917:
1918: acl_entry_link->entryp->ace_len = acl_entry->ace_len;
1919:
1920: /* Don't really need this since all types are going *
1921: * to be specified but, it's better than leaving it 0 */
1922:
1923: acl_entry_link->entryp->ace_type = acl_entry->ace_type;
1924:
1925: acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1926:
1927: memcpy(acl_entry_link->entryp->ace_id,idp,sizeof(struct ace_id));
1928:
1929: /* The access in the acl entries must be left shifted by *
1930: * three bites, because they will ultimately be compared *
1931: * to S_IRUSR, S_IWUSR, and S_IXUSR. */
1932:
1933: switch(acl_entry->ace_type){
1934: case ACC_PERMIT:
1935: case ACC_SPECIFY:
1936: acl_entry_link->entryp->ace_access = acl_entry->ace_access;
1937: acl_entry_link->entryp->ace_access <<= 6;
1938: acl_entry_link_head->count++;
1939: break;
1940: case ACC_DENY:
1941: /* Since there is no way to return a DENY acl entry *
1942: * change to PERMIT and then shift. */
1943: DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
1944: acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
1945: DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
1946: acl_entry_link->entryp->ace_access <<= 6;
1947: acl_entry_link_head->count++;
1948: break;
1949: default:
1950: return(0);
1951: }
1952:
1953: DEBUG(10,("acl_entry = %d\n",acl_entry));
1954: DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
1955:
1956: acl_entry = acl_nxt(acl_entry);
1957: }
1958: } /* end of if enabled */
1959:
1960: /* Since owner, group, other acl entries are not *
1961: * part of the acl entries in an acl, they must *
1962: * be dummied up to become part of the list. */
1963:
1964: for( i = 1; i < 4; i++) {
1965: DEBUG(10,("i is %d\n",i));
1966: if(acl_entry_link_head->count != 0) {
1967: acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
1968: if(acl_entry_link->nextp == NULL) {
1969: SAFE_FREE(file_acl);
1970: errno = ENOMEM;
1971: DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1972: return(NULL);
1973: }
1974:
1975: acl_entry_link->nextp->prevp = acl_entry_link;
1976: acl_entry_link = acl_entry_link->nextp;
1977: acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
1978: if(acl_entry_link->entryp == NULL) {
1979: SAFE_FREE(file_acl);
1980: errno = ENOMEM;
1981: DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
1982: return(NULL);
1983: }
1984: }
1985:
1986: acl_entry_link->nextp = NULL;
1987:
1988: new_acl_entry = acl_entry_link->entryp;
1989: idp = new_acl_entry->ace_id;
1990:
1991: new_acl_entry->ace_len = sizeof(struct acl_entry);
1992: new_acl_entry->ace_type = ACC_PERMIT;
1993: idp->id_len = sizeof(struct ace_id);
1994: DEBUG(10,("idp->id_len = %d\n",idp->id_len));
1995: memset(idp->id_data,0,sizeof(uid_t));
1996:
1997: switch(i) {
1998: case 2:
1999: new_acl_entry->ace_access = file_acl->g_access << 6;
2000: idp->id_type = SMB_ACL_GROUP_OBJ;
2001: break;
2002:
2003: case 3:
2004: new_acl_entry->ace_access = file_acl->o_access << 6;
2005: idp->id_type = SMB_ACL_OTHER;
2006: break;
2007:
2008: case 1:
2009: new_acl_entry->ace_access = file_acl->u_access << 6;
2010: idp->id_type = SMB_ACL_USER_OBJ;
2011: break;
2012:
2013: default:
2014: return(NULL);
2015:
2016: }
2017:
2018: acl_entry_link_head->count++;
2019: DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
2020: }
2021:
2022: acl_entry_link_head->count = 0;
2023: SAFE_FREE(file_acl);
2024:
2025: return(acl_entry_link_head);
2026: }
2027:
2028: #if 0
2029: SMB_ACL_T sys_acl_get_fd(int fd)
2030: {
2031: struct acl *file_acl = (struct acl *)NULL;
2032: struct acl_entry *acl_entry;
2033: struct new_acl_entry *new_acl_entry;
2034: struct ace_id *idp;
2035: struct acl_entry_link *acl_entry_link;
2036: struct acl_entry_link *acl_entry_link_head;
2037: int i;
2038: int rc = 0;
2039:
2040: /* Get the acl using fstatacl */
2041:
2042: DEBUG(10,("Entering sys_acl_get_fd\n"));
2043: DEBUG(10,("fd is %d\n",fd));
2044: file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2045:
2046: if(file_acl == NULL) {
2047: errno=ENOMEM;
2048: DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2049: return(NULL);
2050: }
2051:
2052: memset(file_acl,0,BUFSIZ);
2053:
2054: rc = fstatacl(fd,0,file_acl,BUFSIZ);
2055: if(rc == -1) {
2056: DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
2057: SAFE_FREE(file_acl);
2058: return(NULL);
2059: }
2060:
2061: DEBUG(10,("Got facl and returned it\n"));
2062:
2063: /* Point to the first acl entry in the acl */
2064:
2065: acl_entry = file_acl->acl_ext;
2066: /* Begin setting up the head of the linked list *
2067: * that will be used for the storing the acl *
2068: * in a way that is useful for the posix_acls.c *
2069: * code. */
2070:
2071: acl_entry_link_head = acl_entry_link = sys_acl_init(0);
2072: if(acl_entry_link_head == NULL){
2073: SAFE_FREE(file_acl);
2074: return(NULL);
2075: }
2076:
2077: acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2078:
2079: if(acl_entry_link->entryp == NULL) {
2080: errno = ENOMEM;
2081: DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2082: SAFE_FREE(file_acl);
2083: return(NULL);
2084: }
2085:
2086: DEBUG(10,("acl_entry is %d\n",acl_entry));
2087: DEBUG(10,("acl_last(file_acl) id %d\n",acl_last(file_acl)));
2088:
2089: /* Check if the extended acl bit is on. *
2090: * If it isn't, do not show the *
2091: * contents of the acl since AIX intends *
2092: * the extended info to remain unused */
2093:
2094: if(file_acl->acl_mode & S_IXACL){
2095: /* while we are not pointing to the very end */
2096: while(acl_entry < acl_last(file_acl)) {
2097: /* before we malloc anything, make sure this is */
2098: /* a valid acl entry and one that we want to map */
2099:
2100: idp = id_nxt(acl_entry->ace_id);
2101: if((acl_entry->ace_type == ACC_SPECIFY ||
2102: (acl_entry->ace_type == ACC_PERMIT)) && (idp != id_last(acl_entry))) {
2103: acl_entry = acl_nxt(acl_entry);
2104: continue;
2105: }
2106:
2107: idp = acl_entry->ace_id;
2108:
2109: /* Check if this is the first entry in the linked list. *
2110: * The first entry needs to keep prevp pointing to NULL *
2111: * and already has entryp allocated. */
2112:
2113: if(acl_entry_link_head->count != 0) {
2114: acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2115: if(acl_entry_link->nextp == NULL) {
2116: errno = ENOMEM;
2117: DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2118: SAFE_FREE(file_acl);
2119: return(NULL);
2120: }
2121: acl_entry_link->nextp->prevp = acl_entry_link;
2122: acl_entry_link = acl_entry_link->nextp;
2123: acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2124: if(acl_entry_link->entryp == NULL) {
2125: errno = ENOMEM;
2126: DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2127: SAFE_FREE(file_acl);
2128: return(NULL);
2129: }
2130:
2131: acl_entry_link->nextp = NULL;
2132: }
2133:
2134: acl_entry_link->entryp->ace_len = acl_entry->ace_len;
2135:
2136: /* Don't really need this since all types are going *
2137: * to be specified but, it's better than leaving it 0 */
2138:
2139: acl_entry_link->entryp->ace_type = acl_entry->ace_type;
2140: acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2141:
2142: memcpy(acl_entry_link->entryp->ace_id, idp, sizeof(struct ace_id));
2143:
2144: /* The access in the acl entries must be left shifted by *
2145: * three bites, because they will ultimately be compared *
2146: * to S_IRUSR, S_IWUSR, and S_IXUSR. */
2147:
2148: switch(acl_entry->ace_type){
2149: case ACC_PERMIT:
2150: case ACC_SPECIFY:
2151: acl_entry_link->entryp->ace_access = acl_entry->ace_access;
2152: acl_entry_link->entryp->ace_access <<= 6;
2153: acl_entry_link_head->count++;
2154: break;
2155: case ACC_DENY:
2156: /* Since there is no way to return a DENY acl entry *
2157: * change to PERMIT and then shift. */
2158: DEBUG(10,("acl_entry->ace_access is %d\n",acl_entry->ace_access));
2159: acl_entry_link->entryp->ace_access = ~acl_entry->ace_access & 7;
2160: DEBUG(10,("acl_entry_link->entryp->ace_access is %d\n",acl_entry_link->entryp->ace_access));
2161: acl_entry_link->entryp->ace_access <<= 6;
2162: acl_entry_link_head->count++;
2163: break;
2164: default:
2165: return(0);
2166: }
2167:
2168: DEBUG(10,("acl_entry = %d\n",acl_entry));
2169: DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
2170:
2171: acl_entry = acl_nxt(acl_entry);
2172: }
2173: } /* end of if enabled */
2174:
2175: /* Since owner, group, other acl entries are not *
2176: * part of the acl entries in an acl, they must *
2177: * be dummied up to become part of the list. */
2178:
2179: for( i = 1; i < 4; i++) {
2180: DEBUG(10,("i is %d\n",i));
2181: if(acl_entry_link_head->count != 0){
2182: acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
2183: if(acl_entry_link->nextp == NULL) {
2184: errno = ENOMEM;
2185: DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2186: SAFE_FREE(file_acl);
2187: return(NULL);
2188: }
2189:
2190: acl_entry_link->nextp->prevp = acl_entry_link;
2191: acl_entry_link = acl_entry_link->nextp;
2192: acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
2193:
2194: if(acl_entry_link->entryp == NULL) {
2195: SAFE_FREE(file_acl);
2196: errno = ENOMEM;
2197: DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
2198: return(NULL);
2199: }
2200: }
2201:
2202: acl_entry_link->nextp = NULL;
2203:
2204: new_acl_entry = acl_entry_link->entryp;
2205: idp = new_acl_entry->ace_id;
2206:
2207: new_acl_entry->ace_len = sizeof(struct acl_entry);
2208: new_acl_entry->ace_type = ACC_PERMIT;
2209: idp->id_len = sizeof(struct ace_id);
2210: DEBUG(10,("idp->id_len = %d\n",idp->id_len));
2211: memset(idp->id_data,0,sizeof(uid_t));
2212:
2213: switch(i) {
2214: case 2:
2215: new_acl_entry->ace_access = file_acl->g_access << 6;
2216: idp->id_type = SMB_ACL_GROUP_OBJ;
2217: break;
2218:
2219: case 3:
2220: new_acl_entry->ace_access = file_acl->o_access << 6;
2221: idp->id_type = SMB_ACL_OTHER;
2222: break;
2223:
2224: case 1:
2225: new_acl_entry->ace_access = file_acl->u_access << 6;
2226: idp->id_type = SMB_ACL_USER_OBJ;
2227: break;
2228:
2229: default:
2230: return(NULL);
2231: }
2232:
2233: acl_entry_link_head->count++;
2234: DEBUG(10,("new_acl_entry->ace_access = %d\n",new_acl_entry->ace_access));
2235: }
2236:
2237: acl_entry_link_head->count = 0;
2238: SAFE_FREE(file_acl);
2239:
2240: return(acl_entry_link_head);
2241: }
2242: #endif
2243:
2244: int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p)
2245: {
2246: uint *permset;
2247:
2248: if (sys_acl_get_tag_type(entry, tag_type_p) != 0)
2249: return -1;
2250:
2251: if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP)
2252: memcpy(u_g_id_p, entry->ace_id->id_data, sizeof (id_t));
2253:
2254: permset = &entry->ace_access;
2255:
2256: DEBUG(10,("*permset is %d\n",*permset));
2257: *bits_p = (*permset & S_IRUSR ? 4 : 0)
2258: | (*permset & S_IWUSR ? 2 : 0)
2259: | (*permset & S_IXUSR ? 1 : 0);
2260:
2261: return 0;
2262: }
2263:
2264: SMB_ACL_T sys_acl_init( int count)
2265: {
2266: struct acl_entry_link *theacl = NULL;
2267:
2268: if (count < 0) {
2269: errno = EINVAL;
2270: return NULL;
2271: }
2272:
2273: DEBUG(10,("Entering sys_acl_init\n"));
2274:
2275: theacl = SMB_MALLOC_P(struct acl_entry_link);
2276: if(theacl == NULL) {
2277: errno = ENOMEM;
2278: DEBUG(0,("Error in sys_acl_init is %d\n",errno));
2279: return(NULL);
2280: }
2281:
2282: theacl->count = 0;
2283: theacl->nextp = NULL;
2284: theacl->prevp = NULL;
2285: theacl->entryp = NULL;
2286: DEBUG(10,("Exiting sys_acl_init\n"));
2287: return(theacl);
2288: }
2289:
2290: int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2291: {
2292: struct acl_entry_link *theacl;
2293: struct acl_entry_link *acl_entryp;
2294: struct acl_entry_link *temp_entry;
2295: int counting;
2296:
2297: DEBUG(10,("Entering the sys_acl_create_entry\n"));
2298:
2299: theacl = acl_entryp = *pacl;
2300:
2301: /* Get to the end of the acl before adding entry */
2302:
2303: for(counting=0; counting < theacl->count; counting++){
2304: DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
2305: temp_entry = acl_entryp;
2306: acl_entryp = acl_entryp->nextp;
2307: }
2308:
2309: if(theacl->count != 0){
2310: temp_entry->nextp = acl_entryp = SMB_MALLOC_P(struct acl_entry_link);
2311: if(acl_entryp == NULL) {
2312: errno = ENOMEM;
2313: DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
2314: return(-1);
2315: }
2316:
2317: DEBUG(10,("The acl_entryp is %d\n",acl_entryp));
2318: acl_entryp->prevp = temp_entry;
2319: DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
2320: }
2321:
2322: *pentry = acl_entryp->entryp = SMB_MALLOC_P(struct new_acl_entry);
2323: if(*pentry == NULL) {
2324: errno = ENOMEM;
2325: DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
2326: return(-1);
2327: }
2328:
2329: memset(*pentry,0,sizeof(struct new_acl_entry));
2330: acl_entryp->entryp->ace_len = sizeof(struct acl_entry);
2331: acl_entryp->entryp->ace_type = ACC_PERMIT;
2332: acl_entryp->entryp->ace_id->id_len = sizeof(struct ace_id);
2333: acl_entryp->nextp = NULL;
2334: theacl->count++;
2335: DEBUG(10,("Exiting sys_acl_create_entry\n"));
2336: return(0);
2337: }
2338:
2339: int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id)
2340: {
2341: entry->ace_id->id_type = tag_type;
2342: DEBUG(10,("The tag type is %d\n",entry->ace_id->id_type));
2343:
2344: if (tag_type == SMB_ACL_USER || tag_type == SMB_ACL_GROUP)
2345: memcpy(entry->ace_id->id_data, &u_g_id, sizeof (id_t));
2346:
2347: entry->ace_access = bits;
2348: DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
2349:
2350: return 0;
2351: }
2352:
2353: int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits)
2354: {
2355: DEBUG(10,("Starting AIX sys_acl_set_permset\n"));
2356: entry->ace_access = bits;
2357: DEBUG(10,("entry->ace_access = %d\n",entry->ace_access));
2358: DEBUG(10,("Ending AIX sys_acl_set_permset\n"));
2359: return(0);
2360: }
2361:
2362: int sys_acl_valid( SMB_ACL_T theacl )
2363: {
2364: int user_obj = 0;
2365: int group_obj = 0;
2366: int other_obj = 0;
2367: struct acl_entry_link *acl_entry;
2368:
2369: for(acl_entry=theacl; acl_entry != NULL; acl_entry = acl_entry->nextp) {
2370: user_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_USER_OBJ);
2371: group_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_GROUP_OBJ);
2372: other_obj += (acl_entry->entryp->ace_id->id_type == SMB_ACL_OTHER);
2373: }
2374:
2375: DEBUG(10,("user_obj=%d, group_obj=%d, other_obj=%d\n",user_obj,group_obj,other_obj));
2376:
2377: if(user_obj != 1 || group_obj != 1 || other_obj != 1)
2378: return(-1);
2379:
2380: return(0);
2381: }
2382:
2383: int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2384: {
2385: struct acl_entry_link *acl_entry_link = NULL;
2386: struct acl *file_acl = NULL;
2387: struct acl *file_acl_temp = NULL;
2388: struct acl_entry *acl_entry = NULL;
2389: struct ace_id *ace_id = NULL;
2390: uint id_type;
2391: uint user_id;
2392: uint acl_length;
2393: uint rc;
2394:
2395: DEBUG(10,("Entering sys_acl_set_file\n"));
2396: DEBUG(10,("File name is %s\n",name));
2397:
2398: /* AIX has no default ACL */
2399: if(acltype == SMB_ACL_TYPE_DEFAULT)
2400: return(0);
2401:
2402: acl_length = BUFSIZ;
2403: file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2404:
2405: if(file_acl == NULL) {
2406: errno = ENOMEM;
2407: DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2408: return(-1);
2409: }
2410:
2411: memset(file_acl,0,BUFSIZ);
2412:
2413: file_acl->acl_len = ACL_SIZ;
2414: file_acl->acl_mode = S_IXACL;
2415:
2416: for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2417: acl_entry_link->entryp->ace_access >>= 6;
2418: id_type = acl_entry_link->entryp->ace_id->id_type;
2419:
2420: switch(id_type) {
2421: case SMB_ACL_USER_OBJ:
2422: file_acl->u_access = acl_entry_link->entryp->ace_access;
2423: continue;
2424: case SMB_ACL_GROUP_OBJ:
2425: file_acl->g_access = acl_entry_link->entryp->ace_access;
2426: continue;
2427: case SMB_ACL_OTHER:
2428: file_acl->o_access = acl_entry_link->entryp->ace_access;
2429: continue;
2430: case SMB_ACL_MASK:
2431: continue;
2432: }
2433:
2434: if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2435: acl_length += sizeof(struct acl_entry);
2436: file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
2437: if(file_acl_temp == NULL) {
2438: SAFE_FREE(file_acl);
2439: errno = ENOMEM;
2440: DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
2441: return(-1);
2442: }
2443:
2444: memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2445: SAFE_FREE(file_acl);
2446: file_acl = file_acl_temp;
2447: }
2448:
2449: acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2450: file_acl->acl_len += sizeof(struct acl_entry);
2451: acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2452: acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2453:
2454: /* In order to use this, we'll need to wait until we can get denies */
2455: /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2456: acl_entry->ace_type = ACC_SPECIFY; */
2457:
2458: acl_entry->ace_type = ACC_SPECIFY;
2459:
2460: ace_id = acl_entry->ace_id;
2461:
2462: ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2463: DEBUG(10,("The id type is %d\n",ace_id->id_type));
2464: ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2465: memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2466: memcpy(acl_entry->ace_id->id_data, &user_id, sizeof(uid_t));
2467: }
2468:
2469: rc = chacl((char*)name,file_acl,file_acl->acl_len);
2470: DEBUG(10,("errno is %d\n",errno));
2471: DEBUG(10,("return code is %d\n",rc));
2472: SAFE_FREE(file_acl);
2473: DEBUG(10,("Exiting the sys_acl_set_file\n"));
2474: return(rc);
2475: }
2476:
2477: #if 0
2478: int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
2479: {
2480: struct acl_entry_link *acl_entry_link = NULL;
2481: struct acl *file_acl = NULL;
2482: struct acl *file_acl_temp = NULL;
2483: struct acl_entry *acl_entry = NULL;
2484: struct ace_id *ace_id = NULL;
2485: uint id_type;
2486: uint user_id;
2487: uint acl_length;
2488: uint rc;
2489:
2490: DEBUG(10,("Entering sys_acl_set_fd\n"));
2491: acl_length = BUFSIZ;
2492: file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
2493:
2494: if(file_acl == NULL) {
2495: errno = ENOMEM;
2496: DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2497: return(-1);
2498: }
2499:
2500: memset(file_acl,0,BUFSIZ);
2501:
2502: file_acl->acl_len = ACL_SIZ;
2503: file_acl->acl_mode = S_IXACL;
2504:
2505: for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
2506: acl_entry_link->entryp->ace_access >>= 6;
2507: id_type = acl_entry_link->entryp->ace_id->id_type;
2508: DEBUG(10,("The id_type is %d\n",id_type));
2509:
2510: switch(id_type) {
2511: case SMB_ACL_USER_OBJ:
2512: file_acl->u_access = acl_entry_link->entryp->ace_access;
2513: continue;
2514: case SMB_ACL_GROUP_OBJ:
2515: file_acl->g_access = acl_entry_link->entryp->ace_access;
2516: continue;
2517: case SMB_ACL_OTHER:
2518: file_acl->o_access = acl_entry_link->entryp->ace_access;
2519: continue;
2520: case SMB_ACL_MASK:
2521: continue;
2522: }
2523:
2524: if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
2525: acl_length += sizeof(struct acl_entry);
2526: file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
2527: if(file_acl_temp == NULL) {
2528: SAFE_FREE(file_acl);
2529: errno = ENOMEM;
2530: DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
2531: return(-1);
2532: }
2533:
2534: memcpy(file_acl_temp,file_acl,file_acl->acl_len);
2535: SAFE_FREE(file_acl);
2536: file_acl = file_acl_temp;
2537: }
2538:
2539: acl_entry = (struct acl_entry *)((char *)file_acl + file_acl->acl_len);
2540: file_acl->acl_len += sizeof(struct acl_entry);
2541: acl_entry->ace_len = acl_entry_link->entryp->ace_len;
2542: acl_entry->ace_access = acl_entry_link->entryp->ace_access;
2543:
2544: /* In order to use this, we'll need to wait until we can get denies */
2545: /* if(!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
2546: acl_entry->ace_type = ACC_SPECIFY; */
2547:
2548: acl_entry->ace_type = ACC_SPECIFY;
2549:
2550: ace_id = acl_entry->ace_id;
2551:
2552: ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
2553: DEBUG(10,("The id type is %d\n",ace_id->id_type));
2554: ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
2555: memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof(uid_t));
2556: memcpy(ace_id->id_data, &user_id, sizeof(uid_t));
2557: }
2558:
2559: rc = fchacl(fd,file_acl,file_acl->acl_len);
2560: DEBUG(10,("errno is %d\n",errno));
2561: DEBUG(10,("return code is %d\n",rc));
2562: SAFE_FREE(file_acl);
2563: DEBUG(10,("Exiting sys_acl_set_fd\n"));
2564: return(rc);
2565: }
2566: #endif
2567:
2568: int sys_acl_delete_def_file(UNUSED(const char *name))
2569: {
2570: /* AIX has no default ACL */
2571: return 0;
2572: }
2573:
2574: int sys_acl_free_acl(SMB_ACL_T posix_acl)
2575: {
2576: struct acl_entry_link *acl_entry_link;
2577:
2578: for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
2579: SAFE_FREE(acl_entry_link->prevp->entryp);
2580: SAFE_FREE(acl_entry_link->prevp);
2581: }
2582:
2583: SAFE_FREE(acl_entry_link->prevp->entryp);
2584: SAFE_FREE(acl_entry_link->prevp);
2585: SAFE_FREE(acl_entry_link->entryp);
2586: SAFE_FREE(acl_entry_link);
2587:
2588: return(0);
2589: }
2590:
2591: #elif defined(HAVE_OSX_ACLS) /*----------------------------------------------*/
2592:
2593: #define OSX_BROKEN_GETENTRY /* returns 0 instead of 1 */
2594:
2595: #include <membership.h>
2596:
2597: int sys_acl_get_entry(SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
2598: {
2599: int ret = acl_get_entry(the_acl, entry_id, entry_p);
2600: #ifdef OSX_BROKEN_GETENTRY
2601: if (ret == 0)
2602: ret = 1;
2603: else if (ret == -1 && errno == 22)
2604: ret = 0;
2605: #endif
2606: return ret;
2607: }
2608:
2609: SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
2610: {
2611: if (type == ACL_TYPE_DEFAULT) {
2612: errno = ENOTSUP;
2613: return NULL;
2614: }
2615: errno = 0;
2616: return acl_get_file(path_p, type);
2617: }
2618:
2619: #if 0
2620: SMB_ACL_T sys_acl_get_fd(int fd)
2621: {
2622: return acl_get_fd(fd);
2623: }
2624: #endif
2625:
2626: int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p)
2627: {
2628: uuid_t *uup;
2629: acl_tag_t tag;
2630: acl_flagset_t flagset;
2631: acl_permset_t permset;
2632: uint32 bits, fb, bb, pb;
2633: int id_type = -1;
2634: int rc;
2635:
2636: if (acl_get_tag_type(entry, &tag) != 0
2637: || acl_get_flagset_np(entry, &flagset) != 0
2638: || acl_get_permset(entry, &permset) != 0
2639: || (uup = acl_get_qualifier(entry)) == NULL)
2640: return -1;
2641:
2642: rc = mbr_uuid_to_id(*uup, u_g_id_p, &id_type);
2643: acl_free(uup);
2644: if (rc != 0)
2645: return rc;
2646:
2647: if (id_type == ID_TYPE_UID)
2648: *tag_type_p = SMB_ACL_USER;
2649: else
2650: *tag_type_p = SMB_ACL_GROUP;
2651:
2652: bits = tag == ACL_EXTENDED_ALLOW ? 1 : 0;
2653:
2654: for (fb = (1u<<4), bb = (1u<<1); bb < (1u<<12); fb *= 2, bb *= 2) {
2655: if (acl_get_flag_np(flagset, fb) == 1)
2656: bits |= bb;
2657: }
2658:
2659: for (pb = (1u<<1), bb = (1u<<12); bb < (1u<<25); pb *= 2, bb *= 2) {
2660: if (acl_get_perm_np(permset, pb) == 1)
2661: bits |= bb;
2662: }
2663:
2664: *bits_p = bits;
2665:
2666: return 0;
2667: }
2668:
2669: SMB_ACL_T sys_acl_init(int count)
2670: {
2671: return acl_init(count);
2672: }
2673:
2674: int sys_acl_create_entry(SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2675: {
2676: return acl_create_entry(pacl, pentry);
2677: }
2678:
2679: int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits, id_t u_g_id)
2680: {
2681: acl_flagset_t flagset;
2682: acl_permset_t permset;
2683: uint32 fb, bb, pb;
2684: int is_user = tag_type == SMB_ACL_USER;
2685: uuid_t uu;
2686: int rc;
2687:
2688: tag_type = bits & 1 ? ACL_EXTENDED_ALLOW : ACL_EXTENDED_DENY;
2689:
2690: if (acl_get_flagset_np(entry, &flagset) != 0
2691: || acl_get_permset(entry, &permset) != 0)
2692: return -1;
2693:
2694: acl_clear_flags_np(flagset);
2695: acl_clear_perms(permset);
2696:
2697: for (fb = (1u<<4), bb = (1u<<1); bb < (1u<<12); fb *= 2, bb *= 2) {
2698: if (bits & bb)
2699: acl_add_flag_np(flagset, fb);
2700: }
2701:
2702: for (pb = (1u<<1), bb = (1u<<12); bb < (1u<<25); pb *= 2, bb *= 2) {
2703: if (bits & bb)
2704: acl_add_perm(permset, pb);
2705: }
2706:
2707: if (is_user)
2708: rc = mbr_uid_to_uuid(u_g_id, uu);
2709: else
2710: rc = mbr_gid_to_uuid(u_g_id, uu);
2711: if (rc != 0)
2712: return rc;
2713:
2714: if (acl_set_tag_type(entry, tag_type) != 0
2715: || acl_set_qualifier(entry, &uu) != 0
2716: || acl_set_permset(entry, permset) != 0
2717: || acl_set_flagset_np(entry, flagset) != 0)
2718: return -1;
2719:
2720: return 0;
2721: }
2722:
2723: #if 0
2724: int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits)
2725: {
2726: return -1; /* Not needed for OS X. */
2727: }
2728: #endif
2729:
2730: int sys_acl_valid(SMB_ACL_T theacl)
2731: {
2732: return acl_valid(theacl);
2733: }
2734:
2735: int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2736: {
2737: return acl_set_file(name, acltype, theacl);
2738: }
2739:
2740: #if 0
2741: int sys_acl_set_fd(int fd, SMB_ACL_T theacl)
2742: {
2743: return acl_set_fd(fd, theacl);
2744: }
2745: #endif
2746:
2747: int sys_acl_delete_def_file(const char *name)
2748: {
2749: return acl_delete_def_file(name);
2750: }
2751:
2752: int sys_acl_free_acl(SMB_ACL_T the_acl)
2753: {
2754: return acl_free(the_acl);
2755: }
2756:
2757: #else /* No ACLs. */
2758:
2759: #error No ACL functions defined for this platform!
2760:
2761: #endif
2762:
2763: /************************************************************************
2764: Deliberately outside the ACL defines. Return 1 if this is a "no acls"
2765: errno, 0 if not.
2766: ************************************************************************/
2767:
2768: int no_acl_syscall_error(int err)
2769: {
2770: #ifdef HAVE_OSX_ACLS
2771: if (err == ENOENT)
2772: return 1; /* Weird problem with directory ACLs. */
2773: #endif
2774: #if defined(ENOSYS)
2775: if (err == ENOSYS) {
2776: return 1;
2777: }
2778: #endif
2779: #if defined(ENOTSUP)
2780: if (err == ENOTSUP) {
2781: return 1;
2782: }
2783: #endif
2784: if (err == EINVAL) {
2785: /* If the type of SMB_ACL_TYPE_ACCESS or SMB_ACL_TYPE_DEFAULT
2786: * isn't valid, then the ACLs must be non-POSIX. */
2787: return 1;
2788: }
2789: return 0;
2790: }
2791:
2792: #endif /* SUPPORT_ACLS */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>