LCOV - code coverage report
Current view: top level - source3/modules - vfs_acl_common.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 341 511 66.7 %
Date: 2024-04-21 15:09:00 Functions: 15 16 93.8 %

          Line data    Source code
       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       53442 : bool init_acl_common_config(vfs_handle_struct *handle,
      47             :                             const char *module_name)
      48             : {
      49       53442 :         struct acl_common_config *config = NULL;
      50       53442 :         const struct enum_list *default_acl_style_list = NULL;
      51             : 
      52       53442 :         default_acl_style_list = get_default_acl_style_list();
      53             : 
      54       53442 :         config = talloc_zero(handle->conn, struct acl_common_config);
      55       53442 :         if (config == NULL) {
      56           0 :                 DBG_ERR("talloc_zero() failed\n");
      57           0 :                 errno = ENOMEM;
      58           0 :                 return false;
      59             :         }
      60             : 
      61       53442 :         config->ignore_system_acls = lp_parm_bool(SNUM(handle->conn),
      62             :                                                   module_name,
      63             :                                                   "ignore system acls",
      64             :                                                   false);
      65       53442 :         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       53442 :         SMB_VFS_HANDLE_SET_DATA(handle, config, NULL,
      72             :                                 struct acl_common_config,
      73         851 :                                 return false);
      74             : 
      75       53442 :         return true;
      76             : }
      77             : 
      78             : 
      79             : /*******************************************************************
      80             :  Hash a security descriptor.
      81             : *******************************************************************/
      82             : 
      83     1070979 : static NTSTATUS hash_blob_sha256(DATA_BLOB blob,
      84             :                                  uint8_t *hash)
      85             : {
      86        1955 :         int rc;
      87             : 
      88     1070979 :         ZERO_ARRAY_LEN(hash, XATTR_SD_HASH_SIZE);
      89             : 
      90     1072934 :         rc = gnutls_hash_fast(GNUTLS_DIG_SHA256,
      91     1070979 :                               blob.data,
      92             :                               blob.length,
      93             :                               hash);
      94     1070979 :         if (rc < 0) {
      95           0 :                 return NT_STATUS_INTERNAL_ERROR;
      96             :         }
      97             : 
      98     1070979 :         return NT_STATUS_OK;
      99             : }
     100             : 
     101             : /*******************************************************************
     102             :  Hash a security descriptor.
     103             : *******************************************************************/
     104             : 
     105      157821 : static NTSTATUS hash_sd_sha256(struct security_descriptor *psd,
     106             :                         uint8_t *hash)
     107             : {
     108         431 :         DATA_BLOB blob;
     109         431 :         NTSTATUS status;
     110             : 
     111      157821 :         memset(hash, '\0', XATTR_SD_HASH_SIZE);
     112      157821 :         status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
     113      157821 :         if (!NT_STATUS_IS_OK(status)) {
     114           0 :                 return status;
     115             :         }
     116      157821 :         return hash_blob_sha256(blob, hash);
     117             : }
     118             : 
     119             : /*******************************************************************
     120             :  Parse out a struct security_descriptor from a DATA_BLOB.
     121             : *******************************************************************/
     122             : 
     123      755835 : 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        1093 :         struct xattr_NTACL xacl;
     132        1093 :         enum ndr_err_code ndr_err;
     133        1093 :         size_t sd_size;
     134      755835 :         TALLOC_CTX *frame = talloc_stackframe();
     135             : 
     136      755835 :         ndr_err = ndr_pull_struct_blob(pblob, frame, &xacl,
     137             :                         (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);
     138             : 
     139      755835 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     140           0 :                 DBG_INFO("ndr_pull_xattr_NTACL failed: %s\n",
     141             :                          ndr_errstr(ndr_err));
     142           0 :                 TALLOC_FREE(frame);
     143           0 :                 return ndr_map_error2ntstatus(ndr_err);
     144             :         }
     145             : 
     146      755835 :         *p_version = xacl.version;
     147             : 
     148      755835 :         switch (xacl.version) {
     149         108 :                 case 1:
     150         216 :                         *ppdesc = make_sec_desc(mem_ctx, SD_REVISION,
     151         108 :                                         xacl.info.sd->type | SEC_DESC_SELF_RELATIVE,
     152         108 :                                         xacl.info.sd->owner_sid,
     153         108 :                                         xacl.info.sd->group_sid,
     154         108 :                                         xacl.info.sd->sacl,
     155         108 :                                         xacl.info.sd->dacl,
     156             :                                         &sd_size);
     157             :                         /* No hash - null out. */
     158         108 :                         *p_hash_type = XATTR_SD_HASH_TYPE_NONE;
     159         108 :                         memset(hash, '\0', XATTR_SD_HASH_SIZE);
     160         108 :                         break;
     161           0 :                 case 2:
     162           0 :                         *ppdesc = make_sec_desc(mem_ctx, SD_REVISION,
     163           0 :                                         xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE,
     164           0 :                                         xacl.info.sd_hs2->sd->owner_sid,
     165           0 :                                         xacl.info.sd_hs2->sd->group_sid,
     166           0 :                                         xacl.info.sd_hs2->sd->sacl,
     167           0 :                                         xacl.info.sd_hs2->sd->dacl,
     168             :                                         &sd_size);
     169             :                         /* No hash - null out. */
     170           0 :                         *p_hash_type = XATTR_SD_HASH_TYPE_NONE;
     171           0 :                         memset(hash, '\0', XATTR_SD_HASH_SIZE);
     172           0 :                         break;
     173         180 :                 case 3:
     174         360 :                         *ppdesc = make_sec_desc(mem_ctx, SD_REVISION,
     175         180 :                                         xacl.info.sd_hs3->sd->type | SEC_DESC_SELF_RELATIVE,
     176         180 :                                         xacl.info.sd_hs3->sd->owner_sid,
     177         180 :                                         xacl.info.sd_hs3->sd->group_sid,
     178         180 :                                         xacl.info.sd_hs3->sd->sacl,
     179         180 :                                         xacl.info.sd_hs3->sd->dacl,
     180             :                                         &sd_size);
     181         180 :                         *p_hash_type = xacl.info.sd_hs3->hash_type;
     182             :                         /* Current version 3 (if no sys acl hash available). */
     183         180 :                         memcpy(hash, xacl.info.sd_hs3->hash, XATTR_SD_HASH_SIZE);
     184         180 :                         break;
     185      755547 :                 case 4:
     186     1511094 :                         *ppdesc = make_sec_desc(mem_ctx, SD_REVISION,
     187      755547 :                                         xacl.info.sd_hs4->sd->type | SEC_DESC_SELF_RELATIVE,
     188      755547 :                                         xacl.info.sd_hs4->sd->owner_sid,
     189      755547 :                                         xacl.info.sd_hs4->sd->group_sid,
     190      754454 :                                         xacl.info.sd_hs4->sd->sacl,
     191      755547 :                                         xacl.info.sd_hs4->sd->dacl,
     192             :                                         &sd_size);
     193      755547 :                         *p_hash_type = xacl.info.sd_hs4->hash_type;
     194             :                         /* Current version 4. */
     195      755547 :                         memcpy(hash, xacl.info.sd_hs4->hash, XATTR_SD_HASH_SIZE);
     196      755547 :                         memcpy(sys_acl_hash, xacl.info.sd_hs4->sys_acl_hash, XATTR_SD_HASH_SIZE);
     197      754454 :                         break;
     198           0 :                 default:
     199           0 :                         TALLOC_FREE(frame);
     200           0 :                         return NT_STATUS_REVISION_MISMATCH;
     201             :         }
     202             : 
     203      755835 :         TALLOC_FREE(frame);
     204             : 
     205      755835 :         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      157867 : 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         431 :         struct xattr_NTACL xacl;
     219         431 :         struct security_descriptor_hash_v3 sd_hs3;
     220         431 :         enum ndr_err_code ndr_err;
     221      157867 :         TALLOC_CTX *ctx = talloc_tos();
     222             : 
     223      157867 :         ZERO_STRUCT(xacl);
     224      157867 :         ZERO_STRUCT(sd_hs3);
     225             : 
     226      157867 :         xacl.version = 3;
     227      157867 :         xacl.info.sd_hs3 = &sd_hs3;
     228      157867 :         xacl.info.sd_hs3->sd = discard_const_p(struct security_descriptor, psd);
     229      157867 :         xacl.info.sd_hs3->hash_type = hash_type;
     230      157867 :         memcpy(&xacl.info.sd_hs3->hash[0], hash, XATTR_SD_HASH_SIZE);
     231             : 
     232      157867 :         ndr_err = ndr_push_struct_blob(
     233             :                         pblob, ctx, &xacl,
     234             :                         (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
     235             : 
     236      157867 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     237           0 :                 DBG_INFO("ndr_push_xattr_NTACL failed: %s\n",
     238             :                          ndr_errstr(ndr_err));
     239           0 :                 return ndr_map_error2ntstatus(ndr_err);
     240             :         }
     241             : 
     242      157867 :         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      157647 : 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         431 :         struct xattr_NTACL xacl;
     259         431 :         struct security_descriptor_hash_v4 sd_hs4;
     260         431 :         enum ndr_err_code ndr_err;
     261      157647 :         TALLOC_CTX *ctx = talloc_tos();
     262             : 
     263      157647 :         ZERO_STRUCT(xacl);
     264      157647 :         ZERO_STRUCT(sd_hs4);
     265             : 
     266      157647 :         xacl.version = 4;
     267      157647 :         xacl.info.sd_hs4 = &sd_hs4;
     268      157647 :         xacl.info.sd_hs4->sd = discard_const_p(struct security_descriptor, psd);
     269      157647 :         xacl.info.sd_hs4->hash_type = hash_type;
     270      157647 :         memcpy(&xacl.info.sd_hs4->hash[0], hash, XATTR_SD_HASH_SIZE);
     271      157647 :         xacl.info.sd_hs4->description = description;
     272      157647 :         memcpy(&xacl.info.sd_hs4->sys_acl_hash[0], sys_acl_hash, XATTR_SD_HASH_SIZE);
     273             : 
     274      157647 :         ndr_err = ndr_push_struct_blob(
     275             :                         pblob, ctx, &xacl,
     276             :                         (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
     277             : 
     278      157647 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     279           0 :                 DBG_INFO("ndr_push_xattr_NTACL failed: %s\n",
     280             :                          ndr_errstr(ndr_err));
     281           0 :                 return ndr_map_error2ntstatus(ndr_err);
     282             :         }
     283             : 
     284      157647 :         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       50986 : 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       50986 :         struct connection_struct *conn = handle->conn;
     298       50986 :         int num_aces = (psd->dacl ? psd->dacl->num_aces : 0);
     299         939 :         struct smb_filename smb_fname;
     300         939 :         enum security_ace_type acltype;
     301         939 :         uint32_t access_mask;
     302         939 :         mode_t dir_mode;
     303         939 :         mode_t file_mode;
     304         939 :         mode_t mode;
     305         939 :         struct security_ace *new_ace_list;
     306             : 
     307       50986 :         if (psd->dacl) {
     308       50986 :                 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           0 :                 new_ace_list = talloc_zero_array(talloc_tos(),
     317             :                                                  struct security_ace,
     318             :                                                  num_aces + 3);
     319             :         }
     320             : 
     321       50986 :         if (new_ace_list == NULL) {
     322           0 :                 return NT_STATUS_NO_MEMORY;
     323             :         }
     324             : 
     325             :         /* Fake a quick smb_filename. */
     326       50986 :         ZERO_STRUCT(smb_fname);
     327       50986 :         smb_fname.st = *psbuf;
     328       50986 :         smb_fname.base_name = discard_const_p(char, name);
     329             : 
     330       50986 :         dir_mode = unix_mode(conn,
     331             :                         FILE_ATTRIBUTE_DIRECTORY, &smb_fname, NULL);
     332       50986 :         file_mode = unix_mode(conn,
     333             :                         FILE_ATTRIBUTE_ARCHIVE, &smb_fname, NULL);
     334             : 
     335       50986 :         mode = dir_mode | file_mode;
     336             : 
     337       50986 :         DBG_DEBUG("directory %s, mode = 0%o\n", name, (unsigned int)mode);
     338             : 
     339       50986 :         if (num_aces) {
     340       50986 :                 memcpy(new_ace_list, psd->dacl->aces,
     341             :                         num_aces * sizeof(struct security_ace));
     342             :         }
     343       50986 :         access_mask = map_canon_ace_perms(SNUM(conn), &acltype,
     344             :                                 mode & 0700, false);
     345             : 
     346       50986 :         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       50986 :         access_mask = map_canon_ace_perms(SNUM(conn), &acltype,
     354       50986 :                                 (mode << 3) & 0700, false);
     355       50986 :         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       50986 :         access_mask = map_canon_ace_perms(SNUM(conn), &acltype,
     363       50986 :                                 (mode << 6) & 0700, false);
     364       50986 :         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       50986 :         if (psd->dacl) {
     372       50986 :                 psd->dacl->aces = new_ace_list;
     373       50986 :                 psd->dacl->num_aces += 3;
     374       50986 :                 psd->dacl->size += new_ace_list[num_aces].size +
     375       50986 :                         new_ace_list[num_aces+1].size +
     376       50986 :                         new_ace_list[num_aces+2].size;
     377             :         } else {
     378           0 :                 psd->dacl = make_sec_acl(psd,
     379             :                                 NT4_ACL_REVISION,
     380             :                                 3,
     381             :                                 new_ace_list);
     382           0 :                 if (psd->dacl == NULL) {
     383           0 :                         return NT_STATUS_NO_MEMORY;
     384             :                 }
     385             :         }
     386       50986 :         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      755835 : 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        1093 :         NTSTATUS status;
     416      755835 :         uint16_t hash_type = XATTR_SD_HASH_TYPE_NONE;
     417      755835 :         uint16_t xattr_version = 0;
     418        1093 :         uint8_t hash[XATTR_SD_HASH_SIZE];
     419        1093 :         uint8_t sys_acl_hash[XATTR_SD_HASH_SIZE];
     420        1093 :         uint8_t hash_tmp[XATTR_SD_HASH_SIZE];
     421        1093 :         uint8_t sys_acl_hash_tmp[XATTR_SD_HASH_SIZE];
     422      755835 :         struct security_descriptor *psd = NULL;
     423      755835 :         struct security_descriptor *psd_blob = NULL;
     424      755835 :         struct security_descriptor *psd_fs = NULL;
     425      755835 :         char *sys_acl_blob_description = NULL;
     426      755835 :         DATA_BLOB sys_acl_blob = { 0 };
     427      755835 :         struct acl_common_config *config = NULL;
     428             : 
     429      755835 :         *ppsd = NULL;
     430      755835 :         *psd_is_from_fs = false;
     431             : 
     432      755835 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     433             :                                 struct acl_common_config,
     434        1093 :                                 return NT_STATUS_UNSUCCESSFUL);
     435             : 
     436      755835 :         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      755835 :         if (!NT_STATUS_IS_OK(status)) {
     444           0 :                 DBG_DEBUG("parse_acl_blob returned %s\n", nt_errstr(status));
     445           0 :                 goto fail;
     446             :         }
     447             : 
     448             :         /* determine which type of xattr we got */
     449      755835 :         switch (xattr_version) {
     450         108 :         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         108 :                 *ppsd = psd_blob;
     457         312 :                 return NT_STATUS_OK;
     458      755727 :         case 3:
     459             :         case 4:
     460      755727 :                 if (config->ignore_system_acls) {
     461         204 :                         *ppsd = psd_blob;
     462         204 :                         return NT_STATUS_OK;
     463             :                 }
     464             : 
     465      755523 :                 break;
     466           0 :         default:
     467           0 :                 DBG_DEBUG("ACL blob revision mismatch (%u) for file %s\n",
     468             :                           (unsigned int)hash_type, smb_fname->base_name);
     469           0 :                 TALLOC_FREE(psd_blob);
     470           0 :                 return NT_STATUS_OK;
     471             :         }
     472             : 
     473             :         /* determine which type of xattr we got */
     474      755523 :         if (hash_type != XATTR_SD_HASH_TYPE_SHA256) {
     475           0 :                 DBG_DEBUG("ACL blob hash type (%u) unexpected for file %s\n",
     476             :                           (unsigned int)hash_type, smb_fname->base_name);
     477           0 :                 TALLOC_FREE(psd_blob);
     478           0 :                 return NT_STATUS_OK;
     479             :         }
     480             : 
     481             :         /* determine which type of xattr we got */
     482      755523 :         switch (xattr_version) {
     483      755511 :         case 4:
     484             :         {
     485        1093 :                 int ret;
     486             :                 /* Get the full underlying sd, then hash. */
     487      755511 :                 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      755511 :                 if (ret == 0) {
     495      755511 :                         status = hash_blob_sha256(sys_acl_blob, sys_acl_hash_tmp);
     496      755511 :                         if (!NT_STATUS_IS_OK(status)) {
     497           0 :                                 goto fail;
     498             :                         }
     499             : 
     500      755511 :                         TALLOC_FREE(sys_acl_blob_description);
     501      755511 :                         TALLOC_FREE(sys_acl_blob.data);
     502             : 
     503      755511 :                         if (memcmp(&sys_acl_hash[0], &sys_acl_hash_tmp[0], 
     504             :                                    XATTR_SD_HASH_SIZE) == 0) {
     505             :                                 /* Hash matches, return blob sd. */
     506      755349 :                                 DBG_DEBUG("blob hash matches for file %s\n",
     507             :                                           smb_fname->base_name);
     508      755349 :                                 *ppsd = psd_blob;
     509      755349 :                                 return NT_STATUS_OK;
     510             :                         }
     511             :                 }
     512             : 
     513             :                 /* Otherwise, fall though and see if the NT ACL hash matches */
     514           0 :                 FALL_THROUGH;
     515             :         }
     516             :         case 3:
     517             :                 /* Get the full underlying sd for the hash
     518             :                    or to return as backup. */
     519         174 :                 status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
     520             :                                                   fsp,
     521             :                                                   HASH_SECURITY_INFO,
     522             :                                                   mem_ctx,
     523             :                                                   &psd_fs);
     524         174 :                 if (!NT_STATUS_IS_OK(status)) {
     525           0 :                         DBG_DEBUG("get_next_acl for file %s returned %s\n",
     526             :                                   smb_fname->base_name, nt_errstr(status));
     527           0 :                         goto fail;
     528             :                 }
     529             : 
     530         174 :                 status = hash_sd_sha256(psd_fs, hash_tmp);
     531         174 :                 if (!NT_STATUS_IS_OK(status)) {
     532           0 :                         TALLOC_FREE(psd_blob);
     533           0 :                         *ppsd = psd_fs;
     534           0 :                         *psd_is_from_fs = true;
     535           0 :                         return NT_STATUS_OK;
     536             :                 }
     537             : 
     538         174 :                 if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) {
     539             :                         /* Hash matches, return blob sd. */
     540          14 :                         DBG_DEBUG("blob hash matches for file %s\n",
     541             :                                   smb_fname->base_name);
     542          14 :                         *ppsd = psd_blob;
     543          14 :                         return NT_STATUS_OK;
     544             :                 }
     545             : 
     546             :                 /* Hash doesn't match, return underlying sd. */
     547         160 :                 DBG_DEBUG("blob hash does not match for file %s - returning "
     548             :                           "file system SD mapping.\n",
     549             :                           smb_fname->base_name);
     550             : 
     551         160 :                 if (DEBUGLEVEL >= 10) {
     552           0 :                         DBG_DEBUG("acl for blob hash for %s is:\n",
     553             :                                   smb_fname->base_name);
     554           0 :                         NDR_PRINT_DEBUG(security_descriptor, psd_fs);
     555             :                 }
     556             : 
     557         160 :                 TALLOC_FREE(psd_blob);
     558         160 :                 *ppsd = psd_fs;
     559         160 :                 *psd_is_from_fs = true;
     560             :         }
     561             : 
     562         160 :         return NT_STATUS_OK;
     563             : 
     564           0 : fail:
     565           0 :         TALLOC_FREE(psd);
     566           0 :         TALLOC_FREE(psd_blob);
     567           0 :         TALLOC_FREE(psd_fs);
     568           0 :         TALLOC_FREE(sys_acl_blob_description);
     569           0 :         TALLOC_FREE(sys_acl_blob.data);
     570           0 :         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      948769 : 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      948769 :         DATA_BLOB blob = data_blob_null;
     591        2317 :         NTSTATUS status;
     592      948769 :         struct security_descriptor *psd = NULL;
     593      948769 :         const struct smb_filename *smb_fname = fsp->fsp_name;
     594      948769 :         bool psd_is_from_fs = false;
     595      948769 :         struct acl_common_config *config = NULL;
     596             : 
     597      948769 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     598             :                                 struct acl_common_config,
     599        2317 :                                 return NT_STATUS_UNSUCCESSFUL);
     600             : 
     601      948769 :         DBG_DEBUG("name=%s\n", smb_fname->base_name);
     602             : 
     603      948769 :         status = fget_acl_blob_fn(mem_ctx, handle, fsp, &blob);
     604      948769 :         if (NT_STATUS_IS_OK(status)) {
     605      755835 :                 status = validate_nt_acl_blob(mem_ctx,
     606             :                                         handle,
     607             :                                         fsp,
     608             :                                         smb_fname,
     609             :                                         &blob,
     610             :                                         &psd,
     611             :                                         &psd_is_from_fs);
     612      755835 :                 TALLOC_FREE(blob.data);
     613      755835 :                 if (!NT_STATUS_IS_OK(status)) {
     614           0 :                         DBG_DEBUG("ACL validation for [%s] failed\n",
     615             :                                   smb_fname->base_name);
     616           0 :                         goto fail;
     617             :                 }
     618             :         }
     619             : 
     620      948769 :         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      192934 :                 if (config->ignore_system_acls) {
     626         286 :                         status = vfs_stat_fsp(fsp);
     627         286 :                         if (!NT_STATUS_IS_OK(status)) {
     628           0 :                                 goto fail;
     629             :                         }
     630             : 
     631         286 :                         status = make_default_filesystem_acl(
     632             :                                 mem_ctx,
     633             :                                 config->default_acl_style,
     634         286 :                                 smb_fname->base_name,
     635         286 :                                 &fsp->fsp_name->st,
     636             :                                 &psd);
     637         286 :                         if (!NT_STATUS_IS_OK(status)) {
     638           0 :                                 goto fail;
     639             :                         }
     640             :                 } else {
     641      192648 :                         status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
     642             :                                                           fsp,
     643             :                                                           security_info,
     644             :                                                           mem_ctx,
     645             :                                                           &psd);
     646             : 
     647      192648 :                         if (!NT_STATUS_IS_OK(status)) {
     648           0 :                                 DBG_DEBUG("get_next_acl for file %s "
     649             :                                           "returned %s\n",
     650             :                                           smb_fname->base_name,
     651             :                                           nt_errstr(status));
     652           0 :                                 goto fail;
     653             :                         }
     654             : 
     655      192648 :                         psd_is_from_fs = true;
     656             :                 }
     657             :         }
     658             : 
     659      948769 :         if (psd_is_from_fs) {
     660      192808 :                 status = vfs_stat_fsp(fsp);
     661      192808 :                 if (!NT_STATUS_IS_OK(status)) {
     662           0 :                         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      193747 :                 if (fsp->fsp_flags.is_directory &&
     672       51410 :                                 !sd_has_inheritable_components(psd, true)) {
     673       51925 :                         status = add_directory_inheritable_components(
     674             :                                 handle,
     675       50986 :                                 smb_fname->base_name,
     676       50986 :                                 &fsp->fsp_name->st,
     677             :                                 psd);
     678       50986 :                         if (!NT_STATUS_IS_OK(status)) {
     679           0 :                                 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      192808 :                 psd->type &= ~SEC_DESC_DACL_PROTECTED;
     689             :         }
     690             : 
     691      948769 :         if (!(security_info & SECINFO_OWNER)) {
     692      306548 :                 psd->owner_sid = NULL;
     693             :         }
     694      948769 :         if (!(security_info & SECINFO_GROUP)) {
     695      311418 :                 psd->group_sid = NULL;
     696             :         }
     697      948769 :         if (!(security_info & SECINFO_DACL)) {
     698          12 :                 psd->type &= ~SEC_DESC_DACL_PRESENT;
     699          12 :                 psd->dacl = NULL;
     700             :         }
     701      948769 :         if (!(security_info & SECINFO_SACL)) {
     702      790206 :                 psd->type &= ~SEC_DESC_SACL_PRESENT;
     703      790206 :                 psd->sacl = NULL;
     704             :         }
     705             : 
     706      948769 :         if (DEBUGLEVEL >= 10) {
     707           0 :                 DBG_DEBUG("returning acl for %s is:\n",
     708             :                           smb_fname->base_name);
     709           0 :                 NDR_PRINT_DEBUG(security_descriptor, psd);
     710             :         }
     711             : 
     712      948769 :         *ppdesc = psd;
     713             : 
     714      948769 :         return NT_STATUS_OK;
     715             : 
     716           0 : fail:
     717           0 :         TALLOC_FREE(psd);
     718           0 :         return status;
     719             : }
     720             : 
     721             : /*********************************************************************
     722             :  Set the underlying ACL (e.g. POSIX ACLS, POSIX owner, etc)
     723             : *********************************************************************/
     724      157671 : 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         431 :         NTSTATUS status;
     730      157671 :         const struct security_token *token = NULL;
     731         431 :         struct dom_sid_buf buf;
     732             : 
     733      157671 :         status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
     734      157671 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
     735      157671 :                 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           0 :         if (get_current_uid(handle->conn) == 0 || !chown_needed) {
     742           0 :                 return NT_STATUS_ACCESS_DENIED;
     743             :         }
     744           0 :         status = check_any_access_fsp(fsp, SEC_STD_WRITE_OWNER);
     745           0 :         if (!NT_STATUS_IS_OK(status)) {
     746           0 :                 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           0 :         token = get_current_nttok(fsp->conn);
     757           0 :         if (!security_token_is_sid(token, psd->owner_sid)) {
     758           0 :                 return NT_STATUS_INVALID_OWNER;
     759             :         }
     760             : 
     761           0 :         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           0 :         become_root();
     768           0 :         status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
     769           0 :         unbecome_root();
     770             : 
     771           0 :         return status;
     772             : }
     773             : 
     774             : /*********************************************************************
     775             :  Store a v3 security descriptor
     776             : *********************************************************************/
     777          46 : 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           0 :         NTSTATUS status;
     787           0 :         DATA_BLOB blob;
     788             : 
     789          46 :         if (DEBUGLEVEL >= 10) {
     790           0 :                 DBG_DEBUG("storing xattr sd for file %s\n",
     791             :                           fsp_str_dbg(fsp));
     792           0 :                 NDR_PRINT_DEBUG(
     793             :                     security_descriptor,
     794             :                     discard_const_p(struct security_descriptor, psd));
     795             : 
     796           0 :                 if (pdesc_next != NULL) {
     797           0 :                         DBG_DEBUG("storing xattr sd based on \n");
     798           0 :                         NDR_PRINT_DEBUG(
     799             :                             security_descriptor,
     800             :                             discard_const_p(struct security_descriptor,
     801             :                                             pdesc_next));
     802             :                 } else {
     803           0 :                         DBG_DEBUG("ignoring underlying sd\n");
     804             :                 }
     805             :         }
     806          46 :         status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash);
     807          46 :         if (!NT_STATUS_IS_OK(status)) {
     808           0 :                 DBG_DEBUG("create_acl_blob failed\n");
     809           0 :                 return status;
     810             :         }
     811             : 
     812          46 :         status = store_acl_blob_fsp_fn(handle, fsp, &blob);
     813          46 :         return status;
     814             : }
     815             : 
     816             : /*********************************************************************
     817             :  Store a security descriptor given an fsp.
     818             : *********************************************************************/
     819             : 
     820      157695 : 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         431 :         NTSTATUS status;
     834         431 :         int ret;
     835         431 :         DATA_BLOB blob, sys_acl_blob;
     836      157695 :         struct security_descriptor *pdesc_next = NULL;
     837      157695 :         struct security_descriptor *psd = NULL;
     838         431 :         uint8_t hash[XATTR_SD_HASH_SIZE];
     839         431 :         uint8_t sys_acl_hash[XATTR_SD_HASH_SIZE];
     840      157695 :         bool chown_needed = false;
     841         431 :         char *sys_acl_description;
     842      157695 :         TALLOC_CTX *frame = talloc_stackframe();
     843      157695 :         bool ignore_file_system_acl = lp_parm_bool(
     844      157695 :             SNUM(handle->conn), module_name, "ignore system acls", false);
     845      157695 :         struct acl_common_fsp_ext *ext = NULL;
     846             : 
     847      157695 :         if (DEBUGLEVEL >= 10) {
     848           0 :                 DBG_DEBUG("incoming sd for file %s\n", fsp_str_dbg(fsp));
     849           0 :                 NDR_PRINT_DEBUG(security_descriptor,
     850             :                         discard_const_p(struct security_descriptor, orig_psd));
     851             :         }
     852             : 
     853      157695 :         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      157695 :         if (!NT_STATUS_IS_OK(status)) {
     859           0 :                 TALLOC_FREE(frame);
     860           0 :                 return status;
     861             :         }
     862             : 
     863      157695 :         psd->revision = orig_psd->revision;
     864      157695 :         if (security_info_sent & SECINFO_DACL) {
     865      155607 :                 psd->type = orig_psd->type;
     866             :                 /* All our SD's are self relative. */
     867      155607 :                 psd->type |= SEC_DESC_SELF_RELATIVE;
     868             :         }
     869             : 
     870      157695 :         if ((security_info_sent & SECINFO_OWNER) && (orig_psd->owner_sid != NULL)) {
     871      153176 :                 if (!dom_sid_equal(orig_psd->owner_sid, psd->owner_sid)) {
     872             :                         /* We're changing the owner. */
     873       61914 :                         chown_needed = true;
     874             :                 }
     875      153176 :                 psd->owner_sid = orig_psd->owner_sid;
     876             :         }
     877      157695 :         if ((security_info_sent & SECINFO_GROUP) && (orig_psd->group_sid != NULL)) {
     878      150884 :                 if (!dom_sid_equal(orig_psd->group_sid, psd->group_sid)) {
     879             :                         /* We're changing the group. */
     880      148757 :                         chown_needed = true;
     881             :                 }
     882      150884 :                 psd->group_sid = orig_psd->group_sid;
     883             :         }
     884      157695 :         if (security_info_sent & SECINFO_DACL) {
     885      155607 :                 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           0 :                         TALLOC_FREE(frame);
     892           0 :                         return NT_STATUS_OK;
     893             :                 }
     894      155607 :                 psd->dacl = orig_psd->dacl;
     895      155607 :                 psd->type |= SEC_DESC_DACL_PRESENT;
     896             :         }
     897      157695 :         if (security_info_sent & SECINFO_SACL) {
     898        2108 :                 psd->sacl = orig_psd->sacl;
     899        2108 :                 psd->type |= SEC_DESC_SACL_PRESENT;
     900             :         }
     901             : 
     902      157695 :         ext = VFS_ADD_FSP_EXTENSION(handle,
     903             :                                     fsp,
     904             :                                     struct acl_common_fsp_ext,
     905             :                                     NULL);
     906      157695 :         ext->setting_nt_acl = true;
     907             : 
     908      157695 :         if (ignore_file_system_acl) {
     909          46 :                 if (chown_needed) {
     910             :                         /* send only ownership stuff to lower layer */
     911          22 :                         security_info_sent &= (SECINFO_OWNER | SECINFO_GROUP);
     912          22 :                         status = set_underlying_acl(handle, fsp, psd,
     913             :                                                     security_info_sent, true);
     914          22 :                         if (!NT_STATUS_IS_OK(status)) {
     915           0 :                                 goto done;
     916             :                         }
     917             :                 }
     918          46 :                 ZERO_ARRAY(hash);
     919          46 :                 status = store_v3_blob(store_acl_blob_fsp_fn, handle, fsp, psd,
     920             :                                        NULL, hash);
     921          46 :                 goto done;
     922             :         }
     923             : 
     924      157649 :         status = set_underlying_acl(handle, fsp, psd, security_info_sent,
     925             :                                     chown_needed);
     926      157649 :         if (!NT_STATUS_IS_OK(status)) {
     927           2 :                 goto done;
     928             :         }
     929             : 
     930             :         /* Get the full underlying sd, then hash. */
     931      157647 :         status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
     932             :                                           fsp,
     933             :                                           HASH_SECURITY_INFO,
     934             :                                           frame,
     935             :                                           &pdesc_next);
     936             : 
     937      157647 :         if (!NT_STATUS_IS_OK(status)) {
     938           0 :                 goto done;
     939             :         }
     940             : 
     941      157647 :         status = hash_sd_sha256(pdesc_next, hash);
     942      157647 :         if (!NT_STATUS_IS_OK(status)) {
     943           0 :                 goto done;
     944             :         }
     945             : 
     946             :         /* Get the full underlying sd, then hash. */
     947      157647 :         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      157647 :         if (ret != 0) {
     956           0 :                 status = store_v3_blob(store_acl_blob_fsp_fn, handle, fsp, psd,
     957             :                                        pdesc_next, hash);
     958             : 
     959           0 :                 goto done;
     960             :         }
     961             : 
     962      157647 :         status = hash_blob_sha256(sys_acl_blob, sys_acl_hash);
     963      157647 :         if (!NT_STATUS_IS_OK(status)) {
     964           0 :                 goto done;
     965             :         }
     966             : 
     967      157647 :         if (DEBUGLEVEL >= 10) {
     968           0 :                 DBG_DEBUG("storing xattr sd for file %s based on system ACL\n",
     969             :                           fsp_str_dbg(fsp));
     970           0 :                 NDR_PRINT_DEBUG(security_descriptor,
     971             :                                 discard_const_p(struct security_descriptor, psd));
     972             : 
     973           0 :                 DBG_DEBUG("storing hash in xattr sd based on system ACL and:\n");
     974           0 :                 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      157647 :         status = create_sys_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash, 
     983             :                                      sys_acl_description, sys_acl_hash);
     984      157647 :         if (!NT_STATUS_IS_OK(status)) {
     985           0 :                 DBG_DEBUG("create_sys_acl_blob failed\n");
     986           0 :                 goto done;
     987             :         }
     988             : 
     989      157647 :         status = store_acl_blob_fsp_fn(handle, fsp, &blob);
     990             : 
     991      157695 : done:
     992      157695 :         VFS_REMOVE_FSP_EXTENSION(handle, fsp);
     993      157695 :         TALLOC_FREE(frame);
     994      157695 :         return status;
     995             : }
     996             : 
     997           0 : 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           0 :         connection_struct *conn = handle->conn;
    1003           0 :         struct file_id id;
    1004           0 :         files_struct *fsp = NULL;
    1005           0 :         int ret = 0;
    1006           0 :         struct smb_filename *full_fname = NULL;
    1007           0 :         struct smb_filename *local_fname = NULL;
    1008           0 :         struct smb_filename *parent_dir_fname = NULL;
    1009           0 :         int saved_errno = 0;
    1010           0 :         struct smb_filename *saved_dir_fname = NULL;
    1011           0 :         NTSTATUS status;
    1012             : 
    1013           0 :         saved_dir_fname = vfs_GetWd(talloc_tos(),conn);
    1014           0 :         if (saved_dir_fname == NULL) {
    1015           0 :                 saved_errno = errno;
    1016           0 :                 goto out;
    1017             :         }
    1018             : 
    1019           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
    1020             :                                                   dirfsp,
    1021             :                                                   smb_fname);
    1022           0 :         if (full_fname == NULL) {
    1023           0 :                 goto out;
    1024             :         }
    1025             : 
    1026           0 :         status = SMB_VFS_PARENT_PATHNAME(conn,
    1027             :                                          talloc_tos(),
    1028             :                                          full_fname,
    1029             :                                          &parent_dir_fname,
    1030             :                                          &local_fname);
    1031           0 :         if (!NT_STATUS_IS_OK(status)) {
    1032           0 :                 saved_errno = map_errno_from_nt_status(status);
    1033           0 :                 goto out;
    1034             :         }
    1035             : 
    1036           0 :         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           0 :         ret = vfs_ChDir(conn, parent_dir_fname);
    1041           0 :         if (ret == -1) {
    1042           0 :                 saved_errno = errno;
    1043           0 :                 goto out;
    1044             :         }
    1045             : 
    1046             :         /* Must use lstat here. */
    1047           0 :         ret = SMB_VFS_LSTAT(conn, local_fname);
    1048           0 :         if (ret == -1) {
    1049           0 :                 saved_errno = errno;
    1050           0 :                 goto out;
    1051             :         }
    1052             : 
    1053             :         /* Ensure we have this file open with DELETE access. */
    1054           0 :         id = vfs_file_id_from_sbuf(conn, &local_fname->st);
    1055           0 :         for (fsp = file_find_di_first(conn->sconn, id, true); fsp;
    1056           0 :                      fsp = file_find_di_next(fsp, true)) {
    1057           0 :                 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           0 :                         break;
    1064             :                 }
    1065             :         }
    1066             : 
    1067           0 :         if (!fsp) {
    1068           0 :                 DBG_DEBUG("%s %s not an open file\n",
    1069             :                           is_directory ? "directory" : "file",
    1070             :                           smb_fname_str_dbg(full_fname));
    1071           0 :                 saved_errno = EACCES;
    1072           0 :                 goto out;
    1073             :         }
    1074             : 
    1075           0 :         become_root();
    1076           0 :         if (is_directory) {
    1077           0 :                 ret = SMB_VFS_NEXT_UNLINKAT(handle,
    1078             :                                 dirfsp,
    1079             :                                 smb_fname,
    1080             :                                 AT_REMOVEDIR);
    1081             :         } else {
    1082           0 :                 ret = SMB_VFS_NEXT_UNLINKAT(handle,
    1083             :                                 dirfsp,
    1084             :                                 smb_fname,
    1085             :                                 0);
    1086             :         }
    1087           0 :         unbecome_root();
    1088             : 
    1089           0 :         if (ret == -1) {
    1090           0 :                 saved_errno = errno;
    1091             :         }
    1092             : 
    1093           0 :   out:
    1094             : 
    1095           0 :         TALLOC_FREE(parent_dir_fname);
    1096           0 :         TALLOC_FREE(full_fname);
    1097             : 
    1098           0 :         if (saved_dir_fname) {
    1099           0 :                 vfs_ChDir(conn, saved_dir_fname);
    1100           0 :                 TALLOC_FREE(saved_dir_fname);
    1101             :         }
    1102           0 :         if (saved_errno) {
    1103           0 :                 errno = saved_errno;
    1104             :         }
    1105           0 :         return ret;
    1106             : }
    1107             : 
    1108       10007 : int rmdir_acl_common(struct vfs_handle_struct *handle,
    1109             :                 struct files_struct *dirfsp,
    1110             :                 const struct smb_filename *smb_fname)
    1111             : {
    1112          64 :         int ret;
    1113             : 
    1114             :         /* Try the normal rmdir first. */
    1115       10007 :         ret = SMB_VFS_NEXT_UNLINKAT(handle,
    1116             :                         dirfsp,
    1117             :                         smb_fname,
    1118             :                         AT_REMOVEDIR);
    1119       10007 :         if (ret == 0) {
    1120        9927 :                 return 0;
    1121             :         }
    1122          16 :         if (errno == EACCES || errno == EPERM) {
    1123             :                 /* Failed due to access denied,
    1124             :                    see if we need to root override. */
    1125           0 :                 return acl_common_remove_object(handle,
    1126             :                                                 dirfsp,
    1127             :                                                 smb_fname,
    1128             :                                                 true);
    1129             :         }
    1130             : 
    1131          16 :         DBG_DEBUG("unlink of %s failed %s\n",
    1132             :                   smb_fname->base_name,
    1133             :                   strerror(errno));
    1134          16 :         return -1;
    1135             : }
    1136             : 
    1137      138521 : 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         273 :         int ret;
    1143             : 
    1144             :         /* Try the normal unlink first. */
    1145      138521 :         ret = SMB_VFS_NEXT_UNLINKAT(handle,
    1146             :                                 dirfsp,
    1147             :                                 smb_fname,
    1148             :                                 flags);
    1149      138521 :         if (ret == 0) {
    1150      137752 :                 return 0;
    1151             :         }
    1152         496 :         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           0 :                 if (smb_fname->stream_name) {
    1158           0 :                         return -1;
    1159             :                 }
    1160           0 :                 return acl_common_remove_object(handle,
    1161             :                                         dirfsp,
    1162             :                                         smb_fname,
    1163             :                                         false);
    1164             :         }
    1165             : 
    1166         496 :         DBG_DEBUG("unlink of %s failed %s\n",
    1167             :                   smb_fname->base_name,
    1168             :                   strerror(errno));
    1169         496 :         return -1;
    1170             : }
    1171             : 
    1172         278 : int fchmod_acl_module_common(struct vfs_handle_struct *handle,
    1173             :                              struct files_struct *fsp, mode_t mode)
    1174             : {
    1175         278 :         if (fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES
    1176         278 :             || fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
    1177             :                 /* Only allow this on POSIX opens. */
    1178          12 :                 return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
    1179             :         }
    1180         244 :         return 0;
    1181             : }

Generated by: LCOV version 1.14