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

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

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