diff --git a/source3/modules/vfs_ixnas.c b/source3/modules/vfs_ixnas.c index 4a3bd40e518..6746c802ffc 100644 --- a/source3/modules/vfs_ixnas.c +++ b/source3/modules/vfs_ixnas.c @@ -328,8 +328,8 @@ static bool smbace2bsdentry(acl_t bsdacl, SMB_ACE4PROP_T *aceprop) acl_entry_t new_entry; acl_perm_t permset = 0; acl_entry_type_t type = 0; - acl_flag_t flags; - uid_t id; + acl_flag_t flags = 0; + uid_t id = ACL_UNDEFINED_ID; acl_tag_t tag; int i; @@ -373,7 +373,9 @@ static bool smbace2bsdentry(acl_t bsdacl, SMB_ACE4PROP_T *aceprop) smb_panic("Unsupported special id."); } } else { - tag = ACL_GROUP ? aceprop->aceFlags & SMB_ACE4_IDENTIFIER_GROUP : ACL_USER; + tag = aceprop->aceFlags & SMB_ACE4_IDENTIFIER_GROUP ? + ACL_GROUP : ACL_USER; + id = aceprop->who.id; } new_entry->ae_perm = permset; @@ -553,6 +555,7 @@ static bool ixnas_process_smbacl(vfs_handle_struct *handle, hidden_entry->ae_perm = 0; hidden_entry->ae_entry_type = ACL_ENTRY_TYPE_ALLOW; + hidden_entry->ae_flags = ACL_ENTRY_FILE_INHERIT | ACL_ENTRY_DIRECTORY_INHERIT; hidden_entry->ae_tag = ACL_EVERYONE; hidden_entry->ae_id = ACL_UNDEFINED_ID; } diff --git a/source3/modules/vfs_zfs_core.c b/source3/modules/vfs_zfs_core.c index f77e2384531..ea2b1712e19 100644 --- a/source3/modules/vfs_zfs_core.c +++ b/source3/modules/vfs_zfs_core.c @@ -326,6 +326,7 @@ static bool get_synthetic_fsp(vfs_handle_struct *handle, DBG_ERR("Failed to open %s, mode: 0o%o: %s\n", smb_fname_str_dbg(tmp_fname), unix_mode, strerror(errno)); + file_free(NULL, tmp_fsp); return false; } tmp_fsp->fsp_flags.is_directory = true; @@ -373,6 +374,8 @@ static bool zfs_inherit_acls(vfs_handle_struct *handle, ok = get_synthetic_fsp(handle, ds->mountpoint + root_len, &c_fsp); if (!ok) { + fd_close(pathref); + file_free(NULL, pathref); return false; } @@ -380,6 +383,9 @@ static bool zfs_inherit_acls(vfs_handle_struct *handle, if (error) { DBG_ERR("%s: stat() failed: %s\n", fsp_str_dbg(c_fsp), strerror(errno)); fd_close(c_fsp); + file_free(NULL, c_fsp); + fd_close(pathref); + file_free(NULL, pathref); return false; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 1e3104f58f2..5b0de5d72f4 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -7126,7 +7126,9 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, NTSTATUS status = NT_STATUS_OK; struct share_mode_lock *lck = NULL; uint32_t access_mask = SEC_DIR_ADD_FILE; - bool dst_exists, old_is_stream, new_is_stream; + bool dst_exists, old_is_stream, new_is_stream, is_same_fileid; + struct file_id fileid_src; + struct file_id fileid_dst; int ret; status = parent_dirname_compatible_open(conn, smb_fname_dst_in); @@ -7283,7 +7285,19 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, dst_exists = vfs_stat(conn, smb_fname_dst) == 0; - if(!replace_if_exists && dst_exists) { + /* + * Some filesystems are case-insensitive, but case-preserving + * Compare fileid in this situation to determine whether the + * source and destination are the same file. If this is the + * case, then bypass these checks and hand off to VFS_RENAME + * and hope that a VFS module is enabled that has special + * handling for this situation. + */ + fileid_src = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st); + fileid_dst = vfs_file_id_from_sbuf(conn, &smb_fname_dst->st); + is_same_fileid = file_id_equal(&fileid_src, &fileid_dst); + + if(!replace_if_exists && dst_exists && !is_same_fileid) { DEBUG(3, ("rename_internals_fsp: dest exists doing rename " "%s -> %s\n", smb_fname_str_dbg(fsp->fsp_name), smb_fname_str_dbg(smb_fname_dst))); @@ -7301,7 +7315,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, SMB_ASSERT(smb_fname_dst_in->fsp == NULL); } - if (dst_exists) { + if (dst_exists && !is_same_fileid) { struct file_id fileid = vfs_file_id_from_sbuf(conn, &smb_fname_dst->st); files_struct *dst_fsp = file_find_di_first(conn->sconn,