r15118: - do access checks also when the owner and group are not changed
[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 old_uid = -1;
198         gid_t old_gid = -1;
199         uid_t new_uid = -1;
200         gid_t new_gid = -1;
201
202         acl = talloc(req, struct xattr_NTACL);
203         if (acl == NULL) {
204                 return NT_STATUS_NO_MEMORY;
205         }
206
207         status = pvfs_acl_load(pvfs, name, fd, acl);
208         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
209                 status = pvfs_default_acl(pvfs, req, name, fd, acl);
210         }
211         if (!NT_STATUS_IS_OK(status)) {
212                 return status;
213         }
214
215         switch (acl->version) {
216         case 1:
217                 sd = acl->info.sd;
218                 break;
219         default:
220                 return NT_STATUS_INVALID_ACL;
221         }
222
223         new_sd = info->set_secdesc.in.sd;
224         orig_sd = *sd;
225
226         old_uid = name->st.st_uid;
227         old_gid = name->st.st_gid;
228
229         /* only set the elements that have been specified */
230         if (secinfo_flags & SECINFO_OWNER) {
231                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
232                         return NT_STATUS_ACCESS_DENIED;
233                 }
234                 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
235                         status = sidmap_sid_to_unixuid(pvfs->sidmap, new_sd->owner_sid, &new_uid);
236                         NT_STATUS_NOT_OK_RETURN(status);
237                 }
238                 sd->owner_sid = new_sd->owner_sid;
239         }
240         if (secinfo_flags & SECINFO_GROUP) {
241                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
242                         return NT_STATUS_ACCESS_DENIED;
243                 }
244                 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
245                         status = sidmap_sid_to_unixgid(pvfs->sidmap, new_sd->group_sid, &new_gid);
246                         NT_STATUS_NOT_OK_RETURN(status);
247                 }
248                 sd->group_sid = new_sd->group_sid;
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 (new_uid == old_uid) {
266                 new_uid = -1;
267         }
268
269         if (new_gid == old_gid) {
270                 new_gid = -1;
271         }
272
273         /* if there's something to change try it */
274         if (new_uid != -1 || new_gid != -1) {
275                 int ret;
276                 if (fd == -1) {
277                         ret = chown(name->full_name, new_uid, new_gid);
278                 } else {
279                         ret = fchown(fd, new_uid, new_gid);
280                 }
281                 if (ret == -1) {
282                         return pvfs_map_errno(pvfs, errno);
283                 }
284         }
285
286         /* we avoid saving if the sd is the same. This means when clients
287            copy files and end up copying the default sd that we don't
288            needlessly use xattrs */
289         if (!security_descriptor_equal(sd, &orig_sd)) {
290                 status = pvfs_acl_save(pvfs, name, fd, acl);
291         }
292
293         return status;
294 }
295
296
297 /*
298   answer a fileinfo query for the ACL
299 */
300 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, 
301                         struct ntvfs_request *req,
302                         struct pvfs_filename *name, int fd, 
303                         union smb_fileinfo *info)
304 {
305         struct xattr_NTACL *acl;
306         NTSTATUS status;
307         struct security_descriptor *sd;
308
309         acl = talloc(req, struct xattr_NTACL);
310         if (acl == NULL) {
311                 return NT_STATUS_NO_MEMORY;
312         }
313
314         status = pvfs_acl_load(pvfs, name, fd, acl);
315         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
316                 status = pvfs_default_acl(pvfs, req, name, fd, acl);
317         }
318         if (!NT_STATUS_IS_OK(status)) {
319                 return status;
320         }
321
322         switch (acl->version) {
323         case 1:
324                 sd = acl->info.sd;
325                 break;
326         default:
327                 return NT_STATUS_INVALID_ACL;
328         }
329
330         normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
331
332         info->query_secdesc.out.sd = sd;
333
334         return NT_STATUS_OK;
335 }
336
337
338 /*
339   default access check function based on unix permissions
340   doing this saves on building a full security descriptor
341   for the common case of access check on files with no 
342   specific NT ACL
343 */
344 NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, 
345                                 struct ntvfs_request *req,
346                                 struct pvfs_filename *name,
347                                 uint32_t *access_mask)
348 {
349         uid_t uid = geteuid();
350         uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL;
351
352         /* owner and root get extra permissions */
353         if (uid == 0 || uid == name->st.st_uid) {
354                 max_bits |= SEC_STD_ALL;
355         }
356
357         if (*access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
358                 *access_mask = max_bits;
359                 return NT_STATUS_OK;
360         }
361
362         if (*access_mask & ~max_bits) {
363                 return NT_STATUS_ACCESS_DENIED;
364         }
365
366         *access_mask |= SEC_FILE_READ_ATTRIBUTE;
367
368         return NT_STATUS_OK;
369 }
370
371
372 /*
373   check the security descriptor on a file, if any
374   
375   *access_mask is modified with the access actually granted
376 */
377 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, 
378                            struct ntvfs_request *req,
379                            struct pvfs_filename *name,
380                            uint32_t *access_mask)
381 {
382         struct security_token *token = req->session_info->security_token;
383         struct xattr_NTACL *acl;
384         NTSTATUS status;
385         struct security_descriptor *sd;
386
387         acl = talloc(req, struct xattr_NTACL);
388         if (acl == NULL) {
389                 return NT_STATUS_NO_MEMORY;
390         }
391
392         /* expand the generic access bits to file specific bits */
393         *access_mask = pvfs_translate_mask(*access_mask);
394         *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
395
396         status = pvfs_acl_load(pvfs, name, -1, acl);
397         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
398                 talloc_free(acl);
399                 return pvfs_access_check_unix(pvfs, req, name, access_mask);
400         }
401         if (!NT_STATUS_IS_OK(status)) {
402                 return status;
403         }
404
405         switch (acl->version) {
406         case 1:
407                 sd = acl->info.sd;
408                 break;
409         default:
410                 return NT_STATUS_INVALID_ACL;
411         }
412
413         /* check the acl against the required access mask */
414         status = sec_access_check(sd, token, *access_mask, access_mask);
415
416         /* this bit is always granted, even if not asked for */
417         *access_mask |= SEC_FILE_READ_ATTRIBUTE;
418
419         talloc_free(acl);
420         
421         return status;
422 }
423
424
425 /*
426   a simplified interface to access check, designed for calls that
427   do not take or return an access check mask
428 */
429 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, 
430                                   struct ntvfs_request *req,
431                                   struct pvfs_filename *name,
432                                   uint32_t access_needed)
433 {
434         if (access_needed == 0) {
435                 return NT_STATUS_OK;
436         }
437         return pvfs_access_check(pvfs, req, name, &access_needed);
438 }
439
440 /*
441   access check for creating a new file/directory
442 */
443 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, 
444                                   struct ntvfs_request *req,
445                                   struct pvfs_filename *name,
446                                   uint32_t *access_mask)
447 {
448         struct pvfs_filename *parent;
449         NTSTATUS status;
450
451         status = pvfs_resolve_parent(pvfs, req, name, &parent);
452         if (!NT_STATUS_IS_OK(status)) {
453                 return status;
454         }
455
456         status = pvfs_access_check(pvfs, req, parent, access_mask);
457         if (!NT_STATUS_IS_OK(status)) {
458                 return status;
459         }
460
461         if (! ((*access_mask) & SEC_DIR_ADD_FILE)) {
462                 return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE);
463         }
464
465         return status;
466 }
467
468 /*
469   access check for creating a new file/directory - no access mask supplied
470 */
471 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs, 
472                                   struct ntvfs_request *req,
473                                   struct pvfs_filename *name,
474                                   uint32_t access_mask)
475 {
476         struct pvfs_filename *parent;
477         NTSTATUS status;
478
479         status = pvfs_resolve_parent(pvfs, req, name, &parent);
480         if (!NT_STATUS_IS_OK(status)) {
481                 return status;
482         }
483
484         return pvfs_access_check_simple(pvfs, req, parent, access_mask);
485 }
486
487
488 /*
489   determine if an ACE is inheritable
490 */
491 static BOOL pvfs_inheritable_ace(struct pvfs_state *pvfs,
492                                  const struct security_ace *ace,
493                                  BOOL container)
494 {
495         if (!container) {
496                 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
497         }
498
499         if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
500                 return True;
501         }
502
503         if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
504             !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
505                 return True;
506         }
507
508         return False;
509 }
510
511 /*
512   this is the core of ACL inheritance. It copies any inheritable
513   aces from the parent SD to the child SD. Note that the algorithm 
514   depends on whether the child is a container or not
515 */
516 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, 
517                                       struct security_descriptor *parent_sd,
518                                       struct security_descriptor *sd,
519                                       BOOL container)
520 {
521         int i;
522         
523         for (i=0;i<parent_sd->dacl->num_aces;i++) {
524                 struct security_ace ace = parent_sd->dacl->aces[i];
525                 NTSTATUS status;
526                 const struct dom_sid *creator = NULL, *new_id = NULL;
527                 uint32_t orig_flags;
528
529                 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
530                         continue;
531                 }
532
533                 orig_flags = ace.flags;
534
535                 /* see the RAW-ACLS inheritance test for details on these rules */
536                 if (!container) {
537                         ace.flags = 0;
538                 } else {
539                         ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
540
541                         if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
542                                 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
543                         }
544                         if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
545                                 ace.flags = 0;
546                         }
547                 }
548
549                 /* the CREATOR sids are special when inherited */
550                 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
551                         creator = pvfs->sid_cache.creator_owner;
552                         new_id = sd->owner_sid;
553                 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
554                         creator = pvfs->sid_cache.creator_group;
555                         new_id = sd->group_sid;
556                 } else {
557                         new_id = &ace.trustee;
558                 }
559
560                 if (creator && container && 
561                     (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
562                         uint32_t flags = ace.flags;
563
564                         ace.trustee = *new_id;
565                         ace.flags = 0;
566                         status = security_descriptor_dacl_add(sd, &ace);
567                         if (!NT_STATUS_IS_OK(status)) {
568                                 return status;
569                         }
570
571                         ace.trustee = *creator;
572                         ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
573                         status = security_descriptor_dacl_add(sd, &ace);
574                 } else if (container && 
575                            !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
576                         status = security_descriptor_dacl_add(sd, &ace);
577                 } else {
578                         ace.trustee = *new_id;
579                         status = security_descriptor_dacl_add(sd, &ace);
580                 }
581
582                 if (!NT_STATUS_IS_OK(status)) {
583                         return status;
584                 }
585         }
586
587         return NT_STATUS_OK;
588 }
589
590
591
592 /*
593   setup an ACL on a new file/directory based on the inherited ACL from
594   the parent. If there is no inherited ACL then we don't set anything,
595   as the default ACL applies anyway
596 */
597 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, 
598                           struct ntvfs_request *req,
599                           struct pvfs_filename *name,
600                           int fd)
601 {
602         struct xattr_NTACL *acl;
603         NTSTATUS status;
604         struct pvfs_filename *parent;
605         struct security_descriptor *parent_sd, *sd;
606         BOOL container;
607
608         /* form the parents path */
609         status = pvfs_resolve_parent(pvfs, req, name, &parent);
610         if (!NT_STATUS_IS_OK(status)) {
611                 return status;
612         }
613
614         acl = talloc(req, struct xattr_NTACL);
615         if (acl == NULL) {
616                 return NT_STATUS_NO_MEMORY;
617         }
618
619         status = pvfs_acl_load(pvfs, parent, -1, acl);
620         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
621                 return NT_STATUS_OK;
622         }
623         if (!NT_STATUS_IS_OK(status)) {
624                 return status;
625         }
626
627         switch (acl->version) {
628         case 1:
629                 parent_sd = acl->info.sd;
630                 break;
631         default:
632                 return NT_STATUS_INVALID_ACL;
633         }
634
635         if (parent_sd == NULL ||
636             parent_sd->dacl == NULL ||
637             parent_sd->dacl->num_aces == 0) {
638                 /* go with the default ACL */
639                 return NT_STATUS_OK;
640         }
641
642         /* create the new sd */
643         sd = security_descriptor_initialise(req);
644         if (sd == NULL) {
645                 return NT_STATUS_NO_MEMORY;
646         }
647
648         status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid);
649         if (!NT_STATUS_IS_OK(status)) {
650                 return status;
651         }
652         status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid);
653         if (!NT_STATUS_IS_OK(status)) {
654                 return status;
655         }
656
657         sd->type |= SEC_DESC_DACL_PRESENT;
658
659         container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? True:False;
660
661         /* fill in the aces from the parent */
662         status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
663         if (!NT_STATUS_IS_OK(status)) {
664                 return status;
665         }
666
667         /* if there is nothing to inherit then we fallback to the
668            default acl */
669         if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
670                 return NT_STATUS_OK;
671         }
672
673         acl->info.sd = sd;
674
675         status = pvfs_acl_save(pvfs, name, fd, acl);
676         
677         return status;
678 }