NTSTATUS *err)
{
bool ignore;
- if (lp_posix_pathnames()) {
- return srvstr_get_path_wcard_internal(ctx,
- base_ptr,
- smb_flags2,
- pp_dest,
- src,
- src_len,
- flags,
- true,
- err,
- &ignore);
- } else {
- return srvstr_get_path_wcard_internal(ctx,
- base_ptr,
- smb_flags2,
- pp_dest,
- src,
- src_len,
- flags,
- false,
- err,
- &ignore);
- }
+ return srvstr_get_path_wcard_internal(ctx,
+ base_ptr,
+ smb_flags2,
+ pp_dest,
+ src,
+ src_len,
+ flags,
+ false,
+ err,
+ &ignore);
}
/****************************************************************************
return 0;
}
- if (lp_posix_pathnames()) {
+ if (req->posix_pathnames) {
return srvstr_get_path_wcard_internal(mem_ctx,
(const char *)req->inbuf,
req->flags2,
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
msg_type, msg_flags));
- srv_send_smb(xconn, outbuf, false, 0, false, NULL);
+ if (!srv_send_smb(xconn, outbuf, false, 0, false, NULL)) {
+ exit_server_cleanly("reply_special: srv_send_smb failed.");
+ }
if (CVAL(outbuf, 0) != 0x82) {
exit_server_cleanly("invalid netbios session");
connection_struct *conn = req->conn;
const char *service = NULL;
TALLOC_CTX *ctx = talloc_tos();
- /* what the cleint thinks the device is */
+ /* what the client thinks the device is */
char *client_devicetype = NULL;
/* what the server tells the client the share represents */
const char *server_devicetype;
struct smb_filename *smb_fname = NULL;
char *name = NULL;
NTSTATUS status;
- uint32_t ucf_flags = (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags = ucf_flags_from_smb_request(req);
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBcheckpath);
status = filename_convert(ctx,
conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
name,
ucf_flags,
NULL,
size = 0;
mtime = 0;
} else {
- uint32_t ucf_flags = (lp_posix_pathnames() ?
- UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags = ucf_flags_from_smb_request(req);
status = filename_convert(ctx,
conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
ucf_flags,
NULL,
time_t mtime;
const char *p;
NTSTATUS status;
- uint32_t ucf_flags = (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags = ucf_flags_from_smb_request(req);
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBsetatr);
status = filename_convert(ctx,
conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
ucf_flags,
NULL,
connection_struct *conn = req->conn;
uint64_t ret;
uint64_t dfree,dsize,bsize;
+ struct smb_filename smb_fname;
START_PROFILE(SMBdskattr);
- ret = get_dfree_info(conn, ".", &bsize, &dfree, &dsize);
+ ZERO_STRUCT(smb_fname);
+ smb_fname.base_name = discard_const_p(char, ".");
+
+ if (SMB_VFS_STAT(conn, &smb_fname) != 0) {
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ DBG_WARNING("stat of . failed (%s)\n", strerror(errno));
+ END_PROFILE(SMBdskattr);
+ return;
+ }
+
+ ret = get_dfree_info(conn, &smb_fname, &bsize, &dfree, &dsize);
if (ret == (uint64_t)-1) {
reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBdskattr);
goto out;
}
- if (lp_posix_pathnames()) {
+ if (req->posix_pathnames) {
reply_unknown_new(req, req->cmd);
goto out;
}
/* dirtype &= ~FILE_ATTRIBUTE_DIRECTORY; */
if (status_len == 0) {
+ struct smb_filename *smb_dname = NULL;
uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ ucf_flags_from_smb_request(req);
nt_status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
path,
ucf_flags,
&mask_contains_wcard,
memset((char *)status,'\0',21);
SCVAL(status,0,(dirtype & 0x1F));
+ smb_dname = synthetic_smb_fname(talloc_tos(),
+ directory,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (smb_dname == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ goto out;
+ }
+
nt_status = dptr_create(conn,
NULL, /* req */
NULL, /* fsp */
- directory,
+ smb_dname,
True,
expect_close,
req->smbpid,
mask_contains_wcard,
dirtype,
&dirptr);
+
+ TALLOC_FREE(smb_dname);
+
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
goto out;
* For a 'continue' search we have no string. So
* check from the initial saved string.
*/
- if (!lp_posix_pathnames()) {
+ if (!req->posix_pathnames) {
mask_contains_wcard = ms_has_wild(mask);
}
dirtype = dptr_attr(sconn, dptr_num);
START_PROFILE(SMBfclose);
- if (lp_posix_pathnames()) {
+ if (req->posix_pathnames) {
reply_unknown_new(req, req->cmd);
END_PROFILE(SMBfclose);
return;
uint32_t create_options = 0;
uint32_t private_flags = 0;
NTSTATUS status;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBopen);
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, create_disposition);
+
status = filename_convert(ctx,
conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
ucf_flags,
NULL,
uint32_t create_disposition;
uint32_t create_options = 0;
uint32_t private_flags = 0;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBopenX);
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, create_disposition);
+
status = filename_convert(ctx,
conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
ucf_flags,
NULL,
uint32_t share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
uint32_t create_disposition;
uint32_t create_options = 0;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBcreate);
fattr = SVAL(req->vwv+0, 0);
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
+ if (req->cmd == SMBmknew) {
+ /* We should fail if file exists. */
+ create_disposition = FILE_CREATE;
+ } else {
+ /* Create if file doesn't exist, truncate if it does. */
+ create_disposition = FILE_OVERWRITE_IF;
+ }
+
/* mtime. */
ft.mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1));
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, create_disposition);
status = filename_convert(ctx,
conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
ucf_flags,
NULL,
smb_fname_str_dbg(smb_fname)));
}
- if(req->cmd == SMBmknew) {
- /* We should fail if file exists. */
- create_disposition = FILE_CREATE;
- } else {
- /* Create if file doesn't exist, truncate if it does. */
- create_disposition = FILE_OVERWRITE_IF;
- }
-
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
char *s;
NTSTATUS status;
int i;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBctemp);
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, FILE_CREATE);
status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
ucf_flags,
NULL,
uint32_t dirtype_orig = dirtype;
NTSTATUS status;
int ret;
- bool posix_paths = lp_posix_pathnames();
+ bool posix_paths = (req != NULL && req->posix_pathnames);
DEBUG(10,("do_unlink: %s, dirtype = %d\n",
smb_fname_str_dbg(smb_fname),
char *fname_mask = NULL;
int count=0;
NTSTATUS status = NT_STATUS_OK;
+ struct smb_filename *smb_fname_dir = NULL;
TALLOC_CTX *ctx = talloc_tos();
/* Split up the directory from the filename/mask. */
dirtype = FILE_ATTRIBUTE_NORMAL;
}
- status = check_name(conn, smb_fname->base_name);
+ status = check_name(conn, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
}
}
- status = check_name(conn, fname_dir);
+ smb_fname_dir = synthetic_smb_fname(talloc_tos(),
+ fname_dir,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (smb_fname_dir == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ status = check_name(conn, smb_fname_dir);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
- dir_hnd = OpenDir(talloc_tos(), conn, fname_dir, fname_mask,
+ dir_hnd = OpenDir(talloc_tos(), conn, smb_fname_dir, fname_mask,
dirtype);
if (dir_hnd == NULL) {
status = map_nt_error_from_unix(errno);
goto out;
}
- status = check_name(conn, smb_fname->base_name);
+ status = check_name(conn, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
TALLOC_FREE(frame);
}
out:
+ TALLOC_FREE(smb_fname_dir);
TALLOC_FREE(fname_dir);
TALLOC_FREE(fname_mask);
return status;
NTSTATUS status;
bool path_contains_wcard = False;
uint32_t ucf_flags = UCF_COND_ALLOW_WCARD_LCOMP |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ ucf_flags_from_smb_request(req);
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBunlink);
}
status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
name,
ucf_flags,
&path_contains_wcard,
(uint64_t)startpos, (uint64_t)maxcount, READ_LOCK,
&lock);
- if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
reply_readbraw_error(xconn);
END_PROFILE(SMBreadbraw);
return;
DEBUG(5,("reply_readbraw finished\n"));
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
-
END_PROFILE(SMBreadbraw);
return;
}
(uint64_t)startpos, (uint64_t)numtoread, READ_LOCK,
&lock);
- if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
END_PROFILE(SMBread);
return;
if (nread < 0) {
reply_nterror(req, map_nt_error_from_unix(errno));
- goto strict_unlock;
+ goto out;
}
srv_set_message((char *)req->outbuf, 5, nread+3, False);
DEBUG(3, ("read %s num=%d nread=%d\n",
fsp_fnum_dbg(fsp), (int)numtoread, (int)nread));
-strict_unlock:
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
-
+out:
END_PROFILE(SMBread);
return;
}
Setup readX header.
****************************************************************************/
-static int setup_readX_header(struct smb_request *req, char *outbuf,
- size_t smb_maxcnt)
+int setup_readX_header(char *outbuf, size_t smb_maxcnt)
{
int outsize;
+ 2 /* the buflen field */
+ 1); /* padding byte */
SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
- SSVAL(outbuf,smb_vwv11,smb_maxcnt);
SCVAL(smb_buf(outbuf), 0, 0); /* padding byte */
/* Reset the outgoing length, set_message truncates at 0x1FFFF. */
_smb_setlen_large(outbuf,
(uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
&lock);
- if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
return;
}
if(fsp_stat(fsp) == -1) {
reply_nterror(req, map_nt_error_from_unix(errno));
- goto strict_unlock;
+ goto out;
}
if (!S_ISREG(fsp->fsp_name->st.st_ex_mode) ||
header = data_blob_const(headerbuf, sizeof(headerbuf));
construct_reply_common_req(req, (char *)headerbuf);
- setup_readX_header(req, (char *)headerbuf, smb_maxcnt);
+ setup_readX_header((char *)headerbuf, smb_maxcnt);
nread = SMB_VFS_SENDFILE(xconn->transport.sock, fsp, &header,
startpos, smb_maxcnt);
DEBUG(3, ("send_file_readX: fake_sendfile %s max=%d nread=%d\n",
fsp_fnum_dbg(fsp), (int)smb_maxcnt, (int)nread));
/* No outbuf here means successful sendfile. */
- goto strict_unlock;
+ goto out;
}
DEBUG(0,("send_file_readX: sendfile failed for file "
/* No outbuf here means successful sendfile. */
SMB_PERFCOUNT_SET_MSGLEN_OUT(&req->pcd, nread);
SMB_PERFCOUNT_END(&req->pcd);
- goto strict_unlock;
+ goto out;
}
normal_read:
uint8_t headerbuf[smb_size + 2*12 + 1 /* padding byte */];
ssize_t ret;
+ if (!S_ISREG(fsp->fsp_name->st.st_ex_mode) ||
+ (startpos > fsp->fsp_name->st.st_ex_size) ||
+ (smb_maxcnt > (fsp->fsp_name->st.st_ex_size - startpos))) {
+ /*
+ * We already know that we would do a short
+ * read, so don't try the sendfile() path.
+ */
+ goto nosendfile_read;
+ }
+
construct_reply_common_req(req, (char *)headerbuf);
- setup_readX_header(req, (char *)headerbuf, smb_maxcnt);
+ setup_readX_header((char *)headerbuf, smb_maxcnt);
/* Send out the header. */
ret = write_data(xconn->transport.sock, (char *)headerbuf,
errno = saved_errno;
exit_server_cleanly("send_file_readX: fake_sendfile failed");
}
- goto strict_unlock;
+ goto out;
}
nosendfile_read:
startpos, smb_maxcnt);
saved_errno = errno;
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
-
if (nread < 0) {
reply_nterror(req, map_nt_error_from_unix(saved_errno));
return;
}
- setup_readX_header(req, (char *)req->outbuf, nread);
+ setup_readX_header((char *)req->outbuf, nread);
DEBUG(3, ("send_file_readX %s max=%d nread=%d\n",
fsp_fnum_dbg(fsp), (int)smb_maxcnt, (int)nread));
return;
- strict_unlock:
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+out:
TALLOC_FREE(req->outbuf);
return;
}
(uint64_t)startpos, (uint64_t)tcount, WRITE_LOCK,
&lock);
- if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
error_to_writebrawerr(req);
END_PROFILE(SMBwritebraw);
if (nwritten < (ssize_t)numtowrite) {
reply_nterror(req, NT_STATUS_DISK_FULL);
error_to_writebrawerr(req);
- goto strict_unlock;
+ goto out;
}
total_written = nwritten;
if (!buf) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
error_to_writebrawerr(req);
- goto strict_unlock;
+ goto out;
}
/* Return a SMBwritebraw message to the redirector to tell
TALLOC_FREE(buf);
reply_nterror(req, map_nt_error_from_unix(errno));
error_to_writebrawerr(req);
- goto strict_unlock;
+ goto out;
}
if (nwritten < (ssize_t)numtowrite) {
fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
error_to_writebrawerr(req);
- goto strict_unlock;
+ goto out;
}
DEBUG(3,("reply_writebraw: secondart write %s start=%.0f num=%d "
fsp_fnum_dbg(fsp), (double)startpos, (int)numtowrite,
(int)total_written));
- if (!fsp->print_file) {
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
- }
-
/* We won't return a status if write through is not selected - this
* follows what WfWg does */
END_PROFILE(SMBwritebraw);
}
return;
-strict_unlock:
- if (!fsp->print_file) {
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
- }
-
+out:
END_PROFILE(SMBwritebraw);
return;
}
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
&lock);
- if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
END_PROFILE(SMBwriteunlock);
return;
DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
- goto strict_unlock;
+ goto out;
}
if(nwritten < 0) {
reply_nterror(req, map_nt_error_from_unix(saved_errno));
- goto strict_unlock;
+ goto out;
}
if((nwritten < numtowrite) && (numtowrite != 0)) {
reply_nterror(req, NT_STATUS_DISK_FULL);
- goto strict_unlock;
+ goto out;
}
if (numtowrite && !fsp->print_file) {
if (NT_STATUS_V(status)) {
reply_nterror(req, status);
- goto strict_unlock;
+ goto out;
}
}
DEBUG(3, ("writeunlock %s num=%d wrote=%d\n",
fsp_fnum_dbg(fsp), (int)numtowrite, (int)nwritten));
-strict_unlock:
- if (numtowrite && !fsp->print_file) {
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
- }
-
+out:
END_PROFILE(SMBwriteunlock);
return;
}
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
&lock);
- if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
END_PROFILE(SMBwrite);
return;
nwritten = vfs_allocate_file_space(fsp, (off_t)startpos);
if (nwritten < 0) {
reply_nterror(req, NT_STATUS_DISK_FULL);
- goto strict_unlock;
+ goto out;
}
nwritten = vfs_set_filelen(fsp, (off_t)startpos);
if (nwritten < 0) {
reply_nterror(req, NT_STATUS_DISK_FULL);
- goto strict_unlock;
+ goto out;
}
trigger_write_time_update_immediate(fsp);
} else {
DEBUG(5,("reply_write: sync_file for %s returned %s\n",
fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
- goto strict_unlock;
+ goto out;
}
if(nwritten < 0) {
reply_nterror(req, map_nt_error_from_unix(saved_errno));
- goto strict_unlock;
+ goto out;
}
if((nwritten == 0) && (numtowrite != 0)) {
reply_nterror(req, NT_STATUS_DISK_FULL);
- goto strict_unlock;
+ goto out;
}
reply_outbuf(req, 1, 0);
DEBUG(3, ("write %s num=%d wrote=%d\n", fsp_fnum_dbg(fsp), (int)numtowrite, (int)nwritten));
-strict_unlock:
- if (!fsp->print_file) {
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
- }
-
+out:
END_PROFILE(SMBwrite);
return;
}
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
&lock);
- if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
goto out;
}
nwritten = write_file(req,fsp,data,startpos,numtowrite);
saved_errno = errno;
-
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
}
if(nwritten < 0) {
(uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
&lock);
- if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
END_PROFILE(SMBwriteclose);
return;
nwritten = write_file(req,fsp,data,startpos,numtowrite);
- if (fsp->print_file == NULL) {
- SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
- }
-
set_close_write_time(fsp, mtime);
/*
ZERO_STRUCT(handle);
- status = rpc_pipe_open_interface(conn,
+ status = rpc_pipe_open_interface(mem_ctx,
&ndr_table_spoolss,
conn->session_info,
conn->sconn->remote_address,
+ conn->sconn->local_address,
conn->sconn->msg_ctx,
&cli);
if (!NT_STATUS_IS_OK(status)) {
struct smb_filename *smb_dname = NULL;
char *directory = NULL;
NTSTATUS status;
- uint32_t ucf_flags = UCF_PREP_CREATEFILE |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBmkdir);
goto out;
}
+ ucf_flags = filename_create_ucf_flags(req, FILE_CREATE);
status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
ucf_flags,
NULL,
TALLOC_CTX *ctx = talloc_tos();
files_struct *fsp = NULL;
int info = 0;
- uint32_t ucf_flags = (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ uint32_t ucf_flags = ucf_flags_from_smb_request(req);
struct smbd_server_connection *sconn = req->sconn;
START_PROFILE(SMBrmdir);
}
status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
ucf_flags,
NULL,
struct smb_filename *smb_fname_dst = NULL;
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;
- status = check_name(conn, smb_fname_dst_in->base_name);
+ status = check_name(conn, smb_fname_dst_in);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (!conn->case_sensitive && conn->case_preserve &&
strequal(fsp->fsp_name->base_name, smb_fname_dst->base_name) &&
strequal(fsp->fsp_name->stream_name, smb_fname_dst->stream_name)) {
- char *last_slash;
- char *fname_dst_lcomp_base_mod = NULL;
- struct smb_filename *smb_fname_orig_lcomp = NULL;
+ char *fname_dst_parent = NULL;
+ const char *fname_dst_lcomp = NULL;
+ char *orig_lcomp_path = NULL;
+ char *orig_lcomp_stream = NULL;
+ bool ok = true;
/*
- * Get the last component of the destination name.
+ * Split off the last component of the processed
+ * destination name. We will compare this to
+ * the split components of smb_fname_dst->original_lcomp.
*/
- last_slash = strrchr_m(smb_fname_dst->base_name, '/');
- if (last_slash) {
- fname_dst_lcomp_base_mod = talloc_strdup(ctx, last_slash + 1);
- } else {
- fname_dst_lcomp_base_mod = talloc_strdup(ctx, smb_fname_dst->base_name);
- }
- if (!fname_dst_lcomp_base_mod) {
+ if (!parent_dirname(ctx,
+ smb_fname_dst->base_name,
+ &fname_dst_parent,
+ &fname_dst_lcomp)) {
status = NT_STATUS_NO_MEMORY;
goto out;
}
/*
- * Create an smb_filename struct using the original last
- * component of the destination.
+ * The original_lcomp component contains
+ * the last_component of the path + stream
+ * name (if a stream exists).
+ *
+ * Split off the stream name so we
+ * can check them separately.
*/
- smb_fname_orig_lcomp = synthetic_smb_fname_split(
- ctx, smb_fname_dst->original_lcomp, NULL);
- if (smb_fname_orig_lcomp == NULL) {
+
+ if (fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) {
+ /* POSIX - no stream component. */
+ orig_lcomp_path = talloc_strdup(ctx,
+ smb_fname_dst->original_lcomp);
+ if (orig_lcomp_path == NULL) {
+ ok = false;
+ }
+ } else {
+ ok = split_stream_filename(ctx,
+ smb_fname_dst->original_lcomp,
+ &orig_lcomp_path,
+ &orig_lcomp_stream);
+ }
+
+ if (!ok) {
+ TALLOC_FREE(fname_dst_parent);
status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE(fname_dst_lcomp_base_mod);
goto out;
}
/* If the base names only differ by case, use original. */
- if(!strcsequal(fname_dst_lcomp_base_mod,
- smb_fname_orig_lcomp->base_name)) {
+ if(!strcsequal(fname_dst_lcomp, orig_lcomp_path)) {
char *tmp;
/*
* Replace the modified last component with the
* original.
*/
- if (last_slash) {
- *last_slash = '\0'; /* Truncate at the '/' */
+ if (!ISDOT(fname_dst_parent)) {
tmp = talloc_asprintf(smb_fname_dst,
"%s/%s",
- smb_fname_dst->base_name,
- smb_fname_orig_lcomp->base_name);
+ fname_dst_parent,
+ orig_lcomp_path);
} else {
- tmp = talloc_asprintf(smb_fname_dst,
- "%s",
- smb_fname_orig_lcomp->base_name);
+ tmp = talloc_strdup(smb_fname_dst,
+ orig_lcomp_path);
}
if (tmp == NULL) {
status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE(fname_dst_lcomp_base_mod);
- TALLOC_FREE(smb_fname_orig_lcomp);
+ TALLOC_FREE(fname_dst_parent);
+ TALLOC_FREE(orig_lcomp_path);
+ TALLOC_FREE(orig_lcomp_stream);
goto out;
}
TALLOC_FREE(smb_fname_dst->base_name);
/* If the stream_names only differ by case, use original. */
if(!strcsequal(smb_fname_dst->stream_name,
- smb_fname_orig_lcomp->stream_name)) {
- char *tmp = NULL;
+ orig_lcomp_stream)) {
/* Use the original stream. */
- tmp = talloc_strdup(smb_fname_dst,
- smb_fname_orig_lcomp->stream_name);
+ char *tmp = talloc_strdup(smb_fname_dst,
+ orig_lcomp_stream);
if (tmp == NULL) {
status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE(fname_dst_lcomp_base_mod);
- TALLOC_FREE(smb_fname_orig_lcomp);
+ TALLOC_FREE(fname_dst_parent);
+ TALLOC_FREE(orig_lcomp_path);
+ TALLOC_FREE(orig_lcomp_stream);
goto out;
}
TALLOC_FREE(smb_fname_dst->stream_name);
smb_fname_dst->stream_name = tmp;
}
- TALLOC_FREE(fname_dst_lcomp_base_mod);
- TALLOC_FREE(smb_fname_orig_lcomp);
+ TALLOC_FREE(fname_dst_parent);
+ TALLOC_FREE(orig_lcomp_path);
+ TALLOC_FREE(orig_lcomp_stream);
}
/*
if (rename_path_prefix_equal(fsp->fsp_name, smb_fname_dst)) {
status = NT_STATUS_ACCESS_DENIED;
+ goto out;
+ }
+
+ /* Do we have rights to move into the destination ? */
+ if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
+ /* We're moving a directory. */
+ access_mask = SEC_DIR_ADD_SUBDIR;
+ }
+ status = check_parent_access(conn,
+ smb_fname_dst,
+ access_mask);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_INFO("check_parent_access on "
+ "dst %s returned %s\n",
+ smb_fname_str_dbg(smb_fname_dst),
+ nt_errstr(status));
+ goto out;
}
lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
smb_fname_str_dbg(smb_fname_dst)));
if (!fsp->is_directory &&
- !lp_posix_pathnames() &&
+ !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
(lp_map_archive(SNUM(conn)) ||
lp_store_dos_attributes(SNUM(conn)))) {
/* We must set the archive bit on the newly
uint32_t access_mask)
{
char *fname_src_dir = NULL;
+ struct smb_filename *smb_fname_src_dir = NULL;
char *fname_src_mask = NULL;
int count=0;
NTSTATUS status = NT_STATUS_OK;
char *talloced = NULL;
long offset = 0;
int create_options = 0;
- bool posix_pathnames = lp_posix_pathnames();
+ bool posix_pathnames = (req != NULL && req->posix_pathnames);
int rc;
/*
}
}
- status = check_name(conn, fname_src_dir);
+ smb_fname_src_dir = synthetic_smb_fname(talloc_tos(),
+ fname_src_dir,
+ NULL,
+ NULL,
+ smb_fname_src->flags);
+ if (smb_fname_src_dir == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ status = check_name(conn, smb_fname_src_dir);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
- dir_hnd = OpenDir(talloc_tos(), conn, fname_src_dir, fname_src_mask,
+ dir_hnd = OpenDir(talloc_tos(), conn, smb_fname_src_dir, fname_src_mask,
attrs);
if (dir_hnd == NULL) {
status = map_nt_error_from_unix(errno);
out:
TALLOC_FREE(talloced);
+ TALLOC_FREE(smb_fname_src_dir);
TALLOC_FREE(fname_src_dir);
TALLOC_FREE(fname_src_mask);
return status;
TALLOC_CTX *ctx = talloc_tos();
struct smb_filename *smb_fname_src = NULL;
struct smb_filename *smb_fname_dst = NULL;
- uint32_t src_ucf_flags = (lp_posix_pathnames() ?
- (UCF_UNIX_NAME_LOOKUP|UCF_POSIX_PATHNAMES) :
- UCF_COND_ALLOW_WCARD_LCOMP);
- uint32_t dst_ucf_flags = UCF_SAVE_LCOMP |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES :
- UCF_COND_ALLOW_WCARD_LCOMP);
+ uint32_t src_ucf_flags = ucf_flags_from_smb_request(req) |
+ (req->posix_pathnames ?
+ UCF_UNIX_NAME_LOOKUP :
+ UCF_COND_ALLOW_WCARD_LCOMP);
+ uint32_t dst_ucf_flags = ucf_flags_from_smb_request(req) |
+ UCF_SAVE_LCOMP |
+ (req->posix_pathnames ?
+ 0 :
+ UCF_COND_ALLOW_WCARD_LCOMP);
bool stream_rename = false;
START_PROFILE(SMBmv);
goto out;
}
- if (!lp_posix_pathnames()) {
+ if (!req->posix_pathnames) {
/* The newname must begin with a ':' if the
name contains a ':'. */
if (strchr_m(name, ':')) {
status = filename_convert(ctx,
conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
name,
src_ucf_flags,
&src_has_wcard,
status = filename_convert(ctx,
conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
newname,
dst_ucf_flags,
&dest_has_wcard,
{
connection_struct *conn = req->conn;
struct smb_filename *smb_fname_src = NULL;
+ struct smb_filename *smb_fname_src_dir = NULL;
struct smb_filename *smb_fname_dst = NULL;
char *fname_src = NULL;
char *fname_dst = NULL;
bool dest_has_wild = False;
NTSTATUS status;
uint32_t ucf_flags_src = UCF_COND_ALLOW_WCARD_LCOMP |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ ucf_flags_from_smb_request(req);
uint32_t ucf_flags_dst = UCF_COND_ALLOW_WCARD_LCOMP |
- (lp_posix_pathnames() ? UCF_POSIX_PATHNAMES : 0);
+ ucf_flags_from_smb_request(req);
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBcopy);
}
status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_src,
ucf_flags_src,
&source_has_wild,
}
status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_dst,
ucf_flags_dst,
&dest_has_wild,
smb_fname_dst->base_name = fname_dst_mod;
}
- status = check_name(conn, smb_fname_src->base_name);
+ status = check_name(conn, smb_fname_src);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
goto out;
}
- status = check_name(conn, smb_fname_dst->base_name);
+ status = check_name(conn, smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
goto out;
}
}
- status = check_name(conn, fname_src_dir);
+ smb_fname_src_dir = synthetic_smb_fname(talloc_tos(),
+ fname_src_dir,
+ NULL,
+ NULL,
+ smb_fname_src->flags);
+ if (smb_fname_src_dir == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ goto out;
+ }
+
+ status = check_name(conn, smb_fname_src_dir);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
goto out;
}
- dir_hnd = OpenDir(ctx, conn, fname_src_dir, fname_src_mask, 0);
+ dir_hnd = OpenDir(ctx,
+ conn,
+ smb_fname_src_dir,
+ fname_src_mask,
+ 0);
if (dir_hnd == NULL) {
status = map_nt_error_from_unix(errno);
reply_nterror(req, status);
TALLOC_FREE(smb_fname_dst->base_name);
smb_fname_dst->base_name = destname;
- status = check_name(conn, smb_fname_src->base_name);
+ status = check_name(conn, smb_fname_src);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
TALLOC_FREE(talloced);
goto out;
}
- status = check_name(conn, smb_fname_dst->base_name);
+ status = check_name(conn, smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
TALLOC_FREE(talloced);
SSVAL(req->outbuf,smb_vwv0,count);
out:
TALLOC_FREE(smb_fname_src);
+ TALLOC_FREE(smb_fname_src_dir);
TALLOC_FREE(smb_fname_dst);
TALLOC_FREE(fname_src);
TALLOC_FREE(fname_dst);