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 : 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 1329 : const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
74 : {
75 : int i;
76 :
77 1333 : for (i=0;i<num_backends;i++) {
78 1325 : if (strcmp(backends[i].ops->name, name) == 0) {
79 1321 : return backends[i].ops;
80 : }
81 : }
82 :
83 8 : return NULL;
84 : }
85 :
86 1321 : NTSTATUS pvfs_acl_init(void)
87 : {
88 : static bool initialized = false;
89 : #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
90 : STATIC_pvfs_acl_MODULES_PROTO;
91 1321 : init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
92 : init_module_fn *shared_init;
93 :
94 1321 : 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 476960 : static uint32_t pvfs_translate_mask(uint32_t access_mask)
112 : {
113 476960 : 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 476960 : 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 973 : static void pvfs_translate_generic_bits(struct security_acl *acl)
130 : {
131 : unsigned i;
132 :
133 973 : if (!acl) return;
134 :
135 5334 : for (i=0;i<acl->num_aces;i++) {
136 4365 : struct security_ace *ace = &acl->aces[i];
137 4365 : ace->access_mask = pvfs_translate_mask(ace->access_mask);
138 : }
139 : }
140 :
141 :
142 : /*
143 : setup a default ACL for a file
144 : */
145 776 : 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 : struct security_descriptor *sd;
151 : NTSTATUS status;
152 : struct security_ace ace;
153 : mode_t mode;
154 : struct id_map *ids;
155 :
156 776 : *psd = security_descriptor_initialise(req);
157 776 : if (*psd == NULL) {
158 0 : return NT_STATUS_NO_MEMORY;
159 : }
160 776 : sd = *psd;
161 :
162 776 : ids = talloc_zero_array(sd, struct id_map, 2);
163 776 : NT_STATUS_HAVE_NO_MEMORY(ids);
164 :
165 776 : ids[0].xid.id = name->st.st_uid;
166 776 : ids[0].xid.type = ID_TYPE_UID;
167 776 : ids[0].sid = NULL;
168 :
169 776 : ids[1].xid.id = name->st.st_gid;
170 776 : ids[1].xid.type = ID_TYPE_GID;
171 776 : ids[1].sid = NULL;
172 :
173 776 : status = wbc_xids_to_sids(ids, 2);
174 776 : NT_STATUS_NOT_OK_RETURN(status);
175 :
176 776 : sd->owner_sid = talloc_steal(sd, ids[0].sid);
177 776 : sd->group_sid = talloc_steal(sd, ids[1].sid);
178 :
179 776 : talloc_free(ids);
180 776 : sd->type |= SEC_DESC_DACL_PRESENT;
181 :
182 776 : 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 776 : ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
195 776 : ace.flags = 0;
196 776 : ace.trustee = *sd->owner_sid;
197 776 : ace.access_mask = 0;
198 :
199 776 : if (mode & S_IRUSR) {
200 776 : if (mode & S_IWUSR) {
201 776 : ace.access_mask |= SEC_RIGHTS_FILE_ALL;
202 : } else {
203 0 : ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
204 : }
205 : }
206 776 : if (mode & S_IWUSR) {
207 776 : ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
208 : }
209 776 : if (ace.access_mask) {
210 776 : security_descriptor_dacl_add(sd, &ace);
211 : }
212 :
213 :
214 : /* setup group ACE */
215 776 : ace.trustee = *sd->group_sid;
216 776 : ace.access_mask = 0;
217 776 : if (mode & S_IRGRP) {
218 776 : ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
219 : }
220 776 : 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 776 : if (ace.access_mask) {
225 776 : security_descriptor_dacl_add(sd, &ace);
226 : }
227 :
228 : /* setup other ACE */
229 776 : ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
230 776 : ace.access_mask = 0;
231 776 : if (mode & S_IROTH) {
232 776 : ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
233 : }
234 776 : if (mode & S_IWOTH) {
235 1 : ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
236 : }
237 776 : if (ace.access_mask) {
238 776 : security_descriptor_dacl_add(sd, &ace);
239 : }
240 :
241 : /* setup system ACE */
242 776 : ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
243 776 : ace.access_mask = SEC_RIGHTS_FILE_ALL;
244 776 : security_descriptor_dacl_add(sd, &ace);
245 :
246 776 : 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 368740 : static bool pvfs_privileged_access(uid_t uid)
271 : {
272 : uid_t euid;
273 :
274 368740 : if (uid_wrapper_enabled()) {
275 368740 : setenv("UID_WRAPPER_MYUID", "1", 1);
276 : }
277 :
278 368740 : euid = geteuid();
279 :
280 368740 : if (uid_wrapper_enabled()) {
281 368740 : unsetenv("UID_WRAPPER_MYUID");
282 : }
283 :
284 368740 : return (uid == euid);
285 : }
286 :
287 : /*
288 : answer a setfileinfo for an ACL
289 : */
290 973 : 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 973 : uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
297 : struct security_descriptor *new_sd, *sd, orig_sd;
298 973 : NTSTATUS status = NT_STATUS_NOT_FOUND;
299 973 : uid_t old_uid = -1;
300 973 : gid_t old_gid = -1;
301 973 : uid_t new_uid = -1;
302 973 : gid_t new_gid = -1;
303 : struct id_map *ids;
304 :
305 973 : if (pvfs->acl_ops != NULL) {
306 973 : status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
307 : }
308 973 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
309 552 : status = pvfs_default_acl(pvfs, req, name, fd, &sd);
310 : }
311 973 : if (!NT_STATUS_IS_OK(status)) {
312 0 : return status;
313 : }
314 :
315 973 : ids = talloc(req, struct id_map);
316 973 : NT_STATUS_HAVE_NO_MEMORY(ids);
317 973 : ZERO_STRUCT(ids->xid);
318 973 : ids->sid = NULL;
319 973 : ids->status = ID_UNKNOWN;
320 :
321 973 : new_sd = info->set_secdesc.in.sd;
322 973 : orig_sd = *sd;
323 :
324 973 : old_uid = name->st.st_uid;
325 973 : old_gid = name->st.st_gid;
326 :
327 : /* only set the elements that have been specified */
328 973 : if (secinfo_flags & SECINFO_OWNER) {
329 85 : if (!(access_mask & SEC_STD_WRITE_OWNER)) {
330 0 : return NT_STATUS_ACCESS_DENIED;
331 : }
332 85 : if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
333 65 : ids->sid = new_sd->owner_sid;
334 65 : status = wbc_sids_to_xids(ids, 1);
335 65 : NT_STATUS_NOT_OK_RETURN(status);
336 :
337 89 : if (ids->xid.type == ID_TYPE_BOTH ||
338 24 : ids->xid.type == ID_TYPE_UID) {
339 65 : new_uid = ids->xid.id;
340 : }
341 : }
342 85 : sd->owner_sid = new_sd->owner_sid;
343 : }
344 :
345 973 : if (secinfo_flags & SECINFO_GROUP) {
346 45 : if (!(access_mask & SEC_STD_WRITE_OWNER)) {
347 0 : return NT_STATUS_ACCESS_DENIED;
348 : }
349 45 : if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
350 41 : ids->sid = new_sd->group_sid;
351 41 : status = wbc_sids_to_xids(ids, 1);
352 41 : NT_STATUS_NOT_OK_RETURN(status);
353 :
354 41 : if (ids->xid.type == ID_TYPE_BOTH ||
355 0 : ids->xid.type == ID_TYPE_GID) {
356 41 : new_gid = ids->xid.id;
357 : }
358 :
359 : }
360 45 : sd->group_sid = new_sd->group_sid;
361 : }
362 :
363 973 : if (secinfo_flags & SECINFO_DACL) {
364 973 : if (!(access_mask & SEC_STD_WRITE_DAC)) {
365 0 : return NT_STATUS_ACCESS_DENIED;
366 : }
367 973 : sd->dacl = new_sd->dacl;
368 973 : pvfs_translate_generic_bits(sd->dacl);
369 973 : sd->type |= SEC_DESC_DACL_PRESENT;
370 : }
371 :
372 973 : if (secinfo_flags & SECINFO_SACL) {
373 0 : if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
374 0 : return NT_STATUS_ACCESS_DENIED;
375 : }
376 0 : sd->sacl = new_sd->sacl;
377 0 : pvfs_translate_generic_bits(sd->sacl);
378 0 : sd->type |= SEC_DESC_SACL_PRESENT;
379 : }
380 :
381 973 : if (secinfo_flags & SECINFO_PROTECTED_DACL) {
382 41 : if (new_sd->type & SEC_DESC_DACL_PROTECTED) {
383 41 : sd->type |= SEC_DESC_DACL_PROTECTED;
384 : } else {
385 0 : sd->type &= ~SEC_DESC_DACL_PROTECTED;
386 : }
387 : }
388 :
389 973 : 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 973 : if (new_uid == old_uid) {
398 12 : new_uid = -1;
399 : }
400 :
401 973 : if (new_gid == old_gid) {
402 0 : new_gid = -1;
403 : }
404 :
405 : /* if there's something to change try it */
406 973 : if (new_uid != -1 || new_gid != -1) {
407 : int ret;
408 53 : if (fd == -1) {
409 46 : ret = chown(name->full_name, new_uid, new_gid);
410 : } else {
411 7 : ret = fchown(fd, new_uid, new_gid);
412 : }
413 53 : if (errno == EPERM) {
414 53 : if (pvfs_privileged_access(name->st.st_uid)) {
415 53 : 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 : 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 53 : 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 973 : if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
443 585 : status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
444 : }
445 :
446 973 : 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 : 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 841282 : static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
483 : {
484 841282 : 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 841282 : 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 : int i, ngroups;
504 : 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 368687 : 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 368687 : uint32_t max_bits = 0;
541 368687 : struct security_token *token = req->session_info->security_token;
542 :
543 368687 : if (pvfs_read_only(pvfs, *access_mask)) {
544 0 : return NT_STATUS_ACCESS_DENIED;
545 : }
546 :
547 368687 : if (name == NULL) {
548 0 : max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
549 368687 : } else if (pvfs_privileged_access(name->st.st_uid)) {
550 : /* use the IxUSR bits */
551 368687 : if ((name->st.st_mode & S_IWUSR)) {
552 368687 : 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 368687 : if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
573 340 : *access_mask |= max_bits;
574 340 : *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
575 : }
576 :
577 368776 : 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 368687 : 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 368687 : 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 368687 : 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 368687 : if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
598 : /* on SMB, this bit is always granted, even if not
599 : asked for */
600 163467 : *access_mask |= SEC_FILE_READ_ATTRIBUTE;
601 : }
602 :
603 368687 : 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 370944 : 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 370944 : struct security_token *token = req->session_info->security_token;
618 : struct xattr_NTACL *acl;
619 : NTSTATUS status;
620 : struct security_descriptor *sd;
621 370944 : bool allow_delete = false;
622 :
623 : /* on SMB2 a blank access mask is always denied */
624 578143 : if (pvfs->ntvfs->ctx->protocol >= PROTOCOL_SMB2_02 &&
625 207199 : *access_mask == 0) {
626 1 : return NT_STATUS_ACCESS_DENIED;
627 : }
628 :
629 370943 : if (pvfs_read_only(pvfs, *access_mask)) {
630 0 : return NT_STATUS_ACCESS_DENIED;
631 : }
632 :
633 741468 : if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
634 370570 : *access_mask & SEC_STD_DELETE) {
635 113202 : status = pvfs_access_check_parent(pvfs, req,
636 : name, SEC_DIR_DELETE_CHILD);
637 113202 : if (NT_STATUS_IS_OK(status)) {
638 113199 : allow_delete = true;
639 113199 : *access_mask &= ~SEC_STD_DELETE;
640 : }
641 : }
642 :
643 370943 : acl = talloc(req, struct xattr_NTACL);
644 370943 : if (acl == NULL) {
645 0 : return NT_STATUS_NO_MEMORY;
646 : }
647 :
648 : /* expand the generic access bits to file specific bits */
649 370943 : *access_mask = pvfs_translate_mask(*access_mask);
650 370943 : if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
651 163745 : *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
652 : }
653 :
654 370943 : status = pvfs_acl_load(pvfs, name, -1, acl);
655 370943 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
656 368687 : talloc_free(acl);
657 368687 : status = pvfs_access_check_unix(pvfs, req, name, access_mask);
658 368687 : goto done;
659 : }
660 2256 : if (!NT_STATUS_IS_OK(status)) {
661 0 : return status;
662 : }
663 :
664 2256 : switch (acl->version) {
665 2256 : case 1:
666 2256 : sd = acl->info.sd;
667 2256 : break;
668 0 : default:
669 0 : return NT_STATUS_INVALID_ACL;
670 : }
671 :
672 : /* check the acl against the required access mask */
673 2256 : status = se_access_check(sd, token, *access_mask, access_mask);
674 2256 : 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 2256 : if (NT_STATUS_IS_OK(status)) {
680 2212 : name->allow_override = (pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) != 0;
681 : }
682 :
683 370942 : done:
684 370943 : if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
685 : /* on SMB, this bit is always granted, even if not
686 : asked for */
687 163745 : *access_mask |= SEC_FILE_READ_ATTRIBUTE;
688 : }
689 :
690 370943 : if (allow_delete) {
691 113199 : *access_mask |= SEC_STD_DELETE;
692 : }
693 :
694 370943 : 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 166186 : 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 166186 : if (access_needed == 0) {
708 32 : return NT_STATUS_OK;
709 : }
710 166154 : return pvfs_access_check(pvfs, req, name, &access_needed);
711 : }
712 :
713 : /*
714 : access check for creating a new file/directory
715 : */
716 101652 : 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 : struct pvfs_filename *parent;
724 : NTSTATUS status;
725 : uint32_t parent_mask;
726 101652 : bool allow_delete = false;
727 :
728 101652 : if (pvfs_read_only(pvfs, *access_mask)) {
729 0 : return NT_STATUS_ACCESS_DENIED;
730 : }
731 :
732 101652 : status = pvfs_resolve_parent(pvfs, req, name, &parent);
733 101652 : NT_STATUS_NOT_OK_RETURN(status);
734 :
735 101652 : if (container) {
736 4661 : parent_mask = SEC_DIR_ADD_SUBDIR;
737 : } else {
738 96991 : parent_mask = SEC_DIR_ADD_FILE;
739 : }
740 203067 : if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
741 101419 : *access_mask & SEC_STD_DELETE) {
742 85579 : parent_mask |= SEC_DIR_DELETE_CHILD;
743 : }
744 :
745 101652 : status = pvfs_access_check(pvfs, req, parent, &parent_mask);
746 101652 : if (NT_STATUS_IS_OK(status)) {
747 101646 : if (parent_mask & SEC_DIR_DELETE_CHILD) {
748 85573 : 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 101652 : if (*sd == NULL) {
766 101638 : status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
767 : }
768 :
769 101652 : talloc_free(parent);
770 101652 : if (!NT_STATUS_IS_OK(status)) {
771 0 : return status;
772 : }
773 :
774 : /* expand the generic access bits to file specific bits */
775 101652 : *access_mask = pvfs_translate_mask(*access_mask);
776 :
777 101652 : if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
778 233 : *access_mask |= SEC_RIGHTS_FILE_ALL;
779 233 : *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
780 : }
781 :
782 101652 : if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
783 : /* on SMB, this bit is always granted, even if not
784 : asked for */
785 35380 : *access_mask |= SEC_FILE_READ_ATTRIBUTE;
786 : }
787 :
788 101652 : if (allow_delete) {
789 85573 : *access_mask |= SEC_STD_DELETE;
790 : }
791 :
792 101652 : return NT_STATUS_OK;
793 : }
794 :
795 : /*
796 : access check for creating a new file/directory - no access mask supplied
797 : */
798 123020 : 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 : struct pvfs_filename *parent;
804 : NTSTATUS status;
805 :
806 123020 : status = pvfs_resolve_parent(pvfs, req, name, &parent);
807 123020 : if (!NT_STATUS_IS_OK(status)) {
808 3 : return status;
809 : }
810 :
811 123017 : status = pvfs_access_check_simple(pvfs, req, parent, access_mask);
812 123017 : if (NT_STATUS_IS_OK(status) && parent->allow_override) {
813 388 : name->allow_override = true;
814 : }
815 123017 : return status;
816 : }
817 :
818 :
819 : /*
820 : determine if an ACE is inheritable
821 : */
822 2739 : static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
823 : const struct security_ace *ace,
824 : bool container)
825 : {
826 2739 : if (!container) {
827 1057 : return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
828 : }
829 :
830 1682 : if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
831 1572 : return true;
832 : }
833 :
834 114 : 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 385 : 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 : int i;
853 :
854 3124 : for (i=0;i<parent_sd->dacl->num_aces;i++) {
855 2739 : struct security_ace ace = parent_sd->dacl->aces[i];
856 : NTSTATUS status;
857 2739 : const struct dom_sid *creator = NULL, *new_id = NULL;
858 : uint32_t orig_flags;
859 :
860 2739 : if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
861 218 : continue;
862 : }
863 :
864 2521 : orig_flags = ace.flags;
865 :
866 : /* see the RAW-ACLS inheritance test for details on these rules */
867 2521 : if (!container) {
868 947 : ace.flags = 0;
869 : } else {
870 1574 : ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
871 :
872 1574 : if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
873 2 : ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
874 : }
875 1574 : 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 2521 : if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
882 296 : creator = pvfs->sid_cache.creator_owner;
883 296 : new_id = sd->owner_sid;
884 2225 : } 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 2225 : new_id = &ace.trustee;
889 : }
890 :
891 2699 : if (creator && container &&
892 350 : (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
893 172 : uint32_t flags = ace.flags;
894 :
895 172 : ace.trustee = *new_id;
896 172 : ace.flags = 0;
897 172 : status = security_descriptor_dacl_add(sd, &ace);
898 172 : if (!NT_STATUS_IS_OK(status)) {
899 0 : return status;
900 : }
901 :
902 172 : ace.trustee = *creator;
903 172 : ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
904 172 : status = security_descriptor_dacl_add(sd, &ace);
905 3751 : } else if (container &&
906 1402 : !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
907 1398 : status = security_descriptor_dacl_add(sd, &ace);
908 : } else {
909 951 : ace.trustee = *new_id;
910 951 : status = security_descriptor_dacl_add(sd, &ace);
911 : }
912 :
913 2521 : if (!NT_STATUS_IS_OK(status)) {
914 0 : return status;
915 : }
916 : }
917 :
918 385 : 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 104225 : 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 : struct xattr_NTACL *acl;
936 : NTSTATUS status;
937 : struct security_descriptor *parent_sd, *sd;
938 : struct id_map *ids;
939 104225 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
940 :
941 104225 : *ret_sd = NULL;
942 :
943 104225 : acl = talloc(req, struct xattr_NTACL);
944 104225 : if (acl == NULL) {
945 0 : TALLOC_FREE(tmp_ctx);
946 0 : return NT_STATUS_NO_MEMORY;
947 : }
948 :
949 104225 : status = pvfs_acl_load(pvfs, parent, -1, acl);
950 104225 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
951 103840 : talloc_free(tmp_ctx);
952 103840 : return NT_STATUS_OK;
953 : }
954 385 : if (!NT_STATUS_IS_OK(status)) {
955 0 : TALLOC_FREE(tmp_ctx);
956 0 : return status;
957 : }
958 :
959 385 : switch (acl->version) {
960 385 : case 1:
961 385 : parent_sd = acl->info.sd;
962 385 : break;
963 0 : default:
964 0 : talloc_free(tmp_ctx);
965 0 : return NT_STATUS_INVALID_ACL;
966 : }
967 :
968 770 : if (parent_sd == NULL ||
969 770 : parent_sd->dacl == NULL ||
970 385 : 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 385 : sd = security_descriptor_initialise(req);
978 385 : if (sd == NULL) {
979 0 : TALLOC_FREE(tmp_ctx);
980 0 : return NT_STATUS_NO_MEMORY;
981 : }
982 :
983 385 : ids = talloc_array(sd, struct id_map, 2);
984 385 : if (ids == NULL) {
985 0 : TALLOC_FREE(tmp_ctx);
986 0 : return NT_STATUS_NO_MEMORY;
987 : }
988 :
989 385 : ids[0].xid.id = geteuid();
990 385 : ids[0].xid.type = ID_TYPE_UID;
991 385 : ids[0].sid = NULL;
992 385 : ids[0].status = ID_UNKNOWN;
993 :
994 385 : ids[1].xid.id = getegid();
995 385 : ids[1].xid.type = ID_TYPE_GID;
996 385 : ids[1].sid = NULL;
997 385 : ids[1].status = ID_UNKNOWN;
998 :
999 385 : status = wbc_xids_to_sids(ids, 2);
1000 385 : if (!NT_STATUS_IS_OK(status)) {
1001 0 : TALLOC_FREE(tmp_ctx);
1002 0 : return status;
1003 : }
1004 :
1005 385 : sd->owner_sid = talloc_steal(sd, ids[0].sid);
1006 385 : sd->group_sid = talloc_steal(sd, ids[1].sid);
1007 :
1008 385 : sd->type |= SEC_DESC_DACL_PRESENT;
1009 :
1010 : /* fill in the aces from the parent */
1011 385 : status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
1012 385 : 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 385 : if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
1020 14 : talloc_free(tmp_ctx);
1021 14 : return NT_STATUS_OK;
1022 : }
1023 :
1024 371 : *ret_sd = talloc_steal(mem_ctx, sd);
1025 :
1026 371 : talloc_free(tmp_ctx);
1027 371 : 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 2587 : NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
1037 : struct ntvfs_request *req,
1038 : struct pvfs_filename *name,
1039 : int fd)
1040 : {
1041 : struct xattr_NTACL acl;
1042 : NTSTATUS status;
1043 : struct security_descriptor *sd;
1044 : struct pvfs_filename *parent;
1045 : bool container;
1046 :
1047 : /* form the parents path */
1048 2587 : status = pvfs_resolve_parent(pvfs, req, name, &parent);
1049 2587 : NT_STATUS_NOT_OK_RETURN(status);
1050 :
1051 2587 : container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
1052 :
1053 2587 : status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
1054 2587 : if (!NT_STATUS_IS_OK(status)) {
1055 0 : talloc_free(parent);
1056 0 : return status;
1057 : }
1058 :
1059 2587 : if (sd == NULL) {
1060 2587 : 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 : }
|