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