Annotation of embedaddon/rsync/lib/sysacls.c, revision 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>