Annotation of embedaddon/rsync/lib/sysacls.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>