merge.c revision 87254
174465Srwatson/* 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 1774465Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE VOICES IN HIS HEAD BE 1874465Srwatson * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1974465Srwatson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2074465Srwatson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2174465Srwatson * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2274465Srwatson * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2374465Srwatson * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2474465Srwatson * POSSIBILITY OF SUCH DAMAGE. 2574465Srwatson * 2674465Srwatson * $FreeBSD: head/bin/setfacl/merge.c 87254 2001-12-03 00:51:36Z jedgar $ 2774465Srwatson */ 2874465Srwatson 2974465Srwatson#include <sys/types.h> 3074465Srwatson#include <sys/acl.h> 3174465Srwatson#include <sys/stat.h> 3274465Srwatson 3374465Srwatson#include <err.h> 3474465Srwatson#include <stdio.h> 3574465Srwatson 3674465Srwatson#include "setfacl.h" 3774465Srwatson 3887254Sjedgar/* 3987254Sjedgar * merge an ACL into existing file's ACL 4087254Sjedgar */ 4174465Srwatsonint 4274465Srwatsonmerge_acl(acl_t acl, acl_t *prev_acl) 4374465Srwatson{ 4475928Sjedgar acl_entry_t entry, entry_new; 4575928Sjedgar acl_permset_t permset; 4674465Srwatson acl_t acl_new; 4775928Sjedgar acl_tag_t tag, tag_new; 4875928Sjedgar int entry_id, entry_id_new, have_entry; 4975928Sjedgar uid_t *id, *id_new; 5074465Srwatson 5174465Srwatson if (acl_type == ACL_TYPE_ACCESS) 5274465Srwatson acl_new = acl_dup(prev_acl[0]); 5374465Srwatson else 5474465Srwatson acl_new = acl_dup(prev_acl[1]); 5587254Sjedgar if (acl_new == NULL) 5687254Sjedgar err(1, "acl_dup() failed"); 5774465Srwatson 5875928Sjedgar entry_id = ACL_FIRST_ENTRY; 5975928Sjedgar 6075928Sjedgar while (acl_get_entry(acl, entry_id, &entry) == 1) { 6175928Sjedgar entry_id = ACL_NEXT_ENTRY; 6274465Srwatson have_entry = 0; 6374465Srwatson 6475928Sjedgar /* keep track of existing ACL_MASK entries */ 6575928Sjedgar if (acl_get_tag_type(entry, &tag) == -1) 6687254Sjedgar err(1, "acl_get_tag_type() failed - invalid ACL entry"); 6775928Sjedgar if (tag == ACL_MASK) 6874465Srwatson have_mask = 1; 6974465Srwatson 7074465Srwatson /* check against the existing ACL entries */ 7175928Sjedgar entry_id_new = ACL_FIRST_ENTRY; 7287254Sjedgar while (have_entry == 0 && 7375928Sjedgar acl_get_entry(acl_new, entry_id_new, &entry_new) == 1) { 7475928Sjedgar entry_id_new = ACL_NEXT_ENTRY; 7575928Sjedgar 7675928Sjedgar if (acl_get_tag_type(entry, &tag) == -1) 7787254Sjedgar err(1, "acl_get_tag_type() failed"); 7875928Sjedgar if (acl_get_tag_type(entry_new, &tag_new) == -1) 7987254Sjedgar err(1, "acl_get_tag_type() failed"); 8075928Sjedgar if (tag != tag_new) 8175928Sjedgar continue; 8275928Sjedgar 8375928Sjedgar switch(tag) { 8475928Sjedgar case ACL_USER: 8575928Sjedgar case ACL_GROUP: 8675928Sjedgar id = acl_get_qualifier(entry); 8775928Sjedgar if (id == NULL) 8887254Sjedgar err(1, "acl_get_qualifier() failed"); 8975928Sjedgar id_new = acl_get_qualifier(entry_new); 9075928Sjedgar if (id_new == NULL) 9187254Sjedgar err(1, "acl_get_qualifier() failed"); 9275928Sjedgar if (*id == *id_new) { 9375928Sjedgar /* any other matches */ 9475928Sjedgar if (acl_get_permset(entry, &permset) 9575928Sjedgar == -1) 9687254Sjedgar err(1, 9775928Sjedgar "acl_get_permset() failed"); 9875928Sjedgar if (acl_set_permset(entry_new, permset) 9975928Sjedgar == -1) 10087254Sjedgar err(1, 10175928Sjedgar "acl_set_permset() failed"); 10274465Srwatson have_entry = 1; 10375928Sjedgar } 10475928Sjedgar acl_free(id); 10575928Sjedgar acl_free(id_new); 10687254Sjedgar if (have_entry == 0) 10774465Srwatson break; 10875928Sjedgar /* FALLTHROUGH */ 10975928Sjedgar case ACL_USER_OBJ: 11075928Sjedgar case ACL_GROUP_OBJ: 11175928Sjedgar case ACL_OTHER: 11275928Sjedgar case ACL_MASK: 11375928Sjedgar if (acl_get_permset(entry, &permset) == -1) 11487254Sjedgar err(1, "acl_get_permset() failed"); 11575928Sjedgar if (acl_set_permset(entry_new, permset) == -1) 11687254Sjedgar err(1, "acl_set_permset() failed"); 11775928Sjedgar have_entry = 1; 11875928Sjedgar break; 11975928Sjedgar default: 12075928Sjedgar /* should never be here */ 12187254Sjedgar errx(1, "Invalid tag type: %i", tag); 12275928Sjedgar break; 12374465Srwatson } 12474465Srwatson } 12574465Srwatson 12674465Srwatson /* if this entry has not been found, it must be new */ 12787254Sjedgar if (have_entry == 0) { 12875928Sjedgar if (acl_create_entry(&acl_new, &entry_new) == -1) { 12974465Srwatson acl_free(acl_new); 13087254Sjedgar return (-1); 13174465Srwatson } 13275928Sjedgar if (acl_copy_entry(entry_new, entry) == -1) 13387254Sjedgar err(1, "acl_copy_entry() failed"); 13474465Srwatson } 13574465Srwatson } 13674465Srwatson 13774465Srwatson 13875928Sjedgar if (acl_type == ACL_TYPE_ACCESS) { 13975928Sjedgar acl_free(prev_acl[0]); 14075928Sjedgar prev_acl[0] = acl_new; 14175928Sjedgar } else { 14275928Sjedgar acl_free(prev_acl[1]); 14375928Sjedgar prev_acl[1] = acl_new; 14475928Sjedgar } 14575928Sjedgar 14675928Sjedgar 14787254Sjedgar return (0); 14874465Srwatson} 149