vfs_acl_common: Windows style default ACL
[samba.git] / source3 / modules / vfs_acl_common.c
1 /*
2  * Store Windows ACLs in data store - common functions.
3  * #included into modules/vfs_acl_xattr.c and modules/vfs_acl_tdb.c
4  *
5  * Copyright (C) Volker Lendecke, 2008
6  * Copyright (C) Jeremy Allison, 2009
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 "smbd/smbd.h"
23 #include "system/filesys.h"
24 #include "../libcli/security/security.h"
25 #include "../librpc/gen_ndr/ndr_security.h"
26 #include "../lib/util/bitmap.h"
27 #include "passdb/lookup_sid.h"
28
29 static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
30                         DATA_BLOB *pblob,
31                         uint16_t hash_type,
32                         uint8_t hash[XATTR_SD_HASH_SIZE]);
33
34 static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
35                         vfs_handle_struct *handle,
36                         files_struct *fsp,
37                         const struct smb_filename *smb_fname,
38                         DATA_BLOB *pblob);
39
40 static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
41                         files_struct *fsp,
42                         DATA_BLOB *pblob);
43
44 #define HASH_SECURITY_INFO (SECINFO_OWNER | \
45                                 SECINFO_GROUP | \
46                                 SECINFO_DACL | \
47                                 SECINFO_SACL)
48
49 enum default_acl_style {DEFAULT_ACL_POSIX, DEFAULT_ACL_WINDOWS};
50
51 static const struct enum_list default_acl_style[] = {
52         {DEFAULT_ACL_POSIX,     "posix"},
53         {DEFAULT_ACL_WINDOWS,   "windows"}
54 };
55
56 struct acl_common_config {
57         bool ignore_system_acls;
58         enum default_acl_style default_acl_style;
59 };
60
61 static bool init_acl_common_config(vfs_handle_struct *handle)
62 {
63         struct acl_common_config *config = NULL;
64
65         config = talloc_zero(handle->conn, struct acl_common_config);
66         if (config == NULL) {
67                 DBG_ERR("talloc_zero() failed\n");
68                 errno = ENOMEM;
69                 return false;
70         }
71
72         config->ignore_system_acls = lp_parm_bool(SNUM(handle->conn),
73                                                   ACL_MODULE_NAME,
74                                                   "ignore system acls",
75                                                   false);
76         config->default_acl_style = lp_parm_enum(SNUM(handle->conn),
77                                                  ACL_MODULE_NAME,
78                                                  "default acl style",
79                                                  default_acl_style,
80                                                  DEFAULT_ACL_POSIX);
81
82         SMB_VFS_HANDLE_SET_DATA(handle, config, NULL,
83                                 struct acl_common_config,
84                                 return false);
85
86         return true;
87 }
88
89
90 /*******************************************************************
91  Hash a security descriptor.
92 *******************************************************************/
93
94 static NTSTATUS hash_blob_sha256(DATA_BLOB blob,
95                                  uint8_t *hash)
96 {
97         SHA256_CTX tctx;
98
99         memset(hash, '\0', XATTR_SD_HASH_SIZE);
100
101         samba_SHA256_Init(&tctx);
102         samba_SHA256_Update(&tctx, blob.data, blob.length);
103         samba_SHA256_Final(hash, &tctx);
104
105         return NT_STATUS_OK;
106 }
107
108 /*******************************************************************
109  Hash a security descriptor.
110 *******************************************************************/
111
112 static NTSTATUS hash_sd_sha256(struct security_descriptor *psd,
113                         uint8_t *hash)
114 {
115         DATA_BLOB blob;
116         NTSTATUS status;
117
118         memset(hash, '\0', XATTR_SD_HASH_SIZE);
119         status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
120         if (!NT_STATUS_IS_OK(status)) {
121                 return status;
122         }
123         return hash_blob_sha256(blob, hash);
124 }
125
126 /*******************************************************************
127  Parse out a struct security_descriptor from a DATA_BLOB.
128 *******************************************************************/
129
130 static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
131                                TALLOC_CTX *mem_ctx,
132                                struct security_descriptor **ppdesc,
133                                uint16_t *p_hash_type,
134                                uint16_t *p_version,
135                                uint8_t hash[XATTR_SD_HASH_SIZE],
136                                uint8_t sys_acl_hash[XATTR_SD_HASH_SIZE])
137 {
138         struct xattr_NTACL xacl;
139         enum ndr_err_code ndr_err;
140         size_t sd_size;
141         TALLOC_CTX *frame = talloc_stackframe();
142
143         ndr_err = ndr_pull_struct_blob(pblob, frame, &xacl,
144                         (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);
145
146         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
147                 DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n",
148                         ndr_errstr(ndr_err)));
149                 TALLOC_FREE(frame);
150                 return ndr_map_error2ntstatus(ndr_err);
151         }
152
153         *p_version = xacl.version;
154
155         switch (xacl.version) {
156                 case 1:
157                         *ppdesc = make_sec_desc(mem_ctx, SD_REVISION,
158                                         xacl.info.sd->type | SEC_DESC_SELF_RELATIVE,
159                                         xacl.info.sd->owner_sid,
160                                         xacl.info.sd->group_sid,
161                                         xacl.info.sd->sacl,
162                                         xacl.info.sd->dacl,
163                                         &sd_size);
164                         /* No hash - null out. */
165                         *p_hash_type = XATTR_SD_HASH_TYPE_NONE;
166                         memset(hash, '\0', XATTR_SD_HASH_SIZE);
167                         break;
168                 case 2:
169                         *ppdesc = make_sec_desc(mem_ctx, SD_REVISION,
170                                         xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE,
171                                         xacl.info.sd_hs2->sd->owner_sid,
172                                         xacl.info.sd_hs2->sd->group_sid,
173                                         xacl.info.sd_hs2->sd->sacl,
174                                         xacl.info.sd_hs2->sd->dacl,
175                                         &sd_size);
176                         /* No hash - null out. */
177                         *p_hash_type = XATTR_SD_HASH_TYPE_NONE;
178                         memset(hash, '\0', XATTR_SD_HASH_SIZE);
179                         break;
180                 case 3:
181                         *ppdesc = make_sec_desc(mem_ctx, SD_REVISION,
182                                         xacl.info.sd_hs3->sd->type | SEC_DESC_SELF_RELATIVE,
183                                         xacl.info.sd_hs3->sd->owner_sid,
184                                         xacl.info.sd_hs3->sd->group_sid,
185                                         xacl.info.sd_hs3->sd->sacl,
186                                         xacl.info.sd_hs3->sd->dacl,
187                                         &sd_size);
188                         *p_hash_type = xacl.info.sd_hs3->hash_type;
189                         /* Current version 3 (if no sys acl hash available). */
190                         memcpy(hash, xacl.info.sd_hs3->hash, XATTR_SD_HASH_SIZE);
191                         break;
192                 case 4:
193                         *ppdesc = make_sec_desc(mem_ctx, SD_REVISION,
194                                         xacl.info.sd_hs4->sd->type | SEC_DESC_SELF_RELATIVE,
195                                         xacl.info.sd_hs4->sd->owner_sid,
196                                         xacl.info.sd_hs4->sd->group_sid,
197                                         xacl.info.sd_hs4->sd->sacl,
198                                         xacl.info.sd_hs4->sd->dacl,
199                                         &sd_size);
200                         *p_hash_type = xacl.info.sd_hs4->hash_type;
201                         /* Current version 4. */
202                         memcpy(hash, xacl.info.sd_hs4->hash, XATTR_SD_HASH_SIZE);
203                         memcpy(sys_acl_hash, xacl.info.sd_hs4->sys_acl_hash, XATTR_SD_HASH_SIZE);
204                         break;
205                 default:
206                         TALLOC_FREE(frame);
207                         return NT_STATUS_REVISION_MISMATCH;
208         }
209
210         TALLOC_FREE(frame);
211
212         return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
213 }
214
215 /*******************************************************************
216  Create a DATA_BLOB from a hash of the security descriptor storead at
217  the system layer and the NT ACL we wish to preserve
218 *******************************************************************/
219
220 static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
221                         DATA_BLOB *pblob,
222                         uint16_t hash_type,
223                         uint8_t hash[XATTR_SD_HASH_SIZE])
224 {
225         struct xattr_NTACL xacl;
226         struct security_descriptor_hash_v3 sd_hs3;
227         enum ndr_err_code ndr_err;
228         TALLOC_CTX *ctx = talloc_tos();
229
230         ZERO_STRUCT(xacl);
231         ZERO_STRUCT(sd_hs3);
232
233         xacl.version = 3;
234         xacl.info.sd_hs3 = &sd_hs3;
235         xacl.info.sd_hs3->sd = discard_const_p(struct security_descriptor, psd);
236         xacl.info.sd_hs3->hash_type = hash_type;
237         memcpy(&xacl.info.sd_hs3->hash[0], hash, XATTR_SD_HASH_SIZE);
238
239         ndr_err = ndr_push_struct_blob(
240                         pblob, ctx, &xacl,
241                         (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
242
243         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
244                 DEBUG(5, ("create_acl_blob: ndr_push_xattr_NTACL failed: %s\n",
245                         ndr_errstr(ndr_err)));
246                 return ndr_map_error2ntstatus(ndr_err);
247         }
248
249         return NT_STATUS_OK;
250 }
251
252 /*******************************************************************
253  Create a DATA_BLOB from a hash of the security descriptors 
254  (system and NT) stored at the system layer and the NT ACL we wish 
255  to preserve.
256 *******************************************************************/
257
258 static NTSTATUS create_sys_acl_blob(const struct security_descriptor *psd,
259                                     DATA_BLOB *pblob,
260                                     uint16_t hash_type,
261                                     uint8_t hash[XATTR_SD_HASH_SIZE],
262                                     const char *description,
263                                     uint8_t sys_acl_hash[XATTR_SD_HASH_SIZE])
264 {
265         struct xattr_NTACL xacl;
266         struct security_descriptor_hash_v4 sd_hs4;
267         enum ndr_err_code ndr_err;
268         TALLOC_CTX *ctx = talloc_tos();
269         NTTIME nttime_now;
270         struct timeval now = timeval_current();
271         nttime_now = timeval_to_nttime(&now);
272
273         ZERO_STRUCT(xacl);
274         ZERO_STRUCT(sd_hs4);
275
276         xacl.version = 4;
277         xacl.info.sd_hs4 = &sd_hs4;
278         xacl.info.sd_hs4->sd = discard_const_p(struct security_descriptor, psd);
279         xacl.info.sd_hs4->hash_type = hash_type;
280         memcpy(&xacl.info.sd_hs4->hash[0], hash, XATTR_SD_HASH_SIZE);
281         xacl.info.sd_hs4->description = description;
282         xacl.info.sd_hs4->time = nttime_now;
283         memcpy(&xacl.info.sd_hs4->sys_acl_hash[0], sys_acl_hash, XATTR_SD_HASH_SIZE);
284
285         ndr_err = ndr_push_struct_blob(
286                         pblob, ctx, &xacl,
287                         (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
288
289         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
290                 DEBUG(5, ("create_acl_blob: ndr_push_xattr_NTACL failed: %s\n",
291                         ndr_errstr(ndr_err)));
292                 return ndr_map_error2ntstatus(ndr_err);
293         }
294
295         return NT_STATUS_OK;
296 }
297
298 /*******************************************************************
299  Add in 3 inheritable components for a non-inheritable directory ACL.
300  CREATOR_OWNER/CREATOR_GROUP/WORLD.
301 *******************************************************************/
302
303 static NTSTATUS add_directory_inheritable_components(vfs_handle_struct *handle,
304                                 const char *name,
305                                 SMB_STRUCT_STAT *psbuf,
306                                 struct security_descriptor *psd)
307 {
308         struct connection_struct *conn = handle->conn;
309         int num_aces = (psd->dacl ? psd->dacl->num_aces : 0);
310         struct smb_filename smb_fname;
311         enum security_ace_type acltype;
312         uint32_t access_mask;
313         mode_t dir_mode;
314         mode_t file_mode;
315         mode_t mode;
316         struct security_ace *new_ace_list;
317
318         if (psd->dacl) {
319                 new_ace_list = talloc_zero_array(psd->dacl,
320                                                  struct security_ace,
321                                                  num_aces + 3);
322         } else {
323                 /*
324                  * make_sec_acl() at the bottom of this function
325                  * dupliates new_ace_list
326                  */
327                 new_ace_list = talloc_zero_array(talloc_tos(),
328                                                  struct security_ace,
329                                                  num_aces + 3);
330         }
331
332         if (new_ace_list == NULL) {
333                 return NT_STATUS_NO_MEMORY;
334         }
335
336         /* Fake a quick smb_filename. */
337         ZERO_STRUCT(smb_fname);
338         smb_fname.st = *psbuf;
339         smb_fname.base_name = discard_const_p(char, name);
340
341         dir_mode = unix_mode(conn,
342                         FILE_ATTRIBUTE_DIRECTORY, &smb_fname, NULL);
343         file_mode = unix_mode(conn,
344                         FILE_ATTRIBUTE_ARCHIVE, &smb_fname, NULL);
345
346         mode = dir_mode | file_mode;
347
348         DEBUG(10, ("add_directory_inheritable_components: directory %s, "
349                 "mode = 0%o\n",
350                 name,
351                 (unsigned int)mode ));
352
353         if (num_aces) {
354                 memcpy(new_ace_list, psd->dacl->aces,
355                         num_aces * sizeof(struct security_ace));
356         }
357         access_mask = map_canon_ace_perms(SNUM(conn), &acltype,
358                                 mode & 0700, false);
359
360         init_sec_ace(&new_ace_list[num_aces],
361                         &global_sid_Creator_Owner,
362                         acltype,
363                         access_mask,
364                         SEC_ACE_FLAG_CONTAINER_INHERIT|
365                                 SEC_ACE_FLAG_OBJECT_INHERIT|
366                                 SEC_ACE_FLAG_INHERIT_ONLY);
367         access_mask = map_canon_ace_perms(SNUM(conn), &acltype,
368                                 (mode << 3) & 0700, false);
369         init_sec_ace(&new_ace_list[num_aces+1],
370                         &global_sid_Creator_Group,
371                         acltype,
372                         access_mask,
373                         SEC_ACE_FLAG_CONTAINER_INHERIT|
374                                 SEC_ACE_FLAG_OBJECT_INHERIT|
375                                 SEC_ACE_FLAG_INHERIT_ONLY);
376         access_mask = map_canon_ace_perms(SNUM(conn), &acltype,
377                                 (mode << 6) & 0700, false);
378         init_sec_ace(&new_ace_list[num_aces+2],
379                         &global_sid_World,
380                         acltype,
381                         access_mask,
382                         SEC_ACE_FLAG_CONTAINER_INHERIT|
383                                 SEC_ACE_FLAG_OBJECT_INHERIT|
384                                 SEC_ACE_FLAG_INHERIT_ONLY);
385         if (psd->dacl) {
386                 psd->dacl->aces = new_ace_list;
387                 psd->dacl->num_aces += 3;
388                 psd->dacl->size += new_ace_list[num_aces].size +
389                         new_ace_list[num_aces+1].size +
390                         new_ace_list[num_aces+2].size;
391         } else {
392                 psd->dacl = make_sec_acl(psd,
393                                 NT4_ACL_REVISION,
394                                 3,
395                                 new_ace_list);
396                 if (psd->dacl == NULL) {
397                         return NT_STATUS_NO_MEMORY;
398                 }
399         }
400         return NT_STATUS_OK;
401 }
402
403 static NTSTATUS make_default_acl_posix(TALLOC_CTX *ctx,
404                                        const char *name,
405                                        SMB_STRUCT_STAT *psbuf,
406                                        struct security_descriptor **ppdesc)
407 {
408         struct dom_sid owner_sid, group_sid;
409         size_t size = 0;
410         struct security_ace aces[4];
411         uint32_t access_mask = 0;
412         mode_t mode = psbuf->st_ex_mode;
413         struct security_acl *new_dacl = NULL;
414         int idx = 0;
415
416         DBG_DEBUG("file %s mode = 0%o\n",name, (int)mode);
417
418         uid_to_sid(&owner_sid, psbuf->st_ex_uid);
419         gid_to_sid(&group_sid, psbuf->st_ex_gid);
420
421         /*
422          We provide up to 4 ACEs
423                 - Owner
424                 - Group
425                 - Everyone
426                 - NT System
427         */
428
429         if (mode & S_IRUSR) {
430                 if (mode & S_IWUSR) {
431                         access_mask |= SEC_RIGHTS_FILE_ALL;
432                 } else {
433                         access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
434                 }
435         }
436         if (mode & S_IWUSR) {
437                 access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
438         }
439
440         init_sec_ace(&aces[idx],
441                         &owner_sid,
442                         SEC_ACE_TYPE_ACCESS_ALLOWED,
443                         access_mask,
444                         0);
445         idx++;
446
447         access_mask = 0;
448         if (mode & S_IRGRP) {
449                 access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
450         }
451         if (mode & S_IWGRP) {
452                 /* note that delete is not granted - this matches posix behaviour */
453                 access_mask |= SEC_RIGHTS_FILE_WRITE;
454         }
455         if (access_mask) {
456                 init_sec_ace(&aces[idx],
457                         &group_sid,
458                         SEC_ACE_TYPE_ACCESS_ALLOWED,
459                         access_mask,
460                         0);
461                 idx++;
462         }
463
464         access_mask = 0;
465         if (mode & S_IROTH) {
466                 access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
467         }
468         if (mode & S_IWOTH) {
469                 access_mask |= SEC_RIGHTS_FILE_WRITE;
470         }
471         if (access_mask) {
472                 init_sec_ace(&aces[idx],
473                         &global_sid_World,
474                         SEC_ACE_TYPE_ACCESS_ALLOWED,
475                         access_mask,
476                         0);
477                 idx++;
478         }
479
480         init_sec_ace(&aces[idx],
481                         &global_sid_System,
482                         SEC_ACE_TYPE_ACCESS_ALLOWED,
483                         SEC_RIGHTS_FILE_ALL,
484                         0);
485         idx++;
486
487         new_dacl = make_sec_acl(ctx,
488                         NT4_ACL_REVISION,
489                         idx,
490                         aces);
491
492         if (!new_dacl) {
493                 return NT_STATUS_NO_MEMORY;
494         }
495
496         *ppdesc = make_sec_desc(ctx,
497                         SECURITY_DESCRIPTOR_REVISION_1,
498                         SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
499                         &owner_sid,
500                         &group_sid,
501                         NULL,
502                         new_dacl,
503                         &size);
504         if (!*ppdesc) {
505                 return NT_STATUS_NO_MEMORY;
506         }
507         return NT_STATUS_OK;
508 }
509
510 static NTSTATUS make_default_acl_windows(TALLOC_CTX *ctx,
511                                          const char *name,
512                                          SMB_STRUCT_STAT *psbuf,
513                                          struct security_descriptor **ppdesc)
514 {
515         struct dom_sid owner_sid, group_sid;
516         size_t size = 0;
517         struct security_ace aces[4];
518         uint32_t access_mask = 0;
519         mode_t mode = psbuf->st_ex_mode;
520         struct security_acl *new_dacl = NULL;
521         int idx = 0;
522
523         DBG_DEBUG("file [%s] mode [0%o]\n", name, (int)mode);
524
525         uid_to_sid(&owner_sid, psbuf->st_ex_uid);
526         gid_to_sid(&group_sid, psbuf->st_ex_gid);
527
528         /*
529          * We provide 2 ACEs:
530          * - Owner
531          * - NT System
532          */
533
534         if (mode & S_IRUSR) {
535                 if (mode & S_IWUSR) {
536                         access_mask |= SEC_RIGHTS_FILE_ALL;
537                 } else {
538                         access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
539                 }
540         }
541         if (mode & S_IWUSR) {
542                 access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
543         }
544
545         init_sec_ace(&aces[idx],
546                      &owner_sid,
547                      SEC_ACE_TYPE_ACCESS_ALLOWED,
548                      access_mask,
549                      0);
550         idx++;
551
552         init_sec_ace(&aces[idx],
553                      &global_sid_System,
554                      SEC_ACE_TYPE_ACCESS_ALLOWED,
555                      SEC_RIGHTS_FILE_ALL,
556                      0);
557         idx++;
558
559         new_dacl = make_sec_acl(ctx,
560                                 NT4_ACL_REVISION,
561                                 idx,
562                                 aces);
563
564         if (!new_dacl) {
565                 return NT_STATUS_NO_MEMORY;
566         }
567
568         *ppdesc = make_sec_desc(ctx,
569                                 SECURITY_DESCRIPTOR_REVISION_1,
570                                 SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
571                                 &owner_sid,
572                                 &group_sid,
573                                 NULL,
574                                 new_dacl,
575                                 &size);
576         if (!*ppdesc) {
577                 return NT_STATUS_NO_MEMORY;
578         }
579         return NT_STATUS_OK;
580 }
581
582 static NTSTATUS make_default_filesystem_acl(TALLOC_CTX *ctx,
583                                             struct acl_common_config *config,
584                                             const char *name,
585                                             SMB_STRUCT_STAT *psbuf,
586                                             struct security_descriptor **ppdesc)
587 {
588         NTSTATUS status;
589
590         switch (config->default_acl_style) {
591
592         case DEFAULT_ACL_POSIX:
593                 status =  make_default_acl_posix(ctx, name, psbuf, ppdesc);
594                 break;
595
596         case DEFAULT_ACL_WINDOWS:
597                 status =  make_default_acl_windows(ctx, name, psbuf, ppdesc);
598                 break;
599
600         default:
601                 DBG_ERR("unknown acl style %d", config->default_acl_style);
602                 status = NT_STATUS_INTERNAL_ERROR;
603                 break;
604         }
605
606         return status;
607 }
608
609 /**
610  * Validate an ACL blob
611  *
612  * This validates an ACL blob against the underlying filesystem ACL. If this
613  * function returns NT_STATUS_OK ppsd can be
614  *
615  * 1. the ACL from the blob (psd_from_fs=false), or
616  * 2. the ACL from the fs (psd_from_fs=true), or
617  * 3. NULL (!)
618  *
619  * If the return value is anything else then NT_STATUS_OK, ppsd is set to NULL
620  * and psd_from_fs set to false.
621  *
622  * Returning the underlying filesystem ACL in case no. 2 is really just an
623  * optimisation, because some validations have to fetch the filesytem ACL as
624  * part of the validation, so we already have it available and callers might
625  * need it as well.
626  **/
627 static NTSTATUS validate_nt_acl_blob(TALLOC_CTX *mem_ctx,
628                                      vfs_handle_struct *handle,
629                                      files_struct *fsp,
630                                      const struct smb_filename *smb_fname,
631                                      const DATA_BLOB *blob,
632                                      struct security_descriptor **ppsd,
633                                      bool *psd_is_from_fs)
634 {
635         NTSTATUS status;
636         uint16_t hash_type = XATTR_SD_HASH_TYPE_NONE;
637         uint16_t xattr_version = 0;
638         uint8_t hash[XATTR_SD_HASH_SIZE];
639         uint8_t sys_acl_hash[XATTR_SD_HASH_SIZE];
640         uint8_t hash_tmp[XATTR_SD_HASH_SIZE];
641         uint8_t sys_acl_hash_tmp[XATTR_SD_HASH_SIZE];
642         struct security_descriptor *psd = NULL;
643         struct security_descriptor *psd_blob = NULL;
644         struct security_descriptor *psd_fs = NULL;
645         char *sys_acl_blob_description = NULL;
646         DATA_BLOB sys_acl_blob = { 0 };
647         struct acl_common_config *config = NULL;
648
649         *ppsd = NULL;
650         *psd_is_from_fs = false;
651
652         SMB_VFS_HANDLE_GET_DATA(handle, config,
653                                 struct acl_common_config,
654                                 return NT_STATUS_UNSUCCESSFUL);
655
656         status = parse_acl_blob(blob,
657                                 mem_ctx,
658                                 &psd_blob,
659                                 &hash_type,
660                                 &xattr_version,
661                                 &hash[0],
662                                 &sys_acl_hash[0]);
663         if (!NT_STATUS_IS_OK(status)) {
664                 DBG_DEBUG("parse_acl_blob returned %s\n", nt_errstr(status));
665                 goto fail;
666         }
667
668         /* determine which type of xattr we got */
669         switch (xattr_version) {
670         case 1:
671         case 2:
672                 /* These xattr types are unilatteral, they do not
673                  * require confirmation of the hash.  In particular,
674                  * the NTVFS file server uses version 1, but
675                  * 'samba-tool ntacl' can set these as well */
676                 *ppsd = psd_blob;
677                 return NT_STATUS_OK;
678         case 3:
679         case 4:
680                 if (config->ignore_system_acls) {
681                         *ppsd = psd_blob;
682                         return NT_STATUS_OK;
683                 }
684
685                 break;
686         default:
687                 DBG_DEBUG("ACL blob revision mismatch (%u) for file %s\n",
688                           (unsigned int)hash_type, smb_fname->base_name);
689                 TALLOC_FREE(psd_blob);
690                 return NT_STATUS_OK;
691         }
692
693         /* determine which type of xattr we got */
694         if (hash_type != XATTR_SD_HASH_TYPE_SHA256) {
695                 DBG_DEBUG("ACL blob hash type (%u) unexpected for file %s\n",
696                           (unsigned int)hash_type, smb_fname->base_name);
697                 TALLOC_FREE(psd_blob);
698                 return NT_STATUS_OK;
699         }
700
701         /* determine which type of xattr we got */
702         switch (xattr_version) {
703         case 4:
704         {
705                 int ret;
706                 if (fsp) {
707                         /* Get the full underlying sd, then hash. */
708                         ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle,
709                                                                fsp,
710                                                                mem_ctx,
711                                                                &sys_acl_blob_description,
712                                                                &sys_acl_blob);
713                 } else {
714                         /* Get the full underlying sd, then hash. */
715                         ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle,
716                                                  smb_fname->base_name,
717                                                  mem_ctx,
718                                                  &sys_acl_blob_description,
719                                                  &sys_acl_blob);
720                 }
721
722                 /* If we fail to get the ACL blob (for some reason) then this
723                  * is not fatal, we just work based on the NT ACL only */
724                 if (ret == 0) {
725                         status = hash_blob_sha256(sys_acl_blob, sys_acl_hash_tmp);
726                         if (!NT_STATUS_IS_OK(status)) {
727                                 goto fail;
728                         }
729
730                         TALLOC_FREE(sys_acl_blob_description);
731                         TALLOC_FREE(sys_acl_blob.data);
732
733                         if (memcmp(&sys_acl_hash[0], &sys_acl_hash_tmp[0], 
734                                    XATTR_SD_HASH_SIZE) == 0) {
735                                 /* Hash matches, return blob sd. */
736                                 DBG_DEBUG("blob hash matches for file %s\n",
737                                           smb_fname->base_name);
738                                 *ppsd = psd_blob;
739                                 return NT_STATUS_OK;
740                         }
741                 }
742
743                 /* Otherwise, fall though and see if the NT ACL hash matches */
744         }
745         case 3:
746                 /* Get the full underlying sd for the hash
747                    or to return as backup. */
748                 if (fsp) {
749                         status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
750                                                           fsp,
751                                                           HASH_SECURITY_INFO,
752                                                           mem_ctx,
753                                                           &psd_fs);
754                 } else {
755                         status = SMB_VFS_NEXT_GET_NT_ACL(handle,
756                                                          smb_fname,
757                                                          HASH_SECURITY_INFO,
758                                                          mem_ctx,
759                                                          &psd_fs);
760                 }
761
762                 if (!NT_STATUS_IS_OK(status)) {
763                         DBG_DEBUG("get_next_acl for file %s returned %s\n",
764                                   smb_fname->base_name, nt_errstr(status));
765                         goto fail;
766                 }
767
768                 status = hash_sd_sha256(psd_fs, hash_tmp);
769                 if (!NT_STATUS_IS_OK(status)) {
770                         TALLOC_FREE(psd_blob);
771                         *ppsd = psd_fs;
772                         *psd_is_from_fs = true;
773                         return NT_STATUS_OK;
774                 }
775
776                 if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) {
777                         /* Hash matches, return blob sd. */
778                         DBG_DEBUG("blob hash matches for file %s\n",
779                                   smb_fname->base_name);
780                         *ppsd = psd_blob;
781                         return NT_STATUS_OK;
782                 }
783
784                 /* Hash doesn't match, return underlying sd. */
785                 DBG_DEBUG("blob hash does not match for file %s - returning "
786                           "file system SD mapping.\n",
787                           smb_fname->base_name);
788
789                 if (DEBUGLEVEL >= 10) {
790                         DBG_DEBUG("acl for blob hash for %s is:\n",
791                                   smb_fname->base_name);
792                         NDR_PRINT_DEBUG(security_descriptor, psd_fs);
793                 }
794
795                 TALLOC_FREE(psd_blob);
796                 *ppsd = psd_fs;
797                 *psd_is_from_fs = true;
798         }
799
800         return NT_STATUS_OK;
801
802 fail:
803         TALLOC_FREE(psd);
804         TALLOC_FREE(psd_blob);
805         TALLOC_FREE(psd_fs);
806         TALLOC_FREE(sys_acl_blob_description);
807         TALLOC_FREE(sys_acl_blob.data);
808         return status;
809 }
810
811 static NTSTATUS stat_fsp_or_smb_fname(vfs_handle_struct *handle,
812                                       files_struct *fsp,
813                                       const struct smb_filename *smb_fname,
814                                       SMB_STRUCT_STAT *sbuf,
815                                       SMB_STRUCT_STAT **psbuf)
816 {
817         NTSTATUS status;
818         int ret;
819
820         if (fsp) {
821                 status = vfs_stat_fsp(fsp);
822                 if (!NT_STATUS_IS_OK(status)) {
823                         return status;
824                 }
825                 *psbuf = &fsp->fsp_name->st;
826         } else {
827                 /*
828                  * https://bugzilla.samba.org/show_bug.cgi?id=11249
829                  *
830                  * We are currently guaranteed that 'name' here is a
831                  * smb_fname->base_name, which *cannot* contain a stream name
832                  * (':'). vfs_stat_smb_fname() splits a name into a base name +
833                  * stream name, which when we get here we know we've already
834                  * done.  So we have to call the stat or lstat VFS calls
835                  * directly here. Else, a base_name that contains a ':' (from a
836                  * demangled name) will get split again.
837                  *
838                  * FIXME.
839                  * This uglyness will go away once smb_fname is fully plumbed
840                  * through the VFS.
841                  */
842                 ret = vfs_stat_smb_basename(handle->conn,
843                                             smb_fname,
844                                             sbuf);
845                 if (ret == -1) {
846                         return map_nt_error_from_unix(errno);
847                 }
848         }
849
850         return NT_STATUS_OK;
851 }
852
853 /*******************************************************************
854  Pull a DATA_BLOB from an xattr given a pathname.
855  If the hash doesn't match, or doesn't exist - return the underlying
856  filesystem sd.
857 *******************************************************************/
858
859 static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
860                                     files_struct *fsp,
861                                     const struct smb_filename *smb_fname_in,
862                                     uint32_t security_info,
863                                     TALLOC_CTX *mem_ctx,
864                                     struct security_descriptor **ppdesc)
865 {
866         DATA_BLOB blob = data_blob_null;
867         NTSTATUS status;
868         struct security_descriptor *psd = NULL;
869         const struct smb_filename *smb_fname = NULL;
870         bool psd_is_from_fs = false;
871         struct acl_common_config *config = NULL;
872
873         SMB_VFS_HANDLE_GET_DATA(handle, config,
874                                 struct acl_common_config,
875                                 return NT_STATUS_UNSUCCESSFUL);
876
877         if (fsp && smb_fname_in == NULL) {
878                 smb_fname = fsp->fsp_name;
879         } else {
880                 smb_fname = smb_fname_in;
881         }
882
883         DEBUG(10, ("get_nt_acl_internal: name=%s\n", smb_fname->base_name));
884
885         status = get_acl_blob(mem_ctx, handle, fsp, smb_fname, &blob);
886         if (NT_STATUS_IS_OK(status)) {
887                 status = validate_nt_acl_blob(mem_ctx,
888                                               handle,
889                                               fsp,
890                                               smb_fname,
891                                               &blob,
892                                               &psd,
893                                               &psd_is_from_fs);
894                 TALLOC_FREE(blob.data);
895                 if (!NT_STATUS_IS_OK(status)) {
896                         DBG_DEBUG("ACL validation for [%s] failed\n",
897                                   smb_fname->base_name);
898                         goto fail;
899                 }
900         }
901
902         if (psd == NULL) {
903                 /* Get the full underlying sd, as we failed to get the
904                  * blob for the hash, or the revision/hash type wasn't
905                  * known */
906
907                 if (config->ignore_system_acls) {
908                         SMB_STRUCT_STAT sbuf;
909                         SMB_STRUCT_STAT *psbuf = &sbuf;
910
911                         status = stat_fsp_or_smb_fname(handle, fsp, smb_fname,
912                                                        &sbuf, &psbuf);
913                         if (!NT_STATUS_IS_OK(status)) {
914                                 goto fail;
915                         }
916
917                         status = make_default_filesystem_acl(
918                                 mem_ctx,
919                                 config,
920                                 smb_fname->base_name,
921                                 psbuf,
922                                 &psd);
923                         if (!NT_STATUS_IS_OK(status)) {
924                                 goto fail;
925                         }
926                 } else {
927                         if (fsp) {
928                                 status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
929                                                                   fsp,
930                                                                   security_info,
931                                                                   mem_ctx,
932                                                                   &psd);
933                         } else {
934                                 status = SMB_VFS_NEXT_GET_NT_ACL(handle,
935                                                                  smb_fname,
936                                                                  security_info,
937                                                                  mem_ctx,
938                                                                  &psd);
939                         }
940
941                         if (!NT_STATUS_IS_OK(status)) {
942                                 DBG_DEBUG("get_next_acl for file %s "
943                                           "returned %s\n",
944                                           smb_fname->base_name,
945                                           nt_errstr(status));
946                                 goto fail;
947                         }
948
949                         psd_is_from_fs = true;
950                 }
951         }
952
953         if (psd_is_from_fs) {
954                 SMB_STRUCT_STAT sbuf;
955                 SMB_STRUCT_STAT *psbuf = &sbuf;
956                 bool is_directory = false;
957
958                 /*
959                  * We're returning the underlying ACL from the
960                  * filesystem. If it's a directory, and has no
961                  * inheritable ACE entries we have to fake them.
962                  */
963
964                 status = stat_fsp_or_smb_fname(handle, fsp, smb_fname,
965                                                &sbuf, &psbuf);
966                 if (!NT_STATUS_IS_OK(status)) {
967                         goto fail;
968                 }
969
970                 is_directory = S_ISDIR(psbuf->st_ex_mode);
971
972                 if (is_directory && !sd_has_inheritable_components(psd, true)) {
973                         status = add_directory_inheritable_components(
974                                 handle,
975                                 smb_fname->base_name,
976                                 psbuf,
977                                 psd);
978                         if (!NT_STATUS_IS_OK(status)) {
979                                 goto fail;
980                         }
981                 }
982
983                 /*
984                  * The underlying POSIX module always sets the
985                  * ~SEC_DESC_DACL_PROTECTED bit, as ACLs can't be inherited in
986                  * this way under POSIX. Remove it for Windows-style ACLs.
987                  */
988                 psd->type &= ~SEC_DESC_DACL_PROTECTED;
989         }
990
991         if (!(security_info & SECINFO_OWNER)) {
992                 psd->owner_sid = NULL;
993         }
994         if (!(security_info & SECINFO_GROUP)) {
995                 psd->group_sid = NULL;
996         }
997         if (!(security_info & SECINFO_DACL)) {
998                 psd->type &= ~SEC_DESC_DACL_PRESENT;
999                 psd->dacl = NULL;
1000         }
1001         if (!(security_info & SECINFO_SACL)) {
1002                 psd->type &= ~SEC_DESC_SACL_PRESENT;
1003                 psd->sacl = NULL;
1004         }
1005
1006         if (DEBUGLEVEL >= 10) {
1007                 DEBUG(10,("get_nt_acl_internal: returning acl for %s is:\n",
1008                         smb_fname->base_name ));
1009                 NDR_PRINT_DEBUG(security_descriptor, psd);
1010         }
1011
1012         *ppdesc = psd;
1013
1014         return NT_STATUS_OK;
1015
1016 fail:
1017         TALLOC_FREE(psd);
1018         return status;
1019 }
1020
1021 /*********************************************************************
1022  Fetch a security descriptor given an fsp.
1023 *********************************************************************/
1024
1025 static NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle,
1026                                    files_struct *fsp,
1027                                    uint32_t security_info,
1028                                    TALLOC_CTX *mem_ctx,
1029                                    struct security_descriptor **ppdesc)
1030 {
1031         return get_nt_acl_internal(handle, fsp,
1032                                    NULL, security_info, mem_ctx, ppdesc);
1033 }
1034
1035 /*********************************************************************
1036  Fetch a security descriptor given a pathname.
1037 *********************************************************************/
1038
1039 static NTSTATUS get_nt_acl_common(vfs_handle_struct *handle,
1040                                   const struct smb_filename *smb_fname,
1041                                   uint32_t security_info,
1042                                   TALLOC_CTX *mem_ctx,
1043                                   struct security_descriptor **ppdesc)
1044 {
1045         return get_nt_acl_internal(handle,
1046                                 NULL,
1047                                 smb_fname,
1048                                 security_info,
1049                                 mem_ctx,
1050                                 ppdesc);
1051 }
1052
1053 /*********************************************************************
1054  Set the underlying ACL (e.g. POSIX ACLS, POSIX owner, etc)
1055 *********************************************************************/
1056 static NTSTATUS set_underlying_acl(vfs_handle_struct *handle, files_struct *fsp,
1057                                    struct security_descriptor *psd,
1058                                    uint32_t security_info_sent,
1059                                    bool chown_needed)
1060 {
1061         NTSTATUS status =
1062             SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
1063         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1064                 return status;
1065         }
1066
1067         /* We got access denied here. If we're already root,
1068            or we didn't need to do a chown, or the fsp isn't
1069            open with WRITE_OWNER access, just return. */
1070         if (get_current_uid(handle->conn) == 0 || chown_needed == false ||
1071             !(fsp->access_mask & SEC_STD_WRITE_OWNER)) {
1072                 return NT_STATUS_ACCESS_DENIED;
1073         }
1074
1075         DEBUG(10, ("fset_nt_acl_common: overriding chown on file %s "
1076                    "for sid %s\n",
1077                    fsp_str_dbg(fsp), sid_string_tos(psd->owner_sid)));
1078
1079         /* Ok, we failed to chown and we have
1080            SEC_STD_WRITE_OWNER access - override. */
1081         become_root();
1082         status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
1083         unbecome_root();
1084
1085         return status;
1086 }
1087
1088 /*********************************************************************
1089  Store a v3 security descriptor
1090 *********************************************************************/
1091 static NTSTATUS store_v3_blob(vfs_handle_struct *handle, files_struct *fsp,
1092                               struct security_descriptor *psd,
1093                               struct security_descriptor *pdesc_next,
1094                               uint8_t hash[XATTR_SD_HASH_SIZE])
1095 {
1096         NTSTATUS status;
1097         DATA_BLOB blob;
1098
1099         if (DEBUGLEVEL >= 10) {
1100                 DEBUG(10, ("fset_nt_acl_xattr: storing xattr sd for file %s\n",
1101                            fsp_str_dbg(fsp)));
1102                 NDR_PRINT_DEBUG(
1103                     security_descriptor,
1104                     discard_const_p(struct security_descriptor, psd));
1105
1106                 if (pdesc_next != NULL) {
1107                         DEBUG(10, ("fset_nt_acl_xattr: storing has in xattr sd "
1108                                    "based on \n"));
1109                         NDR_PRINT_DEBUG(
1110                             security_descriptor,
1111                             discard_const_p(struct security_descriptor,
1112                                             pdesc_next));
1113                 } else {
1114                         DEBUG(10,
1115                               ("fset_nt_acl_xattr: ignoring underlying sd\n"));
1116                 }
1117         }
1118         status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
1119         if (!NT_STATUS_IS_OK(status)) {
1120                 DEBUG(10, ("fset_nt_acl_xattr: create_acl_blob failed\n"));
1121                 return status;
1122         }
1123
1124         status = store_acl_blob_fsp(handle, fsp, &blob);
1125         return status;
1126 }
1127
1128 /*********************************************************************
1129  Store a security descriptor given an fsp.
1130 *********************************************************************/
1131
1132 static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
1133         uint32_t security_info_sent, const struct security_descriptor *orig_psd)
1134 {
1135         NTSTATUS status;
1136         int ret;
1137         DATA_BLOB blob, sys_acl_blob;
1138         struct security_descriptor *pdesc_next = NULL;
1139         struct security_descriptor *psd = NULL;
1140         uint8_t hash[XATTR_SD_HASH_SIZE];
1141         uint8_t sys_acl_hash[XATTR_SD_HASH_SIZE];
1142         bool chown_needed = false;
1143         char *sys_acl_description;
1144         TALLOC_CTX *frame = talloc_stackframe();
1145         bool ignore_file_system_acl = lp_parm_bool(
1146             SNUM(handle->conn), ACL_MODULE_NAME, "ignore system acls", false);
1147
1148         if (DEBUGLEVEL >= 10) {
1149                 DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
1150                           fsp_str_dbg(fsp)));
1151                 NDR_PRINT_DEBUG(security_descriptor,
1152                         discard_const_p(struct security_descriptor, orig_psd));
1153         }
1154
1155         status = get_nt_acl_internal(handle, fsp,
1156                         NULL,
1157                         SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL,
1158                                      frame,
1159                         &psd);
1160
1161         if (!NT_STATUS_IS_OK(status)) {
1162                 TALLOC_FREE(frame);
1163                 return status;
1164         }
1165
1166         psd->revision = orig_psd->revision;
1167         /* All our SD's are self relative. */
1168         psd->type = orig_psd->type | SEC_DESC_SELF_RELATIVE;
1169
1170         if ((security_info_sent & SECINFO_OWNER) && (orig_psd->owner_sid != NULL)) {
1171                 if (!dom_sid_equal(orig_psd->owner_sid, psd->owner_sid)) {
1172                         /* We're changing the owner. */
1173                         chown_needed = true;
1174                 }
1175                 psd->owner_sid = orig_psd->owner_sid;
1176         }
1177         if ((security_info_sent & SECINFO_GROUP) && (orig_psd->group_sid != NULL)) {
1178                 if (!dom_sid_equal(orig_psd->group_sid, psd->group_sid)) {
1179                         /* We're changing the group. */
1180                         chown_needed = true;
1181                 }
1182                 psd->group_sid = orig_psd->group_sid;
1183         }
1184         if (security_info_sent & SECINFO_DACL) {
1185                 if (security_descriptor_with_ms_nfs(orig_psd)) {
1186                         /*
1187                          * If the sd contains a MS NFS SID, do
1188                          * nothing, it's a chmod() request from OS X
1189                          * with AAPL context.
1190                          */
1191                         TALLOC_FREE(frame);
1192                         return NT_STATUS_OK;
1193                 }
1194                 psd->dacl = orig_psd->dacl;
1195                 psd->type |= SEC_DESC_DACL_PRESENT;
1196         }
1197         if (security_info_sent & SECINFO_SACL) {
1198                 psd->sacl = orig_psd->sacl;
1199                 psd->type |= SEC_DESC_SACL_PRESENT;
1200         }
1201
1202         if (ignore_file_system_acl) {
1203                 if (chown_needed) {
1204                         /* send only ownership stuff to lower layer */
1205                         security_info_sent &= (SECINFO_OWNER | SECINFO_GROUP);
1206                         status = set_underlying_acl(handle, fsp, psd,
1207                                                     security_info_sent, true);
1208                         if (!NT_STATUS_IS_OK(status)) {
1209                                 TALLOC_FREE(frame);
1210                                 return status;
1211                         }
1212                 }
1213                 ZERO_ARRAY(hash);
1214                 status = store_v3_blob(handle, fsp, psd, NULL, hash);
1215
1216                 TALLOC_FREE(frame);
1217                 return status;
1218         }
1219
1220         status = set_underlying_acl(handle, fsp, psd, security_info_sent,
1221                                     chown_needed);
1222         if (!NT_STATUS_IS_OK(status)) {
1223                 TALLOC_FREE(frame);
1224                 return status;
1225         }
1226
1227         /* Get the full underlying sd, then hash. */
1228         status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
1229                                           fsp,
1230                                           HASH_SECURITY_INFO,
1231                                           frame,
1232                                           &pdesc_next);
1233
1234         if (!NT_STATUS_IS_OK(status)) {
1235                 TALLOC_FREE(frame);
1236                 return status;
1237         }
1238
1239         status = hash_sd_sha256(pdesc_next, hash);
1240         if (!NT_STATUS_IS_OK(status)) {
1241                 TALLOC_FREE(frame);
1242                 return status;
1243         }
1244
1245         /* Get the full underlying sd, then hash. */
1246         ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle,
1247                                                fsp,
1248                                                frame,
1249                                                &sys_acl_description,
1250                                                &sys_acl_blob);
1251
1252         /* If we fail to get the ACL blob (for some reason) then this
1253          * is not fatal, we just work based on the NT ACL only */
1254         if (ret != 0) {
1255                 status = store_v3_blob(handle, fsp, psd, pdesc_next, hash);
1256
1257                 TALLOC_FREE(frame);
1258                 return status;
1259         }
1260
1261         status = hash_blob_sha256(sys_acl_blob, sys_acl_hash);
1262         if (!NT_STATUS_IS_OK(status)) {
1263                 TALLOC_FREE(frame);
1264                 return status;
1265         }
1266
1267         if (DEBUGLEVEL >= 10) {
1268                 DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s based on system ACL\n",
1269                           fsp_str_dbg(fsp)));
1270                 NDR_PRINT_DEBUG(security_descriptor,
1271                                 discard_const_p(struct security_descriptor, psd));
1272
1273                 DEBUG(10,("fset_nt_acl_xattr: storing hash in xattr sd based on system ACL and:\n"));
1274                 NDR_PRINT_DEBUG(security_descriptor,
1275                                 discard_const_p(struct security_descriptor, pdesc_next));
1276         }
1277
1278         /* We store hashes of both the sys ACL blob and the NT
1279          * security desciptor mapped from that ACL so as to improve
1280          * our chances against some inadvertant change breaking the
1281          * hash used */
1282         status = create_sys_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash, 
1283                                      sys_acl_description, sys_acl_hash);
1284         if (!NT_STATUS_IS_OK(status)) {
1285                 DEBUG(10, ("fset_nt_acl_xattr: create_sys_acl_blob failed\n"));
1286                 TALLOC_FREE(frame);
1287                 return status;
1288         }
1289
1290         status = store_acl_blob_fsp(handle, fsp, &blob);
1291
1292         TALLOC_FREE(frame);
1293         return status;
1294 }
1295
1296 static int acl_common_remove_object(vfs_handle_struct *handle,
1297                                         const char *path,
1298                                         bool is_directory)
1299 {
1300         connection_struct *conn = handle->conn;
1301         struct file_id id;
1302         files_struct *fsp = NULL;
1303         int ret = 0;
1304         char *parent_dir = NULL;
1305         const char *final_component = NULL;
1306         struct smb_filename local_fname;
1307         int saved_errno = 0;
1308         char *saved_dir = NULL;
1309
1310         saved_dir = vfs_GetWd(talloc_tos(),conn);
1311         if (!saved_dir) {
1312                 saved_errno = errno;
1313                 goto out;
1314         }
1315
1316         if (!parent_dirname(talloc_tos(), path,
1317                         &parent_dir, &final_component)) {
1318                 saved_errno = ENOMEM;
1319                 goto out;
1320         }
1321
1322         DEBUG(10,("acl_common_remove_object: removing %s %s/%s\n",
1323                 is_directory ? "directory" : "file",
1324                 parent_dir, final_component ));
1325
1326         /* cd into the parent dir to pin it. */
1327         ret = vfs_ChDir(conn, parent_dir);
1328         if (ret == -1) {
1329                 saved_errno = errno;
1330                 goto out;
1331         }
1332
1333         ZERO_STRUCT(local_fname);
1334         local_fname.base_name = discard_const_p(char, final_component);
1335
1336         /* Must use lstat here. */
1337         ret = SMB_VFS_LSTAT(conn, &local_fname);
1338         if (ret == -1) {
1339                 saved_errno = errno;
1340                 goto out;
1341         }
1342
1343         /* Ensure we have this file open with DELETE access. */
1344         id = vfs_file_id_from_sbuf(conn, &local_fname.st);
1345         for (fsp = file_find_di_first(conn->sconn, id); fsp;
1346                      fsp = file_find_di_next(fsp)) {
1347                 if (fsp->access_mask & DELETE_ACCESS &&
1348                                 fsp->delete_on_close) {
1349                         /* We did open this for delete,
1350                          * allow the delete as root.
1351                          */
1352                         break;
1353                 }
1354         }
1355
1356         if (!fsp) {
1357                 DEBUG(10,("acl_common_remove_object: %s %s/%s "
1358                         "not an open file\n",
1359                         is_directory ? "directory" : "file",
1360                         parent_dir, final_component ));
1361                 saved_errno = EACCES;
1362                 goto out;
1363         }
1364
1365         become_root();
1366         if (is_directory) {
1367                 ret = SMB_VFS_NEXT_RMDIR(handle, &local_fname);
1368         } else {
1369                 ret = SMB_VFS_NEXT_UNLINK(handle, &local_fname);
1370         }
1371         unbecome_root();
1372
1373         if (ret == -1) {
1374                 saved_errno = errno;
1375         }
1376
1377   out:
1378
1379         TALLOC_FREE(parent_dir);
1380
1381         if (saved_dir) {
1382                 vfs_ChDir(conn, saved_dir);
1383         }
1384         if (saved_errno) {
1385                 errno = saved_errno;
1386         }
1387         return ret;
1388 }
1389
1390 static int rmdir_acl_common(struct vfs_handle_struct *handle,
1391                                 const struct smb_filename *smb_fname)
1392 {
1393         int ret;
1394
1395         /* Try the normal rmdir first. */
1396         ret = SMB_VFS_NEXT_RMDIR(handle, smb_fname);
1397         if (ret == 0) {
1398                 return 0;
1399         }
1400         if (errno == EACCES || errno == EPERM) {
1401                 /* Failed due to access denied,
1402                    see if we need to root override. */
1403                 return acl_common_remove_object(handle,
1404                                                 smb_fname->base_name,
1405                                                 true);
1406         }
1407
1408         DEBUG(10,("rmdir_acl_common: unlink of %s failed %s\n",
1409                 smb_fname->base_name,
1410                 strerror(errno) ));
1411         return -1;
1412 }
1413
1414 static int unlink_acl_common(struct vfs_handle_struct *handle,
1415                         const struct smb_filename *smb_fname)
1416 {
1417         int ret;
1418
1419         /* Try the normal unlink first. */
1420         ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
1421         if (ret == 0) {
1422                 return 0;
1423         }
1424         if (errno == EACCES || errno == EPERM) {
1425                 /* Failed due to access denied,
1426                    see if we need to root override. */
1427
1428                 /* Don't do anything fancy for streams. */
1429                 if (smb_fname->stream_name) {
1430                         return -1;
1431                 }
1432                 return acl_common_remove_object(handle,
1433                                         smb_fname->base_name,
1434                                         false);
1435         }
1436
1437         DEBUG(10,("unlink_acl_common: unlink of %s failed %s\n",
1438                 smb_fname->base_name,
1439                 strerror(errno) ));
1440         return -1;
1441 }
1442
1443 static int chmod_acl_module_common(struct vfs_handle_struct *handle,
1444                         const struct smb_filename *smb_fname,
1445                         mode_t mode)
1446 {
1447         if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1448                 /* Only allow this on POSIX pathnames. */
1449                 return SMB_VFS_NEXT_CHMOD(handle, smb_fname, mode);
1450         }
1451         return 0;
1452 }
1453
1454 static int fchmod_acl_module_common(struct vfs_handle_struct *handle,
1455                         struct files_struct *fsp, mode_t mode)
1456 {
1457         if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1458                 /* Only allow this on POSIX opens. */
1459                 return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
1460         }
1461         return 0;
1462 }
1463
1464 static int chmod_acl_acl_module_common(struct vfs_handle_struct *handle,
1465                         const struct smb_filename *smb_fname,
1466                         mode_t mode)
1467 {
1468         if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1469                 /* Only allow this on POSIX pathnames. */
1470                 return SMB_VFS_NEXT_CHMOD_ACL(handle, smb_fname, mode);
1471         }
1472         return 0;
1473 }
1474
1475 static int fchmod_acl_acl_module_common(struct vfs_handle_struct *handle,
1476                         struct files_struct *fsp, mode_t mode)
1477 {
1478         if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1479                 /* Only allow this on POSIX opens. */
1480                 return SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
1481         }
1482         return 0;
1483 }