X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source3%2Fmodules%2Fvfs_acl_common.c;h=66c58e73ad50d351066a5548256aab3a117ce51b;hb=335527c647331148927feea2a7ae2f2c88986bc6;hp=30574e0e06fcb9e146039be7287a7350721b00de;hpb=616d068f0cebb8e50a855b6e30f36fccb7f5a3c8;p=gd%2Fsamba-autobuild%2F.git diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index 30574e0e06f..66c58e73ad5 100644 --- a/source3/modules/vfs_acl_common.c +++ b/source3/modules/vfs_acl_common.c @@ -24,6 +24,7 @@ #include "../libcli/security/security.h" #include "../librpc/gen_ndr/ndr_security.h" #include "../lib/util/bitmap.h" +#include "passdb/lookup_sid.h" static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob, @@ -33,7 +34,7 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd, static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, vfs_handle_struct *handle, files_struct *fsp, - const char *name, + const struct smb_filename *smb_fname, DATA_BLOB *pblob); static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, @@ -358,6 +359,114 @@ static NTSTATUS add_directory_inheritable_components(vfs_handle_struct *handle, return NT_STATUS_OK; } +static NTSTATUS make_default_filesystem_acl(TALLOC_CTX *ctx, + const char *name, + SMB_STRUCT_STAT *psbuf, + struct security_descriptor **ppdesc) +{ + struct dom_sid owner_sid, group_sid; + size_t size = 0; + struct security_ace aces[4]; + uint32_t access_mask = 0; + mode_t mode = psbuf->st_ex_mode; + struct security_acl *new_dacl = NULL; + int idx = 0; + + DEBUG(10,("make_default_filesystem_acl: file %s mode = 0%o\n", + name, (int)mode )); + + uid_to_sid(&owner_sid, psbuf->st_ex_uid); + gid_to_sid(&group_sid, psbuf->st_ex_gid); + + /* + We provide up to 4 ACEs + - Owner + - Group + - Everyone + - NT System + */ + + if (mode & S_IRUSR) { + if (mode & S_IWUSR) { + access_mask |= SEC_RIGHTS_FILE_ALL; + } else { + access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; + } + } + if (mode & S_IWUSR) { + access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE; + } + + init_sec_ace(&aces[idx], + &owner_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, + access_mask, + 0); + idx++; + + access_mask = 0; + if (mode & S_IRGRP) { + access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; + } + if (mode & S_IWGRP) { + /* note that delete is not granted - this matches posix behaviour */ + access_mask |= SEC_RIGHTS_FILE_WRITE; + } + if (access_mask) { + init_sec_ace(&aces[idx], + &group_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, + access_mask, + 0); + idx++; + } + + access_mask = 0; + if (mode & S_IROTH) { + access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; + } + if (mode & S_IWOTH) { + access_mask |= SEC_RIGHTS_FILE_WRITE; + } + if (access_mask) { + init_sec_ace(&aces[idx], + &global_sid_World, + SEC_ACE_TYPE_ACCESS_ALLOWED, + access_mask, + 0); + idx++; + } + + init_sec_ace(&aces[idx], + &global_sid_System, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_RIGHTS_FILE_ALL, + 0); + idx++; + + new_dacl = make_sec_acl(ctx, + NT4_ACL_REVISION, + idx, + aces); + + if (!new_dacl) { + return NT_STATUS_NO_MEMORY; + } + + *ppdesc = make_sec_desc(ctx, + SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT, + &owner_sid, + &group_sid, + NULL, + new_dacl, + &size); + if (!*ppdesc) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + /******************************************************************* Pull a DATA_BLOB from an xattr given a pathname. If the hash doesn't match, or doesn't exist - return the underlying @@ -366,7 +475,7 @@ static NTSTATUS add_directory_inheritable_components(vfs_handle_struct *handle, static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, files_struct *fsp, - const struct smb_filename *smb_fname, + const struct smb_filename *smb_fname_in, uint32_t security_info, TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) @@ -380,45 +489,42 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, uint8_t hash_tmp[XATTR_SD_HASH_SIZE]; uint8_t sys_acl_hash_tmp[XATTR_SD_HASH_SIZE]; struct security_descriptor *psd = NULL; - struct security_descriptor *pdesc_next = NULL; - const char *name = NULL; + struct security_descriptor *psd_blob = NULL; + struct security_descriptor *psd_fs = NULL; + const struct smb_filename *smb_fname = NULL; bool ignore_file_system_acl = lp_parm_bool(SNUM(handle->conn), ACL_MODULE_NAME, "ignore system acls", false); - TALLOC_CTX *frame = talloc_stackframe(); + char *sys_acl_blob_description = NULL; + DATA_BLOB sys_acl_blob = { 0 }; + bool psd_is_from_fs = false; - if (fsp && smb_fname == NULL) { - name = fsp->fsp_name->base_name; + if (fsp && smb_fname_in == NULL) { + smb_fname = fsp->fsp_name; } else { - name = smb_fname->base_name; + smb_fname = smb_fname_in; } - DEBUG(10, ("get_nt_acl_internal: name=%s\n", name)); + DEBUG(10, ("get_nt_acl_internal: name=%s\n", smb_fname->base_name)); - status = get_acl_blob(frame, handle, fsp, name, &blob); + status = get_acl_blob(mem_ctx, handle, fsp, smb_fname, &blob); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("get_nt_acl_internal: get_acl_blob returned %s\n", nt_errstr(status))); - psd = NULL; goto out; } else { - status = parse_acl_blob(&blob, mem_ctx, &psd, + status = parse_acl_blob(&blob, mem_ctx, &psd_blob, &hash_type, &xattr_version, &hash[0], &sys_acl_hash[0]); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("parse_acl_blob returned %s\n", nt_errstr(status))); - psd = NULL; + TALLOC_FREE(blob.data); goto out; } } - /* Ensure we don't leak psd if we don't choose it. - * - * We don't allocate it onto frame as it is preferred not to - * steal from a talloc pool. - */ - talloc_steal(frame, psd); + TALLOC_FREE(blob.data); /* determine which type of xattr we got */ switch (xattr_version) { @@ -428,10 +534,14 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, * require confirmation of the hash. In particular, * the NTVFS file server uses version 1, but * 'samba-tool ntacl' can set these as well */ + psd = psd_blob; + psd_blob = NULL; goto out; case 3: case 4: if (ignore_file_system_acl) { + psd = psd_blob; + psd_blob = NULL; goto out; } @@ -440,9 +550,8 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, DEBUG(10, ("get_nt_acl_internal: ACL blob revision " "mismatch (%u) for file %s\n", (unsigned int)hash_type, - name)); - TALLOC_FREE(psd); - psd = NULL; + smb_fname->base_name)); + TALLOC_FREE(psd_blob); goto out; } @@ -451,9 +560,8 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, DEBUG(10, ("get_nt_acl_internal: ACL blob hash type " "(%u) unexpected for file %s\n", (unsigned int)hash_type, - name)); - TALLOC_FREE(psd); - psd = NULL; + smb_fname->base_name)); + TALLOC_FREE(psd_blob); goto out; } @@ -462,22 +570,20 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, case 4: { int ret; - char *sys_acl_blob_description; - DATA_BLOB sys_acl_blob; if (fsp) { /* Get the full underlying sd, then hash. */ ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, - frame, + mem_ctx, &sys_acl_blob_description, &sys_acl_blob); } else { /* Get the full underlying sd, then hash. */ ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, - name, - frame, - &sys_acl_blob_description, - &sys_acl_blob); + smb_fname->base_name, + mem_ctx, + &sys_acl_blob_description, + &sys_acl_blob); } /* If we fail to get the ACL blob (for some reason) then this @@ -485,16 +591,20 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, if (ret == 0) { status = hash_blob_sha256(sys_acl_blob, sys_acl_hash_tmp); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(frame); - return status; + goto fail; } + TALLOC_FREE(sys_acl_blob_description); + TALLOC_FREE(sys_acl_blob.data); + if (memcmp(&sys_acl_hash[0], &sys_acl_hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) { /* Hash matches, return blob sd. */ DEBUG(10, ("get_nt_acl_internal: blob hash " "matches for file %s\n", - name )); + smb_fname->base_name )); + psd = psd_blob; + psd_blob = NULL; goto out; } } @@ -509,35 +619,29 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, fsp, HASH_SECURITY_INFO, mem_ctx, - &pdesc_next); + &psd_fs); } else { status = SMB_VFS_NEXT_GET_NT_ACL(handle, smb_fname, HASH_SECURITY_INFO, mem_ctx, - &pdesc_next); + &psd_fs); } if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("get_nt_acl_internal: get_next_acl for file %s " "returned %s\n", - name, + smb_fname->base_name, nt_errstr(status))); - TALLOC_FREE(frame); - return status; + goto fail; } - /* Ensure we don't leak psd_next if we don't choose it. - * - * We don't allocate it onto frame as it is preferred not to - * steal from a talloc pool. - */ - talloc_steal(frame, pdesc_next); - - status = hash_sd_sha256(pdesc_next, hash_tmp); + status = hash_sd_sha256(psd_fs, hash_tmp); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(psd); - psd = pdesc_next; + TALLOC_FREE(psd_blob); + psd = psd_fs; + psd_fs = NULL; + psd_is_from_fs = true; goto out; } @@ -545,7 +649,9 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, /* Hash matches, return blob sd. */ DEBUG(10, ("get_nt_acl_internal: blob hash " "matches for file %s\n", - name )); + smb_fname->base_name )); + psd = psd_blob; + psd_blob = NULL; goto out; } @@ -553,19 +659,21 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, DEBUG(10, ("get_nt_acl_internal: blob hash " "does not match for file %s - returning " "file system SD mapping.\n", - name )); + smb_fname->base_name )); if (DEBUGLEVEL >= 10) { DEBUG(10,("get_nt_acl_internal: acl for blob hash for %s is:\n", - name )); - NDR_PRINT_DEBUG(security_descriptor, pdesc_next); + smb_fname->base_name )); + NDR_PRINT_DEBUG(security_descriptor, psd_fs); } - TALLOC_FREE(psd); - psd = pdesc_next; + TALLOC_FREE(psd_blob); + psd = psd_fs; + psd_fs = NULL; + psd_is_from_fs = true; } - out: +out: if (psd == NULL) { /* Get the full underlying sd, as we failed to get the * blob for the hash, or the revision/hash type wasn't @@ -575,38 +683,27 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, fsp, security_info, mem_ctx, - &pdesc_next); + &psd); } else { status = SMB_VFS_NEXT_GET_NT_ACL(handle, smb_fname, security_info, mem_ctx, - &pdesc_next); + &psd); } if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("get_nt_acl_internal: get_next_acl for file %s " "returned %s\n", - name, + smb_fname->base_name, nt_errstr(status))); - TALLOC_FREE(frame); - return status; + goto fail; } - /* Ensure we don't leak psd_next if we don't choose it. - * - * We don't allocate it onto frame as it is preferred not to - * steal from a talloc pool. - */ - talloc_steal(frame, pdesc_next); - psd = pdesc_next; + psd_is_from_fs = true; } - if (psd != pdesc_next) { - /* We're returning the blob, throw - * away the filesystem SD. */ - TALLOC_FREE(pdesc_next); - } else { + if (psd_is_from_fs) { SMB_STRUCT_STAT sbuf; SMB_STRUCT_STAT *psbuf = &sbuf; bool is_directory = false; @@ -618,8 +715,7 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, if (fsp) { status = vfs_stat_fsp(fsp); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(frame); - return status; + goto fail; } psbuf = &fsp->fsp_name->st; } else { @@ -641,24 +737,23 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, * is fully plumbed through the VFS. */ int ret = vfs_stat_smb_basename(handle->conn, - name, + smb_fname, &sbuf); if (ret == -1) { - TALLOC_FREE(frame); - return map_nt_error_from_unix(errno); + status = map_nt_error_from_unix(errno); + goto fail; } } is_directory = S_ISDIR(psbuf->st_ex_mode); if (ignore_file_system_acl) { - TALLOC_FREE(pdesc_next); + TALLOC_FREE(psd); status = make_default_filesystem_acl(mem_ctx, - name, + smb_fname->base_name, psbuf, &psd); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(frame); - return status; + goto fail; } } else { if (is_directory && @@ -666,12 +761,11 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, true)) { status = add_directory_inheritable_components( handle, - name, + smb_fname->base_name, psbuf, psd); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(frame); - return status; + goto fail; } } /* The underlying POSIX module always sets @@ -697,19 +791,23 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, psd->sacl = NULL; } - TALLOC_FREE(blob.data); - if (DEBUGLEVEL >= 10) { DEBUG(10,("get_nt_acl_internal: returning acl for %s is:\n", - name )); + smb_fname->base_name )); NDR_PRINT_DEBUG(security_descriptor, psd); } - /* The VFS API is that the ACL is expected to be on mem_ctx */ - *ppdesc = talloc_move(mem_ctx, &psd); + *ppdesc = psd; - TALLOC_FREE(frame); return NT_STATUS_OK; + +fail: + TALLOC_FREE(psd); + TALLOC_FREE(psd_blob); + TALLOC_FREE(psd_fs); + TALLOC_FREE(sys_acl_blob_description); + TALLOC_FREE(sys_acl_blob.data); + return status; } /********************************************************************* @@ -744,6 +842,81 @@ static NTSTATUS get_nt_acl_common(vfs_handle_struct *handle, ppdesc); } +/********************************************************************* + Set the underlying ACL (e.g. POSIX ACLS, POSIX owner, etc) +*********************************************************************/ +static NTSTATUS set_underlying_acl(vfs_handle_struct *handle, files_struct *fsp, + struct security_descriptor *psd, + uint32_t security_info_sent, + bool chown_needed) +{ + NTSTATUS status = + SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); + if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + return status; + } + + /* We got access denied here. If we're already root, + or we didn't need to do a chown, or the fsp isn't + open with WRITE_OWNER access, just return. */ + if (get_current_uid(handle->conn) == 0 || chown_needed == false || + !(fsp->access_mask & SEC_STD_WRITE_OWNER)) { + return NT_STATUS_ACCESS_DENIED; + } + + DEBUG(10, ("fset_nt_acl_common: overriding chown on file %s " + "for sid %s\n", + fsp_str_dbg(fsp), sid_string_tos(psd->owner_sid))); + + /* Ok, we failed to chown and we have + SEC_STD_WRITE_OWNER access - override. */ + become_root(); + status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); + unbecome_root(); + + return status; +} + +/********************************************************************* + Store a v3 security descriptor +*********************************************************************/ +static NTSTATUS store_v3_blob(vfs_handle_struct *handle, files_struct *fsp, + struct security_descriptor *psd, + struct security_descriptor *pdesc_next, + uint8_t hash[XATTR_SD_HASH_SIZE]) +{ + NTSTATUS status; + DATA_BLOB blob; + + if (DEBUGLEVEL >= 10) { + DEBUG(10, ("fset_nt_acl_xattr: storing xattr sd for file %s\n", + fsp_str_dbg(fsp))); + NDR_PRINT_DEBUG( + security_descriptor, + discard_const_p(struct security_descriptor, psd)); + + if (pdesc_next != NULL) { + DEBUG(10, ("fset_nt_acl_xattr: storing has in xattr sd " + "based on \n")); + NDR_PRINT_DEBUG( + security_descriptor, + discard_const_p(struct security_descriptor, + pdesc_next)); + } else { + DEBUG(10, + ("fset_nt_acl_xattr: ignoring underlying sd\n")); + } + } + status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("fset_nt_acl_xattr: create_acl_blob failed\n")); + return status; + } + + status = store_acl_blob_fsp(handle, fsp, &blob); + return status; +} + /********************************************************************* Store a security descriptor given an fsp. *********************************************************************/ @@ -761,6 +934,8 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, bool chown_needed = false; char *sys_acl_description; TALLOC_CTX *frame = talloc_stackframe(); + bool ignore_file_system_acl = lp_parm_bool( + SNUM(handle->conn), ACL_MODULE_NAME, "ignore system acls", false); if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", @@ -816,38 +991,29 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, psd->type |= SEC_DESC_SACL_PRESENT; } - status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); - if (!NT_STATUS_IS_OK(status)) { - if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { - TALLOC_FREE(frame); - return status; - } - /* We got access denied here. If we're already root, - or we didn't need to do a chown, or the fsp isn't - open with WRITE_OWNER access, just return. */ - if (get_current_uid(handle->conn) == 0 || - chown_needed == false || - !(fsp->access_mask & SEC_STD_WRITE_OWNER)) { - TALLOC_FREE(frame); - return NT_STATUS_ACCESS_DENIED; + if (ignore_file_system_acl) { + if (chown_needed) { + /* send only ownership stuff to lower layer */ + security_info_sent &= (SECINFO_OWNER | SECINFO_GROUP); + status = set_underlying_acl(handle, fsp, psd, + security_info_sent, true); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } } + ZERO_ARRAY(hash); + status = store_v3_blob(handle, fsp, psd, NULL, hash); - DEBUG(10,("fset_nt_acl_common: overriding chown on file %s " - "for sid %s\n", - fsp_str_dbg(fsp), - sid_string_tos(psd->owner_sid) - )); - - /* Ok, we failed to chown and we have - SEC_STD_WRITE_OWNER access - override. */ - become_root(); - status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, - security_info_sent, psd); - unbecome_root(); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(frame); - return status; - } + TALLOC_FREE(frame); + return status; + } + + status = set_underlying_acl(handle, fsp, psd, security_info_sent, + chown_needed); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; } /* Get the full underlying sd, then hash. */ @@ -878,24 +1044,7 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, /* If we fail to get the ACL blob (for some reason) then this * is not fatal, we just work based on the NT ACL only */ if (ret != 0) { - if (DEBUGLEVEL >= 10) { - DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n", - fsp_str_dbg(fsp))); - NDR_PRINT_DEBUG(security_descriptor, - discard_const_p(struct security_descriptor, psd)); - - DEBUG(10,("fset_nt_acl_xattr: storing has in xattr sd based on \n")); - NDR_PRINT_DEBUG(security_descriptor, - discard_const_p(struct security_descriptor, pdesc_next)); - } - status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("fset_nt_acl_xattr: create_acl_blob failed\n")); - TALLOC_FREE(frame); - return status; - } - - status = store_acl_blob_fsp(handle, fsp, &blob); + status = store_v3_blob(handle, fsp, psd, pdesc_next, hash); TALLOC_FREE(frame); return status; @@ -1007,7 +1156,7 @@ static int acl_common_remove_object(vfs_handle_struct *handle, become_root(); if (is_directory) { - ret = SMB_VFS_NEXT_RMDIR(handle, final_component); + ret = SMB_VFS_NEXT_RMDIR(handle, &local_fname); } else { ret = SMB_VFS_NEXT_UNLINK(handle, &local_fname); } @@ -1031,12 +1180,12 @@ static int acl_common_remove_object(vfs_handle_struct *handle, } static int rmdir_acl_common(struct vfs_handle_struct *handle, - const char *path) + const struct smb_filename *smb_fname) { int ret; /* Try the normal rmdir first. */ - ret = SMB_VFS_NEXT_RMDIR(handle, path); + ret = SMB_VFS_NEXT_RMDIR(handle, smb_fname); if (ret == 0) { return 0; } @@ -1044,12 +1193,12 @@ static int rmdir_acl_common(struct vfs_handle_struct *handle, /* Failed due to access denied, see if we need to root override. */ return acl_common_remove_object(handle, - path, + smb_fname->base_name, true); } DEBUG(10,("rmdir_acl_common: unlink of %s failed %s\n", - path, + smb_fname->base_name, strerror(errno) )); return -1; } @@ -1084,11 +1233,12 @@ static int unlink_acl_common(struct vfs_handle_struct *handle, } static int chmod_acl_module_common(struct vfs_handle_struct *handle, - const char *path, mode_t mode) + const struct smb_filename *smb_fname, + mode_t mode) { - if (lp_posix_pathnames()) { + if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) { /* Only allow this on POSIX pathnames. */ - return SMB_VFS_NEXT_CHMOD(handle, path, mode); + return SMB_VFS_NEXT_CHMOD(handle, smb_fname, mode); } return 0; } @@ -1104,11 +1254,12 @@ static int fchmod_acl_module_common(struct vfs_handle_struct *handle, } static int chmod_acl_acl_module_common(struct vfs_handle_struct *handle, - const char *name, mode_t mode) + const struct smb_filename *smb_fname, + mode_t mode) { - if (lp_posix_pathnames()) { + if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) { /* Only allow this on POSIX pathnames. */ - return SMB_VFS_NEXT_CHMOD_ACL(handle, name, mode); + return SMB_VFS_NEXT_CHMOD_ACL(handle, smb_fname, mode); } return 0; }