fb01bf4203444353fdfc15b748de8d2211c2e39d
[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  *
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_blob = NULL;
492         struct security_descriptor *psd_fs = NULL;
493         const struct smb_filename *smb_fname = NULL;
494         bool ignore_file_system_acl = lp_parm_bool(SNUM(handle->conn),
495                                                 ACL_MODULE_NAME,
496                                                 "ignore system acls",
497                                                 false);
498         TALLOC_CTX *frame = talloc_stackframe();
499
500         if (fsp && smb_fname_in == NULL) {
501                 smb_fname = fsp->fsp_name;
502         } else {
503                 smb_fname = smb_fname_in;
504         }
505
506         DEBUG(10, ("get_nt_acl_internal: name=%s\n", smb_fname->base_name));
507
508         status = get_acl_blob(frame, handle, fsp, smb_fname, &blob);
509         if (!NT_STATUS_IS_OK(status)) {
510                 DEBUG(10, ("get_nt_acl_internal: get_acl_blob returned %s\n",
511                         nt_errstr(status)));
512                 psd_blob = NULL;
513                 goto out;
514         } else {
515                 status = parse_acl_blob(&blob, mem_ctx, &psd_blob,
516                                         &hash_type, &xattr_version, &hash[0], &sys_acl_hash[0]);
517                 if (!NT_STATUS_IS_OK(status)) {
518                         DEBUG(10, ("parse_acl_blob returned %s\n",
519                                    nt_errstr(status)));
520                         psd_blob = NULL;
521                         goto out;
522                 }
523         }
524
525         /* Ensure we don't leak psd_blob if we don't choose it.
526          *
527          * We don't allocate it onto frame as it is preferred not to
528          * steal from a talloc pool.
529          */
530         talloc_steal(frame, psd_blob);
531
532         /* determine which type of xattr we got */
533         switch (xattr_version) {
534         case 1:
535         case 2:
536                 /* These xattr types are unilatteral, they do not
537                  * require confirmation of the hash.  In particular,
538                  * the NTVFS file server uses version 1, but
539                  * 'samba-tool ntacl' can set these as well */
540                 goto out;
541         case 3:
542         case 4:
543                 if (ignore_file_system_acl) {
544                         goto out;
545                 }
546
547                 break;
548         default:
549                 DEBUG(10, ("get_nt_acl_internal: ACL blob revision "
550                            "mismatch (%u) for file %s\n",
551                            (unsigned int)hash_type,
552                            smb_fname->base_name));
553                 TALLOC_FREE(psd_blob);
554                 psd_blob = NULL;
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                 psd_blob = NULL;
566                 goto out;
567         }
568
569         /* determine which type of xattr we got */
570         switch (xattr_version) {
571         case 4:
572         {
573                 int ret;
574                 char *sys_acl_blob_description;
575                 DATA_BLOB sys_acl_blob;
576                 if (fsp) {
577                         /* Get the full underlying sd, then hash. */
578                         ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle,
579                                                                fsp,
580                                                                frame,
581                                                                &sys_acl_blob_description,
582                                                                &sys_acl_blob);
583                 } else {
584                         /* Get the full underlying sd, then hash. */
585                         ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle,
586                                                  smb_fname->base_name,
587                                                  frame,
588                                                  &sys_acl_blob_description,
589                                                  &sys_acl_blob);
590                 }
591
592                 /* If we fail to get the ACL blob (for some reason) then this
593                  * is not fatal, we just work based on the NT ACL only */
594                 if (ret == 0) {
595                         status = hash_blob_sha256(sys_acl_blob, sys_acl_hash_tmp);
596                         if (!NT_STATUS_IS_OK(status)) {
597                                 TALLOC_FREE(frame);
598                                 return status;
599                         }
600
601                         if (memcmp(&sys_acl_hash[0], &sys_acl_hash_tmp[0], 
602                                    XATTR_SD_HASH_SIZE) == 0) {
603                                 /* Hash matches, return blob sd. */
604                                 DEBUG(10, ("get_nt_acl_internal: blob hash "
605                                            "matches for file %s\n",
606                                            smb_fname->base_name ));
607                                 goto out;
608                         }
609                 }
610
611                 /* Otherwise, fall though and see if the NT ACL hash matches */
612         }
613         case 3:
614                 /* Get the full underlying sd for the hash
615                    or to return as backup. */
616                 if (fsp) {
617                         status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
618                                                           fsp,
619                                                           HASH_SECURITY_INFO,
620                                                           mem_ctx,
621                                                           &psd_fs);
622                 } else {
623                         status = SMB_VFS_NEXT_GET_NT_ACL(handle,
624                                                          smb_fname,
625                                                          HASH_SECURITY_INFO,
626                                                          mem_ctx,
627                                                          &psd_fs);
628                 }
629
630                 if (!NT_STATUS_IS_OK(status)) {
631                         DEBUG(10, ("get_nt_acl_internal: get_next_acl for file %s "
632                                    "returned %s\n",
633                                    smb_fname->base_name,
634                                    nt_errstr(status)));
635                         TALLOC_FREE(frame);
636                         return status;
637                 }
638
639                 /* Ensure we don't leak psd_fs if we don't choose it.
640                  *
641                  * We don't allocate it onto frame as it is preferred not to
642                  * steal from a talloc pool.
643                  */
644                 talloc_steal(frame, psd_fs);
645
646                 status = hash_sd_sha256(psd_fs, hash_tmp);
647                 if (!NT_STATUS_IS_OK(status)) {
648                         TALLOC_FREE(psd_blob);
649                         psd_blob = psd_fs;
650                         goto out;
651                 }
652
653                 if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) {
654                         /* Hash matches, return blob sd. */
655                         DEBUG(10, ("get_nt_acl_internal: blob hash "
656                                    "matches for file %s\n",
657                                    smb_fname->base_name ));
658                         goto out;
659                 }
660
661                 /* Hash doesn't match, return underlying sd. */
662                 DEBUG(10, ("get_nt_acl_internal: blob hash "
663                            "does not match for file %s - returning "
664                            "file system SD mapping.\n",
665                            smb_fname->base_name ));
666
667                 if (DEBUGLEVEL >= 10) {
668                         DEBUG(10,("get_nt_acl_internal: acl for blob hash for %s is:\n",
669                                   smb_fname->base_name ));
670                         NDR_PRINT_DEBUG(security_descriptor, psd_fs);
671                 }
672
673                 TALLOC_FREE(psd_blob);
674                 psd_blob = psd_fs;
675         }
676   out:
677
678         if (psd_blob == NULL) {
679                 /* Get the full underlying sd, as we failed to get the
680                  * blob for the hash, or the revision/hash type wasn't
681                  * known */
682                 if (fsp) {
683                         status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
684                                                           fsp,
685                                                           security_info,
686                                                           mem_ctx,
687                                                           &psd_fs);
688                 } else {
689                         status = SMB_VFS_NEXT_GET_NT_ACL(handle,
690                                                          smb_fname,
691                                                          security_info,
692                                                          mem_ctx,
693                                                          &psd_fs);
694                 }
695
696                 if (!NT_STATUS_IS_OK(status)) {
697                         DEBUG(10, ("get_nt_acl_internal: get_next_acl for file %s "
698                                    "returned %s\n",
699                                    smb_fname->base_name,
700                                    nt_errstr(status)));
701                         TALLOC_FREE(frame);
702                         return status;
703                 }
704
705                 /* Ensure we don't leak psd_fs if we don't choose it.
706                  *
707                  * We don't allocate it onto frame as it is preferred not to
708                  * steal from a talloc pool.
709                  */
710                 talloc_steal(frame, psd_fs);
711                 psd_blob = psd_fs;
712         }
713
714         if (psd_blob != psd_fs) {
715                 /* We're returning the blob, throw
716                  * away the filesystem SD. */
717                 TALLOC_FREE(psd_fs);
718         } else {
719                 SMB_STRUCT_STAT sbuf;
720                 SMB_STRUCT_STAT *psbuf = &sbuf;
721                 bool is_directory = false;
722                 /*
723                  * We're returning the underlying ACL from the
724                  * filesystem. If it's a directory, and has no
725                  * inheritable ACE entries we have to fake them.
726                  */
727                 if (fsp) {
728                         status = vfs_stat_fsp(fsp);
729                         if (!NT_STATUS_IS_OK(status)) {
730                                 TALLOC_FREE(frame);
731                                 return status;
732                         }
733                         psbuf = &fsp->fsp_name->st;
734                 } else {
735                         /*
736                          * https://bugzilla.samba.org/show_bug.cgi?id=11249
737                          *
738                          * We are currently guaranteed that 'name' here is
739                          * a smb_fname->base_name, which *cannot* contain
740                          * a stream name (':'). vfs_stat_smb_fname() splits
741                          * a name into a base name + stream name, which
742                          * when we get here we know we've already done.
743                          * So we have to call the stat or lstat VFS
744                          * calls directly here. Else, a base_name that
745                          * contains a ':' (from a demangled name) will
746                          * get split again.
747                          *
748                          * FIXME.
749                          * This uglyness will go away once smb_fname
750                          * is fully plumbed through the VFS.
751                          */
752                         int ret = vfs_stat_smb_basename(handle->conn,
753                                                 smb_fname,
754                                                 &sbuf);
755                         if (ret == -1) {
756                                 TALLOC_FREE(frame);
757                                 return map_nt_error_from_unix(errno);
758                         }
759                 }
760                 is_directory = S_ISDIR(psbuf->st_ex_mode);
761
762                 if (ignore_file_system_acl) {
763                         TALLOC_FREE(psd_fs);
764                         status = make_default_filesystem_acl(mem_ctx,
765                                                 smb_fname->base_name,
766                                                 psbuf,
767                                                 &psd_blob);
768                         if (!NT_STATUS_IS_OK(status)) {
769                                 TALLOC_FREE(frame);
770                                 return status;
771                         }
772                 } else {
773                         if (is_directory &&
774                                 !sd_has_inheritable_components(psd_blob,
775                                                         true)) {
776                                 status = add_directory_inheritable_components(
777                                                         handle,
778                                                         smb_fname->base_name,
779                                                         psbuf,
780                                                         psd_blob);
781                                 if (!NT_STATUS_IS_OK(status)) {
782                                         TALLOC_FREE(frame);
783                                         return status;
784                                 }
785                         }
786                         /* The underlying POSIX module always sets
787                            the ~SEC_DESC_DACL_PROTECTED bit, as ACLs
788                            can't be inherited in this way under POSIX.
789                            Remove it for Windows-style ACLs. */
790                         psd_blob->type &= ~SEC_DESC_DACL_PROTECTED;
791                 }
792         }
793
794         if (!(security_info & SECINFO_OWNER)) {
795                 psd_blob->owner_sid = NULL;
796         }
797         if (!(security_info & SECINFO_GROUP)) {
798                 psd_blob->group_sid = NULL;
799         }
800         if (!(security_info & SECINFO_DACL)) {
801                 psd_blob->type &= ~SEC_DESC_DACL_PRESENT;
802                 psd_blob->dacl = NULL;
803         }
804         if (!(security_info & SECINFO_SACL)) {
805                 psd_blob->type &= ~SEC_DESC_SACL_PRESENT;
806                 psd_blob->sacl = NULL;
807         }
808
809         TALLOC_FREE(blob.data);
810
811         if (DEBUGLEVEL >= 10) {
812                 DEBUG(10,("get_nt_acl_internal: returning acl for %s is:\n",
813                         smb_fname->base_name ));
814                 NDR_PRINT_DEBUG(security_descriptor, psd_blob);
815         }
816
817         /* The VFS API is that the ACL is expected to be on mem_ctx */
818         *ppdesc = talloc_move(mem_ctx, &psd_blob);
819
820         TALLOC_FREE(frame);
821         return NT_STATUS_OK;
822 }
823
824 /*********************************************************************
825  Fetch a security descriptor given an fsp.
826 *********************************************************************/
827
828 static NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle,
829                                    files_struct *fsp,
830                                    uint32_t security_info,
831                                    TALLOC_CTX *mem_ctx,
832                                    struct security_descriptor **ppdesc)
833 {
834         return get_nt_acl_internal(handle, fsp,
835                                    NULL, security_info, mem_ctx, ppdesc);
836 }
837
838 /*********************************************************************
839  Fetch a security descriptor given a pathname.
840 *********************************************************************/
841
842 static NTSTATUS get_nt_acl_common(vfs_handle_struct *handle,
843                                   const struct smb_filename *smb_fname,
844                                   uint32_t security_info,
845                                   TALLOC_CTX *mem_ctx,
846                                   struct security_descriptor **ppdesc)
847 {
848         return get_nt_acl_internal(handle,
849                                 NULL,
850                                 smb_fname,
851                                 security_info,
852                                 mem_ctx,
853                                 ppdesc);
854 }
855
856 /*********************************************************************
857  Set the underlying ACL (e.g. POSIX ACLS, POSIX owner, etc)
858 *********************************************************************/
859 static NTSTATUS set_underlying_acl(vfs_handle_struct *handle, files_struct *fsp,
860                                    struct security_descriptor *psd,
861                                    uint32_t security_info_sent,
862                                    bool chown_needed)
863 {
864         NTSTATUS status =
865             SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
866         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
867                 return status;
868         }
869
870         /* We got access denied here. If we're already root,
871            or we didn't need to do a chown, or the fsp isn't
872            open with WRITE_OWNER access, just return. */
873         if (get_current_uid(handle->conn) == 0 || chown_needed == false ||
874             !(fsp->access_mask & SEC_STD_WRITE_OWNER)) {
875                 return NT_STATUS_ACCESS_DENIED;
876         }
877
878         DEBUG(10, ("fset_nt_acl_common: overriding chown on file %s "
879                    "for sid %s\n",
880                    fsp_str_dbg(fsp), sid_string_tos(psd->owner_sid)));
881
882         /* Ok, we failed to chown and we have
883            SEC_STD_WRITE_OWNER access - override. */
884         become_root();
885         status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
886         unbecome_root();
887
888         return status;
889 }
890
891 /*********************************************************************
892  Store a v3 security descriptor
893 *********************************************************************/
894 static NTSTATUS store_v3_blob(vfs_handle_struct *handle, files_struct *fsp,
895                               struct security_descriptor *psd,
896                               struct security_descriptor *pdesc_next,
897                               uint8_t hash[XATTR_SD_HASH_SIZE])
898 {
899         NTSTATUS status;
900         DATA_BLOB blob;
901
902         if (DEBUGLEVEL >= 10) {
903                 DEBUG(10, ("fset_nt_acl_xattr: storing xattr sd for file %s\n",
904                            fsp_str_dbg(fsp)));
905                 NDR_PRINT_DEBUG(
906                     security_descriptor,
907                     discard_const_p(struct security_descriptor, psd));
908
909                 if (pdesc_next != NULL) {
910                         DEBUG(10, ("fset_nt_acl_xattr: storing has in xattr sd "
911                                    "based on \n"));
912                         NDR_PRINT_DEBUG(
913                             security_descriptor,
914                             discard_const_p(struct security_descriptor,
915                                             pdesc_next));
916                 } else {
917                         DEBUG(10,
918                               ("fset_nt_acl_xattr: ignoring underlying sd\n"));
919                 }
920         }
921         status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
922         if (!NT_STATUS_IS_OK(status)) {
923                 DEBUG(10, ("fset_nt_acl_xattr: create_acl_blob failed\n"));
924                 return status;
925         }
926
927         status = store_acl_blob_fsp(handle, fsp, &blob);
928         return status;
929 }
930
931 /*********************************************************************
932  Store a security descriptor given an fsp.
933 *********************************************************************/
934
935 static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
936         uint32_t security_info_sent, const struct security_descriptor *orig_psd)
937 {
938         NTSTATUS status;
939         int ret;
940         DATA_BLOB blob, sys_acl_blob;
941         struct security_descriptor *pdesc_next = NULL;
942         struct security_descriptor *psd = NULL;
943         uint8_t hash[XATTR_SD_HASH_SIZE];
944         uint8_t sys_acl_hash[XATTR_SD_HASH_SIZE];
945         bool chown_needed = false;
946         char *sys_acl_description;
947         TALLOC_CTX *frame = talloc_stackframe();
948         bool ignore_file_system_acl = lp_parm_bool(
949             SNUM(handle->conn), ACL_MODULE_NAME, "ignore system acls", false);
950
951         if (DEBUGLEVEL >= 10) {
952                 DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
953                           fsp_str_dbg(fsp)));
954                 NDR_PRINT_DEBUG(security_descriptor,
955                         discard_const_p(struct security_descriptor, orig_psd));
956         }
957
958         status = get_nt_acl_internal(handle, fsp,
959                         NULL,
960                         SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL,
961                                      frame,
962                         &psd);
963
964         if (!NT_STATUS_IS_OK(status)) {
965                 TALLOC_FREE(frame);
966                 return status;
967         }
968
969         psd->revision = orig_psd->revision;
970         /* All our SD's are self relative. */
971         psd->type = orig_psd->type | SEC_DESC_SELF_RELATIVE;
972
973         if ((security_info_sent & SECINFO_OWNER) && (orig_psd->owner_sid != NULL)) {
974                 if (!dom_sid_equal(orig_psd->owner_sid, psd->owner_sid)) {
975                         /* We're changing the owner. */
976                         chown_needed = true;
977                 }
978                 psd->owner_sid = orig_psd->owner_sid;
979         }
980         if ((security_info_sent & SECINFO_GROUP) && (orig_psd->group_sid != NULL)) {
981                 if (!dom_sid_equal(orig_psd->group_sid, psd->group_sid)) {
982                         /* We're changing the group. */
983                         chown_needed = true;
984                 }
985                 psd->group_sid = orig_psd->group_sid;
986         }
987         if (security_info_sent & SECINFO_DACL) {
988                 if (security_descriptor_with_ms_nfs(orig_psd)) {
989                         /*
990                          * If the sd contains a MS NFS SID, do
991                          * nothing, it's a chmod() request from OS X
992                          * with AAPL context.
993                          */
994                         TALLOC_FREE(frame);
995                         return NT_STATUS_OK;
996                 }
997                 psd->dacl = orig_psd->dacl;
998                 psd->type |= SEC_DESC_DACL_PRESENT;
999         }
1000         if (security_info_sent & SECINFO_SACL) {
1001                 psd->sacl = orig_psd->sacl;
1002                 psd->type |= SEC_DESC_SACL_PRESENT;
1003         }
1004
1005         if (ignore_file_system_acl) {
1006                 if (chown_needed) {
1007                         /* send only ownership stuff to lower layer */
1008                         security_info_sent &= (SECINFO_OWNER | SECINFO_GROUP);
1009                         status = set_underlying_acl(handle, fsp, psd,
1010                                                     security_info_sent, true);
1011                         if (!NT_STATUS_IS_OK(status)) {
1012                                 TALLOC_FREE(frame);
1013                                 return status;
1014                         }
1015                 }
1016                 ZERO_ARRAY(hash);
1017                 status = store_v3_blob(handle, fsp, psd, NULL, hash);
1018
1019                 TALLOC_FREE(frame);
1020                 return status;
1021         }
1022
1023         status = set_underlying_acl(handle, fsp, psd, security_info_sent,
1024                                     chown_needed);
1025         if (!NT_STATUS_IS_OK(status)) {
1026                 TALLOC_FREE(frame);
1027                 return status;
1028         }
1029
1030         /* Get the full underlying sd, then hash. */
1031         status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
1032                                           fsp,
1033                                           HASH_SECURITY_INFO,
1034                                           frame,
1035                                           &pdesc_next);
1036
1037         if (!NT_STATUS_IS_OK(status)) {
1038                 TALLOC_FREE(frame);
1039                 return status;
1040         }
1041
1042         status = hash_sd_sha256(pdesc_next, hash);
1043         if (!NT_STATUS_IS_OK(status)) {
1044                 TALLOC_FREE(frame);
1045                 return status;
1046         }
1047
1048         /* Get the full underlying sd, then hash. */
1049         ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle,
1050                                                fsp,
1051                                                frame,
1052                                                &sys_acl_description,
1053                                                &sys_acl_blob);
1054
1055         /* If we fail to get the ACL blob (for some reason) then this
1056          * is not fatal, we just work based on the NT ACL only */
1057         if (ret != 0) {
1058                 status = store_v3_blob(handle, fsp, psd, pdesc_next, hash);
1059
1060                 TALLOC_FREE(frame);
1061                 return status;
1062         }
1063
1064         status = hash_blob_sha256(sys_acl_blob, sys_acl_hash);
1065         if (!NT_STATUS_IS_OK(status)) {
1066                 TALLOC_FREE(frame);
1067                 return status;
1068         }
1069
1070         if (DEBUGLEVEL >= 10) {
1071                 DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s based on system ACL\n",
1072                           fsp_str_dbg(fsp)));
1073                 NDR_PRINT_DEBUG(security_descriptor,
1074                                 discard_const_p(struct security_descriptor, psd));
1075
1076                 DEBUG(10,("fset_nt_acl_xattr: storing hash in xattr sd based on system ACL and:\n"));
1077                 NDR_PRINT_DEBUG(security_descriptor,
1078                                 discard_const_p(struct security_descriptor, pdesc_next));
1079         }
1080
1081         /* We store hashes of both the sys ACL blob and the NT
1082          * security desciptor mapped from that ACL so as to improve
1083          * our chances against some inadvertant change breaking the
1084          * hash used */
1085         status = create_sys_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash, 
1086                                      sys_acl_description, sys_acl_hash);
1087         if (!NT_STATUS_IS_OK(status)) {
1088                 DEBUG(10, ("fset_nt_acl_xattr: create_sys_acl_blob failed\n"));
1089                 TALLOC_FREE(frame);
1090                 return status;
1091         }
1092
1093         status = store_acl_blob_fsp(handle, fsp, &blob);
1094
1095         TALLOC_FREE(frame);
1096         return status;
1097 }
1098
1099 static int acl_common_remove_object(vfs_handle_struct *handle,
1100                                         const char *path,
1101                                         bool is_directory)
1102 {
1103         connection_struct *conn = handle->conn;
1104         struct file_id id;
1105         files_struct *fsp = NULL;
1106         int ret = 0;
1107         char *parent_dir = NULL;
1108         const char *final_component = NULL;
1109         struct smb_filename local_fname;
1110         int saved_errno = 0;
1111         char *saved_dir = NULL;
1112
1113         saved_dir = vfs_GetWd(talloc_tos(),conn);
1114         if (!saved_dir) {
1115                 saved_errno = errno;
1116                 goto out;
1117         }
1118
1119         if (!parent_dirname(talloc_tos(), path,
1120                         &parent_dir, &final_component)) {
1121                 saved_errno = ENOMEM;
1122                 goto out;
1123         }
1124
1125         DEBUG(10,("acl_common_remove_object: removing %s %s/%s\n",
1126                 is_directory ? "directory" : "file",
1127                 parent_dir, final_component ));
1128
1129         /* cd into the parent dir to pin it. */
1130         ret = vfs_ChDir(conn, parent_dir);
1131         if (ret == -1) {
1132                 saved_errno = errno;
1133                 goto out;
1134         }
1135
1136         ZERO_STRUCT(local_fname);
1137         local_fname.base_name = discard_const_p(char, final_component);
1138
1139         /* Must use lstat here. */
1140         ret = SMB_VFS_LSTAT(conn, &local_fname);
1141         if (ret == -1) {
1142                 saved_errno = errno;
1143                 goto out;
1144         }
1145
1146         /* Ensure we have this file open with DELETE access. */
1147         id = vfs_file_id_from_sbuf(conn, &local_fname.st);
1148         for (fsp = file_find_di_first(conn->sconn, id); fsp;
1149                      fsp = file_find_di_next(fsp)) {
1150                 if (fsp->access_mask & DELETE_ACCESS &&
1151                                 fsp->delete_on_close) {
1152                         /* We did open this for delete,
1153                          * allow the delete as root.
1154                          */
1155                         break;
1156                 }
1157         }
1158
1159         if (!fsp) {
1160                 DEBUG(10,("acl_common_remove_object: %s %s/%s "
1161                         "not an open file\n",
1162                         is_directory ? "directory" : "file",
1163                         parent_dir, final_component ));
1164                 saved_errno = EACCES;
1165                 goto out;
1166         }
1167
1168         become_root();
1169         if (is_directory) {
1170                 ret = SMB_VFS_NEXT_RMDIR(handle, &local_fname);
1171         } else {
1172                 ret = SMB_VFS_NEXT_UNLINK(handle, &local_fname);
1173         }
1174         unbecome_root();
1175
1176         if (ret == -1) {
1177                 saved_errno = errno;
1178         }
1179
1180   out:
1181
1182         TALLOC_FREE(parent_dir);
1183
1184         if (saved_dir) {
1185                 vfs_ChDir(conn, saved_dir);
1186         }
1187         if (saved_errno) {
1188                 errno = saved_errno;
1189         }
1190         return ret;
1191 }
1192
1193 static int rmdir_acl_common(struct vfs_handle_struct *handle,
1194                                 const struct smb_filename *smb_fname)
1195 {
1196         int ret;
1197
1198         /* Try the normal rmdir first. */
1199         ret = SMB_VFS_NEXT_RMDIR(handle, smb_fname);
1200         if (ret == 0) {
1201                 return 0;
1202         }
1203         if (errno == EACCES || errno == EPERM) {
1204                 /* Failed due to access denied,
1205                    see if we need to root override. */
1206                 return acl_common_remove_object(handle,
1207                                                 smb_fname->base_name,
1208                                                 true);
1209         }
1210
1211         DEBUG(10,("rmdir_acl_common: unlink of %s failed %s\n",
1212                 smb_fname->base_name,
1213                 strerror(errno) ));
1214         return -1;
1215 }
1216
1217 static int unlink_acl_common(struct vfs_handle_struct *handle,
1218                         const struct smb_filename *smb_fname)
1219 {
1220         int ret;
1221
1222         /* Try the normal unlink first. */
1223         ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
1224         if (ret == 0) {
1225                 return 0;
1226         }
1227         if (errno == EACCES || errno == EPERM) {
1228                 /* Failed due to access denied,
1229                    see if we need to root override. */
1230
1231                 /* Don't do anything fancy for streams. */
1232                 if (smb_fname->stream_name) {
1233                         return -1;
1234                 }
1235                 return acl_common_remove_object(handle,
1236                                         smb_fname->base_name,
1237                                         false);
1238         }
1239
1240         DEBUG(10,("unlink_acl_common: unlink of %s failed %s\n",
1241                 smb_fname->base_name,
1242                 strerror(errno) ));
1243         return -1;
1244 }
1245
1246 static int chmod_acl_module_common(struct vfs_handle_struct *handle,
1247                         const struct smb_filename *smb_fname,
1248                         mode_t mode)
1249 {
1250         if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1251                 /* Only allow this on POSIX pathnames. */
1252                 return SMB_VFS_NEXT_CHMOD(handle, smb_fname, mode);
1253         }
1254         return 0;
1255 }
1256
1257 static int fchmod_acl_module_common(struct vfs_handle_struct *handle,
1258                         struct files_struct *fsp, mode_t mode)
1259 {
1260         if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1261                 /* Only allow this on POSIX opens. */
1262                 return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
1263         }
1264         return 0;
1265 }
1266
1267 static int chmod_acl_acl_module_common(struct vfs_handle_struct *handle,
1268                         const struct smb_filename *smb_fname,
1269                         mode_t mode)
1270 {
1271         if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1272                 /* Only allow this on POSIX pathnames. */
1273                 return SMB_VFS_NEXT_CHMOD_ACL(handle, smb_fname, mode);
1274         }
1275         return 0;
1276 }
1277
1278 static int fchmod_acl_acl_module_common(struct vfs_handle_struct *handle,
1279                         struct files_struct *fsp, mode_t mode)
1280 {
1281         if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1282                 /* Only allow this on POSIX opens. */
1283                 return SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
1284         }
1285         return 0;
1286 }