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