aclutils.c revision a3c49ce110f325a563c245bedc4d533adddb7211
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * Common Development and Distribution License (the "License").
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
a3c49ce110f325a563c245bedc4d533adddb7211Albert Lee * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef union {
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *file;
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Determine whether a file has a trivial ACL
fa9e4066f08beec538e775443c5be79dd423fcabahrens * returns: 0 = trivial
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 1 = nontrivial
fa9e4066f08beec538e775443c5be79dd423fcabahrens * <0 some other system failure, such as ENOENT or EPERM
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks return (-1);
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrenscacl_get(acl_inp inp, int get_flag, int type, acl_t **aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *fname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if acl's aren't supported then
fa9e4066f08beec538e775443c5be79dd423fcabahrens * send it through the old GETACL interface
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens malloc(acl_info->acl_cnt * acl_info->acl_entry_size);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ace_trivial(acl_info->acl_aclp, acl_info->acl_cnt) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * return -1 on failure, otherwise the number of acl
fa9e4066f08beec538e775443c5be79dd423fcabahrens * entries is returned
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (cacl_get(acl_inp, get_flag, ACL_PATH, aclp));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Set an ACL, translates acl to ace_t when appropriate.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_flavor_target = pathconf(acl_inp->file, _PC_ACL_ENABLED);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_flavor_target = fpathconf(acl_inp->fd, _PC_ACL_ENABLED);
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * If target returns an error or 0 from pathconf call then
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * fall back to UFS/POSIX Draft interface.
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * In the case of 0 we will then fail in either acl(2) or
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * acl_translate(). We could erroneously get 0 back from
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * a file system that is using fs_pathconf() and not answering
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * the _PC_ACL_ENABLED question itself.
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks if (acl_flavor_target == 0 || acl_flavor_target == -1)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((error = acl_translate(aclp, acl_flavor_target, isdir,
fa9e4066f08beec538e775443c5be79dd423fcabahrens newaclp->acl_aclp = malloc(aclp->acl_entry_size * aclp->acl_cnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_aclp, aclp->acl_entry_size * aclp->acl_cnt);
49f0e51890161901ae4f49c7a47602d97b52b934marks * Take an acl array and build an acl_t.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Remove an ACL from a file and create a trivial ACL based
fa9e4066f08beec538e775443c5be79dd423fcabahrens * off of the mode argument. After acl has been set owner/group
fa9e4066f08beec538e775443c5be79dd423fcabahrens * are updated to match owner,group arguments
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_strip(const char *file, uid_t owner, gid_t group, mode_t mode)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * force it through aclent flavor when file system doesn't
fa9e4066f08beec538e775443c5be79dd423fcabahrens * understand question
a3c49ce110f325a563c245bedc4d533adddb7211Albert Lee if ((error = acl_trivial_create(mode, S_ISDIR(statbuf.st_mode),
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum error = acl(file, ACE_SETACL, aclcnt, min_ace_acl);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Need to fixup who field for abstrations for
fa9e4066f08beec538e775443c5be79dd423fcabahrens * accurate comparison, since field is undefined.
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ace1.a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE))
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ace2.a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE))
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (memcmp(aclent1, aclent2, sizeof (aclent_t)));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Find acl entries in acl that correspond to removeacl. Search
fa9e4066f08beec538e775443c5be79dd423fcabahrens * is started from slot. The flag argument indicates whether to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * remove all matches or just the first match.
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_removeentries(acl_t *acl, acl_t *removeacl, int start_slot, int flag)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (flag != ACL_REMOVE_ALL && flag != ACL_REMOVE_FIRST)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (match == 0) {
57841ad7c4da76238b3e15b3f642e30e046a5256Renaud Manus /* avoid memmove if last entry */
b249c65cf0a7400e86a36ddab5c3fce085809859marks * List has changed, just continue so this
b249c65cf0a7400e86a36ddab5c3fce085809859marks * slot gets checked with it's new contents.
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_entry = ((char *)acl_entry + acl->acl_entry_size);
b249c65cf0a7400e86a36ddab5c3fce085809859marks remove_entry = (char *)remove_entry + removeacl->acl_entry_size;
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Replace entires entries in acl1 with the corresponding entries
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in newentries. The where argument specifies where to begin
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the replacement. If the where argument is 1 greater than the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * number of acl entries in acl1 then they are appended. If the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * where argument is 2+ greater than the number of acl entries then
fa9e4066f08beec538e775443c5be79dd423fcabahrens * EACL_INVALID_SLOT is returned.
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_modifyentries(acl_t *acl1, acl_t *newentries, int where)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memcpy((char *)acl1->acl_aclp + (acl1->acl_entry_size * slot),
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Did ACL grow?
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add acl2 entries into acl1. The where argument specifies where
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to add the entries.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * allow where to specify 1 past last slot for an append operation
fa9e4066f08beec538e775443c5be79dd423fcabahrens * but anything greater is an error.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * first push down entries where new ones will be inserted
fa9e4066f08beec538e775443c5be79dd423fcabahrens len = (acl1->acl_cnt - where) * acl1->acl_entry_size;
fa9e4066f08beec538e775443c5be79dd423fcabahrens * now stick in new entries.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * return text for an ACL error.
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks "There is more than one group or default group entry"));
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks "There is more than one user or default user entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "There is more than one other entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "There is more than one mask entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Duplicate user or group entries"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Missing user/group owner, other, mask entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Memory error"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Unrecognized entry type"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Invalid inheritance flags"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Unrecognized entry flags"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Invalid ACL permissions"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Invalid ACL count"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Invalid ACL entry number specified"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ACL entry doesn't exist"));
2269545aca348693948db4c9329109dbd770ffa9stephanie scheffler "Different file system ACL types cannot be merged"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "Invalid user or group"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "ACL string is invalid"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "Field expected to be blank"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "Invalid access type"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "Unrecognized entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ACL specification missing required fields"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Inheritance flags are only allowed on directories"));
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks/* PRINTFLIKE1 */
b249c65cf0a7400e86a36ddab5c3fce085809859marks *rid_start = '-'; /* putback character removed earlier */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen error = idmap_getuidbywinname(name, domain_start,