remove.c revision 74465
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 THE VOICES IN HIS HEAD BE 18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 * POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD: head/bin/setfacl/remove.c 74465 2001-03-19 18:09:25Z rwatson $ 27 */ 28 29#include <sys/types.h> 30#include <sys/acl.h> 31#include <sys/stat.h> 32 33#include <err.h> 34#include <stdio.h> 35#include <string.h> 36#include <sysexits.h> 37 38#include "setfacl.h" 39 40/* remove ACL entries from an ACL */ 41int 42remove_acl(acl_t acl, acl_t *prev_acl) 43{ 44 acl_t acl_new; 45 int carried_error, i; 46 47 carried_error = 0; 48 49 if (acl_type == ACL_TYPE_ACCESS) 50 acl_new = acl_dup(prev_acl[0]); 51 else 52 acl_new = acl_dup(prev_acl[1]); 53 if (!acl_new) 54 err(EX_OSERR, "acl_dup() failed"); 55 56 /* find and delete the entry */ 57 for (i = 0; i < acl->acl_cnt; i++) { 58 if (acl->acl_entry[i].ae_tag == ACL_MASK) 59 have_mask++; 60 if (acl_delete_entry(acl_new, &acl->acl_entry[i]) == -1) { 61 carried_error++; 62 warnx("cannot remove non-existent acl entry"); 63 } 64 } 65 66 if (acl_type == ACL_TYPE_ACCESS) { 67 acl_free(prev_acl[0]); 68 prev_acl[0] = acl_new; 69 } else { 70 acl_free(prev_acl[1]); 71 prev_acl[1] = acl_new; 72 } 73 74 if (carried_error) 75 return -1; 76 77 return 0; 78} 79 80/* remove default entries */ 81int 82remove_default(acl_t *prev_acl) 83{ 84 85 if (prev_acl[1]) { 86 bzero(prev_acl[1], sizeof(struct acl)); 87 prev_acl[1]->acl_cnt = 0; 88 } else { 89 warn("cannot remove default ACL"); 90 return -1; 91 } 92 return 0; 93} 94 95/* remove extended entries */ 96void 97remove_ext(acl_t *prev_acl) 98{ 99 acl_t acl_new, acl_old; 100 acl_perm_t group_perm, mask_perm; 101 int have_mask_entry, i; 102 103 if (acl_type == ACL_TYPE_ACCESS) 104 acl_old = acl_dup(prev_acl[0]); 105 else 106 acl_old = acl_dup(prev_acl[1]); 107 if (!acl_old) 108 err(EX_OSERR, "acl_dup() failed"); 109 110 group_perm = mask_perm = 0; 111 have_mask_entry = 0; 112 acl_new = acl_init(ACL_MAX_ENTRIES); 113 if (!acl_new) 114 err(EX_OSERR, "%s", "acl_init() failed"); 115 116 /* only save the default user/group/other entries */ 117 for (i = 0; i < acl_old->acl_cnt; i++) 118 switch(acl_old->acl_entry[i].ae_tag) { 119 case ACL_USER_OBJ: 120 acl_new->acl_entry[0] = acl_old->acl_entry[i]; 121 break; 122 case ACL_GROUP_OBJ: 123 acl_new->acl_entry[1] = acl_old->acl_entry[i]; 124 group_perm = acl_old->acl_entry[i].ae_perm; 125 break; 126 case ACL_OTHER_OBJ: 127 acl_new->acl_entry[2] = acl_old->acl_entry[i]; 128 break; 129 case ACL_MASK: 130 mask_perm = acl_old->acl_entry[i].ae_perm; 131 have_mask_entry = 1; 132 break; 133 default: 134 break; 135 } 136 /* 137 * If the ACL contains a mask entry, then the permissions associated 138 * with the owning group entry in the resulting ACL shall be set to 139 * only those permissions associated with both the owning group entry 140 * and the mask entry of the current ACL. 141 */ 142 if (have_mask_entry) 143 acl_new->acl_entry[1].ae_perm = group_perm & mask_perm; 144 acl_new->acl_cnt = 3; 145 146 if (acl_type == ACL_TYPE_ACCESS) { 147 acl_free(prev_acl[0]); 148 prev_acl[0] = acl_new; 149 } else { 150 acl_free(prev_acl[1]); 151 prev_acl[1] = acl_new; 152 } 153 154 have_mask = 0; 155} 156