r15069: - don't crash on a NULL acl
[kai/samba.git] / source4 / ntvfs / posix / pvfs_acl.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    POSIX NTVFS backend - ACL support
5
6    Copyright (C) Andrew Tridgell 2004
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.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
29
30 /*
31   map a single access_mask from generic to specific bits for files/dirs
32 */
33 static uint32_t pvfs_translate_mask(uint32_t access_mask)
34 {
35         if (access_mask & SEC_MASK_GENERIC) {
36                 if (access_mask & SEC_GENERIC_READ)    access_mask |= SEC_RIGHTS_FILE_READ;
37                 if (access_mask & SEC_GENERIC_WRITE)   access_mask |= SEC_RIGHTS_FILE_WRITE;
38                 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
39                 if (access_mask & SEC_GENERIC_ALL)     access_mask |= SEC_RIGHTS_FILE_ALL;
40                 access_mask &= ~SEC_MASK_GENERIC;
41         }
42         return access_mask;
43 }
44
45
46 /*
47   map any generic access bits in the given acl
48   this relies on the fact that the mappings for files and directories
49   are the same
50 */
51 static void pvfs_translate_generic_bits(struct security_acl *acl)
52 {
53         unsigned i;
54
55         if (!acl) return;
56
57         for (i=0;i<acl->num_aces;i++) {
58                 struct security_ace *ace = &acl->aces[i];
59                 ace->access_mask = pvfs_translate_mask(ace->access_mask);
60         }
61 }
62
63
64 /*
65   setup a default ACL for a file
66 */
67 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
68                                  struct ntvfs_request *req,
69                                  struct pvfs_filename *name, int fd, 
70                                  struct xattr_NTACL *acl)
71 {
72         struct security_descriptor *sd;
73         NTSTATUS status;
74         struct security_ace ace;
75         mode_t mode;
76
77         sd = security_descriptor_initialise(req);
78         if (sd == NULL) {
79                 return NT_STATUS_NO_MEMORY;
80         }
81
82         status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid);
83         if (!NT_STATUS_IS_OK(status)) {
84                 return status;
85         }
86         status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid);
87         if (!NT_STATUS_IS_OK(status)) {
88                 return status;
89         }
90
91         sd->type |= SEC_DESC_DACL_PRESENT;
92
93         mode = name->st.st_mode;
94
95         /*
96           we provide up to 4 ACEs
97             - Owner
98             - Group
99             - Everyone
100             - Administrator
101          */
102
103
104         /* setup owner ACE */
105         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
106         ace.flags = 0;
107         ace.trustee = *sd->owner_sid;
108         ace.access_mask = 0;
109
110         if (mode & S_IRUSR) {
111                 if (mode & S_IWUSR) {
112                         ace.access_mask |= SEC_RIGHTS_FILE_ALL;
113                 } else {
114                         ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
115                 }
116         }
117         if (mode & S_IWUSR) {
118                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
119         }
120         if (ace.access_mask) {
121                 security_descriptor_dacl_add(sd, &ace);
122         }
123
124
125         /* setup group ACE */
126         ace.trustee = *sd->group_sid;
127         ace.access_mask = 0;
128         if (mode & S_IRGRP) {
129                 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
130         }
131         if (mode & S_IWGRP) {
132                 /* note that delete is not granted - this matches posix behaviour */
133                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
134         }
135         if (ace.access_mask) {
136                 security_descriptor_dacl_add(sd, &ace);
137         }
138
139         /* setup other ACE */
140         ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
141         ace.access_mask = 0;
142         if (mode & S_IROTH) {
143                 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
144         }
145         if (mode & S_IWOTH) {
146                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
147         }
148         if (ace.access_mask) {
149                 security_descriptor_dacl_add(sd, &ace);
150         }
151
152         /* setup system ACE */
153         ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
154         ace.access_mask = SEC_RIGHTS_FILE_ALL;
155         security_descriptor_dacl_add(sd, &ace);
156         
157         acl->version = 1;
158         acl->info.sd = sd;
159
160         return NT_STATUS_OK;
161 }
162                                  
163
164 /*
165   omit any security_descriptor elements not specified in the given
166   secinfo flags
167 */
168 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
169 {
170         if (!(secinfo_flags & SECINFO_OWNER)) {
171                 sd->owner_sid = NULL;
172         }
173         if (!(secinfo_flags & SECINFO_GROUP)) {
174                 sd->group_sid = NULL;
175         }
176         if (!(secinfo_flags & SECINFO_DACL)) {
177                 sd->dacl = NULL;
178         }
179         if (!(secinfo_flags & SECINFO_SACL)) {
180                 sd->sacl = NULL;
181         }
182 }
183
184 /*
185   answer a setfileinfo for an ACL
186 */
187 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, 
188                       struct ntvfs_request *req,
189                       struct pvfs_filename *name, int fd, 
190                       uint32_t access_mask,
191                       union smb_setfileinfo *info)
192 {
193         struct xattr_NTACL *acl;
194         uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
195         struct security_descriptor *new_sd, *sd, orig_sd;
196         NTSTATUS status;
197         uid_t uid = -1;
198         gid_t gid = -1;
199
200         acl = talloc(req, struct xattr_NTACL);
201         if (acl == NULL) {
202                 return NT_STATUS_NO_MEMORY;
203         }
204
205         status = pvfs_acl_load(pvfs, name, fd, acl);
206         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
207                 status = pvfs_default_acl(pvfs, req, name, fd, acl);
208         }
209         if (!NT_STATUS_IS_OK(status)) {
210                 return status;
211         }
212
213         switch (acl->version) {
214         case 1:
215                 sd = acl->info.sd;
216                 break;
217         default:
218                 return NT_STATUS_INVALID_ACL;
219         }
220
221         new_sd = info->set_secdesc.in.sd;
222         orig_sd = *sd;
223
224         uid = name->st.st_uid;
225         gid = name->st.st_gid;
226
227         /* only set the elements that have been specified */
228         if ((secinfo_flags & SECINFO_OWNER) && 
229             !dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
230                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
231                         return NT_STATUS_ACCESS_DENIED;
232                 }
233                 sd->owner_sid = new_sd->owner_sid;
234                 status = sidmap_sid_to_unixuid(pvfs->sidmap, sd->owner_sid, &uid);
235                 if (!NT_STATUS_IS_OK(status)) {
236                         return status;
237                 }
238         }
239         if ((secinfo_flags & SECINFO_GROUP) &&
240             !dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
241                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
242                         return NT_STATUS_ACCESS_DENIED;
243                 }
244                 sd->group_sid = new_sd->group_sid;
245                 status = sidmap_sid_to_unixgid(pvfs->sidmap, sd->owner_sid, &gid);
246                 if (!NT_STATUS_IS_OK(status)) {
247                         return status;
248                 }
249         }
250         if (secinfo_flags & SECINFO_DACL) {
251                 if (!(access_mask & SEC_STD_WRITE_DAC)) {
252                         return NT_STATUS_ACCESS_DENIED;
253                 }
254                 sd->dacl = new_sd->dacl;
255                 pvfs_translate_generic_bits(sd->dacl);
256         }
257         if (secinfo_flags & SECINFO_SACL) {
258                 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
259                         return NT_STATUS_ACCESS_DENIED;
260                 }
261                 sd->sacl = new_sd->sacl;
262                 pvfs_translate_generic_bits(sd->sacl);
263         }
264
265         if (uid != -1 || gid != -1) {
266                 int ret;
267                 if (fd == -1) {
268                         ret = chown(name->full_name, uid, gid);
269                 } else {
270                         ret = fchown(fd, uid, gid);
271                 }
272                 if (ret == -1) {
273                         return pvfs_map_errno(pvfs, errno);
274                 }
275         }
276
277         /* we avoid saving if the sd is the same. This means when clients
278            copy files and end up copying the default sd that we don't
279            needlessly use xattrs */
280         if (!security_descriptor_equal(sd, &orig_sd)) {
281                 status = pvfs_acl_save(pvfs, name, fd, acl);
282         }
283
284         return status;
285 }
286
287
288 /*
289   answer a fileinfo query for the ACL
290 */
291 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, 
292                         struct ntvfs_request *req,
293                         struct pvfs_filename *name, int fd, 
294                         union smb_fileinfo *info)
295 {
296         struct xattr_NTACL *acl;
297         NTSTATUS status;
298         struct security_descriptor *sd;
299
300         acl = talloc(req, struct xattr_NTACL);
301         if (acl == NULL) {
302                 return NT_STATUS_NO_MEMORY;
303         }
304
305         status = pvfs_acl_load(pvfs, name, fd, acl);
306         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
307                 status = pvfs_default_acl(pvfs, req, name, fd, acl);
308         }
309         if (!NT_STATUS_IS_OK(status)) {
310                 return status;
311         }
312
313         switch (acl->version) {
314         case 1:
315                 sd = acl->info.sd;
316                 break;
317         default:
318                 return NT_STATUS_INVALID_ACL;
319         }
320
321         normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
322
323         info->query_secdesc.out.sd = sd;
324
325         return NT_STATUS_OK;
326 }
327
328
329 /*
330   default access check function based on unix permissions
331   doing this saves on building a full security descriptor
332   for the common case of access check on files with no 
333   specific NT ACL
334 */
335 NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, 
336                                 struct ntvfs_request *req,
337                                 struct pvfs_filename *name,
338                                 uint32_t *access_mask)
339 {
340         uid_t uid = geteuid();
341         uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL;
342
343         /* owner and root get extra permissions */
344         if (uid == 0 || uid == name->st.st_uid) {
345                 max_bits |= SEC_STD_ALL;
346         }
347
348         if (*access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
349                 *access_mask = max_bits;
350                 return NT_STATUS_OK;
351         }
352
353         if (*access_mask & ~max_bits) {
354                 return NT_STATUS_ACCESS_DENIED;
355         }
356
357         *access_mask |= SEC_FILE_READ_ATTRIBUTE;
358
359         return NT_STATUS_OK;
360 }
361
362
363 /*
364   check the security descriptor on a file, if any
365   
366   *access_mask is modified with the access actually granted
367 */
368 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, 
369                            struct ntvfs_request *req,
370                            struct pvfs_filename *name,
371                            uint32_t *access_mask)
372 {
373         struct security_token *token = req->session_info->security_token;
374         struct xattr_NTACL *acl;
375         NTSTATUS status;
376         struct security_descriptor *sd;
377
378         acl = talloc(req, struct xattr_NTACL);
379         if (acl == NULL) {
380                 return NT_STATUS_NO_MEMORY;
381         }
382
383         /* expand the generic access bits to file specific bits */
384         *access_mask = pvfs_translate_mask(*access_mask);
385         *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
386
387         status = pvfs_acl_load(pvfs, name, -1, acl);
388         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
389                 talloc_free(acl);
390                 return pvfs_access_check_unix(pvfs, req, name, access_mask);
391         }
392         if (!NT_STATUS_IS_OK(status)) {
393                 return status;
394         }
395
396         switch (acl->version) {
397         case 1:
398                 sd = acl->info.sd;
399                 break;
400         default:
401                 return NT_STATUS_INVALID_ACL;
402         }
403
404         /* check the acl against the required access mask */
405         status = sec_access_check(sd, token, *access_mask, access_mask);
406
407         /* this bit is always granted, even if not asked for */
408         *access_mask |= SEC_FILE_READ_ATTRIBUTE;
409
410         talloc_free(acl);
411         
412         return status;
413 }
414
415
416 /*
417   a simplified interface to access check, designed for calls that
418   do not take or return an access check mask
419 */
420 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, 
421                                   struct ntvfs_request *req,
422                                   struct pvfs_filename *name,
423                                   uint32_t access_needed)
424 {
425         if (access_needed == 0) {
426                 return NT_STATUS_OK;
427         }
428         return pvfs_access_check(pvfs, req, name, &access_needed);
429 }
430
431 /*
432   access check for creating a new file/directory
433 */
434 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, 
435                                   struct ntvfs_request *req,
436                                   struct pvfs_filename *name,
437                                   uint32_t *access_mask)
438 {
439         struct pvfs_filename *parent;
440         NTSTATUS status;
441
442         status = pvfs_resolve_parent(pvfs, req, name, &parent);
443         if (!NT_STATUS_IS_OK(status)) {
444                 return status;
445         }
446
447         status = pvfs_access_check(pvfs, req, parent, access_mask);
448         if (!NT_STATUS_IS_OK(status)) {
449                 return status;
450         }
451
452         if (! ((*access_mask) & SEC_DIR_ADD_FILE)) {
453                 return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE);
454         }
455
456         return status;
457 }
458
459 /*
460   access check for creating a new file/directory - no access mask supplied
461 */
462 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs, 
463                                   struct ntvfs_request *req,
464                                   struct pvfs_filename *name,
465                                   uint32_t access_mask)
466 {
467         struct pvfs_filename *parent;
468         NTSTATUS status;
469
470         status = pvfs_resolve_parent(pvfs, req, name, &parent);
471         if (!NT_STATUS_IS_OK(status)) {
472                 return status;
473         }
474
475         return pvfs_access_check_simple(pvfs, req, parent, access_mask);
476 }
477
478
479 /*
480   determine if an ACE is inheritable
481 */
482 static BOOL pvfs_inheritable_ace(struct pvfs_state *pvfs,
483                                  const struct security_ace *ace,
484                                  BOOL container)
485 {
486         if (!container) {
487                 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
488         }
489
490         if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
491                 return True;
492         }
493
494         if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
495             !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
496                 return True;
497         }
498
499         return False;
500 }
501
502 /*
503   this is the core of ACL inheritance. It copies any inheritable
504   aces from the parent SD to the child SD. Note that the algorithm 
505   depends on whether the child is a container or not
506 */
507 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, 
508                                       struct security_descriptor *parent_sd,
509                                       struct security_descriptor *sd,
510                                       BOOL container)
511 {
512         int i;
513         
514         for (i=0;i<parent_sd->dacl->num_aces;i++) {
515                 struct security_ace ace = parent_sd->dacl->aces[i];
516                 NTSTATUS status;
517                 const struct dom_sid *creator = NULL, *new_id = NULL;
518                 uint32_t orig_flags;
519
520                 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
521                         continue;
522                 }
523
524                 orig_flags = ace.flags;
525
526                 /* see the RAW-ACLS inheritance test for details on these rules */
527                 if (!container) {
528                         ace.flags = 0;
529                 } else {
530                         ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
531
532                         if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
533                                 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
534                         }
535                         if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
536                                 ace.flags = 0;
537                         }
538                 }
539
540                 /* the CREATOR sids are special when inherited */
541                 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
542                         creator = pvfs->sid_cache.creator_owner;
543                         new_id = sd->owner_sid;
544                 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
545                         creator = pvfs->sid_cache.creator_group;
546                         new_id = sd->group_sid;
547                 } else {
548                         new_id = &ace.trustee;
549                 }
550
551                 if (creator && container && 
552                     (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
553                         uint32_t flags = ace.flags;
554
555                         ace.trustee = *new_id;
556                         ace.flags = 0;
557                         status = security_descriptor_dacl_add(sd, &ace);
558                         if (!NT_STATUS_IS_OK(status)) {
559                                 return status;
560                         }
561
562                         ace.trustee = *creator;
563                         ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
564                         status = security_descriptor_dacl_add(sd, &ace);
565                 } else if (container && 
566                            !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
567                         status = security_descriptor_dacl_add(sd, &ace);
568                 } else {
569                         ace.trustee = *new_id;
570                         status = security_descriptor_dacl_add(sd, &ace);
571                 }
572
573                 if (!NT_STATUS_IS_OK(status)) {
574                         return status;
575                 }
576         }
577
578         return NT_STATUS_OK;
579 }
580
581
582
583 /*
584   setup an ACL on a new file/directory based on the inherited ACL from
585   the parent. If there is no inherited ACL then we don't set anything,
586   as the default ACL applies anyway
587 */
588 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, 
589                           struct ntvfs_request *req,
590                           struct pvfs_filename *name,
591                           int fd)
592 {
593         struct xattr_NTACL *acl;
594         NTSTATUS status;
595         struct pvfs_filename *parent;
596         struct security_descriptor *parent_sd, *sd;
597         BOOL container;
598
599         /* form the parents path */
600         status = pvfs_resolve_parent(pvfs, req, name, &parent);
601         if (!NT_STATUS_IS_OK(status)) {
602                 return status;
603         }
604
605         acl = talloc(req, struct xattr_NTACL);
606         if (acl == NULL) {
607                 return NT_STATUS_NO_MEMORY;
608         }
609
610         status = pvfs_acl_load(pvfs, parent, -1, acl);
611         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
612                 return NT_STATUS_OK;
613         }
614         if (!NT_STATUS_IS_OK(status)) {
615                 return status;
616         }
617
618         switch (acl->version) {
619         case 1:
620                 parent_sd = acl->info.sd;
621                 break;
622         default:
623                 return NT_STATUS_INVALID_ACL;
624         }
625
626         if (parent_sd == NULL ||
627             parent_sd->dacl == NULL ||
628             parent_sd->dacl->num_aces == 0) {
629                 /* go with the default ACL */
630                 return NT_STATUS_OK;
631         }
632
633         /* create the new sd */
634         sd = security_descriptor_initialise(req);
635         if (sd == NULL) {
636                 return NT_STATUS_NO_MEMORY;
637         }
638
639         status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid);
640         if (!NT_STATUS_IS_OK(status)) {
641                 return status;
642         }
643         status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid);
644         if (!NT_STATUS_IS_OK(status)) {
645                 return status;
646         }
647
648         sd->type |= SEC_DESC_DACL_PRESENT;
649
650         container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? True:False;
651
652         /* fill in the aces from the parent */
653         status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
654         if (!NT_STATUS_IS_OK(status)) {
655                 return status;
656         }
657
658         /* if there is nothing to inherit then we fallback to the
659            default acl */
660         if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
661                 return NT_STATUS_OK;
662         }
663
664         acl->info.sd = sd;
665
666         status = pvfs_acl_save(pvfs, name, fd, acl);
667         
668         return status;
669 }