Deleted Added
full compact
merge.c (74465) merge.c (75928)
1/*
2 * Copyright (c) 2001 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 unchanged lines hidden (view full) ---

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 *
1/*
2 * Copyright (c) 2001 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 unchanged lines hidden (view full) ---

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: head/bin/setfacl/merge.c 74465 2001-03-19 18:09:25Z rwatson $
26 * $FreeBSD: head/bin/setfacl/merge.c 75928 2001-04-24 22:45:41Z jedgar $
27 */
28
29#include <sys/types.h>
30#include <sys/acl.h>
31#include <sys/stat.h>
32
33#include <err.h>
34#include <stdio.h>
35#include <sysexits.h>
36
37#include "setfacl.h"
38
39/* merge acl into existing file's ACL */
40int
41merge_acl(acl_t acl, acl_t *prev_acl)
42{
27 */
28
29#include <sys/types.h>
30#include <sys/acl.h>
31#include <sys/stat.h>
32
33#include <err.h>
34#include <stdio.h>
35#include <sysexits.h>
36
37#include "setfacl.h"
38
39/* merge acl into existing file's ACL */
40int
41merge_acl(acl_t acl, acl_t *prev_acl)
42{
43 acl_entry_t entry, entry_new;
44 acl_permset_t permset;
43 acl_t acl_new;
45 acl_t acl_new;
44 int blank_acl_user, blank_acl_group, have_entry, i, j;
45 struct stat sb;
46 acl_tag_t tag, tag_new;
47 int entry_id, entry_id_new, have_entry;
48 uid_t *id, *id_new;
46
49
47 blank_acl_user = blank_acl_group = 0;
48
49 if (acl_type == ACL_TYPE_ACCESS)
50 acl_new = acl_dup(prev_acl[0]);
51 else
52 acl_new = acl_dup(prev_acl[1]);
53 if (!acl_new)
54 err(EX_OSERR, "acl_dup() failed");
55
50 if (acl_type == ACL_TYPE_ACCESS)
51 acl_new = acl_dup(prev_acl[0]);
52 else
53 acl_new = acl_dup(prev_acl[1]);
54 if (!acl_new)
55 err(EX_OSERR, "acl_dup() failed");
56
56 /* step through new ACL entries */
57 for (i = 0; i < acl->acl_cnt; i++) {
57 entry_id = ACL_FIRST_ENTRY;
58
59 while (acl_get_entry(acl, entry_id, &entry) == 1) {
60 entry_id = ACL_NEXT_ENTRY;
58 have_entry = 0;
59
61 have_entry = 0;
62
60 /* oh look, we have an ACL_MASK entry */
61 if (acl->acl_entry[i].ae_tag == ACL_MASK)
63 /* keep track of existing ACL_MASK entries */
64 if (acl_get_tag_type(entry, &tag) == -1)
65 err(EX_OSERR,
66 "acl_get_tag_type() failed - invalid ACL entry");
67 if (tag == ACL_MASK)
62 have_mask = 1;
63
64 /* check against the existing ACL entries */
68 have_mask = 1;
69
70 /* check against the existing ACL entries */
65 for (j = 0; j < acl_new->acl_cnt && !have_entry; j++) {
66 if (acl_new->acl_entry[j].ae_tag ==
67 acl->acl_entry[i].ae_tag) {
68 switch(acl->acl_entry[i].ae_tag) {
69 case ACL_USER_OBJ:
70 acl_new->acl_entry[j].ae_perm =
71 acl->acl_entry[i].ae_perm;
72 acl_new->acl_entry[j].ae_id = sb.st_uid;
71 entry_id_new = ACL_FIRST_ENTRY;
72 while (!have_entry &&
73 acl_get_entry(acl_new, entry_id_new, &entry_new) == 1) {
74 entry_id_new = ACL_NEXT_ENTRY;
75
76 if (acl_get_tag_type(entry, &tag) == -1)
77 err(EX_OSERR, "acl_get_tag_type() failed");
78 if (acl_get_tag_type(entry_new, &tag_new) == -1)
79 err(EX_OSERR, "acl_get_tag_type() failed");
80 if (tag != tag_new)
81 continue;
82
83 switch(tag) {
84 case ACL_USER:
85 case ACL_GROUP:
86 id = acl_get_qualifier(entry);
87 if (id == NULL)
88 err(EX_OSERR,
89 "acl_get_qualifier() failed");
90 id_new = acl_get_qualifier(entry_new);
91 if (id_new == NULL)
92 err(EX_OSERR,
93 "acl_get_qualifier() failed");
94 if (*id == *id_new) {
95 /* any other matches */
96 if (acl_get_permset(entry, &permset)
97 == -1)
98 err(EX_OSERR,
99 "acl_get_permset() failed");
100 if (acl_set_permset(entry_new, permset)
101 == -1)
102 err(EX_OSERR,
103 "acl_set_permset() failed");
73 have_entry = 1;
104 have_entry = 1;
74 break;
75 case ACL_GROUP_OBJ:
76 acl_new->acl_entry[j].ae_perm =
77 acl->acl_entry[i].ae_perm;
78 acl_new->acl_entry[j].ae_id = sb.st_gid;
79 have_entry = 1;
80 break;
81 default:
82 if (acl_new->acl_entry[j].ae_id ==
83 acl->acl_entry[i].ae_id) {
84 /* any other matches */
85 acl_new->acl_entry[j].ae_perm =
86 acl->acl_entry[i].ae_perm;
87 have_entry = 1;
88 }
89 break;
90 }
105 }
106 acl_free(id);
107 acl_free(id_new);
108 if (!have_entry)
109 break;
110 /* FALLTHROUGH */
111 case ACL_USER_OBJ:
112 case ACL_GROUP_OBJ:
113 case ACL_OTHER:
114 case ACL_MASK:
115 if (acl_get_permset(entry, &permset) == -1)
116 err(EX_OSERR,
117 "acl_get_permset() failed");
118 if (acl_set_permset(entry_new, permset) == -1)
119 err(EX_OSERR,
120 "acl_set_permset() failed");
121 have_entry = 1;
122 break;
123 default:
124 /* should never be here */
125 errx(EX_OSERR, "Invalid tag type: %i", tag);
126 break;
91 }
92 }
93
94 /* if this entry has not been found, it must be new */
95 if (!have_entry) {
127 }
128 }
129
130 /* if this entry has not been found, it must be new */
131 if (!have_entry) {
96 if (acl_new->acl_cnt == ACL_MAX_ENTRIES) {
97 warn("too many ACL entries");
132 if (acl_create_entry(&acl_new, &entry_new) == -1) {
98 acl_free(acl_new);
99 return -1;
100 }
133 acl_free(acl_new);
134 return -1;
135 }
101 acl_new->acl_entry[acl_new->acl_cnt++] =
102 acl->acl_entry[i];
136 if (acl_copy_entry(entry_new, entry) == -1)
137 err(EX_OSERR, "acl_copy_entry() failed");
103 }
104 }
105
138 }
139 }
140
106 if (acl_type == ACL_TYPE_ACCESS)
107 *prev_acl[0] = *acl_new;
108 else
109 *prev_acl[1] = *acl_new;
110 acl_free(acl_new);
111
141
142 if (acl_type == ACL_TYPE_ACCESS) {
143 acl_free(prev_acl[0]);
144 prev_acl[0] = acl_new;
145 } else {
146 acl_free(prev_acl[1]);
147 prev_acl[1] = acl_new;
148 }
149
150
112 return 0;
113}
151 return 0;
152}