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