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