5b5b37adc82baec27933f85d261b4cd0f4a91ea1
[autobuild.flakey.sn-devel-184/.git] / source3 / modules / test_nfs4_acls.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *
4  *  Unit test for NFS4 ACL handling
5  *
6  *  Copyright (C) Christof Schmitt 2019
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "nfs4_acls.c"
23 #include "librpc/gen_ndr/idmap.h"
24 #include "idmap_cache.h"
25 #include <cmocka.h>
26
27 struct test_sids {
28         const char *sid_str;
29         struct unixid unix_id;
30 } test_sids[] = {
31         { "S-1-5-2-123-456-789-100",    { 1000, ID_TYPE_UID     }},
32         { "S-1-5-2-123-456-789-101",    { 1001, ID_TYPE_GID     }},
33         { "S-1-5-2-123-456-789-102",    { 1002, ID_TYPE_BOTH    }},
34         { SID_CREATOR_OWNER,            { 1003, ID_TYPE_UID     }},
35         { SID_CREATOR_GROUP,            { 1004, ID_TYPE_GID     }},
36         { "S-1-5-2-123-456-789-103",    { 1000, ID_TYPE_GID     }},
37         { "S-1-5-2-123-456-789-104",    { 1005, ID_TYPE_BOTH    }},
38         { "S-1-5-2-123-456-789-105",    { 1006, ID_TYPE_BOTH    }},
39         { "S-1-5-2-123-456-789-106",    { 1007, ID_TYPE_BOTH    }},
40 };
41
42 static int group_setup(void **state)
43 {
44         struct dom_sid *sids = NULL;
45         int i;
46
47         sids = talloc_array(NULL, struct dom_sid, ARRAY_SIZE(test_sids));
48         assert_non_null(sids);
49
50         for (i = 0; i < ARRAY_SIZE(test_sids); i++) {
51                 assert_true(dom_sid_parse(test_sids[i].sid_str, &sids[i]));
52                 idmap_cache_set_sid2unixid(&sids[i], &test_sids[i].unix_id);
53         }
54
55         *state = sids;
56
57         return 0;
58
59 }
60
61 static int group_teardown(void **state)
62 {
63         struct dom_sid *sids = *state;
64         int i;
65
66         for (i = 0; i < ARRAY_SIZE(test_sids); i++) {
67                 assert_true(idmap_cache_del_sid(&sids[i]));
68         }
69
70         TALLOC_FREE(sids);
71         *state = NULL;
72
73         return 0;
74 }
75
76 /*
77  * Run this as first test to verify that the id mappings used by other
78  * tests are available in the cache.
79  */
80 static void test_cached_id_mappings(void **state)
81 {
82         struct dom_sid *sids = *state;
83         int i;
84
85         for (i = 0; i < ARRAY_SIZE(test_sids); i++) {
86                 struct dom_sid *sid = &sids[i];
87                 struct unixid *unix_id = &test_sids[i].unix_id;
88                 uid_t uid;
89                 gid_t gid;
90
91                 switch(unix_id->type) {
92                 case ID_TYPE_UID:
93                         assert_true(sid_to_uid(sid, &uid));
94                         assert_int_equal(uid, unix_id->id);
95                         assert_false(sid_to_gid(sid, &gid));
96                         break;
97                 case ID_TYPE_GID:
98                         assert_false(sid_to_uid(sid, &uid));
99                         assert_true(sid_to_gid(sid, &gid));
100                         assert_int_equal(gid, unix_id->id);
101                         break;
102                 case ID_TYPE_BOTH:
103                         assert_true(sid_to_uid(sid, &uid));
104                         assert_int_equal(uid, unix_id->id);
105                         assert_true(sid_to_gid(sid, &gid));
106                         assert_int_equal(gid, unix_id->id);
107                         break;
108                 default:
109                         fail_msg("Unknown id type %d\n", unix_id->type);
110                         break;
111                 }
112         }
113 }
114
115 static void test_empty_nfs4_to_dacl(void **state)
116 {
117         struct dom_sid *sids = *state;
118         TALLOC_CTX *frame = talloc_stackframe();
119         struct SMB4ACL_T *nfs4_acl;
120         struct security_ace *dacl_aces;
121         int good_aces;
122         struct smbacl4_vfs_params params = {
123                 .mode = e_simple,
124                 .do_chown = true,
125                 .acedup = e_merge,
126                 .map_full_control = true,
127         };
128
129         nfs4_acl = smb_create_smb4acl(frame);
130         assert_non_null(nfs4_acl);
131
132         assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
133                                      &sids[0], &sids[1], false,
134                                      &dacl_aces, &good_aces));
135
136         assert_int_equal(good_aces, 0);
137         assert_null(dacl_aces);
138
139         TALLOC_FREE(frame);
140 }
141
142 static void test_empty_dacl_to_nfs4(void **state)
143 {
144         TALLOC_CTX *frame = talloc_stackframe();
145         struct SMB4ACL_T *nfs4_acl;
146         struct security_acl *dacl;
147         struct smbacl4_vfs_params params = {
148                 .mode = e_simple,
149                 .do_chown = true,
150                 .acedup = e_merge,
151                 .map_full_control = true,
152         };
153
154         dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, 0, NULL);
155         assert_non_null(dacl);
156
157         nfs4_acl = smbacl4_win2nfs4(frame, false, dacl, &params, 1001, 1002);
158
159         assert_non_null(nfs4_acl);
160         assert_int_equal(smbacl4_get_controlflags(nfs4_acl),
161                          SEC_DESC_SELF_RELATIVE);
162         assert_int_equal(smb_get_naces(nfs4_acl), 0);
163         assert_null(smb_first_ace4(nfs4_acl));
164 }
165
166 struct ace_dacl_type_mapping {
167         uint32_t nfs4_type;
168         enum security_ace_type dacl_type;
169 } ace_dacl_type_mapping[] = {
170         { SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,     SEC_ACE_TYPE_ACCESS_ALLOWED   },
171         { SMB_ACE4_ACCESS_DENIED_ACE_TYPE,      SEC_ACE_TYPE_ACCESS_DENIED    },
172 };
173
174 static void test_acl_type_nfs4_to_dacl(void **state)
175 {
176         struct dom_sid *sids = *state;
177         TALLOC_CTX *frame = talloc_stackframe();
178         int i;
179
180         for (i = 0; i < ARRAY_SIZE(ace_dacl_type_mapping); i++) {
181                 struct SMB4ACL_T *nfs4_acl;
182                 SMB_ACE4PROP_T nfs4_ace;
183                 struct security_ace *dacl_aces;
184                 int good_aces;
185                 struct smbacl4_vfs_params params = {
186                         .mode = e_simple,
187                         .do_chown = true,
188                         .acedup = e_merge,
189                         .map_full_control = true,
190                 };
191
192                 nfs4_acl = smb_create_smb4acl(frame);
193                 assert_non_null(nfs4_acl);
194
195                 nfs4_ace = (SMB_ACE4PROP_T) {
196                         .flags          = 0,
197                         .who.uid        = 1000,
198                         .aceType        = ace_dacl_type_mapping[i].nfs4_type,
199                         .aceFlags       = 0,
200                         .aceMask        = SMB_ACE4_READ_DATA,
201                 };
202                 assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
203
204                 assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
205                                              &sids[2], &sids[3], false,
206                                              &dacl_aces, &good_aces));
207
208                 assert_int_equal(good_aces, 1);
209                 assert_non_null(dacl_aces);
210
211                 assert_int_equal(dacl_aces[0].type,
212                                  ace_dacl_type_mapping[i].dacl_type);
213                 assert_int_equal(dacl_aces[0].flags, 0);
214                 assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA);
215                 assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
216         }
217
218         TALLOC_FREE(frame);
219 }
220
221 static void test_acl_type_dacl_to_nfs4(void **state)
222 {
223         struct dom_sid *sids = *state;
224         TALLOC_CTX *frame = talloc_stackframe();
225         int i;
226
227         for (i = 0; i < ARRAY_SIZE(ace_dacl_type_mapping); i++) {
228                 struct SMB4ACL_T *nfs4_acl;
229                 struct SMB4ACE_T *nfs4_ace_container;
230                 SMB_ACE4PROP_T *nfs4_ace;
231                 struct security_ace dacl_aces[1];
232                 struct security_acl *dacl;
233                 struct smbacl4_vfs_params params = {
234                         .mode = e_simple,
235                         .do_chown = true,
236                         .acedup = e_merge,
237                         .map_full_control = true,
238                 };
239
240                 init_sec_ace(&dacl_aces[0], &sids[0],
241                              ace_dacl_type_mapping[i].dacl_type,
242                              SEC_FILE_READ_DATA, 0);
243                 dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
244                                     ARRAY_SIZE(dacl_aces), dacl_aces);
245                 assert_non_null(dacl);
246
247                 nfs4_acl = smbacl4_win2nfs4(frame, false, dacl, &params,
248                                             101, 102);
249
250                 assert_non_null(nfs4_acl);
251                 assert_int_equal(smbacl4_get_controlflags(nfs4_acl),
252                                  SEC_DESC_SELF_RELATIVE);
253                 assert_int_equal(smb_get_naces(nfs4_acl), 1);
254
255                 nfs4_ace_container = smb_first_ace4(nfs4_acl);
256                 assert_non_null(nfs4_ace_container);
257                 assert_null(smb_next_ace4(nfs4_ace_container));
258
259                 nfs4_ace = smb_get_ace4(nfs4_ace_container);
260                 assert_int_equal(nfs4_ace->flags, 0);
261                 assert_int_equal(nfs4_ace->who.uid, 1000);
262                 assert_int_equal(nfs4_ace->aceFlags, 0);
263                 assert_int_equal(nfs4_ace->aceType,
264                                  ace_dacl_type_mapping[i].nfs4_type);
265                 assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
266         }
267
268         TALLOC_FREE(frame);
269 }
270
271 struct ace_flag_mapping_nfs4_to_dacl {
272         bool is_directory;
273         uint32_t nfs4_flag;
274         uint32_t dacl_flag;
275 } ace_flags_nfs4_to_dacl[] = {
276         { true,  SMB_ACE4_FILE_INHERIT_ACE,
277           SEC_ACE_FLAG_OBJECT_INHERIT },
278         { false, SMB_ACE4_FILE_INHERIT_ACE,
279           0 },
280         { true, SMB_ACE4_DIRECTORY_INHERIT_ACE,
281           SEC_ACE_FLAG_CONTAINER_INHERIT },
282         { false, SMB_ACE4_DIRECTORY_INHERIT_ACE,
283           0 },
284         { true, SMB_ACE4_NO_PROPAGATE_INHERIT_ACE,
285           SEC_ACE_FLAG_NO_PROPAGATE_INHERIT },
286         { false, SMB_ACE4_NO_PROPAGATE_INHERIT_ACE,
287           SEC_ACE_FLAG_NO_PROPAGATE_INHERIT },
288         { true, SMB_ACE4_INHERIT_ONLY_ACE,
289           SEC_ACE_FLAG_INHERIT_ONLY },
290         { false, SMB_ACE4_INHERIT_ONLY_ACE,
291           SEC_ACE_FLAG_INHERIT_ONLY },
292         { true, SMB_ACE4_SUCCESSFUL_ACCESS_ACE_FLAG,
293           0 },
294         { false, SMB_ACE4_SUCCESSFUL_ACCESS_ACE_FLAG,
295           0 },
296         { true, SMB_ACE4_FAILED_ACCESS_ACE_FLAG,
297           0 },
298         { false, SMB_ACE4_FAILED_ACCESS_ACE_FLAG,
299           0 },
300         { true, SMB_ACE4_INHERITED_ACE,
301           SEC_ACE_FLAG_INHERITED_ACE },
302         { false, SMB_ACE4_INHERITED_ACE,
303           SEC_ACE_FLAG_INHERITED_ACE },
304 };
305
306 static void test_ace_flags_nfs4_to_dacl(void **state)
307 {
308         struct dom_sid *sids = *state;
309         TALLOC_CTX *frame = talloc_stackframe();
310         SMB_ACE4PROP_T nfs4_ace;
311         int i;
312
313         for (i = 0; i < ARRAY_SIZE(ace_flags_nfs4_to_dacl); i++) {
314                 struct SMB4ACL_T *nfs4_acl;
315                 bool is_directory;
316                 struct security_ace *dacl_aces;
317                 int good_aces;
318                 struct smbacl4_vfs_params params = {
319                         .mode = e_simple,
320                         .do_chown = true,
321                         .acedup = e_merge,
322                         .map_full_control = true,
323                 };
324
325                 nfs4_acl = smb_create_smb4acl(frame);
326                 assert_non_null(nfs4_acl);
327
328                 nfs4_ace = (SMB_ACE4PROP_T) {
329                         .flags          = 0,
330                         .who.uid        = 1000,
331                         .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
332                         .aceFlags       = ace_flags_nfs4_to_dacl[i].nfs4_flag,
333                         .aceMask        = SMB_ACE4_READ_DATA,
334                 };
335                 assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
336
337                 is_directory = ace_flags_nfs4_to_dacl[i].is_directory;
338
339                 assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
340                                              &sids[2], &sids[3], is_directory,
341                                              &dacl_aces, &good_aces));
342
343                 assert_int_equal(good_aces, 1);
344                 assert_non_null(dacl_aces);
345
346                 assert_int_equal(dacl_aces[0].type,
347                                  SEC_ACE_TYPE_ACCESS_ALLOWED);
348                 assert_int_equal(dacl_aces[0].flags,
349                                  ace_flags_nfs4_to_dacl[i].dacl_flag);
350                 assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA);
351                 assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
352         }
353
354         TALLOC_FREE(frame);
355 }
356
357 struct ace_flag_mapping_dacl_to_nfs4 {
358         bool is_directory;
359         uint32_t dacl_flag;
360         uint32_t nfs4_flag;
361 } ace_flags_dacl_to_nfs4[] = {
362         { true, SEC_ACE_FLAG_OBJECT_INHERIT,
363           SMB_ACE4_FILE_INHERIT_ACE },
364         { false, SEC_ACE_FLAG_OBJECT_INHERIT,
365           0 },
366         { true, SEC_ACE_FLAG_CONTAINER_INHERIT,
367           SMB_ACE4_DIRECTORY_INHERIT_ACE },
368         { false, SEC_ACE_FLAG_CONTAINER_INHERIT,
369           0 },
370         { true, SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
371           SMB_ACE4_NO_PROPAGATE_INHERIT_ACE },
372         { false, SEC_ACE_FLAG_NO_PROPAGATE_INHERIT,
373           0 },
374         { true, SEC_ACE_FLAG_INHERIT_ONLY,
375           SMB_ACE4_INHERIT_ONLY_ACE },
376         { false, SEC_ACE_FLAG_INHERIT_ONLY,
377           0 },
378         { true, SEC_ACE_FLAG_INHERITED_ACE,
379           SMB_ACE4_INHERITED_ACE },
380         { false, SEC_ACE_FLAG_INHERITED_ACE,
381           SMB_ACE4_INHERITED_ACE },
382         { true, SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
383           0 },
384         { false, SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
385           0 },
386         { true, SEC_ACE_FLAG_FAILED_ACCESS,
387           0 },
388         { false, SEC_ACE_FLAG_FAILED_ACCESS,
389           0 },
390 };
391
392 static void test_ace_flags_dacl_to_nfs4(void **state)
393 {
394         struct dom_sid *sids = *state;
395         TALLOC_CTX *frame = talloc_stackframe();
396         int i;
397
398         for (i = 0; i < ARRAY_SIZE(ace_flags_dacl_to_nfs4); i++) {
399                 struct SMB4ACL_T *nfs4_acl;
400                 struct SMB4ACE_T *nfs4_ace_container;
401                 SMB_ACE4PROP_T *nfs4_ace;
402                 bool is_directory;
403                 struct security_ace dacl_aces[1];
404                 struct security_acl *dacl;
405                 struct smbacl4_vfs_params params = {
406                         .mode = e_simple,
407                         .do_chown = true,
408                         .acedup = e_merge,
409                         .map_full_control = true,
410                 };
411
412                 init_sec_ace(&dacl_aces[0], &sids[0],
413                              SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA,
414                              ace_flags_dacl_to_nfs4[i].dacl_flag);
415                 dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
416                                     ARRAY_SIZE(dacl_aces), dacl_aces);
417                 assert_non_null(dacl);
418
419                 is_directory = ace_flags_dacl_to_nfs4[i].is_directory;
420                 nfs4_acl = smbacl4_win2nfs4(frame, is_directory, dacl, &params,
421                                             101, 102);
422
423                 assert_non_null(nfs4_acl);
424                 assert_int_equal(smbacl4_get_controlflags(nfs4_acl),
425                                  SEC_DESC_SELF_RELATIVE);
426                 assert_int_equal(smb_get_naces(nfs4_acl), 1);
427
428                 nfs4_ace_container = smb_first_ace4(nfs4_acl);
429                 assert_non_null(nfs4_ace_container);
430                 assert_null(smb_next_ace4(nfs4_ace_container));
431
432                 nfs4_ace = smb_get_ace4(nfs4_ace_container);
433                 assert_int_equal(nfs4_ace->flags, 0);
434                 assert_int_equal(nfs4_ace->who.uid, 1000);
435                 assert_int_equal(nfs4_ace->aceFlags,
436                                  ace_flags_dacl_to_nfs4[i].nfs4_flag);
437                 assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA);
438         }
439
440         TALLOC_FREE(frame);
441 }
442
443 struct ace_perm_mapping {
444         uint32_t nfs4_perm;
445         uint32_t dacl_perm;
446 } perm_table_nfs4_to_dacl[] = {
447         { SMB_ACE4_READ_DATA,           SEC_FILE_READ_DATA              },
448         { SMB_ACE4_LIST_DIRECTORY,      SEC_DIR_LIST                    },
449         { SMB_ACE4_WRITE_DATA,          SEC_FILE_WRITE_DATA             },
450         { SMB_ACE4_ADD_FILE,            SEC_DIR_ADD_FILE                },
451         { SMB_ACE4_APPEND_DATA, SEC_FILE_APPEND_DATA            },
452         { SMB_ACE4_ADD_SUBDIRECTORY,    SEC_DIR_ADD_SUBDIR,             },
453         { SMB_ACE4_READ_NAMED_ATTRS,    SEC_FILE_READ_EA                },
454         { SMB_ACE4_READ_NAMED_ATTRS,    SEC_DIR_READ_EA         },
455         { SMB_ACE4_WRITE_NAMED_ATTRS,   SEC_FILE_WRITE_EA               },
456         { SMB_ACE4_WRITE_NAMED_ATTRS,   SEC_DIR_WRITE_EA                },
457         { SMB_ACE4_EXECUTE,             SEC_FILE_EXECUTE                },
458         { SMB_ACE4_EXECUTE,             SEC_DIR_TRAVERSE                },
459         { SMB_ACE4_DELETE_CHILD,        SEC_DIR_DELETE_CHILD            },
460         { SMB_ACE4_READ_ATTRIBUTES,     SEC_FILE_READ_ATTRIBUTE },
461         { SMB_ACE4_READ_ATTRIBUTES,     SEC_DIR_READ_ATTRIBUTE          },
462         { SMB_ACE4_WRITE_ATTRIBUTES,    SEC_FILE_WRITE_ATTRIBUTE        },
463         { SMB_ACE4_WRITE_ATTRIBUTES,    SEC_DIR_WRITE_ATTRIBUTE },
464         { SMB_ACE4_DELETE,              SEC_STD_DELETE                  },
465         { SMB_ACE4_READ_ACL,            SEC_STD_READ_CONTROL            },
466         { SMB_ACE4_WRITE_ACL,           SEC_STD_WRITE_DAC,              },
467         { SMB_ACE4_WRITE_OWNER, SEC_STD_WRITE_OWNER             },
468         { SMB_ACE4_SYNCHRONIZE, SEC_STD_SYNCHRONIZE             },
469 };
470
471 static void test_nfs4_permissions_to_dacl(void **state)
472 {
473         struct dom_sid *sids = *state;
474         TALLOC_CTX *frame = talloc_stackframe();
475         int i;
476
477         for (i = 0; i < ARRAY_SIZE(perm_table_nfs4_to_dacl); i++) {
478                 struct SMB4ACL_T *nfs4_acl;
479                 SMB_ACE4PROP_T nfs4_ace;
480                 struct security_ace *dacl_aces;
481                 int good_aces;
482                 struct smbacl4_vfs_params params = {
483                         .mode = e_simple,
484                         .do_chown = true,
485                         .acedup = e_merge,
486                         .map_full_control = true,
487                 };
488
489                 nfs4_acl = smb_create_smb4acl(frame);
490                 assert_non_null(nfs4_acl);
491
492                 nfs4_ace = (SMB_ACE4PROP_T) {
493                         .flags          = 0,
494                         .who.uid        = 1000,
495                         .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
496                         .aceFlags       = 0,
497                         .aceMask        = perm_table_nfs4_to_dacl[i].nfs4_perm,
498                 };
499                 assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
500
501                 assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
502                                              &sids[0], &sids[1], false,
503                                              &dacl_aces, &good_aces));
504
505                 assert_int_equal(good_aces, 1);
506                 assert_non_null(dacl_aces);
507
508                 assert_int_equal(dacl_aces[0].type,
509                                  SEC_ACE_TYPE_ACCESS_ALLOWED);
510                 assert_int_equal(dacl_aces[0].flags, 0);
511                 assert_int_equal(dacl_aces[0].access_mask,
512                                  perm_table_nfs4_to_dacl[i].dacl_perm);
513                 assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
514         }
515
516         TALLOC_FREE(frame);
517 }
518
519 struct ace_perm_mapping_dacl_to_nfs4 {
520         uint32_t dacl_perm;
521         uint32_t nfs4_perm;
522 } perm_table_dacl_to_nfs4[] = {
523         { SEC_FILE_READ_DATA,           SMB_ACE4_READ_DATA,             },
524         { SEC_DIR_LIST,         SMB_ACE4_LIST_DIRECTORY,        },
525         { SEC_FILE_WRITE_DATA,          SMB_ACE4_WRITE_DATA,            },
526         { SEC_DIR_ADD_FILE,             SMB_ACE4_ADD_FILE,              },
527         { SEC_FILE_APPEND_DATA, SMB_ACE4_APPEND_DATA,           },
528         { SEC_DIR_ADD_SUBDIR,           SMB_ACE4_ADD_SUBDIRECTORY,      },
529         { SEC_FILE_READ_EA,             SMB_ACE4_READ_NAMED_ATTRS,      },
530         { SEC_DIR_READ_EA,              SMB_ACE4_READ_NAMED_ATTRS,      },
531         { SEC_FILE_WRITE_EA,            SMB_ACE4_WRITE_NAMED_ATTRS,     },
532         { SEC_DIR_WRITE_EA,             SMB_ACE4_WRITE_NAMED_ATTRS,     },
533         { SEC_FILE_EXECUTE,             SMB_ACE4_EXECUTE,               },
534         { SEC_DIR_TRAVERSE,             SMB_ACE4_EXECUTE,               },
535         { SEC_DIR_DELETE_CHILD, SMB_ACE4_DELETE_CHILD,          },
536         { SEC_FILE_READ_ATTRIBUTE,      SMB_ACE4_READ_ATTRIBUTES,       },
537         { SEC_DIR_READ_ATTRIBUTE,       SMB_ACE4_READ_ATTRIBUTES,       },
538         { SEC_FILE_WRITE_ATTRIBUTE,     SMB_ACE4_WRITE_ATTRIBUTES,      },
539         { SEC_DIR_WRITE_ATTRIBUTE,      SMB_ACE4_WRITE_ATTRIBUTES,      },
540         { SEC_STD_DELETE,               SMB_ACE4_DELETE,                },
541         { SEC_STD_READ_CONTROL, SMB_ACE4_READ_ACL,              },
542         { SEC_STD_WRITE_DAC,            SMB_ACE4_WRITE_ACL,             },
543         { SEC_STD_WRITE_OWNER,          SMB_ACE4_WRITE_OWNER,           },
544         { SEC_STD_SYNCHRONIZE,          SMB_ACE4_SYNCHRONIZE,           },
545         { SEC_GENERIC_READ,             SMB_ACE4_READ_ACL|
546                                         SMB_ACE4_READ_DATA|
547                                         SMB_ACE4_READ_ATTRIBUTES|
548                                         SMB_ACE4_READ_NAMED_ATTRS|
549                                         SMB_ACE4_SYNCHRONIZE            },
550         { SEC_GENERIC_WRITE,            SMB_ACE4_WRITE_ACL|
551                                         SMB_ACE4_WRITE_DATA|
552                                         SMB_ACE4_WRITE_ATTRIBUTES|
553                                         SMB_ACE4_WRITE_NAMED_ATTRS|
554                                         SMB_ACE4_SYNCHRONIZE            },
555         { SEC_GENERIC_EXECUTE,          SMB_ACE4_READ_ACL|
556                                         SMB_ACE4_READ_ATTRIBUTES|
557                                         SMB_ACE4_EXECUTE|
558                                         SMB_ACE4_SYNCHRONIZE            },
559         { SEC_GENERIC_ALL,              SMB_ACE4_DELETE|
560                                         SMB_ACE4_READ_ACL|
561                                         SMB_ACE4_WRITE_ACL|
562                                         SMB_ACE4_WRITE_OWNER|
563                                         SMB_ACE4_SYNCHRONIZE|
564                                         SMB_ACE4_WRITE_ATTRIBUTES|
565                                         SMB_ACE4_READ_ATTRIBUTES|
566                                         SMB_ACE4_EXECUTE|
567                                         SMB_ACE4_READ_NAMED_ATTRS|
568                                         SMB_ACE4_WRITE_NAMED_ATTRS|
569                                         SMB_ACE4_WRITE_DATA|
570                                         SMB_ACE4_APPEND_DATA|
571                                         SMB_ACE4_READ_DATA|
572                                         SMB_ACE4_DELETE_CHILD           },
573 };
574
575 static void test_dacl_permissions_to_nfs4(void **state)
576 {
577         struct dom_sid *sids = *state;
578         TALLOC_CTX *frame = talloc_stackframe();
579         int i;
580
581         for (i = 0; i < ARRAY_SIZE(perm_table_nfs4_to_dacl); i++) {
582                 struct SMB4ACL_T *nfs4_acl;
583                 struct SMB4ACE_T *nfs4_ace_container;
584                 SMB_ACE4PROP_T *nfs4_ace;
585                 struct smbacl4_vfs_params params = {
586                         .mode = e_simple,
587                         .do_chown = true,
588                         .acedup = e_merge,
589                         .map_full_control = true,
590                 };
591                 struct security_ace dacl_aces[1];
592                 struct security_acl *dacl;
593
594                 init_sec_ace(&dacl_aces[0], &sids[0],
595                              SEC_ACE_TYPE_ACCESS_ALLOWED,
596                              perm_table_dacl_to_nfs4[i].dacl_perm, 0);
597                 dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS,
598                                     ARRAY_SIZE(dacl_aces), dacl_aces);
599                 assert_non_null(dacl);
600
601                 nfs4_acl = smbacl4_win2nfs4(frame, false, dacl, &params,
602                                             101, 102);
603
604                 assert_non_null(nfs4_acl);
605                 assert_int_equal(smbacl4_get_controlflags(nfs4_acl),
606                                  SEC_DESC_SELF_RELATIVE);
607                 assert_int_equal(smb_get_naces(nfs4_acl), 1);
608
609                 nfs4_ace_container = smb_first_ace4(nfs4_acl);
610                 assert_non_null(nfs4_ace_container);
611                 assert_null(smb_next_ace4(nfs4_ace_container));
612
613                 nfs4_ace = smb_get_ace4(nfs4_ace_container);
614                 assert_int_equal(nfs4_ace->flags, 0);
615                 assert_int_equal(nfs4_ace->who.uid, 1000);
616                 assert_int_equal(nfs4_ace->aceFlags, 0);
617                 assert_int_equal(nfs4_ace->aceMask,
618                                  perm_table_dacl_to_nfs4[i].nfs4_perm);
619         }
620
621         TALLOC_FREE(frame);
622 }
623
624 /*
625  * Create NFS4 ACL with all possible "special" entries. Verify that
626  * the ones that should be mapped to a DACL are mapped and the other
627  * ones are ignored.
628  */
629 static void test_special_nfs4_to_dacl(void **state)
630 {
631         struct dom_sid *sids = *state;
632         TALLOC_CTX *frame = talloc_stackframe();
633         struct SMB4ACL_T *nfs4_acl;
634         SMB_ACE4PROP_T nfs4_ace;
635         struct security_ace *dacl_aces;
636         int good_aces;
637         struct smbacl4_vfs_params params = {
638                 .mode = e_simple,
639                 .do_chown = true,
640                 .acedup = e_merge,
641                 .map_full_control = true,
642         };
643
644         nfs4_acl = smb_create_smb4acl(frame);
645         assert_non_null(nfs4_acl);
646
647         nfs4_ace = (SMB_ACE4PROP_T) {
648                 .flags          = SMB_ACE4_ID_SPECIAL,
649                 .who.special_id = SMB_ACE4_WHO_OWNER,
650                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
651                 .aceFlags       = 0,
652                 .aceMask        = SMB_ACE4_READ_DATA,
653         };
654         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
655
656         nfs4_ace = (SMB_ACE4PROP_T) {
657                 .flags          = SMB_ACE4_ID_SPECIAL,
658                 .who.special_id = SMB_ACE4_WHO_GROUP,
659                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
660                 .aceFlags       = 0,
661                 .aceMask        = SMB_ACE4_WRITE_DATA,
662         };
663         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
664
665         nfs4_ace = (SMB_ACE4PROP_T) {
666                 .flags          = SMB_ACE4_ID_SPECIAL,
667                 .who.special_id = SMB_ACE4_WHO_EVERYONE,
668                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
669                 .aceFlags       = 0,
670                 .aceMask        = SMB_ACE4_APPEND_DATA,
671         };
672         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
673
674         nfs4_ace = (SMB_ACE4PROP_T) {
675                 .flags          = SMB_ACE4_ID_SPECIAL,
676                 .who.special_id = SMB_ACE4_WHO_INTERACTIVE,
677                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
678                 .aceFlags       = 0,
679                 .aceMask        = SMB_ACE4_READ_NAMED_ATTRS,
680         };
681         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
682
683         nfs4_ace = (SMB_ACE4PROP_T) {
684                 .flags          = SMB_ACE4_ID_SPECIAL,
685                 .who.special_id = SMB_ACE4_WHO_NETWORK,
686                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
687                 .aceFlags       = 0,
688                 .aceMask        = SMB_ACE4_WRITE_NAMED_ATTRS,
689         };
690         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
691
692         nfs4_ace = (SMB_ACE4PROP_T) {
693                 .flags          = SMB_ACE4_ID_SPECIAL,
694                 .who.special_id = SMB_ACE4_WHO_DIALUP,
695                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
696                 .aceFlags       = 0,
697                 .aceMask        = SMB_ACE4_EXECUTE,
698         };
699         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
700
701         nfs4_ace = (SMB_ACE4PROP_T) {
702                 .flags          = SMB_ACE4_ID_SPECIAL,
703                 .who.special_id = SMB_ACE4_WHO_BATCH,
704                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
705                 .aceFlags       = 0,
706                 .aceMask        = SMB_ACE4_READ_ATTRIBUTES,
707         };
708         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
709
710         nfs4_ace = (SMB_ACE4PROP_T) {
711                 .flags          = SMB_ACE4_ID_SPECIAL,
712                 .who.special_id = SMB_ACE4_WHO_ANONYMOUS,
713                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
714                 .aceFlags       = 0,
715                 .aceMask        = SMB_ACE4_WRITE_ATTRIBUTES,
716         };
717         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
718
719         nfs4_ace = (SMB_ACE4PROP_T) {
720                 .flags          = SMB_ACE4_ID_SPECIAL,
721                 .who.special_id = SMB_ACE4_WHO_AUTHENTICATED,
722                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
723                 .aceFlags       = 0,
724                 .aceMask        = SMB_ACE4_READ_ACL,
725         };
726         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
727
728         nfs4_ace = (SMB_ACE4PROP_T) {
729                 .flags          = SMB_ACE4_ID_SPECIAL,
730                 .who.special_id = SMB_ACE4_WHO_SERVICE,
731                 .aceType        = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE,
732                 .aceFlags       = 0,
733                 .aceMask        = SMB_ACE4_WRITE_ACL,
734         };
735         assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace));
736
737         assert_true(smbacl4_nfs42win(frame, &params, nfs4_acl,
738                                      &sids[0], &sids[1], false,
739                                      &dacl_aces, &good_aces));
740
741         assert_int_equal(good_aces, 3);
742         assert_non_null(dacl_aces);
743
744         assert_int_equal(dacl_aces[0].type, SEC_ACE_TYPE_ACCESS_ALLOWED);
745         assert_int_equal(dacl_aces[0].flags, 0);
746         assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA);
747         assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0]));
748
749         assert_int_equal(dacl_aces[1].type, SEC_ACE_TYPE_ACCESS_ALLOWED);
750         assert_int_equal(dacl_aces[1].flags, 0);
751         assert_int_equal(dacl_aces[1].access_mask, SEC_FILE_WRITE_DATA);
752         assert_true(dom_sid_equal(&dacl_aces[1].trustee, &sids[1]));
753
754         assert_int_equal(dacl_aces[2].type, SEC_ACE_TYPE_ACCESS_ALLOWED);
755         assert_int_equal(dacl_aces[2].flags, 0);
756         assert_int_equal(dacl_aces[2].access_mask, SEC_FILE_APPEND_DATA);
757         assert_true(dom_sid_equal(&dacl_aces[2].trustee, &global_sid_World));
758
759         TALLOC_FREE(frame);
760 }
761
762 int main(int argc, char **argv)
763 {
764         const struct CMUnitTest tests[] = {
765                 cmocka_unit_test(test_cached_id_mappings),
766                 cmocka_unit_test(test_empty_nfs4_to_dacl),
767                 cmocka_unit_test(test_empty_dacl_to_nfs4),
768                 cmocka_unit_test(test_acl_type_nfs4_to_dacl),
769                 cmocka_unit_test(test_acl_type_dacl_to_nfs4),
770                 cmocka_unit_test(test_ace_flags_nfs4_to_dacl),
771                 cmocka_unit_test(test_ace_flags_dacl_to_nfs4),
772                 cmocka_unit_test(test_nfs4_permissions_to_dacl),
773                 cmocka_unit_test(test_dacl_permissions_to_nfs4),
774                 cmocka_unit_test(test_special_nfs4_to_dacl),
775         };
776
777         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
778
779         if (argc != 2) {
780                 print_error("Usage: %s smb.conf\n", argv[0]);
781                 exit(1);
782         }
783
784         /*
785          * Initialize enough of the Samba internals to have the
786          * mappings tests work.
787          */
788         talloc_stackframe();
789         lp_load_global(argv[1]);
790
791         return cmocka_run_group_tests(tests, group_setup, group_teardown);
792 }