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