/*- * Copyright (c) 2001 Chris D. Faulhaber * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include "setfacl.h" /* * remove ACL entries from an ACL */ int remove_acl(acl_t acl, acl_t *prev_acl, const char *filename) { acl_entry_t entry; acl_t acl_new; acl_tag_t tag; int carried_error, entry_id, acl_brand, prev_acl_brand; carried_error = 0; acl_get_brand_np(acl, &acl_brand); acl_get_brand_np(*prev_acl, &prev_acl_brand); if (branding_mismatch(acl_brand, prev_acl_brand)) { warnx("%s: branding mismatch; existing ACL is %s, " "entry to be removed is %s", filename, brand_name(prev_acl_brand), brand_name(acl_brand)); return (-1); } carried_error = 0; acl_new = acl_dup(*prev_acl); if (acl_new == NULL) err(1, "%s: acl_dup() failed", filename); tag = ACL_UNDEFINED_TAG; /* find and delete the entry */ entry_id = ACL_FIRST_ENTRY; while (acl_get_entry(acl, entry_id, &entry) == 1) { entry_id = ACL_NEXT_ENTRY; if (acl_get_tag_type(entry, &tag) == -1) err(1, "%s: acl_get_tag_type() failed", filename); if (tag == ACL_MASK) have_mask++; if (acl_delete_entry(acl_new, entry) == -1) { carried_error++; warnx("%s: cannot remove non-existent ACL entry", filename); } } acl_free(*prev_acl); *prev_acl = acl_new; if (carried_error) return (-1); return (0); } int remove_by_number(uint entry_number, acl_t *prev_acl, const char *filename) { acl_entry_t entry; acl_t acl_new; acl_tag_t tag; int carried_error, entry_id; uint i; carried_error = 0; acl_new = acl_dup(*prev_acl); if (acl_new == NULL) err(1, "%s: acl_dup() failed", filename); tag = ACL_UNDEFINED_TAG; /* * Find out whether we're removing the mask entry, * to behave the same as the routine above. * * XXX: Is this loop actually needed? */ entry_id = ACL_FIRST_ENTRY; i = 0; while (acl_get_entry(acl_new, entry_id, &entry) == 1) { entry_id = ACL_NEXT_ENTRY; if (i != entry_number) continue; if (acl_get_tag_type(entry, &tag) == -1) err(1, "%s: acl_get_tag_type() failed", filename); if (tag == ACL_MASK) have_mask++; } if (acl_delete_entry_np(acl_new, entry_number) == -1) { carried_error++; warn("%s: acl_delete_entry_np() failed", filename); } acl_free(*prev_acl); *prev_acl = acl_new; if (carried_error) return (-1); return (0); } /* * remove default entries */ int remove_default(acl_t *prev_acl, const char *filename) { acl_free(*prev_acl); *prev_acl = acl_init(ACL_MAX_ENTRIES); if (*prev_acl == NULL) err(1, "%s: acl_init() failed", filename); return (0); } /* * remove extended entries */ void remove_ext(acl_t *prev_acl, const char *filename) { acl_t acl_new; acl_new = acl_strip_np(*prev_acl, !n_flag); if (acl_new == NULL) err(1, "%s: acl_strip_np() failed", filename); acl_free(*prev_acl); *prev_acl = acl_new; }