19ddb49cbSWarner Losh /*- 243960f15SRobert Watson * Copyright (c) 2001 Chris D. Faulhaber 343960f15SRobert Watson * All rights reserved. 443960f15SRobert Watson * 543960f15SRobert Watson * Redistribution and use in source and binary forms, with or without 643960f15SRobert Watson * modification, are permitted provided that the following conditions 743960f15SRobert Watson * are met: 843960f15SRobert Watson * 1. Redistributions of source code must retain the above copyright 943960f15SRobert Watson * notice, this list of conditions and the following disclaimer. 1043960f15SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 1143960f15SRobert Watson * notice, this list of conditions and the following disclaimer in the 1243960f15SRobert Watson * documentation and/or other materials provided with the distribution. 1343960f15SRobert Watson * 1443960f15SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1543960f15SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1643960f15SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1743960f15SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE VOICES IN HIS HEAD BE 1843960f15SRobert Watson * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1943960f15SRobert Watson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2043960f15SRobert Watson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2143960f15SRobert Watson * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2243960f15SRobert Watson * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2343960f15SRobert Watson * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2443960f15SRobert Watson * POSSIBILITY OF SUCH DAMAGE. 2543960f15SRobert Watson */ 2643960f15SRobert Watson 272749b141SDavid E. O'Brien #include <sys/cdefs.h> 282749b141SDavid E. O'Brien __FBSDID("$FreeBSD$"); 292749b141SDavid E. O'Brien 3043960f15SRobert Watson #include <sys/types.h> 3143960f15SRobert Watson #include <sys/acl.h> 3243960f15SRobert Watson #include <sys/stat.h> 3343960f15SRobert Watson 3443960f15SRobert Watson #include <err.h> 3543960f15SRobert Watson #include <stdio.h> 3643960f15SRobert Watson #include <string.h> 3743960f15SRobert Watson 3843960f15SRobert Watson #include "setfacl.h" 3943960f15SRobert Watson 40a043a09dSChris D. Faulhaber /* 41a043a09dSChris D. Faulhaber * remove ACL entries from an ACL 42a043a09dSChris D. Faulhaber */ 4343960f15SRobert Watson int 443f221878SEdward Tomasz Napierala remove_acl(acl_t acl, acl_t *prev_acl, const char *filename) 4543960f15SRobert Watson { 460f626307SChris D. Faulhaber acl_entry_t entry; 4743960f15SRobert Watson acl_t acl_new; 480f626307SChris D. Faulhaber acl_tag_t tag; 493f221878SEdward Tomasz Napierala int carried_error, entry_id, acl_brand, prev_acl_brand; 5043960f15SRobert Watson 5143960f15SRobert Watson carried_error = 0; 5243960f15SRobert Watson 533f221878SEdward Tomasz Napierala acl_get_brand_np(acl, &acl_brand); 543f221878SEdward Tomasz Napierala acl_get_brand_np(*prev_acl, &prev_acl_brand); 553f221878SEdward Tomasz Napierala 56c93b62deSEdward Tomasz Napierala if (branding_mismatch(acl_brand, prev_acl_brand)) { 573f221878SEdward Tomasz Napierala warnx("%s: branding mismatch; existing ACL is %s, " 583f221878SEdward Tomasz Napierala "entry to be removed is %s", filename, 59c93b62deSEdward Tomasz Napierala brand_name(prev_acl_brand), brand_name(acl_brand)); 603f221878SEdward Tomasz Napierala return (-1); 613f221878SEdward Tomasz Napierala } 623f221878SEdward Tomasz Napierala 633f221878SEdward Tomasz Napierala carried_error = 0; 643f221878SEdward Tomasz Napierala 653f221878SEdward Tomasz Napierala acl_new = acl_dup(*prev_acl); 66a043a09dSChris D. Faulhaber if (acl_new == NULL) 673f221878SEdward Tomasz Napierala err(1, "%s: acl_dup() failed", filename); 6843960f15SRobert Watson 690f626307SChris D. Faulhaber tag = ACL_UNDEFINED_TAG; 700f626307SChris D. Faulhaber 7143960f15SRobert Watson /* find and delete the entry */ 720f626307SChris D. Faulhaber entry_id = ACL_FIRST_ENTRY; 730f626307SChris D. Faulhaber while (acl_get_entry(acl, entry_id, &entry) == 1) { 740f626307SChris D. Faulhaber entry_id = ACL_NEXT_ENTRY; 750f626307SChris D. Faulhaber if (acl_get_tag_type(entry, &tag) == -1) 763f221878SEdward Tomasz Napierala err(1, "%s: acl_get_tag_type() failed", filename); 770f626307SChris D. Faulhaber if (tag == ACL_MASK) 7843960f15SRobert Watson have_mask++; 790f626307SChris D. Faulhaber if (acl_delete_entry(acl_new, entry) == -1) { 8043960f15SRobert Watson carried_error++; 813f221878SEdward Tomasz Napierala warnx("%s: cannot remove non-existent ACL entry", 823f221878SEdward Tomasz Napierala filename); 8343960f15SRobert Watson } 8443960f15SRobert Watson } 8543960f15SRobert Watson 863f221878SEdward Tomasz Napierala acl_free(*prev_acl); 873f221878SEdward Tomasz Napierala *prev_acl = acl_new; 883f221878SEdward Tomasz Napierala 893f221878SEdward Tomasz Napierala if (carried_error) 903f221878SEdward Tomasz Napierala return (-1); 913f221878SEdward Tomasz Napierala 923f221878SEdward Tomasz Napierala return (0); 9343960f15SRobert Watson } 9443960f15SRobert Watson 953f221878SEdward Tomasz Napierala int 963f221878SEdward Tomasz Napierala remove_by_number(uint entry_number, acl_t *prev_acl, const char *filename) 973f221878SEdward Tomasz Napierala { 983f221878SEdward Tomasz Napierala acl_entry_t entry; 993f221878SEdward Tomasz Napierala acl_t acl_new; 1003f221878SEdward Tomasz Napierala acl_tag_t tag; 1013f221878SEdward Tomasz Napierala int carried_error, entry_id; 1023f221878SEdward Tomasz Napierala uint i; 1033f221878SEdward Tomasz Napierala 1043f221878SEdward Tomasz Napierala carried_error = 0; 1053f221878SEdward Tomasz Napierala 1063f221878SEdward Tomasz Napierala acl_new = acl_dup(*prev_acl); 1073f221878SEdward Tomasz Napierala if (acl_new == NULL) 1083f221878SEdward Tomasz Napierala err(1, "%s: acl_dup() failed", filename); 1093f221878SEdward Tomasz Napierala 1103f221878SEdward Tomasz Napierala tag = ACL_UNDEFINED_TAG; 1113f221878SEdward Tomasz Napierala 1123f221878SEdward Tomasz Napierala /* 1133f221878SEdward Tomasz Napierala * Find out whether we're removing the mask entry, 1143f221878SEdward Tomasz Napierala * to behave the same as the routine above. 1153f221878SEdward Tomasz Napierala * 1163f221878SEdward Tomasz Napierala * XXX: Is this loop actually needed? 1173f221878SEdward Tomasz Napierala */ 1183f221878SEdward Tomasz Napierala entry_id = ACL_FIRST_ENTRY; 1193f221878SEdward Tomasz Napierala i = 0; 1203f221878SEdward Tomasz Napierala while (acl_get_entry(acl_new, entry_id, &entry) == 1) { 1213f221878SEdward Tomasz Napierala entry_id = ACL_NEXT_ENTRY; 1223f221878SEdward Tomasz Napierala if (i != entry_number) 1233f221878SEdward Tomasz Napierala continue; 1243f221878SEdward Tomasz Napierala if (acl_get_tag_type(entry, &tag) == -1) 1253f221878SEdward Tomasz Napierala err(1, "%s: acl_get_tag_type() failed", filename); 1263f221878SEdward Tomasz Napierala if (tag == ACL_MASK) 1273f221878SEdward Tomasz Napierala have_mask++; 1283f221878SEdward Tomasz Napierala } 1293f221878SEdward Tomasz Napierala 1303f221878SEdward Tomasz Napierala if (acl_delete_entry_np(acl_new, entry_number) == -1) { 1313f221878SEdward Tomasz Napierala carried_error++; 1323f221878SEdward Tomasz Napierala warn("%s: acl_delete_entry_np() failed", filename); 1333f221878SEdward Tomasz Napierala } 1343f221878SEdward Tomasz Napierala 1353f221878SEdward Tomasz Napierala acl_free(*prev_acl); 1363f221878SEdward Tomasz Napierala *prev_acl = acl_new; 1373f221878SEdward Tomasz Napierala 13843960f15SRobert Watson if (carried_error) 139a043a09dSChris D. Faulhaber return (-1); 14043960f15SRobert Watson 141a043a09dSChris D. Faulhaber return (0); 14243960f15SRobert Watson } 14343960f15SRobert Watson 144a043a09dSChris D. Faulhaber /* 145a043a09dSChris D. Faulhaber * remove default entries 146a043a09dSChris D. Faulhaber */ 14743960f15SRobert Watson int 1483f221878SEdward Tomasz Napierala remove_default(acl_t *prev_acl, const char *filename) 14943960f15SRobert Watson { 15043960f15SRobert Watson 1513f221878SEdward Tomasz Napierala acl_free(*prev_acl); 1523f221878SEdward Tomasz Napierala *prev_acl = acl_init(ACL_MAX_ENTRIES); 1533f221878SEdward Tomasz Napierala if (*prev_acl == NULL) 1543f221878SEdward Tomasz Napierala err(1, "%s: acl_init() failed", filename); 1553f221878SEdward Tomasz Napierala 156a043a09dSChris D. Faulhaber return (0); 15743960f15SRobert Watson } 15843960f15SRobert Watson 159a043a09dSChris D. Faulhaber /* 160a043a09dSChris D. Faulhaber * remove extended entries 161a043a09dSChris D. Faulhaber */ 16243960f15SRobert Watson void 1633f221878SEdward Tomasz Napierala remove_ext(acl_t *prev_acl, const char *filename) 16443960f15SRobert Watson { 1653f221878SEdward Tomasz Napierala acl_t acl_new; 16643960f15SRobert Watson 1673f221878SEdward Tomasz Napierala acl_new = acl_strip_np(*prev_acl, !n_flag); 168a043a09dSChris D. Faulhaber if (acl_new == NULL) 1693f221878SEdward Tomasz Napierala err(1, "%s: acl_strip_np() failed", filename); 17043960f15SRobert Watson 1713f221878SEdward Tomasz Napierala acl_free(*prev_acl); 1723f221878SEdward Tomasz Napierala *prev_acl = acl_new; 17343960f15SRobert Watson } 174