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