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