1 /*-
2  * Copyright (c) 2003-2009 Tim Kientzle
3  * Copyright (c) 2016 Martin Matuska
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #include "test.h"
27 
28 /*
29  * Verify reading entries with POSIX.1e and NFSv4 ACLs from archives created
30  * with Solaris tar.
31  *
32  * This should work on all systems, regardless of whether local filesystems
33  * support ACLs or not.
34  */
35 
36 static struct archive_test_acl_t acls0[] = {
37 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE |
38 	    ARCHIVE_ENTRY_ACL_READ,
39 	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
40 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
41 	  ARCHIVE_ENTRY_ACL_USER, 71, "lp" },
42 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
43 	  ARCHIVE_ENTRY_ACL_USER, 666, "666" },
44 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
45 	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
46 	  ARCHIVE_ENTRY_ACL_USER, 1000, "1000" },
47 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
48 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
49 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
50 	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
51 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
52 	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
53 };
54 
55 static struct archive_test_acl_t acls1[] = {
56 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
57 	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
58 	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
59 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
60 	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
61 	  ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
62 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
63 	    ARCHIVE_ENTRY_ACL_READ,
64 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
65 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
66 	    ARCHIVE_ENTRY_ACL_READ,
67 	  ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
68 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
69 	    ARCHIVE_ENTRY_ACL_READ,
70 	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
71 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
72 	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
73 };
74 
75 static struct archive_test_acl_t acls2[] = {
76 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
77 	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
78 	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1 ,"" },
79 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
80 	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
81 	  ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
82 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
83 	    ARCHIVE_ENTRY_ACL_READ,
84 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
85 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
86 	    ARCHIVE_ENTRY_ACL_READ,
87 	  ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
88 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
89 	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
90 	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
91 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0,
92 	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
93 };
94 
95 static struct archive_test_acl_t acls3[] = {
96 	{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
97 	    ARCHIVE_ENTRY_ACL_EXECUTE |
98 	    ARCHIVE_ENTRY_ACL_READ_DATA |
99 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
100 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
101 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
102 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
103 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
104 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
105 	    ARCHIVE_ENTRY_ACL_READ_ACL |
106 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
107 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
108 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
109 	  ARCHIVE_ENTRY_ACL_GROUP, 12, "daemon" },
110 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
111 	    ARCHIVE_ENTRY_ACL_EXECUTE |
112 	    ARCHIVE_ENTRY_ACL_READ_DATA |
113 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
114 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
115 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
116 	  ARCHIVE_ENTRY_ACL_GROUP, 2, "bin" },
117 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
118 	    ARCHIVE_ENTRY_ACL_READ_DATA |
119 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
120 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
121 	    ARCHIVE_ENTRY_ACL_READ_ACL |
122 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
123 	  ARCHIVE_ENTRY_ACL_USER, 4, "adm" },
124 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
125 	    ARCHIVE_ENTRY_ACL_READ_DATA |
126 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
127 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
128 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
129 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
130 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
131 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
132 	    ARCHIVE_ENTRY_ACL_READ_ACL |
133 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
134 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
135 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
136 	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
137 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
138 	    ARCHIVE_ENTRY_ACL_READ_DATA |
139 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
140 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
141 	    ARCHIVE_ENTRY_ACL_READ_ACL |
142 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
143 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
144 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
145 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
146 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
147 	    ARCHIVE_ENTRY_ACL_READ_ACL |
148 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
149 	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
150 };
151 
152 static struct archive_test_acl_t acls4[] = {
153 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
154 	    ARCHIVE_ENTRY_ACL_EXECUTE |
155 	    ARCHIVE_ENTRY_ACL_READ_DATA |
156 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
157 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
158 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
159 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
160 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
161 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
162 	    ARCHIVE_ENTRY_ACL_READ_ACL |
163 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
164 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
165 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
166 	    ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
167 	    ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT |
168 	    ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
169 	  ARCHIVE_ENTRY_ACL_USER, 1100, "1100" },
170 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
171 	    ARCHIVE_ENTRY_ACL_READ_DATA |
172 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
173 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
174 	    ARCHIVE_ENTRY_ACL_READ_ACL |
175 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
176 	    ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
177 	    ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
178 	  ARCHIVE_ENTRY_ACL_GROUP, 4, "adm" },
179 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
180 	    ARCHIVE_ENTRY_ACL_EXECUTE |
181 	    ARCHIVE_ENTRY_ACL_READ_DATA |
182 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
183 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
184 	    ARCHIVE_ENTRY_ACL_DELETE_CHILD |
185 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
186 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
187 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
188 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
189 	    ARCHIVE_ENTRY_ACL_READ_ACL |
190 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
191 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
192 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
193 	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
194 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
195 	    ARCHIVE_ENTRY_ACL_EXECUTE |
196 	    ARCHIVE_ENTRY_ACL_READ_DATA |
197 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
198 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
199 	    ARCHIVE_ENTRY_ACL_READ_ACL |
200 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
201 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
202 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
203 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
204 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
205 	    ARCHIVE_ENTRY_ACL_READ_ACL |
206 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
207 	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
208 };
209 
210 DEFINE_TEST(test_compat_solaris_tar_acl)
211 {
212 	char name[] = "test_compat_solaris_tar_acl.tar";
213 	struct archive *a;
214 	struct archive_entry *ae;
215 
216 	/* Read archive file */
217 	assert(NULL != (a = archive_read_new()));
218         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
219         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
220         extract_reference_file(name);
221 	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name,
222 	    10240));
223 
224 	/* First item has access ACLs */
225 	assertA(0 == archive_read_next_header(a, &ae));
226 	failure("One extended ACL should flag all ACLs to be returned.");
227 	assertEqualInt(7, archive_entry_acl_reset(ae,
228 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
229 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
230 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0644);
231 	failure("Basic ACLs should set mode to 0644, not %04o",
232 	    archive_entry_mode(ae)&0777);
233 	assert((archive_entry_mode(ae) & 0777) == 0644);
234 
235 	/* Second item has default and access ACLs */
236 	assertA(0 == archive_read_next_header(a, &ae));
237 	assertEqualInt(6, archive_entry_acl_reset(ae,
238 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
239 	assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
240 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0750);
241 	failure("Basic ACLs should set mode to 0750, not %04o",
242 	    archive_entry_mode(ae)&0777);
243 	assert((archive_entry_mode(ae) & 0777) == 0750);
244 	assertEqualInt(6, archive_entry_acl_reset(ae,
245 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
246 	assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
247 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0750);
248 
249 	/* Third item has NFS4 ACLs */
250 	assertA(0 == archive_read_next_header(a, &ae));
251 	assertEqualInt(6, archive_entry_acl_reset(ae,
252 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
253 	assertEntryCompareAcls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
254 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
255 
256 	/* Fourth item has NFS4 ACLs and inheritance flags */
257 	assertA(0 == archive_read_next_header(a, &ae));
258 	assertEqualInt(5, archive_entry_acl_reset(ae,
259 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
260 	assertEntryCompareAcls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
261 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
262 
263 	/* Close the archive. */
264 	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
265 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
266 }
267