1139969Simp/*- 290127Sjedgar * Copyright (c) 2001-2002 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 <errno.h> 3674465Srwatson#include <stdio.h> 3774465Srwatson#include <stdlib.h> 3874465Srwatson 3974465Srwatson#include "setfacl.h" 4074465Srwatson 4174465Srwatson/* set the appropriate mask the given ACL's */ 4274465Srwatsonint 43196936Straszset_acl_mask(acl_t *prev_acl, const char *filename) 4474465Srwatson{ 4590887Sjedgar acl_entry_t entry; 4674465Srwatson acl_t acl; 4775928Sjedgar acl_tag_t tag; 4875928Sjedgar int entry_id; 4974465Srwatson 5075928Sjedgar entry = NULL; 5175928Sjedgar 5274465Srwatson /* 5374465Srwatson * ... if a mask entry is specified, then the permissions of the mask 5474465Srwatson * entry in the resulting ACL shall be set to the permissions in the 5574465Srwatson * specified ACL mask entry. 5674465Srwatson */ 5774465Srwatson if (have_mask) 5887254Sjedgar return (0); 5974465Srwatson 6075928Sjedgar acl = acl_dup(*prev_acl); 6187254Sjedgar if (acl == NULL) 62196936Strasz err(1, "%s: acl_dup() failed", filename); 6374465Srwatson 6487254Sjedgar if (n_flag == 0) { 6574465Srwatson /* 6674465Srwatson * If no mask entry is specified and the -n option is not 6774465Srwatson * specified, then the permissions of the resulting ACL mask 6874465Srwatson * entry shall be set to the union of the permissions 6974465Srwatson * associated with all entries which belong to the file group 7074465Srwatson * class in the resulting ACL 7174465Srwatson */ 7274465Srwatson if (acl_calc_mask(&acl)) { 73196936Strasz warn("%s: acl_calc_mask() failed", filename); 7474465Srwatson acl_free(acl); 7587254Sjedgar return (-1); 7674465Srwatson } 7774465Srwatson } else { 7874465Srwatson /* 7974465Srwatson * If no mask entry is specified and the -n option is 8074465Srwatson * specified, then the permissions of the resulting ACL 8174465Srwatson * mask entry shall remain unchanged ... 8274465Srwatson */ 8375928Sjedgar 8475928Sjedgar entry_id = ACL_FIRST_ENTRY; 8575928Sjedgar 8675928Sjedgar while (acl_get_entry(acl, entry_id, &entry) == 1) { 8775928Sjedgar entry_id = ACL_NEXT_ENTRY; 8875928Sjedgar if (acl_get_tag_type(entry, &tag) == -1) 89196936Strasz err(1, "%s: acl_get_tag_type() failed", 90196936Strasz filename); 9175928Sjedgar 9275928Sjedgar if (tag == ACL_MASK) { 9374465Srwatson acl_free(acl); 9487254Sjedgar return (0); 9574465Srwatson } 9675928Sjedgar } 9774465Srwatson 9874465Srwatson /* 9974465Srwatson * If no mask entry is specified, the -n option is specified, 10074465Srwatson * and no ACL mask entry exists in the ACL associated with the 10174465Srwatson * file, then write an error message to standard error and 10274465Srwatson * continue with the next file. 10374465Srwatson */ 104196936Strasz warnx("%s: warning: no mask entry", filename); 10574465Srwatson acl_free(acl); 10687254Sjedgar return (0); 10774465Srwatson } 10874465Srwatson 10990127Sjedgar acl_free(*prev_acl); 11090887Sjedgar *prev_acl = acl_dup(acl); 11174465Srwatson acl_free(acl); 11274465Srwatson 11387254Sjedgar return (0); 11474465Srwatson} 115