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