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