s3: VFS: Change SMB_VFS_SYS_ACL_BLOB_GET_FILE to use const struct smb_filename *...
[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  * 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(vfs_handle_struct *handle,
858                                     files_struct *fsp,
859                                     const struct smb_filename *smb_fname_in,
860                                     uint32_t security_info,
861                                     TALLOC_CTX *mem_ctx,
862                                     struct security_descriptor **ppdesc)
863 {
864         DATA_BLOB blob = data_blob_null;
865         NTSTATUS status;
866         struct security_descriptor *psd = NULL;
867         const struct smb_filename *smb_fname = NULL;
868         bool psd_is_from_fs = false;
869         struct acl_common_config *config = NULL;
870
871         SMB_VFS_HANDLE_GET_DATA(handle, config,
872                                 struct acl_common_config,
873                                 return NT_STATUS_UNSUCCESSFUL);
874
875         if (fsp && smb_fname_in == NULL) {
876                 smb_fname = fsp->fsp_name;
877         } else {
878                 smb_fname = smb_fname_in;
879         }
880
881         DBG_DEBUG("name=%s\n", smb_fname->base_name);
882
883         status = get_acl_blob(mem_ctx, handle, fsp, smb_fname, &blob);
884         if (NT_STATUS_IS_OK(status)) {
885                 status = validate_nt_acl_blob(mem_ctx,
886                                               handle,
887                                               fsp,
888                                               smb_fname,
889                                               &blob,
890                                               &psd,
891                                               &psd_is_from_fs);
892                 TALLOC_FREE(blob.data);
893                 if (!NT_STATUS_IS_OK(status)) {
894                         DBG_DEBUG("ACL validation for [%s] failed\n",
895                                   smb_fname->base_name);
896                         goto fail;
897                 }
898         }
899
900         if (psd == NULL) {
901                 /* Get the full underlying sd, as we failed to get the
902                  * blob for the hash, or the revision/hash type wasn't
903                  * known */
904
905                 if (config->ignore_system_acls) {
906                         SMB_STRUCT_STAT sbuf;
907                         SMB_STRUCT_STAT *psbuf = &sbuf;
908
909                         status = stat_fsp_or_smb_fname(handle, fsp, smb_fname,
910                                                        &sbuf, &psbuf);
911                         if (!NT_STATUS_IS_OK(status)) {
912                                 goto fail;
913                         }
914
915                         status = make_default_filesystem_acl(
916                                 mem_ctx,
917                                 config,
918                                 smb_fname->base_name,
919                                 psbuf,
920                                 &psd);
921                         if (!NT_STATUS_IS_OK(status)) {
922                                 goto fail;
923                         }
924                 } else {
925                         if (fsp) {
926                                 status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
927                                                                   fsp,
928                                                                   security_info,
929                                                                   mem_ctx,
930                                                                   &psd);
931                         } else {
932                                 status = SMB_VFS_NEXT_GET_NT_ACL(handle,
933                                                                  smb_fname,
934                                                                  security_info,
935                                                                  mem_ctx,
936                                                                  &psd);
937                         }
938
939                         if (!NT_STATUS_IS_OK(status)) {
940                                 DBG_DEBUG("get_next_acl for file %s "
941                                           "returned %s\n",
942                                           smb_fname->base_name,
943                                           nt_errstr(status));
944                                 goto fail;
945                         }
946
947                         psd_is_from_fs = true;
948                 }
949         }
950
951         if (psd_is_from_fs) {
952                 SMB_STRUCT_STAT sbuf;
953                 SMB_STRUCT_STAT *psbuf = &sbuf;
954                 bool is_directory = false;
955
956                 /*
957                  * We're returning the underlying ACL from the
958                  * filesystem. If it's a directory, and has no
959                  * inheritable ACE entries we have to fake them.
960                  */
961
962                 status = stat_fsp_or_smb_fname(handle, fsp, smb_fname,
963                                                &sbuf, &psbuf);
964                 if (!NT_STATUS_IS_OK(status)) {
965                         goto fail;
966                 }
967
968                 is_directory = S_ISDIR(psbuf->st_ex_mode);
969
970                 if (is_directory && !sd_has_inheritable_components(psd, true)) {
971                         status = add_directory_inheritable_components(
972                                 handle,
973                                 smb_fname->base_name,
974                                 psbuf,
975                                 psd);
976                         if (!NT_STATUS_IS_OK(status)) {
977                                 goto fail;
978                         }
979                 }
980
981                 /*
982                  * The underlying POSIX module always sets the
983                  * ~SEC_DESC_DACL_PROTECTED bit, as ACLs can't be inherited in
984                  * this way under POSIX. Remove it for Windows-style ACLs.
985                  */
986                 psd->type &= ~SEC_DESC_DACL_PROTECTED;
987         }
988
989         if (!(security_info & SECINFO_OWNER)) {
990                 psd->owner_sid = NULL;
991         }
992         if (!(security_info & SECINFO_GROUP)) {
993                 psd->group_sid = NULL;
994         }
995         if (!(security_info & SECINFO_DACL)) {
996                 psd->type &= ~SEC_DESC_DACL_PRESENT;
997                 psd->dacl = NULL;
998         }
999         if (!(security_info & SECINFO_SACL)) {
1000                 psd->type &= ~SEC_DESC_SACL_PRESENT;
1001                 psd->sacl = NULL;
1002         }
1003
1004         if (DEBUGLEVEL >= 10) {
1005                 DBG_DEBUG("returning acl for %s is:\n",
1006                           smb_fname->base_name);
1007                 NDR_PRINT_DEBUG(security_descriptor, psd);
1008         }
1009
1010         *ppdesc = psd;
1011
1012         return NT_STATUS_OK;
1013
1014 fail:
1015         TALLOC_FREE(psd);
1016         return status;
1017 }
1018
1019 /*********************************************************************
1020  Fetch a security descriptor given an fsp.
1021 *********************************************************************/
1022
1023 static NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle,
1024                                    files_struct *fsp,
1025                                    uint32_t security_info,
1026                                    TALLOC_CTX *mem_ctx,
1027                                    struct security_descriptor **ppdesc)
1028 {
1029         return get_nt_acl_internal(handle, fsp,
1030                                    NULL, security_info, mem_ctx, ppdesc);
1031 }
1032
1033 /*********************************************************************
1034  Fetch a security descriptor given a pathname.
1035 *********************************************************************/
1036
1037 static NTSTATUS get_nt_acl_common(vfs_handle_struct *handle,
1038                                   const struct smb_filename *smb_fname,
1039                                   uint32_t security_info,
1040                                   TALLOC_CTX *mem_ctx,
1041                                   struct security_descriptor **ppdesc)
1042 {
1043         return get_nt_acl_internal(handle,
1044                                 NULL,
1045                                 smb_fname,
1046                                 security_info,
1047                                 mem_ctx,
1048                                 ppdesc);
1049 }
1050
1051 /*********************************************************************
1052  Set the underlying ACL (e.g. POSIX ACLS, POSIX owner, etc)
1053 *********************************************************************/
1054 static NTSTATUS set_underlying_acl(vfs_handle_struct *handle, files_struct *fsp,
1055                                    struct security_descriptor *psd,
1056                                    uint32_t security_info_sent,
1057                                    bool chown_needed)
1058 {
1059         NTSTATUS status =
1060             SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
1061         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1062                 return status;
1063         }
1064
1065         /* We got access denied here. If we're already root,
1066            or we didn't need to do a chown, or the fsp isn't
1067            open with WRITE_OWNER access, just return. */
1068         if (get_current_uid(handle->conn) == 0 || chown_needed == false ||
1069             !(fsp->access_mask & SEC_STD_WRITE_OWNER)) {
1070                 return NT_STATUS_ACCESS_DENIED;
1071         }
1072
1073         DBG_DEBUG("overriding chown on file %s for sid %s\n",
1074                    fsp_str_dbg(fsp), sid_string_tos(psd->owner_sid));
1075
1076         /* Ok, we failed to chown and we have
1077            SEC_STD_WRITE_OWNER access - override. */
1078         become_root();
1079         status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
1080         unbecome_root();
1081
1082         return status;
1083 }
1084
1085 /*********************************************************************
1086  Store a v3 security descriptor
1087 *********************************************************************/
1088 static NTSTATUS store_v3_blob(vfs_handle_struct *handle, files_struct *fsp,
1089                               struct security_descriptor *psd,
1090                               struct security_descriptor *pdesc_next,
1091                               uint8_t hash[XATTR_SD_HASH_SIZE])
1092 {
1093         NTSTATUS status;
1094         DATA_BLOB blob;
1095
1096         if (DEBUGLEVEL >= 10) {
1097                 DBG_DEBUG("storing xattr sd for file %s\n",
1098                           fsp_str_dbg(fsp));
1099                 NDR_PRINT_DEBUG(
1100                     security_descriptor,
1101                     discard_const_p(struct security_descriptor, psd));
1102
1103                 if (pdesc_next != NULL) {
1104                         DBG_DEBUG("storing xattr sd based on \n");
1105                         NDR_PRINT_DEBUG(
1106                             security_descriptor,
1107                             discard_const_p(struct security_descriptor,
1108                                             pdesc_next));
1109                 } else {
1110                         DBG_DEBUG("ignoring underlying sd\n");
1111                 }
1112         }
1113         status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
1114         if (!NT_STATUS_IS_OK(status)) {
1115                 DBG_DEBUG("create_acl_blob failed\n");
1116                 return status;
1117         }
1118
1119         status = store_acl_blob_fsp(handle, fsp, &blob);
1120         return status;
1121 }
1122
1123 /*********************************************************************
1124  Store a security descriptor given an fsp.
1125 *********************************************************************/
1126
1127 static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
1128         uint32_t security_info_sent, const struct security_descriptor *orig_psd)
1129 {
1130         NTSTATUS status;
1131         int ret;
1132         DATA_BLOB blob, sys_acl_blob;
1133         struct security_descriptor *pdesc_next = NULL;
1134         struct security_descriptor *psd = NULL;
1135         uint8_t hash[XATTR_SD_HASH_SIZE];
1136         uint8_t sys_acl_hash[XATTR_SD_HASH_SIZE];
1137         bool chown_needed = false;
1138         char *sys_acl_description;
1139         TALLOC_CTX *frame = talloc_stackframe();
1140         bool ignore_file_system_acl = lp_parm_bool(
1141             SNUM(handle->conn), ACL_MODULE_NAME, "ignore system acls", false);
1142
1143         if (DEBUGLEVEL >= 10) {
1144                 DBG_DEBUG("incoming sd for file %s\n", fsp_str_dbg(fsp));
1145                 NDR_PRINT_DEBUG(security_descriptor,
1146                         discard_const_p(struct security_descriptor, orig_psd));
1147         }
1148
1149         status = get_nt_acl_internal(handle, fsp,
1150                         NULL,
1151                         SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL,
1152                                      frame,
1153                         &psd);
1154
1155         if (!NT_STATUS_IS_OK(status)) {
1156                 TALLOC_FREE(frame);
1157                 return status;
1158         }
1159
1160         psd->revision = orig_psd->revision;
1161         /* All our SD's are self relative. */
1162         psd->type = orig_psd->type | SEC_DESC_SELF_RELATIVE;
1163
1164         if ((security_info_sent & SECINFO_OWNER) && (orig_psd->owner_sid != NULL)) {
1165                 if (!dom_sid_equal(orig_psd->owner_sid, psd->owner_sid)) {
1166                         /* We're changing the owner. */
1167                         chown_needed = true;
1168                 }
1169                 psd->owner_sid = orig_psd->owner_sid;
1170         }
1171         if ((security_info_sent & SECINFO_GROUP) && (orig_psd->group_sid != NULL)) {
1172                 if (!dom_sid_equal(orig_psd->group_sid, psd->group_sid)) {
1173                         /* We're changing the group. */
1174                         chown_needed = true;
1175                 }
1176                 psd->group_sid = orig_psd->group_sid;
1177         }
1178         if (security_info_sent & SECINFO_DACL) {
1179                 if (security_descriptor_with_ms_nfs(orig_psd)) {
1180                         /*
1181                          * If the sd contains a MS NFS SID, do
1182                          * nothing, it's a chmod() request from OS X
1183                          * with AAPL context.
1184                          */
1185                         TALLOC_FREE(frame);
1186                         return NT_STATUS_OK;
1187                 }
1188                 psd->dacl = orig_psd->dacl;
1189                 psd->type |= SEC_DESC_DACL_PRESENT;
1190         }
1191         if (security_info_sent & SECINFO_SACL) {
1192                 psd->sacl = orig_psd->sacl;
1193                 psd->type |= SEC_DESC_SACL_PRESENT;
1194         }
1195
1196         if (ignore_file_system_acl) {
1197                 if (chown_needed) {
1198                         /* send only ownership stuff to lower layer */
1199                         security_info_sent &= (SECINFO_OWNER | SECINFO_GROUP);
1200                         status = set_underlying_acl(handle, fsp, psd,
1201                                                     security_info_sent, true);
1202                         if (!NT_STATUS_IS_OK(status)) {
1203                                 TALLOC_FREE(frame);
1204                                 return status;
1205                         }
1206                 }
1207                 ZERO_ARRAY(hash);
1208                 status = store_v3_blob(handle, fsp, psd, NULL, hash);
1209
1210                 TALLOC_FREE(frame);
1211                 return status;
1212         }
1213
1214         status = set_underlying_acl(handle, fsp, psd, security_info_sent,
1215                                     chown_needed);
1216         if (!NT_STATUS_IS_OK(status)) {
1217                 TALLOC_FREE(frame);
1218                 return status;
1219         }
1220
1221         /* Get the full underlying sd, then hash. */
1222         status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
1223                                           fsp,
1224                                           HASH_SECURITY_INFO,
1225                                           frame,
1226                                           &pdesc_next);
1227
1228         if (!NT_STATUS_IS_OK(status)) {
1229                 TALLOC_FREE(frame);
1230                 return status;
1231         }
1232
1233         status = hash_sd_sha256(pdesc_next, hash);
1234         if (!NT_STATUS_IS_OK(status)) {
1235                 TALLOC_FREE(frame);
1236                 return status;
1237         }
1238
1239         /* Get the full underlying sd, then hash. */
1240         ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle,
1241                                                fsp,
1242                                                frame,
1243                                                &sys_acl_description,
1244                                                &sys_acl_blob);
1245
1246         /* If we fail to get the ACL blob (for some reason) then this
1247          * is not fatal, we just work based on the NT ACL only */
1248         if (ret != 0) {
1249                 status = store_v3_blob(handle, fsp, psd, pdesc_next, hash);
1250
1251                 TALLOC_FREE(frame);
1252                 return status;
1253         }
1254
1255         status = hash_blob_sha256(sys_acl_blob, sys_acl_hash);
1256         if (!NT_STATUS_IS_OK(status)) {
1257                 TALLOC_FREE(frame);
1258                 return status;
1259         }
1260
1261         if (DEBUGLEVEL >= 10) {
1262                 DBG_DEBUG("storing xattr sd for file %s based on system ACL\n",
1263                           fsp_str_dbg(fsp));
1264                 NDR_PRINT_DEBUG(security_descriptor,
1265                                 discard_const_p(struct security_descriptor, psd));
1266
1267                 DBG_DEBUG("storing hash in xattr sd based on system ACL and:\n");
1268                 NDR_PRINT_DEBUG(security_descriptor,
1269                                 discard_const_p(struct security_descriptor, pdesc_next));
1270         }
1271
1272         /* We store hashes of both the sys ACL blob and the NT
1273          * security desciptor mapped from that ACL so as to improve
1274          * our chances against some inadvertant change breaking the
1275          * hash used */
1276         status = create_sys_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash, 
1277                                      sys_acl_description, sys_acl_hash);
1278         if (!NT_STATUS_IS_OK(status)) {
1279                 DBG_DEBUG("create_sys_acl_blob failed\n");
1280                 TALLOC_FREE(frame);
1281                 return status;
1282         }
1283
1284         status = store_acl_blob_fsp(handle, fsp, &blob);
1285
1286         TALLOC_FREE(frame);
1287         return status;
1288 }
1289
1290 static int acl_common_remove_object(vfs_handle_struct *handle,
1291                                         const char *path,
1292                                         bool is_directory)
1293 {
1294         connection_struct *conn = handle->conn;
1295         struct file_id id;
1296         files_struct *fsp = NULL;
1297         int ret = 0;
1298         char *parent_dir = NULL;
1299         const char *final_component = NULL;
1300         struct smb_filename local_fname;
1301         int saved_errno = 0;
1302         char *saved_dir = NULL;
1303
1304         saved_dir = vfs_GetWd(talloc_tos(),conn);
1305         if (!saved_dir) {
1306                 saved_errno = errno;
1307                 goto out;
1308         }
1309
1310         if (!parent_dirname(talloc_tos(), path,
1311                         &parent_dir, &final_component)) {
1312                 saved_errno = ENOMEM;
1313                 goto out;
1314         }
1315
1316         DBG_DEBUG("removing %s %s/%s\n", is_directory ? "directory" : "file",
1317                   parent_dir, final_component);
1318
1319         /* cd into the parent dir to pin it. */
1320         ret = vfs_ChDir(conn, parent_dir);
1321         if (ret == -1) {
1322                 saved_errno = errno;
1323                 goto out;
1324         }
1325
1326         ZERO_STRUCT(local_fname);
1327         local_fname.base_name = discard_const_p(char, final_component);
1328
1329         /* Must use lstat here. */
1330         ret = SMB_VFS_LSTAT(conn, &local_fname);
1331         if (ret == -1) {
1332                 saved_errno = errno;
1333                 goto out;
1334         }
1335
1336         /* Ensure we have this file open with DELETE access. */
1337         id = vfs_file_id_from_sbuf(conn, &local_fname.st);
1338         for (fsp = file_find_di_first(conn->sconn, id); fsp;
1339                      fsp = file_find_di_next(fsp)) {
1340                 if (fsp->access_mask & DELETE_ACCESS &&
1341                                 fsp->delete_on_close) {
1342                         /* We did open this for delete,
1343                          * allow the delete as root.
1344                          */
1345                         break;
1346                 }
1347         }
1348
1349         if (!fsp) {
1350                 DBG_DEBUG("%s %s/%s not an open file\n",
1351                           is_directory ? "directory" : "file",
1352                           parent_dir, final_component);
1353                 saved_errno = EACCES;
1354                 goto out;
1355         }
1356
1357         become_root();
1358         if (is_directory) {
1359                 ret = SMB_VFS_NEXT_RMDIR(handle, &local_fname);
1360         } else {
1361                 ret = SMB_VFS_NEXT_UNLINK(handle, &local_fname);
1362         }
1363         unbecome_root();
1364
1365         if (ret == -1) {
1366                 saved_errno = errno;
1367         }
1368
1369   out:
1370
1371         TALLOC_FREE(parent_dir);
1372
1373         if (saved_dir) {
1374                 vfs_ChDir(conn, saved_dir);
1375         }
1376         if (saved_errno) {
1377                 errno = saved_errno;
1378         }
1379         return ret;
1380 }
1381
1382 static int rmdir_acl_common(struct vfs_handle_struct *handle,
1383                                 const struct smb_filename *smb_fname)
1384 {
1385         int ret;
1386
1387         /* Try the normal rmdir first. */
1388         ret = SMB_VFS_NEXT_RMDIR(handle, smb_fname);
1389         if (ret == 0) {
1390                 return 0;
1391         }
1392         if (errno == EACCES || errno == EPERM) {
1393                 /* Failed due to access denied,
1394                    see if we need to root override. */
1395                 return acl_common_remove_object(handle,
1396                                                 smb_fname->base_name,
1397                                                 true);
1398         }
1399
1400         DBG_DEBUG("unlink of %s failed %s\n",
1401                   smb_fname->base_name,
1402                   strerror(errno));
1403         return -1;
1404 }
1405
1406 static int unlink_acl_common(struct vfs_handle_struct *handle,
1407                         const struct smb_filename *smb_fname)
1408 {
1409         int ret;
1410
1411         /* Try the normal unlink first. */
1412         ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
1413         if (ret == 0) {
1414                 return 0;
1415         }
1416         if (errno == EACCES || errno == EPERM) {
1417                 /* Failed due to access denied,
1418                    see if we need to root override. */
1419
1420                 /* Don't do anything fancy for streams. */
1421                 if (smb_fname->stream_name) {
1422                         return -1;
1423                 }
1424                 return acl_common_remove_object(handle,
1425                                         smb_fname->base_name,
1426                                         false);
1427         }
1428
1429         DBG_DEBUG("unlink of %s failed %s\n",
1430                   smb_fname->base_name,
1431                   strerror(errno));
1432         return -1;
1433 }
1434
1435 static int chmod_acl_module_common(struct vfs_handle_struct *handle,
1436                         const struct smb_filename *smb_fname,
1437                         mode_t mode)
1438 {
1439         if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1440                 /* Only allow this on POSIX pathnames. */
1441                 return SMB_VFS_NEXT_CHMOD(handle, smb_fname, mode);
1442         }
1443         return 0;
1444 }
1445
1446 static int fchmod_acl_module_common(struct vfs_handle_struct *handle,
1447                         struct files_struct *fsp, mode_t mode)
1448 {
1449         if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1450                 /* Only allow this on POSIX opens. */
1451                 return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
1452         }
1453         return 0;
1454 }
1455
1456 static int chmod_acl_acl_module_common(struct vfs_handle_struct *handle,
1457                         const struct smb_filename *smb_fname,
1458                         mode_t mode)
1459 {
1460         if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1461                 /* Only allow this on POSIX pathnames. */
1462                 return SMB_VFS_NEXT_CHMOD_ACL(handle, smb_fname, mode);
1463         }
1464         return 0;
1465 }
1466
1467 static int fchmod_acl_acl_module_common(struct vfs_handle_struct *handle,
1468                         struct files_struct *fsp, mode_t mode)
1469 {
1470         if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1471                 /* Only allow this on POSIX opens. */
1472                 return SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
1473         }
1474         return 0;
1475 }