1139969Simp/*- 274465Srwatson * Copyright (c) 2001 Chris D. Faulhaber 374465Srwatson * All rights reserved. 474465Srwatson * 574465Srwatson * Redistribution and use in source and binary forms, with or without 674465Srwatson * modification, are permitted provided that the following conditions 774465Srwatson * are met: 874465Srwatson * 1. Redistributions of source code must retain the above copyright 974465Srwatson * notice, this list of conditions and the following disclaimer. 1074465Srwatson * 2. Redistributions in binary form must reproduce the above copyright 1174465Srwatson * notice, this list of conditions and the following disclaimer in the 1274465Srwatson * documentation and/or other materials provided with the distribution. 1374465Srwatson * 1474465Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1574465Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1674465Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17204819Sjoel * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18204819Sjoel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19204819Sjoel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20204819Sjoel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21204819Sjoel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22204819Sjoel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23204819Sjoel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24204819Sjoel * SUCH DAMAGE. 2574465Srwatson */ 2674465Srwatson 2799110Sobrien#include <sys/cdefs.h> 2899110Sobrien__FBSDID("$FreeBSD$"); 2999110Sobrien 3074465Srwatson#include <sys/types.h> 3174465Srwatson#include <sys/acl.h> 3274465Srwatson#include <sys/stat.h> 3374465Srwatson 3474465Srwatson#include <err.h> 3574465Srwatson#include <stdio.h> 3674465Srwatson#include <string.h> 3774465Srwatson 3874465Srwatson#include "setfacl.h" 3974465Srwatson 4087254Sjedgar/* 4187254Sjedgar * remove ACL entries from an ACL 4287254Sjedgar */ 4374465Srwatsonint 44196936Straszremove_acl(acl_t acl, acl_t *prev_acl, const char *filename) 4574465Srwatson{ 4675928Sjedgar acl_entry_t entry; 4775928Sjedgar acl_t acl_new; 4875928Sjedgar acl_tag_t tag; 49196936Strasz int carried_error, entry_id, acl_brand, prev_acl_brand; 5074465Srwatson 5174465Srwatson carried_error = 0; 5274465Srwatson 53196936Strasz acl_get_brand_np(acl, &acl_brand); 54196936Strasz acl_get_brand_np(*prev_acl, &prev_acl_brand); 55196936Strasz 56201016Strasz if (branding_mismatch(acl_brand, prev_acl_brand)) { 57196936Strasz warnx("%s: branding mismatch; existing ACL is %s, " 58196936Strasz "entry to be removed is %s", filename, 59201016Strasz brand_name(prev_acl_brand), brand_name(acl_brand)); 60196936Strasz return (-1); 61196936Strasz } 62196936Strasz 63196936Strasz carried_error = 0; 64196936Strasz 65196936Strasz acl_new = acl_dup(*prev_acl); 6687254Sjedgar if (acl_new == NULL) 67196936Strasz err(1, "%s: acl_dup() failed", filename); 6874465Srwatson 6975928Sjedgar tag = ACL_UNDEFINED_TAG; 7075928Sjedgar 7174465Srwatson /* find and delete the entry */ 7275928Sjedgar entry_id = ACL_FIRST_ENTRY; 7375928Sjedgar while (acl_get_entry(acl, entry_id, &entry) == 1) { 7475928Sjedgar entry_id = ACL_NEXT_ENTRY; 7575928Sjedgar if (acl_get_tag_type(entry, &tag) == -1) 76196936Strasz err(1, "%s: acl_get_tag_type() failed", filename); 7775928Sjedgar if (tag == ACL_MASK) 7874465Srwatson have_mask++; 7975928Sjedgar if (acl_delete_entry(acl_new, entry) == -1) { 8074465Srwatson carried_error++; 81196936Strasz warnx("%s: cannot remove non-existent ACL entry", 82196936Strasz filename); 8374465Srwatson } 8474465Srwatson } 8574465Srwatson 86196936Strasz acl_free(*prev_acl); 87196936Strasz *prev_acl = acl_new; 88196936Strasz 89196936Strasz if (carried_error) 90196936Strasz return (-1); 91196936Strasz 92196936Strasz return (0); 93196936Strasz} 94196936Strasz 95196936Straszint 96196936Straszremove_by_number(uint entry_number, acl_t *prev_acl, const char *filename) 97196936Strasz{ 98196936Strasz acl_entry_t entry; 99196936Strasz acl_t acl_new; 100196936Strasz acl_tag_t tag; 101196936Strasz int carried_error, entry_id; 102196936Strasz uint i; 103196936Strasz 104196936Strasz carried_error = 0; 105196936Strasz 106196936Strasz acl_new = acl_dup(*prev_acl); 107196936Strasz if (acl_new == NULL) 108196936Strasz err(1, "%s: acl_dup() failed", filename); 109196936Strasz 110196936Strasz tag = ACL_UNDEFINED_TAG; 111196936Strasz 112196936Strasz /* 113196936Strasz * Find out whether we're removing the mask entry, 114196936Strasz * to behave the same as the routine above. 115196936Strasz * 116196936Strasz * XXX: Is this loop actually needed? 117196936Strasz */ 118196936Strasz entry_id = ACL_FIRST_ENTRY; 119196936Strasz i = 0; 120196936Strasz while (acl_get_entry(acl_new, entry_id, &entry) == 1) { 121196936Strasz entry_id = ACL_NEXT_ENTRY; 122196936Strasz if (i != entry_number) 123196936Strasz continue; 124196936Strasz if (acl_get_tag_type(entry, &tag) == -1) 125196936Strasz err(1, "%s: acl_get_tag_type() failed", filename); 126196936Strasz if (tag == ACL_MASK) 127196936Strasz have_mask++; 12874465Srwatson } 12974465Srwatson 130196936Strasz if (acl_delete_entry_np(acl_new, entry_number) == -1) { 131196936Strasz carried_error++; 132196936Strasz warn("%s: acl_delete_entry_np() failed", filename); 133196936Strasz } 134196936Strasz 135196936Strasz acl_free(*prev_acl); 136196936Strasz *prev_acl = acl_new; 137196936Strasz 13874465Srwatson if (carried_error) 13987254Sjedgar return (-1); 14074465Srwatson 14187254Sjedgar return (0); 14274465Srwatson} 14374465Srwatson 14487254Sjedgar/* 14587254Sjedgar * remove default entries 14687254Sjedgar */ 14774465Srwatsonint 148196936Straszremove_default(acl_t *prev_acl, const char *filename) 14974465Srwatson{ 15074465Srwatson 151196936Strasz acl_free(*prev_acl); 152196936Strasz *prev_acl = acl_init(ACL_MAX_ENTRIES); 153196936Strasz if (*prev_acl == NULL) 154196936Strasz err(1, "%s: acl_init() failed", filename); 155196936Strasz 15687254Sjedgar return (0); 15774465Srwatson} 15874465Srwatson 15987254Sjedgar/* 16087254Sjedgar * remove extended entries 16187254Sjedgar */ 16274465Srwatsonvoid 163196936Straszremove_ext(acl_t *prev_acl, const char *filename) 16474465Srwatson{ 165196936Strasz acl_t acl_new; 16674465Srwatson 167196936Strasz acl_new = acl_strip_np(*prev_acl, !n_flag); 16887254Sjedgar if (acl_new == NULL) 169196936Strasz err(1, "%s: acl_strip_np() failed", filename); 17074465Srwatson 171196936Strasz acl_free(*prev_acl); 172196936Strasz *prev_acl = acl_new; 17374465Srwatson} 174