#include "lib/readdir_attr.h"
#include "messages.h"
#include "smb1_utils.h"
+#include "libcli/smb/smb2_posix.h"
#define DIR_ENTRY_SAFETY_MARGIN 4096
uint32_t share_access = FILE_SHARE_READ|
FILE_SHARE_WRITE|
FILE_SHARE_DELETE;
+ struct smb2_create_blobs *posx = NULL;
+
/*
* Only FILE_FLAG_POSIX_SEMANTICS matters on existing files,
* but set reasonable defaults.
*/
- uint32_t file_attributes = 0664|FILE_FLAG_POSIX_SEMANTICS;
+ uint32_t file_attributes = 0664;
uint32_t oplock = NO_OPLOCK;
uint32_t create_options = FILE_NON_DIRECTORY_FILE;
* Only FILE_FLAG_POSIX_SEMANTICS matters on existing
* directories, but set reasonable defaults.
*/
- file_attributes = 0775|FILE_FLAG_POSIX_SEMANTICS;
+ file_attributes = 0775;
create_options = FILE_DIRECTORY_FILE;
}
goto done;
}
+ status = make_smb2_posix_create_ctx(
+ talloc_tos(), &posx, file_attributes);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
+ nt_errstr(status));
+ goto done;
+ }
+
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
NULL, /* ea_list */
ret_fsp, /* result */
NULL, /* pinfo */
- NULL, /* in_context */
+ posx, /* in_context */
NULL); /* out_context */
done:
+ TALLOC_FREE(posx);
TALLOC_FREE(smb_fname_tmp);
return status;
}
NTSTATUS ntstatus = NT_STATUS_OK;
bool ask_sharemode = lp_smbd_search_ask_sharemode(SNUM(conn));
struct smbd_server_connection *sconn = req->sconn;
- uint32_t ucf_flags = UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP |
+ uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP |
ucf_flags_from_smb_request(req);
bool backup_priv = false;
bool as_root = false;
goto out;
}
- mask = smb_dname->original_lcomp;
+ mask = get_original_lcomp(talloc_tos(),
+ conn,
+ directory,
+ ucf_flags);
+ if (mask == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ goto out;
+ }
directory = smb_dname->base_name;
* We can only have default POSIX ACLs on
* directories.
*/
- if (!fsp->is_directory) {
+ if (!fsp->fsp_flags.is_directory) {
DBG_INFO("Non-directory open %s\n",
fsp_str_dbg(fsp));
status = NT_STATUS_INVALID_HANDLE;
get_file_size_stat(psbuf));
if (size == get_file_size_stat(psbuf)) {
+ if (fsp == NULL) {
+ return NT_STATUS_OK;
+ }
+ if (!fsp->fsp_flags.modified) {
+ return NT_STATUS_OK;
+ }
+ trigger_write_time_update_immediate(fsp);
return NT_STATUS_OK;
}
uint32_t len;
char *newname = NULL;
struct smb_filename *smb_fname_dst = NULL;
- uint32_t ucf_flags = UCF_SAVE_LCOMP |
- ucf_flags_from_smb_request(req);
+ const char *dst_original_lcomp = NULL;
+ uint32_t ucf_flags = ucf_flags_from_smb_request(req);
NTSTATUS status = NT_STATUS_OK;
TALLOC_CTX *ctx = talloc_tos();
status = NT_STATUS_NO_MEMORY;
goto out;
}
+ }
- /*
- * Set the original last component, since
- * rename_internals_fsp() requires it.
- */
- smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
- newname);
- if (smb_fname_dst->original_lcomp == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto out;
- }
-
+ /*
+ * Set the original last component, since
+ * rename_internals_fsp() requires it.
+ */
+ dst_original_lcomp = get_original_lcomp(smb_fname_dst,
+ conn,
+ newname,
+ ucf_flags);
+ if (dst_original_lcomp == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
DEBUG(10,("smb2_file_rename_information: "
"SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname_dst)));
- status = rename_internals_fsp(conn, fsp, smb_fname_dst,
+ status = rename_internals_fsp(conn,
+ fsp,
+ smb_fname_dst,
+ dst_original_lcomp,
(FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
overwrite);
char *newname = NULL;
struct smb_filename *smb_fname_dst = NULL;
NTSTATUS status = NT_STATUS_OK;
- uint32_t ucf_flags = UCF_SAVE_LCOMP |
- ucf_flags_from_smb_request(req);
+ uint32_t ucf_flags = ucf_flags_from_smb_request(req);
TALLOC_CTX *ctx = talloc_tos();
if (!fsp) {
uint32_t len;
char *newname = NULL;
struct smb_filename *smb_fname_dst = NULL;
+ const char *dst_original_lcomp = NULL;
bool dest_has_wcard = False;
NTSTATUS status = NT_STATUS_OK;
char *p;
DEBUG(10,("smb_file_rename_information: got name |%s|\n",
newname));
- if (req->flags2 & FLAGS2_DFS_PATHNAMES) {
- status = resolve_dfspath_wcard(ctx, conn,
- newname,
- UCF_COND_ALLOW_WCARD_LCOMP,
- !conn->sconn->using_smb2,
- &newname,
- &dest_has_wcard);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- }
-
/* Check the new name has no '/' characters. */
if (strchr_m(newname, '/')) {
return NT_STATUS_NOT_SUPPORTED;
}
/*
- * Set the original last component, since
+ * Get the original last component, since
* rename_internals_fsp() requires it.
*/
- smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
- newname);
- if (smb_fname_dst->original_lcomp == NULL) {
+ dst_original_lcomp = get_original_lcomp(smb_fname_dst,
+ conn,
+ newname,
+ 0);
+ if (dst_original_lcomp == NULL) {
status = NT_STATUS_NO_MEMORY;
goto out;
}
* the newname instead.
*/
char *base_name = NULL;
- uint32_t ucf_flags = UCF_SAVE_LCOMP |
- ucf_flags_from_smb_request(req);
+ uint32_t ucf_flags = ucf_flags_from_smb_request(req);
if (dest_has_wcard) {
ucf_flags |= UCF_ALWAYS_ALLOW_WCARD_LCOMP;
return NT_STATUS_NO_MEMORY;
}
- status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
- ucf_flags);
+ status = filename_convert(ctx,
+ conn,
+ base_name,
+ ucf_flags,
+ NULL,
+ NULL,
+ &smb_fname_dst);
/* If an error we expect this to be
* NT_STATUS_OBJECT_PATH_NOT_FOUND */
goto out;
}
}
+ dst_original_lcomp = get_original_lcomp(smb_fname_dst,
+ conn,
+ newname,
+ ucf_flags);
+ if (dst_original_lcomp == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
}
if (fsp) {
"SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname_dst)));
- status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
- overwrite);
+ status = rename_internals_fsp(conn,
+ fsp,
+ smb_fname_dst,
+ dst_original_lcomp,
+ 0,
+ overwrite);
} else {
DEBUG(10,("smb_file_rename_information: "
"SMB_FILE_RENAME_INFORMATION %s -> %s\n",
smb_fname_str_dbg(smb_fname_src),
smb_fname_str_dbg(smb_fname_dst)));
- status = rename_internals(ctx, conn, req, smb_fname_src,
- smb_fname_dst, 0, overwrite, false,
- dest_has_wcard,
- FILE_WRITE_ATTRIBUTES);
+ status = rename_internals(ctx,
+ conn,
+ req,
+ smb_fname_src,
+ smb_fname_dst,
+ dst_original_lcomp,
+ 0,
+ overwrite,
+ false,
+ dest_has_wcard,
+ FILE_WRITE_ATTRIBUTES);
}
out:
TALLOC_FREE(smb_fname_dst);
}
/* If we have a default acl, this *must* be a directory. */
- if (valid_def_acls && !fsp->is_directory) {
+ if (valid_def_acls && !fsp->fsp_flags.is_directory) {
DBG_INFO("Can't set default acls on "
"non-directory %s\n",
fsp_str_dbg(fsp));
break;
case POSIX_LOCK_TYPE_WRITE:
/* Return the right POSIX-mappable error code for files opened read-only. */
- if (!fsp->can_write) {
+ if (!fsp->fsp_flags.can_write) {
return NT_STATUS_INVALID_HANDLE;
}
lock_type = WRITE_LOCK;
DEBUG(10, ("smb_set_file_basic_info: file %s\n",
smb_fname_str_dbg(smb_fname)));
- return smb_set_file_time(conn, fsp, smb_fname, &ft,
- true);
+ status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (fsp != NULL && fsp->fsp_flags.modified) {
+ trigger_write_time_update_immediate(fsp);
+ }
+ return NT_STATUS_OK;
}
/****************************************************************************
return status;
}
- return smb_set_file_time(conn,
- fsp,
- smb_fname,
- &ft,
- true);
+ status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (fsp != NULL && fsp->fsp_flags.modified) {
+ trigger_write_time_update_immediate(fsp);
+ }
+ return NT_STATUS_OK;
}
/****************************************************************************
* We're setting the time explicitly for UNIX.
* Cancel any pending changes over all handles.
*/
- all_fsps->update_write_time_on_close = false;
+ all_fsps->fsp_flags.update_write_time_on_close = false;
TALLOC_FREE(all_fsps->update_write_time_event);
}
{
NTSTATUS status = NT_STATUS_OK;
uint32_t raw_unixmode = 0;
- uint32_t mod_unixmode = 0;
mode_t unixmode = (mode_t)0;
files_struct *fsp = NULL;
uint16_t info_level_return = 0;
int info;
char *pdata = *ppdata;
+ struct smb2_create_blobs *posx = NULL;
if (total_data < 18) {
return NT_STATUS_INVALID_PARAMETER;
return status;
}
- mod_unixmode = (uint32_t)unixmode | FILE_FLAG_POSIX_SEMANTICS;
+ status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
+ nt_errstr(status));
+ return status;
+ }
DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
FILE_SHARE_NONE, /* share_access */
FILE_CREATE, /* create_disposition*/
FILE_DIRECTORY_FILE, /* create_options */
- mod_unixmode, /* file_attributes */
+ 0, /* file_attributes */
0, /* oplock_request */
NULL, /* lease */
0, /* allocation_size */
NULL, /* ea_list */
&fsp, /* result */
&info, /* pinfo */
- NULL, NULL); /* create context */
+ posx, /* in_context_blobs */
+ NULL); /* out_context_blobs */
+
+ TALLOC_FREE(posx);
if (NT_STATUS_IS_OK(status)) {
close_file(req, fsp, NORMAL_CLOSE);
uint32_t flags = 0;
uint32_t wire_open_mode = 0;
uint32_t raw_unixmode = 0;
- uint32_t mod_unixmode = 0;
+ uint32_t attributes = 0;
uint32_t create_disp = 0;
uint32_t access_mask = 0;
uint32_t create_options = FILE_NON_DIRECTORY_FILE;
int oplock_request = 0;
int info = 0;
uint16_t info_level_return = 0;
+ struct smb2_create_blobs *posx = NULL;
if (total_data < 18) {
return NT_STATUS_INVALID_PARAMETER;
return status;
}
- mod_unixmode = (uint32_t)unixmode | FILE_FLAG_POSIX_SEMANTICS;
+ status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
+ nt_errstr(status));
+ return status;
+ }
if (wire_open_mode & SMB_O_SYNC) {
create_options |= FILE_WRITE_THROUGH;
access_mask |= FILE_APPEND_DATA;
}
if (wire_open_mode & SMB_O_DIRECT) {
- mod_unixmode |= FILE_FLAG_NO_BUFFERING;
+ attributes |= FILE_FLAG_NO_BUFFERING;
}
if ((wire_open_mode & SMB_O_DIRECTORY) ||
FILE_SHARE_DELETE),
create_disp, /* create_disposition*/
create_options, /* create_options */
- mod_unixmode, /* file_attributes */
+ attributes, /* file_attributes */
oplock_request, /* oplock_request */
NULL, /* lease */
0, /* allocation_size */
NULL, /* ea_list */
&fsp, /* result */
&info, /* pinfo */
- NULL, NULL); /* create context */
+ posx, /* in_context_blobs */
+ NULL); /* out_context_blobs */
+
+ TALLOC_FREE(posx);
if (!NT_STATUS_IS_OK(status)) {
return status;
int create_options = 0;
struct share_mode_lock *lck = NULL;
bool other_nonposix_opens;
+ struct smb2_create_blobs *posx = NULL;
if (total_data < 2) {
return NT_STATUS_INVALID_PARAMETER;
create_options |= FILE_DIRECTORY_FILE;
}
+ status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
+ nt_errstr(status));
+ return status;
+ }
+
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
FILE_SHARE_DELETE),
FILE_OPEN, /* create_disposition*/
create_options, /* create_options */
- FILE_FLAG_POSIX_SEMANTICS|0777, /* file_attributes */
+ 0, /* file_attributes */
0, /* oplock_request */
NULL, /* lease */
0, /* allocation_size */
NULL, /* ea_list */
&fsp, /* result */
&info, /* pinfo */
- NULL, NULL); /* create context */
+ posx, /* in_context_blobs */
+ NULL); /* out_context_blobs */
+
+ TALLOC_FREE(posx);
if (!NT_STATUS_IS_OK(status)) {
return status;