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