xref: /freebsd/bin/setfacl/mask.c (revision c17d43407fe04133a94055b0dbc7ea8965654a9f)
1 /*
2  * Copyright (c) 2001-2002 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$
27  */
28 
29 #include <sys/types.h>
30 #include <sys/acl.h>
31 #include <sys/stat.h>
32 
33 #include <err.h>
34 #include <errno.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 
38 #include "setfacl.h"
39 
40 /* set the appropriate mask the given ACL's */
41 int
42 set_acl_mask(acl_t *prev_acl)
43 {
44 	acl_entry_t entry;
45 	acl_t acl;
46 	acl_tag_t tag;
47 	int entry_id;
48 
49 	entry = NULL;
50 
51 	/*
52 	 * ... if a mask entry is specified, then the permissions of the mask
53 	 * entry in the resulting ACL shall be set to the permissions in the
54 	 * specified ACL mask entry.
55 	 */
56 	if (have_mask)
57 		return (0);
58 
59 	acl = acl_dup(*prev_acl);
60 	if (acl == NULL)
61 		err(1, "acl_dup() failed");
62 
63 	if (n_flag == 0) {
64 		/*
65 		 * If no mask entry is specified and the -n option is not
66 		 * specified, then the permissions of the resulting ACL mask
67 		 * entry shall be set to the union of the permissions
68 		 * associated with all entries which belong to the file group
69 		 * class in the resulting ACL
70 		 */
71 		if (acl_calc_mask(&acl)) {
72 			warn("acl_calc_mask() failed");
73 			acl_free(acl);
74 			return (-1);
75 		}
76 	} else {
77 		/*
78 		 * If no mask entry is specified and the -n option is
79 		 * specified, then the permissions of the resulting ACL
80 		 * mask entry shall remain unchanged ...
81 		 */
82 
83 		entry_id = ACL_FIRST_ENTRY;
84 
85 		while (acl_get_entry(acl, entry_id, &entry) == 1) {
86 			entry_id = ACL_NEXT_ENTRY;
87 			if (acl_get_tag_type(entry, &tag) == -1)
88 				err(1, "acl_get_tag_type() failed");
89 
90 			if (tag == ACL_MASK) {
91 				acl_free(acl);
92 				return (0);
93 			}
94 		}
95 
96 		/*
97 		 * If no mask entry is specified, the -n option is specified,
98 		 * and no ACL mask entry exists in the ACL associated with the
99 		 * file, then write an error message to standard error and
100 		 * continue with the next file.
101 		 */
102 		warnx("warning: no mask entry");
103 		acl_free(acl);
104 		return (0);
105 	}
106 
107 	acl_free(*prev_acl);
108 	*prev_acl = acl_dup(acl);
109 	acl_free(acl);
110 
111 	return (0);
112 }
113