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 __FBSDID("$FreeBSD$"); 29 30 #include <sys/types.h> 31 #include <sys/acl.h> 32 #include <sys/stat.h> 33 34 #include <err.h> 35 36 #include "setfacl.h" 37 38 /* 39 * remove ACL entries from an ACL 40 */ 41 int 42 remove_acl(acl_t acl, acl_t *prev_acl, const char *filename) 43 { 44 acl_entry_t entry; 45 acl_t acl_new; 46 acl_tag_t tag; 47 int carried_error, entry_id, acl_brand, prev_acl_brand; 48 49 carried_error = 0; 50 51 acl_get_brand_np(acl, &acl_brand); 52 acl_get_brand_np(*prev_acl, &prev_acl_brand); 53 54 if (branding_mismatch(acl_brand, prev_acl_brand)) { 55 warnx("%s: branding mismatch; existing ACL is %s, " 56 "entry to be removed is %s", filename, 57 brand_name(prev_acl_brand), brand_name(acl_brand)); 58 return (-1); 59 } 60 61 carried_error = 0; 62 63 acl_new = acl_dup(*prev_acl); 64 if (acl_new == NULL) 65 err(1, "%s: acl_dup() failed", filename); 66 67 tag = ACL_UNDEFINED_TAG; 68 69 /* find and delete the entry */ 70 entry_id = ACL_FIRST_ENTRY; 71 while (acl_get_entry(acl, entry_id, &entry) == 1) { 72 entry_id = ACL_NEXT_ENTRY; 73 if (acl_get_tag_type(entry, &tag) == -1) 74 err(1, "%s: acl_get_tag_type() failed", filename); 75 if (tag == ACL_MASK) 76 have_mask = true; 77 if (acl_delete_entry(acl_new, entry) == -1) { 78 carried_error++; 79 warnx("%s: cannot remove non-existent ACL entry", 80 filename); 81 } 82 } 83 84 acl_free(*prev_acl); 85 *prev_acl = acl_new; 86 87 if (carried_error) 88 return (-1); 89 90 return (0); 91 } 92 93 int 94 remove_by_number(uint entry_number, acl_t *prev_acl, const char *filename) 95 { 96 acl_entry_t entry; 97 acl_t acl_new; 98 acl_tag_t tag; 99 int carried_error, entry_id; 100 uint i; 101 102 carried_error = 0; 103 104 acl_new = acl_dup(*prev_acl); 105 if (acl_new == NULL) 106 err(1, "%s: acl_dup() failed", filename); 107 108 tag = ACL_UNDEFINED_TAG; 109 110 /* 111 * Find out whether we're removing the mask entry, 112 * to behave the same as the routine above. 113 * 114 * XXX: Is this loop actually needed? 115 */ 116 entry_id = ACL_FIRST_ENTRY; 117 i = 0; 118 while (acl_get_entry(acl_new, entry_id, &entry) == 1) { 119 entry_id = ACL_NEXT_ENTRY; 120 if (i != entry_number) 121 continue; 122 if (acl_get_tag_type(entry, &tag) == -1) 123 err(1, "%s: acl_get_tag_type() failed", filename); 124 if (tag == ACL_MASK) 125 have_mask = true; 126 } 127 128 if (acl_delete_entry_np(acl_new, entry_number) == -1) { 129 carried_error++; 130 warn("%s: acl_delete_entry_np() failed", filename); 131 } 132 133 acl_free(*prev_acl); 134 *prev_acl = acl_new; 135 136 if (carried_error) 137 return (-1); 138 139 return (0); 140 } 141 142 /* 143 * remove default entries 144 */ 145 int 146 remove_default(acl_t *prev_acl, const char *filename) 147 { 148 149 acl_free(*prev_acl); 150 *prev_acl = acl_init(ACL_MAX_ENTRIES); 151 if (*prev_acl == NULL) 152 err(1, "%s: acl_init() failed", filename); 153 154 return (0); 155 } 156 157 /* 158 * remove extended entries 159 */ 160 void 161 remove_ext(acl_t *prev_acl, const char *filename) 162 { 163 acl_t acl_new; 164 165 acl_new = acl_strip_np(*prev_acl, !n_flag); 166 if (acl_new == NULL) 167 err(1, "%s: acl_strip_np() failed", filename); 168 169 acl_free(*prev_acl); 170 *prev_acl = acl_new; 171 } 172