source: trunk/server/source4/ntvfs/posix/pvfs_acl.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 26.4 KB
Line 
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 */
40static struct pvfs_acl_backend {
41 const struct pvfs_acl_ops *ops;
42} *backends = NULL;
43static 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*/
51NTSTATUS 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*/
79const 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
92NTSTATUS 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*/
117static 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*/
135static 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*/
151static 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*/
264static 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*/
283NTSTATUS 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*/
430NTSTATUS 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*/
459static 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 */
478static 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*/
512static 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*/
586NTSTATUS 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 bool allow_delete = false;
596
597 /* on SMB2 a blank access mask is always denied */
598 if (pvfs->ntvfs->ctx->protocol == PROTOCOL_SMB2 &&
599 *access_mask == 0) {
600 return NT_STATUS_ACCESS_DENIED;
601 }
602
603 if (pvfs_read_only(pvfs, *access_mask)) {
604 return NT_STATUS_ACCESS_DENIED;
605 }
606
607 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
608 *access_mask & SEC_STD_DELETE) {
609 status = pvfs_access_check_parent(pvfs, req,
610 name, SEC_DIR_DELETE_CHILD);
611 if (NT_STATUS_IS_OK(status)) {
612 allow_delete = true;
613 *access_mask &= ~SEC_STD_DELETE;
614 }
615 }
616
617 acl = talloc(req, struct xattr_NTACL);
618 if (acl == NULL) {
619 return NT_STATUS_NO_MEMORY;
620 }
621
622 /* expand the generic access bits to file specific bits */
623 *access_mask = pvfs_translate_mask(*access_mask);
624 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
625 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
626 }
627
628 status = pvfs_acl_load(pvfs, name, -1, acl);
629 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
630 talloc_free(acl);
631 status = pvfs_access_check_unix(pvfs, req, name, access_mask);
632 goto done;
633 }
634 if (!NT_STATUS_IS_OK(status)) {
635 return status;
636 }
637
638 switch (acl->version) {
639 case 1:
640 sd = acl->info.sd;
641 break;
642 default:
643 return NT_STATUS_INVALID_ACL;
644 }
645
646 /* check the acl against the required access mask */
647 status = se_access_check(sd, token, *access_mask, access_mask);
648 talloc_free(acl);
649done:
650 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
651 /* on SMB, this bit is always granted, even if not
652 asked for */
653 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
654 }
655
656 if (allow_delete) {
657 *access_mask |= SEC_STD_DELETE;
658 }
659
660 return status;
661}
662
663
664/*
665 a simplified interface to access check, designed for calls that
666 do not take or return an access check mask
667*/
668NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
669 struct ntvfs_request *req,
670 struct pvfs_filename *name,
671 uint32_t access_needed)
672{
673 if (access_needed == 0) {
674 return NT_STATUS_OK;
675 }
676 return pvfs_access_check(pvfs, req, name, &access_needed);
677}
678
679/*
680 access check for creating a new file/directory
681*/
682NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs,
683 struct ntvfs_request *req,
684 struct pvfs_filename *name,
685 uint32_t *access_mask,
686 bool container,
687 struct security_descriptor **sd)
688{
689 struct pvfs_filename *parent;
690 NTSTATUS status;
691 uint32_t parent_mask;
692 bool allow_delete = false;
693
694 if (pvfs_read_only(pvfs, *access_mask)) {
695 return NT_STATUS_ACCESS_DENIED;
696 }
697
698 status = pvfs_resolve_parent(pvfs, req, name, &parent);
699 NT_STATUS_NOT_OK_RETURN(status);
700
701 if (container) {
702 parent_mask = SEC_DIR_ADD_SUBDIR;
703 } else {
704 parent_mask = SEC_DIR_ADD_FILE;
705 }
706 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
707 *access_mask & SEC_STD_DELETE) {
708 parent_mask |= SEC_DIR_DELETE_CHILD;
709 }
710
711 status = pvfs_access_check(pvfs, req, parent, &parent_mask);
712 if (NT_STATUS_IS_OK(status)) {
713 if (parent_mask & SEC_DIR_DELETE_CHILD) {
714 allow_delete = true;
715 }
716 } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
717 /*
718 * on ACCESS_DENIED we get the rejected bits
719 * remove the non critical SEC_DIR_DELETE_CHILD
720 * and check if something else was rejected.
721 */
722 parent_mask &= ~SEC_DIR_DELETE_CHILD;
723 if (parent_mask != 0) {
724 return NT_STATUS_ACCESS_DENIED;
725 }
726 status = NT_STATUS_OK;
727 } else {
728 return status;
729 }
730
731 if (*sd == NULL) {
732 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
733 }
734
735 talloc_free(parent);
736 if (!NT_STATUS_IS_OK(status)) {
737 return status;
738 }
739
740 /* expand the generic access bits to file specific bits */
741 *access_mask = pvfs_translate_mask(*access_mask);
742
743 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
744 *access_mask |= SEC_RIGHTS_FILE_ALL;
745 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
746 }
747
748 if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
749 /* on SMB, this bit is always granted, even if not
750 asked for */
751 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
752 }
753
754 if (allow_delete) {
755 *access_mask |= SEC_STD_DELETE;
756 }
757
758 return NT_STATUS_OK;
759}
760
761/*
762 access check for creating a new file/directory - no access mask supplied
763*/
764NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
765 struct ntvfs_request *req,
766 struct pvfs_filename *name,
767 uint32_t access_mask)
768{
769 struct pvfs_filename *parent;
770 NTSTATUS status;
771
772 status = pvfs_resolve_parent(pvfs, req, name, &parent);
773 if (!NT_STATUS_IS_OK(status)) {
774 return status;
775 }
776
777 return pvfs_access_check_simple(pvfs, req, parent, access_mask);
778}
779
780
781/*
782 determine if an ACE is inheritable
783*/
784static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
785 const struct security_ace *ace,
786 bool container)
787{
788 if (!container) {
789 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
790 }
791
792 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
793 return true;
794 }
795
796 if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
797 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
798 return true;
799 }
800
801 return false;
802}
803
804/*
805 this is the core of ACL inheritance. It copies any inheritable
806 aces from the parent SD to the child SD. Note that the algorithm
807 depends on whether the child is a container or not
808*/
809static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs,
810 struct security_descriptor *parent_sd,
811 struct security_descriptor *sd,
812 bool container)
813{
814 int i;
815
816 for (i=0;i<parent_sd->dacl->num_aces;i++) {
817 struct security_ace ace = parent_sd->dacl->aces[i];
818 NTSTATUS status;
819 const struct dom_sid *creator = NULL, *new_id = NULL;
820 uint32_t orig_flags;
821
822 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
823 continue;
824 }
825
826 orig_flags = ace.flags;
827
828 /* see the RAW-ACLS inheritance test for details on these rules */
829 if (!container) {
830 ace.flags = 0;
831 } else {
832 ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
833
834 if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
835 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
836 }
837 if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
838 ace.flags = 0;
839 }
840 }
841
842 /* the CREATOR sids are special when inherited */
843 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
844 creator = pvfs->sid_cache.creator_owner;
845 new_id = sd->owner_sid;
846 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
847 creator = pvfs->sid_cache.creator_group;
848 new_id = sd->group_sid;
849 } else {
850 new_id = &ace.trustee;
851 }
852
853 if (creator && container &&
854 (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
855 uint32_t flags = ace.flags;
856
857 ace.trustee = *new_id;
858 ace.flags = 0;
859 status = security_descriptor_dacl_add(sd, &ace);
860 if (!NT_STATUS_IS_OK(status)) {
861 return status;
862 }
863
864 ace.trustee = *creator;
865 ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
866 status = security_descriptor_dacl_add(sd, &ace);
867 } else if (container &&
868 !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
869 status = security_descriptor_dacl_add(sd, &ace);
870 } else {
871 ace.trustee = *new_id;
872 status = security_descriptor_dacl_add(sd, &ace);
873 }
874
875 if (!NT_STATUS_IS_OK(status)) {
876 return status;
877 }
878 }
879
880 return NT_STATUS_OK;
881}
882
883
884
885/*
886 calculate the ACL on a new file/directory based on the inherited ACL
887 from the parent. If there is no inherited ACL then return a NULL
888 ACL, which means the default ACL should be used
889*/
890NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs,
891 TALLOC_CTX *mem_ctx,
892 struct ntvfs_request *req,
893 struct pvfs_filename *parent,
894 bool container,
895 struct security_descriptor **ret_sd)
896{
897 struct xattr_NTACL *acl;
898 NTSTATUS status;
899 struct security_descriptor *parent_sd, *sd;
900 struct id_map *ids;
901 struct composite_context *ctx;
902 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
903
904 *ret_sd = NULL;
905
906 acl = talloc(req, struct xattr_NTACL);
907 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(acl, tmp_ctx);
908
909 status = pvfs_acl_load(pvfs, parent, -1, acl);
910 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
911 talloc_free(tmp_ctx);
912 return NT_STATUS_OK;
913 }
914 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
915
916 switch (acl->version) {
917 case 1:
918 parent_sd = acl->info.sd;
919 break;
920 default:
921 talloc_free(tmp_ctx);
922 return NT_STATUS_INVALID_ACL;
923 }
924
925 if (parent_sd == NULL ||
926 parent_sd->dacl == NULL ||
927 parent_sd->dacl->num_aces == 0) {
928 /* go with the default ACL */
929 talloc_free(tmp_ctx);
930 return NT_STATUS_OK;
931 }
932
933 /* create the new sd */
934 sd = security_descriptor_initialise(req);
935 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sd, tmp_ctx);
936
937 ids = talloc_array(sd, struct id_map, 2);
938 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ids, tmp_ctx);
939
940 ids[0].xid.id = geteuid();
941 ids[0].xid.type = ID_TYPE_UID;
942 ids[0].sid = NULL;
943 ids[0].status = ID_UNKNOWN;
944
945 ids[1].xid.id = getegid();
946 ids[1].xid.type = ID_TYPE_GID;
947 ids[1].sid = NULL;
948 ids[1].status = ID_UNKNOWN;
949
950 ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
951 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(ctx, tmp_ctx);
952
953 status = wbc_xids_to_sids_recv(ctx, &ids);
954 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
955
956 sd->owner_sid = talloc_steal(sd, ids[0].sid);
957 sd->group_sid = talloc_steal(sd, ids[1].sid);
958
959 sd->type |= SEC_DESC_DACL_PRESENT;
960
961 /* fill in the aces from the parent */
962 status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
963 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
964
965 /* if there is nothing to inherit then we fallback to the
966 default acl */
967 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
968 talloc_free(tmp_ctx);
969 return NT_STATUS_OK;
970 }
971
972 *ret_sd = talloc_steal(mem_ctx, sd);
973
974 talloc_free(tmp_ctx);
975 return NT_STATUS_OK;
976}
977
978
979/*
980 setup an ACL on a new file/directory based on the inherited ACL from
981 the parent. If there is no inherited ACL then we don't set anything,
982 as the default ACL applies anyway
983*/
984NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
985 struct ntvfs_request *req,
986 struct pvfs_filename *name,
987 int fd)
988{
989 struct xattr_NTACL acl;
990 NTSTATUS status;
991 struct security_descriptor *sd;
992 struct pvfs_filename *parent;
993 bool container;
994
995 /* form the parents path */
996 status = pvfs_resolve_parent(pvfs, req, name, &parent);
997 NT_STATUS_NOT_OK_RETURN(status);
998
999 container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
1000
1001 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
1002 if (!NT_STATUS_IS_OK(status)) {
1003 talloc_free(parent);
1004 return status;
1005 }
1006
1007 if (sd == NULL) {
1008 return NT_STATUS_OK;
1009 }
1010
1011 acl.version = 1;
1012 acl.info.sd = sd;
1013
1014 status = pvfs_acl_save(pvfs, name, fd, &acl);
1015 talloc_free(sd);
1016 talloc_free(parent);
1017
1018 return status;
1019}
1020
1021/*
1022 return the maximum allowed access mask
1023*/
1024NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
1025 struct ntvfs_request *req,
1026 struct pvfs_filename *name,
1027 uint32_t *maximal_access)
1028{
1029 *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
1030 return pvfs_access_check(pvfs, req, name, maximal_access);
1031}
Note: See TracBrowser for help on using the repository browser.