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