1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2001 Chris D. Faulhaber 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/types.h> 30 #include <sys/acl.h> 31 #include <sys/stat.h> 32 33 #include <err.h> 34 35 #include "setfacl.h" 36 37 /* 38 * remove ACL entries from an ACL 39 */ 40 int 41 remove_acl(acl_t acl, acl_t *prev_acl, const char *filename) 42 { 43 acl_entry_t entry; 44 acl_t acl_new; 45 acl_tag_t tag; 46 int carried_error, entry_id, acl_brand, prev_acl_brand; 47 48 carried_error = 0; 49 50 acl_get_brand_np(acl, &acl_brand); 51 acl_get_brand_np(*prev_acl, &prev_acl_brand); 52 53 if (branding_mismatch(acl_brand, prev_acl_brand)) { 54 warnx("%s: branding mismatch; existing ACL is %s, " 55 "entry to be removed is %s", filename, 56 brand_name(prev_acl_brand), brand_name(acl_brand)); 57 return (-1); 58 } 59 60 carried_error = 0; 61 62 acl_new = acl_dup(*prev_acl); 63 if (acl_new == NULL) 64 err(1, "%s: acl_dup() failed", filename); 65 66 tag = ACL_UNDEFINED_TAG; 67 68 /* find and delete the entry */ 69 entry_id = ACL_FIRST_ENTRY; 70 while (acl_get_entry(acl, entry_id, &entry) == 1) { 71 entry_id = ACL_NEXT_ENTRY; 72 if (acl_get_tag_type(entry, &tag) == -1) 73 err(1, "%s: acl_get_tag_type() failed", filename); 74 if (tag == ACL_MASK) 75 have_mask = true; 76 if (acl_delete_entry(acl_new, entry) == -1) { 77 carried_error++; 78 warnx("%s: cannot remove non-existent ACL entry", 79 filename); 80 } 81 } 82 83 acl_free(*prev_acl); 84 *prev_acl = acl_new; 85 86 if (carried_error) 87 return (-1); 88 89 return (0); 90 } 91 92 int 93 remove_by_number(uint entry_number, acl_t *prev_acl, const char *filename) 94 { 95 acl_entry_t entry; 96 acl_t acl_new; 97 acl_tag_t tag; 98 int carried_error, entry_id; 99 uint i; 100 101 carried_error = 0; 102 103 acl_new = acl_dup(*prev_acl); 104 if (acl_new == NULL) 105 err(1, "%s: acl_dup() failed", filename); 106 107 tag = ACL_UNDEFINED_TAG; 108 109 /* 110 * Find out whether we're removing the mask entry, 111 * to behave the same as the routine above. 112 * 113 * XXX: Is this loop actually needed? 114 */ 115 entry_id = ACL_FIRST_ENTRY; 116 i = 0; 117 while (acl_get_entry(acl_new, entry_id, &entry) == 1) { 118 entry_id = ACL_NEXT_ENTRY; 119 if (i != entry_number) 120 continue; 121 if (acl_get_tag_type(entry, &tag) == -1) 122 err(1, "%s: acl_get_tag_type() failed", filename); 123 if (tag == ACL_MASK) 124 have_mask = true; 125 } 126 127 if (acl_delete_entry_np(acl_new, entry_number) == -1) { 128 carried_error++; 129 warn("%s: acl_delete_entry_np() failed", filename); 130 } 131 132 acl_free(*prev_acl); 133 *prev_acl = acl_new; 134 135 if (carried_error) 136 return (-1); 137 138 return (0); 139 } 140 141 /* 142 * remove default entries 143 */ 144 int 145 remove_default(acl_t *prev_acl, const char *filename) 146 { 147 148 acl_free(*prev_acl); 149 *prev_acl = acl_init(ACL_MAX_ENTRIES); 150 if (*prev_acl == NULL) 151 err(1, "%s: acl_init() failed", filename); 152 153 return (0); 154 } 155 156 /* 157 * remove extended entries 158 */ 159 void 160 remove_ext(acl_t *prev_acl, const char *filename) 161 { 162 acl_t acl_new; 163 164 acl_new = acl_strip_np(*prev_acl, !n_flag); 165 if (acl_new == NULL) 166 err(1, "%s: acl_strip_np() failed", filename); 167 168 acl_free(*prev_acl); 169 *prev_acl = acl_new; 170 } 171