s4-pvfs: use privileges rather than "uid == 0" in unix access check
[ira/wip.git] / source4 / ntvfs / posix / pvfs_acl.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    POSIX NTVFS backend - ACL support
5
6    Copyright (C) Andrew Tridgell 2004
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 "includes.h"
23 #include "auth/auth.h"
24 #include "vfs_posix.h"
25 #include "librpc/gen_ndr/xattr.h"
26 #include "libcli/security/security.h"
27 #include "param/param.h"
28
29
30 /* the list of currently registered ACL backends */
31 static struct pvfs_acl_backend {
32         const struct pvfs_acl_ops *ops;
33 } *backends = NULL;
34 static int num_backends;
35
36 /*
37   register a pvfs acl backend. 
38
39   The 'name' can be later used by other backends to find the operations
40   structure for this backend.  
41 */
42 NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops)
43 {
44         struct pvfs_acl_ops *new_ops;
45
46         if (pvfs_acl_backend_byname(ops->name) != NULL) {
47                 DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
48                 return NT_STATUS_OBJECT_NAME_COLLISION;
49         }
50
51         backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1);
52         NT_STATUS_HAVE_NO_MEMORY(backends);
53
54         new_ops = (struct pvfs_acl_ops *)talloc_memdup(backends, ops, sizeof(*ops));
55         new_ops->name = talloc_strdup(new_ops, ops->name);
56
57         backends[num_backends].ops = new_ops;
58
59         num_backends++;
60
61         DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
62
63         return NT_STATUS_OK;
64 }
65
66
67 /*
68   return the operations structure for a named backend
69 */
70 const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
71 {
72         int i;
73
74         for (i=0;i<num_backends;i++) {
75                 if (strcmp(backends[i].ops->name, name) == 0) {
76                         return backends[i].ops;
77                 }
78         }
79
80         return NULL;
81 }
82
83 NTSTATUS pvfs_acl_init(struct loadparm_context *lp_ctx)
84 {
85         static bool initialized = false;
86         extern NTSTATUS pvfs_acl_nfs4_init(void);
87         extern NTSTATUS pvfs_acl_xattr_init(void);
88         init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
89         init_module_fn *shared_init;
90
91         if (initialized) return NT_STATUS_OK;
92         initialized = true;
93
94         shared_init = load_samba_modules(NULL, lp_ctx, "pvfs_acl");
95
96         run_init_functions(static_init);
97         run_init_functions(shared_init);
98
99         talloc_free(shared_init);
100
101         return NT_STATUS_OK;
102 }
103
104
105 /*
106   map a single access_mask from generic to specific bits for files/dirs
107 */
108 static uint32_t pvfs_translate_mask(uint32_t access_mask)
109 {
110         if (access_mask & SEC_MASK_GENERIC) {
111                 if (access_mask & SEC_GENERIC_READ)    access_mask |= SEC_RIGHTS_FILE_READ;
112                 if (access_mask & SEC_GENERIC_WRITE)   access_mask |= SEC_RIGHTS_FILE_WRITE;
113                 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
114                 if (access_mask & SEC_GENERIC_ALL)     access_mask |= SEC_RIGHTS_FILE_ALL;
115                 access_mask &= ~SEC_MASK_GENERIC;
116         }
117         return access_mask;
118 }
119
120
121 /*
122   map any generic access bits in the given acl
123   this relies on the fact that the mappings for files and directories
124   are the same
125 */
126 static void pvfs_translate_generic_bits(struct security_acl *acl)
127 {
128         unsigned i;
129
130         if (!acl) return;
131
132         for (i=0;i<acl->num_aces;i++) {
133                 struct security_ace *ace = &acl->aces[i];
134                 ace->access_mask = pvfs_translate_mask(ace->access_mask);
135         }
136 }
137
138
139 /*
140   setup a default ACL for a file
141 */
142 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
143                                  struct ntvfs_request *req,
144                                  struct pvfs_filename *name, int fd, 
145                                  struct security_descriptor **psd)
146 {
147         struct security_descriptor *sd;
148         NTSTATUS status;
149         struct security_ace ace;
150         mode_t mode;
151         struct id_mapping *ids;
152         struct composite_context *ctx;
153
154         *psd = security_descriptor_initialise(req);
155         if (*psd == NULL) {
156                 return NT_STATUS_NO_MEMORY;
157         }
158         sd = *psd;
159
160         ids = talloc_zero_array(sd, struct id_mapping, 2);
161         NT_STATUS_HAVE_NO_MEMORY(ids);
162
163         ids[0].unixid = talloc(ids, struct unixid);
164         NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid);
165
166         ids[0].unixid->id = name->st.st_uid;
167         ids[0].unixid->type = ID_TYPE_UID;
168         ids[0].sid = NULL;
169
170         ids[1].unixid = talloc(ids, struct unixid);
171         NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid);
172
173         ids[1].unixid->id = name->st.st_gid;
174         ids[1].unixid->type = ID_TYPE_GID;
175         ids[1].sid = NULL;
176
177         ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
178         NT_STATUS_HAVE_NO_MEMORY(ctx);
179
180         status = wbc_xids_to_sids_recv(ctx, &ids);
181         NT_STATUS_NOT_OK_RETURN(status);
182
183         sd->owner_sid = talloc_steal(sd, ids[0].sid);
184         sd->group_sid = talloc_steal(sd, ids[1].sid);
185
186         talloc_free(ids);
187         sd->type |= SEC_DESC_DACL_PRESENT;
188
189         mode = name->st.st_mode;
190
191         /*
192           we provide up to 4 ACEs
193             - Owner
194             - Group
195             - Everyone
196             - Administrator
197          */
198
199
200         /* setup owner ACE */
201         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
202         ace.flags = 0;
203         ace.trustee = *sd->owner_sid;
204         ace.access_mask = 0;
205
206         if (mode & S_IRUSR) {
207                 if (mode & S_IWUSR) {
208                         ace.access_mask |= SEC_RIGHTS_FILE_ALL;
209                 } else {
210                         ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
211                 }
212         }
213         if (mode & S_IWUSR) {
214                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
215         }
216         if (ace.access_mask) {
217                 security_descriptor_dacl_add(sd, &ace);
218         }
219
220
221         /* setup group ACE */
222         ace.trustee = *sd->group_sid;
223         ace.access_mask = 0;
224         if (mode & S_IRGRP) {
225                 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
226         }
227         if (mode & S_IWGRP) {
228                 /* note that delete is not granted - this matches posix behaviour */
229                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
230         }
231         if (ace.access_mask) {
232                 security_descriptor_dacl_add(sd, &ace);
233         }
234
235         /* setup other ACE */
236         ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
237         ace.access_mask = 0;
238         if (mode & S_IROTH) {
239                 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
240         }
241         if (mode & S_IWOTH) {
242                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
243         }
244         if (ace.access_mask) {
245                 security_descriptor_dacl_add(sd, &ace);
246         }
247
248         /* setup system ACE */
249         ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
250         ace.access_mask = SEC_RIGHTS_FILE_ALL;
251         security_descriptor_dacl_add(sd, &ace);
252         
253         return NT_STATUS_OK;
254 }
255                                  
256
257 /*
258   omit any security_descriptor elements not specified in the given
259   secinfo flags
260 */
261 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
262 {
263         if (!(secinfo_flags & SECINFO_OWNER)) {
264                 sd->owner_sid = NULL;
265         }
266         if (!(secinfo_flags & SECINFO_GROUP)) {
267                 sd->group_sid = NULL;
268         }
269         if (!(secinfo_flags & SECINFO_DACL)) {
270                 sd->dacl = NULL;
271         }
272         if (!(secinfo_flags & SECINFO_SACL)) {
273                 sd->sacl = NULL;
274         }
275 }
276
277 /*
278   answer a setfileinfo for an ACL
279 */
280 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, 
281                       struct ntvfs_request *req,
282                       struct pvfs_filename *name, int fd, 
283                       uint32_t access_mask,
284                       union smb_setfileinfo *info)
285 {
286         uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
287         struct security_descriptor *new_sd, *sd, orig_sd;
288         NTSTATUS status = NT_STATUS_NOT_FOUND;
289         uid_t old_uid = -1;
290         gid_t old_gid = -1;
291         uid_t new_uid = -1;
292         gid_t new_gid = -1;
293         struct id_mapping *ids;
294         struct composite_context *ctx;
295
296         if (pvfs->acl_ops != NULL) {
297                 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
298         }
299         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
300                 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
301         }
302         if (!NT_STATUS_IS_OK(status)) {
303                 return status;
304         }
305
306         ids = talloc(req, struct id_mapping);
307         NT_STATUS_HAVE_NO_MEMORY(ids);
308         ids->unixid = NULL;
309         ids->sid = NULL;
310         ids->status = NT_STATUS_NONE_MAPPED;
311
312         new_sd = info->set_secdesc.in.sd;
313         orig_sd = *sd;
314
315         old_uid = name->st.st_uid;
316         old_gid = name->st.st_gid;
317
318         /* only set the elements that have been specified */
319         if (secinfo_flags & SECINFO_OWNER) {
320                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
321                         return NT_STATUS_ACCESS_DENIED;
322                 }
323                 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
324                         ids->sid = new_sd->owner_sid;
325                         ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
326                         NT_STATUS_HAVE_NO_MEMORY(ctx);
327                         status = wbc_sids_to_xids_recv(ctx, &ids);
328                         NT_STATUS_NOT_OK_RETURN(status);
329
330                         if (ids->unixid->type == ID_TYPE_BOTH ||
331                             ids->unixid->type == ID_TYPE_UID) {
332                                 new_uid = ids->unixid->id;
333                         }
334                 }
335                 sd->owner_sid = new_sd->owner_sid;
336         }
337         if (secinfo_flags & SECINFO_GROUP) {
338                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
339                         return NT_STATUS_ACCESS_DENIED;
340                 }
341                 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
342                         ids->sid = new_sd->group_sid;
343                         ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
344                         NT_STATUS_HAVE_NO_MEMORY(ctx);
345                         status = wbc_sids_to_xids_recv(ctx, &ids);
346                         NT_STATUS_NOT_OK_RETURN(status);
347
348                         if (ids->unixid->type == ID_TYPE_BOTH ||
349                             ids->unixid->type == ID_TYPE_GID) {
350                                 new_gid = ids->unixid->id;
351                         }
352
353                 }
354                 sd->group_sid = new_sd->group_sid;
355         }
356         if (secinfo_flags & SECINFO_DACL) {
357                 if (!(access_mask & SEC_STD_WRITE_DAC)) {
358                         return NT_STATUS_ACCESS_DENIED;
359                 }
360                 sd->dacl = new_sd->dacl;
361                 pvfs_translate_generic_bits(sd->dacl);
362         }
363         if (secinfo_flags & SECINFO_SACL) {
364                 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
365                         return NT_STATUS_ACCESS_DENIED;
366                 }
367                 sd->sacl = new_sd->sacl;
368                 pvfs_translate_generic_bits(sd->sacl);
369         }
370
371         if (new_uid == old_uid) {
372                 new_uid = -1;
373         }
374
375         if (new_gid == old_gid) {
376                 new_gid = -1;
377         }
378
379         /* if there's something to change try it */
380         if (new_uid != -1 || new_gid != -1) {
381                 int ret;
382                 if (fd == -1) {
383                         ret = chown(name->full_name, new_uid, new_gid);
384                 } else {
385                         ret = fchown(fd, new_uid, new_gid);
386                 }
387                 if (ret == -1) {
388                         return pvfs_map_errno(pvfs, errno);
389                 }
390         }
391
392         /* we avoid saving if the sd is the same. This means when clients
393            copy files and end up copying the default sd that we don't
394            needlessly use xattrs */
395         if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
396                 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
397         }
398
399         return status;
400 }
401
402
403 /*
404   answer a fileinfo query for the ACL
405 */
406 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, 
407                         struct ntvfs_request *req,
408                         struct pvfs_filename *name, int fd, 
409                         union smb_fileinfo *info)
410 {
411         NTSTATUS status = NT_STATUS_NOT_FOUND;
412         struct security_descriptor *sd;
413
414         if (pvfs->acl_ops) {
415                 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
416         }
417         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
418                 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
419         }
420         if (!NT_STATUS_IS_OK(status)) {
421                 return status;
422         }
423
424         normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
425
426         info->query_secdesc.out.sd = sd;
427
428         return NT_STATUS_OK;
429 }
430
431
432 /*
433   check the read only bit against any of the write access bits
434 */
435 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
436 {
437         if ((pvfs->flags & PVFS_FLAG_READONLY) &&
438             (access_mask & (SEC_FILE_WRITE_DATA |
439                             SEC_FILE_APPEND_DATA | 
440                             SEC_FILE_WRITE_EA | 
441                             SEC_FILE_WRITE_ATTRIBUTE | 
442                             SEC_STD_DELETE | 
443                             SEC_STD_WRITE_DAC | 
444                             SEC_STD_WRITE_OWNER | 
445                             SEC_DIR_DELETE_CHILD))) {
446                 return true;
447         }
448         return false;
449 }
450
451 /*
452   see if we are a member of the appropriate unix group
453  */
454 static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
455 {
456         int i, ngroups;
457         gid_t *groups;
458         if (getegid() == gid) {
459                 return true;
460         }
461         ngroups = getgroups(0, NULL);
462         if (ngroups == 0) {
463                 return false;
464         }
465         groups = talloc_array(pvfs, gid_t, ngroups);
466         if (groups == NULL) {
467                 return false;
468         }
469         if (getgroups(ngroups, groups) != ngroups) {
470                 talloc_free(groups);
471                 return false;
472         }
473         for (i=0; i<ngroups; i++) {
474                 if (groups[i] == gid) break;
475         }
476         talloc_free(groups);
477         return i < ngroups;
478 }
479
480 /*
481   default access check function based on unix permissions
482   doing this saves on building a full security descriptor
483   for the common case of access check on files with no 
484   specific NT ACL
485 */
486 NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, 
487                                 struct ntvfs_request *req,
488                                 struct pvfs_filename *name,
489                                 uint32_t *access_mask)
490 {
491         uid_t uid = geteuid();
492         uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL;
493         struct security_token *token = req->session_info->security_token;
494
495         if (pvfs_read_only(pvfs, *access_mask)) {
496                 return NT_STATUS_ACCESS_DENIED;
497         }
498
499         if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
500                 max_bits |= SEC_RIGHTS_PRIV_RESTORE;
501         }
502         if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
503                 max_bits |= SEC_RIGHTS_PRIV_BACKUP;
504         }
505
506         if (uid == name->st.st_uid) {
507                 max_bits |= SEC_STD_ALL;
508         }
509
510         if ((name->st.st_mode & S_IWOTH) ||
511             ((name->st.st_mode & S_IWGRP) && 
512              pvfs_group_member(pvfs, name->st.st_gid))) {
513                 max_bits |= SEC_STD_ALL;
514         }
515
516         if (uwrap_enabled()) {
517                 /* when running with the uid wrapper, files will be created
518                    owned by the ruid, but we may have a different simulated 
519                    euid. We need to force the permission bits as though the 
520                    files owner matches the euid */
521                 max_bits |= SEC_STD_ALL;
522         }
523
524         if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
525                 *access_mask |= max_bits;
526                 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
527         }
528
529         if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
530             security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
531                 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
532         }
533
534         if (*access_mask & ~max_bits) {
535                 DEBUG(0,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
536                          name->full_name, *access_mask, max_bits, *access_mask & ~max_bits));
537                 return NT_STATUS_ACCESS_DENIED;
538         }
539
540         if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
541                 /* on SMB, this bit is always granted, even if not
542                    asked for */
543                 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
544         }
545
546         return NT_STATUS_OK;
547 }
548
549
550 /*
551   check the security descriptor on a file, if any
552   
553   *access_mask is modified with the access actually granted
554 */
555 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, 
556                            struct ntvfs_request *req,
557                            struct pvfs_filename *name,
558                            uint32_t *access_mask)
559 {
560         struct security_token *token = req->session_info->security_token;
561         struct xattr_NTACL *acl;
562         NTSTATUS status;
563         struct security_descriptor *sd;
564
565         /* on SMB2 a blank access mask is always denied */
566         if (pvfs->ntvfs->ctx->protocol == PROTOCOL_SMB2 &&
567             *access_mask == 0) {
568                 return NT_STATUS_ACCESS_DENIED;
569         }
570
571         if (pvfs_read_only(pvfs, *access_mask)) {
572                 return NT_STATUS_ACCESS_DENIED;
573         }
574
575         acl = talloc(req, struct xattr_NTACL);
576         if (acl == NULL) {
577                 return NT_STATUS_NO_MEMORY;
578         }
579
580         /* expand the generic access bits to file specific bits */
581         *access_mask = pvfs_translate_mask(*access_mask);
582         if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
583                 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
584         }
585
586         status = pvfs_acl_load(pvfs, name, -1, acl);
587         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
588                 talloc_free(acl);
589                 return pvfs_access_check_unix(pvfs, req, name, access_mask);
590         }
591         if (!NT_STATUS_IS_OK(status)) {
592                 return status;
593         }
594
595         switch (acl->version) {
596         case 1:
597                 sd = acl->info.sd;
598                 break;
599         default:
600                 return NT_STATUS_INVALID_ACL;
601         }
602
603         /* check the acl against the required access mask */
604         status = sec_access_check(sd, token, *access_mask, access_mask);
605
606         if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
607                 /* on SMB, this bit is always granted, even if not
608                    asked for */
609                 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
610         }
611
612         talloc_free(acl);
613         
614         return status;
615 }
616
617
618 /*
619   a simplified interface to access check, designed for calls that
620   do not take or return an access check mask
621 */
622 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, 
623                                   struct ntvfs_request *req,
624                                   struct pvfs_filename *name,
625                                   uint32_t access_needed)
626 {
627         if (access_needed == 0) {
628                 return NT_STATUS_OK;
629         }
630         return pvfs_access_check(pvfs, req, name, &access_needed);
631 }
632
633 /*
634   access check for creating a new file/directory
635 */
636 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, 
637                                   struct ntvfs_request *req,
638                                   struct pvfs_filename *name,
639                                   uint32_t *access_mask)
640 {
641         struct pvfs_filename *parent;
642         NTSTATUS status;
643
644         status = pvfs_resolve_parent(pvfs, req, name, &parent);
645         if (!NT_STATUS_IS_OK(status)) {
646                 return status;
647         }
648
649         status = pvfs_access_check(pvfs, req, parent, access_mask);
650         if (!NT_STATUS_IS_OK(status)) {
651                 return status;
652         }
653
654         if (! ((*access_mask) & SEC_DIR_ADD_FILE)) {
655                 return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE);
656         }
657
658         return status;
659 }
660
661 /*
662   access check for creating a new file/directory - no access mask supplied
663 */
664 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs, 
665                                   struct ntvfs_request *req,
666                                   struct pvfs_filename *name,
667                                   uint32_t access_mask)
668 {
669         struct pvfs_filename *parent;
670         NTSTATUS status;
671
672         status = pvfs_resolve_parent(pvfs, req, name, &parent);
673         if (!NT_STATUS_IS_OK(status)) {
674                 return status;
675         }
676
677         return pvfs_access_check_simple(pvfs, req, parent, access_mask);
678 }
679
680
681 /*
682   determine if an ACE is inheritable
683 */
684 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
685                                  const struct security_ace *ace,
686                                  bool container)
687 {
688         if (!container) {
689                 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
690         }
691
692         if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
693                 return true;
694         }
695
696         if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
697             !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
698                 return true;
699         }
700
701         return false;
702 }
703
704 /*
705   this is the core of ACL inheritance. It copies any inheritable
706   aces from the parent SD to the child SD. Note that the algorithm 
707   depends on whether the child is a container or not
708 */
709 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, 
710                                       struct security_descriptor *parent_sd,
711                                       struct security_descriptor *sd,
712                                       bool container)
713 {
714         int i;
715         
716         for (i=0;i<parent_sd->dacl->num_aces;i++) {
717                 struct security_ace ace = parent_sd->dacl->aces[i];
718                 NTSTATUS status;
719                 const struct dom_sid *creator = NULL, *new_id = NULL;
720                 uint32_t orig_flags;
721
722                 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
723                         continue;
724                 }
725
726                 orig_flags = ace.flags;
727
728                 /* see the RAW-ACLS inheritance test for details on these rules */
729                 if (!container) {
730                         ace.flags = 0;
731                 } else {
732                         ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
733
734                         if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
735                                 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
736                         }
737                         if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
738                                 ace.flags = 0;
739                         }
740                 }
741
742                 /* the CREATOR sids are special when inherited */
743                 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
744                         creator = pvfs->sid_cache.creator_owner;
745                         new_id = sd->owner_sid;
746                 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
747                         creator = pvfs->sid_cache.creator_group;
748                         new_id = sd->group_sid;
749                 } else {
750                         new_id = &ace.trustee;
751                 }
752
753                 if (creator && container && 
754                     (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
755                         uint32_t flags = ace.flags;
756
757                         ace.trustee = *new_id;
758                         ace.flags = 0;
759                         status = security_descriptor_dacl_add(sd, &ace);
760                         if (!NT_STATUS_IS_OK(status)) {
761                                 return status;
762                         }
763
764                         ace.trustee = *creator;
765                         ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
766                         status = security_descriptor_dacl_add(sd, &ace);
767                 } else if (container && 
768                            !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
769                         status = security_descriptor_dacl_add(sd, &ace);
770                 } else {
771                         ace.trustee = *new_id;
772                         status = security_descriptor_dacl_add(sd, &ace);
773                 }
774
775                 if (!NT_STATUS_IS_OK(status)) {
776                         return status;
777                 }
778         }
779
780         return NT_STATUS_OK;
781 }
782
783
784
785 /*
786   setup an ACL on a new file/directory based on the inherited ACL from
787   the parent. If there is no inherited ACL then we don't set anything,
788   as the default ACL applies anyway
789 */
790 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, 
791                           struct ntvfs_request *req,
792                           struct pvfs_filename *name,
793                           int fd)
794 {
795         struct xattr_NTACL *acl;
796         NTSTATUS status;
797         struct pvfs_filename *parent;
798         struct security_descriptor *parent_sd, *sd;
799         bool container;
800         struct id_mapping *ids;
801         struct composite_context *ctx;
802
803         /* form the parents path */
804         status = pvfs_resolve_parent(pvfs, req, name, &parent);
805         if (!NT_STATUS_IS_OK(status)) {
806                 return status;
807         }
808
809         acl = talloc(req, struct xattr_NTACL);
810         if (acl == NULL) {
811                 return NT_STATUS_NO_MEMORY;
812         }
813
814         status = pvfs_acl_load(pvfs, parent, -1, acl);
815         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
816                 return NT_STATUS_OK;
817         }
818         if (!NT_STATUS_IS_OK(status)) {
819                 return status;
820         }
821
822         switch (acl->version) {
823         case 1:
824                 parent_sd = acl->info.sd;
825                 break;
826         default:
827                 return NT_STATUS_INVALID_ACL;
828         }
829
830         if (parent_sd == NULL ||
831             parent_sd->dacl == NULL ||
832             parent_sd->dacl->num_aces == 0) {
833                 /* go with the default ACL */
834                 return NT_STATUS_OK;
835         }
836
837         /* create the new sd */
838         sd = security_descriptor_initialise(req);
839         if (sd == NULL) {
840                 return NT_STATUS_NO_MEMORY;
841         }
842
843         ids = talloc_array(sd, struct id_mapping, 2);
844         NT_STATUS_HAVE_NO_MEMORY(ids);
845
846         ids[0].unixid = talloc(ids, struct unixid);
847         NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid);
848         ids[0].unixid->id = name->st.st_uid;
849         ids[0].unixid->type = ID_TYPE_UID;
850         ids[0].sid = NULL;
851         ids[0].status = NT_STATUS_NONE_MAPPED;
852
853         ids[1].unixid = talloc(ids, struct unixid);
854         NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid);
855         ids[1].unixid->id = name->st.st_gid;
856         ids[1].unixid->type = ID_TYPE_GID;
857         ids[1].sid = NULL;
858         ids[1].status = NT_STATUS_NONE_MAPPED;
859
860         ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
861         NT_STATUS_HAVE_NO_MEMORY(ctx);
862
863         status = wbc_xids_to_sids_recv(ctx, &ids);
864         NT_STATUS_NOT_OK_RETURN(status);
865
866         sd->owner_sid = talloc_steal(sd, ids[0].sid);
867         sd->group_sid = talloc_steal(sd, ids[1].sid);
868
869         sd->type |= SEC_DESC_DACL_PRESENT;
870
871         container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
872
873         /* fill in the aces from the parent */
874         status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
875         if (!NT_STATUS_IS_OK(status)) {
876                 return status;
877         }
878
879         /* if there is nothing to inherit then we fallback to the
880            default acl */
881         if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
882                 return NT_STATUS_OK;
883         }
884
885         acl->info.sd = sd;
886
887         status = pvfs_acl_save(pvfs, name, fd, acl);
888         
889         return status;
890 }
891
892 /*
893   return the maximum allowed access mask
894 */
895 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs, 
896                                      struct ntvfs_request *req,
897                                      struct pvfs_filename *name,
898                                      uint32_t *maximal_access)
899 {
900         *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
901         return pvfs_access_check(pvfs, req, name, maximal_access);
902 }