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

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

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