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