#include "../lib/tsocket/tsocket.h"
#include "lib/tevent_wait.h"
#include "libcli/smb/smb_signing.h"
+#include "lib/util/sys_rw_data.h"
/****************************************************************************
Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
/****************************************************************************
Pull a string and check the path allowing a wilcard - provide for error return.
+ Passes in posix flag.
****************************************************************************/
-size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
+static size_t srvstr_get_path_wcard_internal(TALLOC_CTX *ctx,
const char *base_ptr,
- uint16 smb_flags2,
+ uint16_t smb_flags2,
char **pp_dest,
const char *src,
size_t src_len,
int flags,
+ bool posix_pathnames,
NTSTATUS *err,
bool *contains_wcard)
{
return ret;
}
- if (lp_posix_pathnames()) {
+ if (posix_pathnames) {
*err = check_path_syntax_posix(*pp_dest);
} else {
*err = check_path_syntax_wcard(*pp_dest, contains_wcard);
return ret;
}
+/****************************************************************************
+ Pull a string and check the path allowing a wilcard - provide for error return.
+****************************************************************************/
+
+size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
+ const char *base_ptr,
+ uint16_t smb_flags2,
+ char **pp_dest,
+ const char *src,
+ size_t src_len,
+ int flags,
+ NTSTATUS *err,
+ bool *contains_wcard)
+{
+ return srvstr_get_path_wcard_internal(ctx,
+ base_ptr,
+ smb_flags2,
+ pp_dest,
+ src,
+ src_len,
+ flags,
+ false,
+ err,
+ contains_wcard);
+}
+
+/****************************************************************************
+ Pull a string and check the path allowing a wilcard - provide for error return.
+ posix_pathnames version.
+****************************************************************************/
+
+size_t srvstr_get_path_wcard_posix(TALLOC_CTX *ctx,
+ const char *base_ptr,
+ uint16_t smb_flags2,
+ char **pp_dest,
+ const char *src,
+ size_t src_len,
+ int flags,
+ NTSTATUS *err,
+ bool *contains_wcard)
+{
+ return srvstr_get_path_wcard_internal(ctx,
+ base_ptr,
+ smb_flags2,
+ pp_dest,
+ src,
+ src_len,
+ flags,
+ true,
+ err,
+ contains_wcard);
+}
+
/****************************************************************************
Pull a string and check the path - provide for error return.
****************************************************************************/
size_t srvstr_get_path(TALLOC_CTX *ctx,
const char *base_ptr,
- uint16 smb_flags2,
+ uint16_t smb_flags2,
+ char **pp_dest,
+ const char *src,
+ size_t src_len,
+ int flags,
+ NTSTATUS *err)
+{
+ bool ignore;
+ return srvstr_get_path_wcard_internal(ctx,
+ base_ptr,
+ smb_flags2,
+ pp_dest,
+ src,
+ src_len,
+ flags,
+ false,
+ err,
+ &ignore);
+}
+
+/****************************************************************************
+ Pull a string and check the path - provide for error return.
+ posix_pathnames version.
+****************************************************************************/
+
+size_t srvstr_get_path_posix(TALLOC_CTX *ctx,
+ const char *base_ptr,
+ uint16_t smb_flags2,
char **pp_dest,
const char *src,
size_t src_len,
NTSTATUS *err)
{
bool ignore;
- return srvstr_get_path_wcard(ctx, base_ptr, smb_flags2, pp_dest, src,
- src_len, flags, err, &ignore);
+ return srvstr_get_path_wcard_internal(ctx,
+ base_ptr,
+ smb_flags2,
+ pp_dest,
+ src,
+ src_len,
+ flags,
+ true,
+ err,
+ &ignore);
}
+
size_t srvstr_get_path_req_wcard(TALLOC_CTX *mem_ctx, struct smb_request *req,
char **pp_dest, const char *src, int flags,
NTSTATUS *err, bool *contains_wcard)
return 0;
}
- return srvstr_get_path_wcard(mem_ctx, (const char *)req->inbuf,
- req->flags2, pp_dest, src, bufrem, flags,
- err, contains_wcard);
+ if (req->posix_pathnames) {
+ return srvstr_get_path_wcard_internal(mem_ctx,
+ (const char *)req->inbuf,
+ req->flags2,
+ pp_dest,
+ src,
+ bufrem,
+ flags,
+ true,
+ err,
+ contains_wcard);
+ } else {
+ return srvstr_get_path_wcard_internal(mem_ctx,
+ (const char *)req->inbuf,
+ req->flags2,
+ pp_dest,
+ src,
+ bufrem,
+ flags,
+ false,
+ err,
+ contains_wcard);
+ }
}
size_t srvstr_get_path_req(TALLOC_CTX *mem_ctx, struct smb_request *req,
static bool netbios_session_retarget(struct smbXsrv_connection *xconn,
const char *name, int name_type)
{
- struct smbd_server_connection *sconn = xconn->sconn;
char *trim_name;
char *trim_name_type;
const char *retarget_parm;
*(uint32_t *)(outbuf+4) = in_addr->sin_addr.s_addr;
*(uint16_t *)(outbuf+8) = htons(retarget_port);
- if (!srv_send_smb(sconn, (char *)outbuf, false, 0, false,
+ if (!srv_send_smb(xconn, (char *)outbuf, false, 0, false,
NULL)) {
exit_server_cleanly("netbios_session_retarget: srv_send_smb "
"failed.");
void reply_special(struct smbXsrv_connection *xconn, char *inbuf, size_t inbuf_size)
{
- struct smbd_server_connection *sconn = xconn->sconn;
+ struct smbd_server_connection *sconn = xconn->client->sconn;
int msg_type = CVAL(inbuf,0);
int msg_flags = CVAL(inbuf,1);
/*
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
msg_type, msg_flags));
- srv_send_smb(sconn, 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");
const uint8_t *p;
const char *p2;
TALLOC_CTX *ctx = talloc_tos();
- struct smbd_server_connection *sconn = req->sconn;
- struct smbXsrv_connection *xconn = sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
NTTIME now = timeval_to_nttime(&req->request_time);
START_PROFILE(SMBtcon);
service = service_buf;
}
- conn = make_connection(sconn, now, service, dev,
+ conn = make_connection(req, now, service, dev,
req->vuid,&nt_status);
req->conn = conn;
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;
NTTIME now = timeval_to_nttime(&req->request_time);
bool session_key_updated = false;
uint16_t optional_support = 0;
- struct smbd_server_connection *sconn = req->sconn;
- struct smbXsrv_connection *xconn = sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
START_PROFILE(SMBtconX);
DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
- nt_status = smb1srv_session_lookup(req->sconn->conn,
+ nt_status = smb1srv_session_lookup(xconn,
req->vuid, now, &session);
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_USER_SESSION_DELETED)) {
reply_force_doserror(req, ERRSRV, ERRbaduid);
session_key_updated = true;
}
- conn = make_connection(sconn, now, service, client_devicetype,
+ conn = make_connection(req, now, service, client_devicetype,
req->vuid, &nt_status);
req->conn =conn;
if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
/* Return permissions. */
- uint32 perm1 = 0;
- uint32 perm2 = 0;
+ uint32_t perm1 = 0;
+ uint32_t perm2 = 0;
reply_outbuf(req, 7, 0);
Reply to an unknown type.
****************************************************************************/
-void reply_unknown_new(struct smb_request *req, uint8 type)
+void reply_unknown_new(struct smb_request *req, uint8_t type)
{
DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
smb_fn_name(type), type, type));
void reply_ioctl(struct smb_request *req)
{
connection_struct *conn = req->conn;
- uint16 device;
- uint16 function;
- uint32 ioctl_code;
+ uint16_t device;
+ uint16_t function;
+ uint32_t ioctl_code;
int replysize;
char *p;
switch (ioctl_code) {
case IOCTL_QUERY_JOB_INFO:
{
+ NTSTATUS status;
+ size_t len = 0;
files_struct *fsp = file_fsp(
req, SVAL(req->vwv+0, 0));
if (!fsp) {
/* Job number */
SSVAL(p, 0, print_spool_rap_jobid(fsp->print_file));
- srvstr_push((char *)req->outbuf, req->flags2, p+2,
+ status = srvstr_push((char *)req->outbuf, req->flags2, p+2,
lp_netbios_name(), 15,
- STR_TERMINATE|STR_ASCII);
+ STR_TERMINATE|STR_ASCII, &len);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ END_PROFILE(SMBioctl);
+ return;
+ }
if (conn) {
- srvstr_push((char *)req->outbuf, req->flags2,
+ status = srvstr_push((char *)req->outbuf, req->flags2,
p+18,
lp_servicename(talloc_tos(),
SNUM(conn)),
- 13, STR_TERMINATE|STR_ASCII);
+ 13, STR_TERMINATE|STR_ASCII, &len);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ END_PROFILE(SMBioctl);
+ return;
+ }
} else {
memset(p+18, 0, 13);
}
struct smb_filename *smb_fname = NULL;
char *name = NULL;
NTSTATUS status;
+ 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,
- 0,
+ ucf_flags,
NULL,
&smb_fname);
size = 0;
mtime = 0;
} else {
+ uint32_t ucf_flags = ucf_flags_from_smb_request(req);
status = filename_convert(ctx,
conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- 0,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
} else {
srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
}
- SIVAL(req->outbuf,smb_vwv3,(uint32)size);
+ SIVAL(req->outbuf,smb_vwv3,(uint32_t)size);
if (get_Protocol() >= PROTOCOL_NT1) {
SSVAL(req->outbuf, smb_flg2,
time_t mtime;
const char *p;
NTSTATUS status;
+ 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,
- 0,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
void reply_dskattr(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ uint64_t ret;
uint64_t dfree,dsize,bsize;
+ struct smb_filename smb_fname;
START_PROFILE(SMBdskattr);
- if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
+ 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);
return;
}
+ /*
+ * Force max to fit in 16 bit fields.
+ */
+ while (dfree > WORDMAX || dsize > WORDMAX || bsize < 512) {
+ dfree /= 2;
+ dsize /= 2;
+ bsize *= 2;
+ if (bsize > (WORDMAX*512)) {
+ bsize = (WORDMAX*512);
+ if (dsize > WORDMAX)
+ dsize = WORDMAX;
+ if (dfree > WORDMAX)
+ dfree = WORDMAX;
+ break;
+ }
+ }
+
reply_outbuf(req, 5, 0);
if (get_Protocol() <= PROTOCOL_LANMAN2) {
return NT_STATUS_OK;
}
+/****************************************************************************
+ Make a dir struct.
+****************************************************************************/
+
+static bool make_dir_struct(TALLOC_CTX *ctx,
+ char *buf,
+ const char *mask,
+ const char *fname,
+ off_t size,
+ uint32_t mode,
+ time_t date,
+ bool uc)
+{
+ char *p;
+ char *mask2 = talloc_strdup(ctx, mask);
+
+ if (!mask2) {
+ return False;
+ }
+
+ if ((mode & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+ size = 0;
+ }
+
+ memset(buf+1,' ',11);
+ if ((p = strchr_m(mask2,'.')) != NULL) {
+ *p = 0;
+ push_ascii(buf+1,mask2,8, 0);
+ push_ascii(buf+9,p+1,3, 0);
+ *p = '.';
+ } else {
+ push_ascii(buf+1,mask2,11, 0);
+ }
+
+ memset(buf+21,'\0',DIR_STRUCT_SIZE-21);
+ SCVAL(buf,21,mode);
+ srv_put_dos_date(buf,22,date);
+ SSVAL(buf,26,size & 0xFFFF);
+ SSVAL(buf,28,(size >> 16)&0xFFFF);
+ /* We only uppercase if FLAGS2_LONG_PATH_COMPONENTS is zero in the input buf.
+ Strange, but verified on W2K3. Needed for OS/2. JRA. */
+ push_ascii(buf+30,fname,12, uc ? STR_UPPER : 0);
+ DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname));
+ return True;
+}
+
/****************************************************************************
Reply to a search.
Can be called from SMBsearch, SMBffirst or SMBfunique.
{
connection_struct *conn = req->conn;
char *path = NULL;
- const char *mask = NULL;
+ char *mask = NULL;
char *directory = NULL;
struct smb_filename *smb_fname = NULL;
char *fname = NULL;
off_t size;
- uint32 mode;
+ uint32_t mode;
struct timespec date;
- uint32 dirtype;
+ uint32_t dirtype;
unsigned int numentries = 0;
unsigned int maxentries = 0;
bool finished = False;
TALLOC_CTX *ctx = talloc_tos();
bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
struct dptr_struct *dirptr = NULL;
+ struct smbXsrv_connection *xconn = req->xconn;
struct smbd_server_connection *sconn = req->sconn;
- struct smbXsrv_connection *xconn = sconn->conn;
START_PROFILE(SMBsearch);
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 |
+ ucf_flags_from_smb_request(req);
nt_status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
path,
- UCF_ALWAYS_ALLOW_WCARD_LCOMP,
+ ucf_flags,
&mask_contains_wcard,
&smb_fname);
if (!NT_STATUS_IS_OK(nt_status)) {
p = strrchr_m(directory,'/');
if ((p != NULL) && (*directory != '/')) {
- mask = p + 1;
+ mask = talloc_strdup(ctx, p + 1);
directory = talloc_strndup(ctx, directory,
PTR_DIFF(p, directory));
} else {
- mask = directory;
+ mask = talloc_strdup(ctx, directory);
directory = talloc_strdup(ctx,".");
}
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;
goto out;
}
- mask = dptr_wcard(sconn, dptr_num);
+ mask = talloc_strdup(ctx, dptr_wcard(sconn, dptr_num));
if (!mask) {
goto SearchEmpty;
}
* For a 'continue' search we have no string. So
* check from the initial saved string.
*/
- mask_contains_wcard = ms_has_wild(mask);
+ if (!req->posix_pathnames) {
+ mask_contains_wcard = ms_has_wild(mask);
+ }
dirtype = dptr_attr(sconn, dptr_num);
}
maxentries ));
out:
TALLOC_FREE(directory);
+ TALLOC_FREE(mask);
TALLOC_FREE(smb_fname);
END_PROFILE(SMBsearch);
return;
START_PROFILE(SMBfclose);
- if (lp_posix_pathnames()) {
+ if (req->posix_pathnames) {
reply_unknown_new(req, req->cmd);
END_PROFILE(SMBfclose);
return;
connection_struct *conn = req->conn;
struct smb_filename *smb_fname = NULL;
char *fname = NULL;
- uint32 fattr=0;
+ uint32_t fattr=0;
off_t size = 0;
time_t mtime=0;
int info;
files_struct *fsp;
int oplock_request;
int deny_mode;
- uint32 dos_attr;
- uint32 access_mask;
- uint32 share_mode;
- uint32 create_disposition;
- uint32 create_options = 0;
+ uint32_t dos_attr;
+ uint32_t access_mask;
+ uint32_t share_mode;
+ uint32_t create_disposition;
+ uint32_t create_options = 0;
uint32_t private_flags = 0;
NTSTATUS status;
+ 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_PREP_CREATEFILE,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
create_options, /* create_options */
dos_attr, /* file_attributes */
oplock_request, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
private_flags,
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- &info); /* pinfo */
+ &info, /* pinfo */
+ NULL, NULL); /* create context */
if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(req->sconn, req->mid)) {
+ if (open_was_deferred(req->xconn, req->mid)) {
/* We have re-scheduled this call. */
goto out;
}
} else {
srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
}
- SIVAL(req->outbuf,smb_vwv4,(uint32)size);
+ SIVAL(req->outbuf,smb_vwv4,(uint32_t)size);
SSVAL(req->outbuf,smb_vwv6,deny_mode);
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
connection_struct *conn = req->conn;
struct smb_filename *smb_fname = NULL;
char *fname = NULL;
- uint16 open_flags;
+ uint16_t open_flags;
int deny_mode;
- uint32 smb_attr;
+ uint32_t smb_attr;
/* Breakout the oplock request bits so we can set the
reply bits separately. */
int ex_oplock_request;
int oplock_request;
#if 0
int smb_sattr = SVAL(req->vwv+4, 0);
- uint32 smb_time = make_unix_date3(req->vwv+6);
+ uint32_t smb_time = make_unix_date3(req->vwv+6);
#endif
int smb_ofun;
- uint32 fattr=0;
+ uint32_t fattr=0;
int mtime=0;
int smb_action = 0;
files_struct *fsp;
NTSTATUS status;
uint64_t allocation_size;
ssize_t retval = -1;
- uint32 access_mask;
- uint32 share_mode;
- uint32 create_disposition;
- uint32 create_options = 0;
+ uint32_t access_mask;
+ uint32_t share_mode;
+ uint32_t create_disposition;
+ uint32_t create_options = 0;
uint32_t private_flags = 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_PREP_CREATEFILE,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
create_options, /* create_options */
smb_attr, /* file_attributes */
oplock_request, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
private_flags,
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- &smb_action); /* pinfo */
+ &smb_action, /* pinfo */
+ NULL, NULL); /* create context */
if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(req->sconn, req->mid)) {
+ if (open_was_deferred(req->xconn, req->mid)) {
/* We have re-scheduled this call. */
goto out;
}
} else {
srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
}
- SIVAL(req->outbuf,smb_vwv6,(uint32)fsp->fsp_name->st.st_ex_size);
+ SIVAL(req->outbuf,smb_vwv6,(uint32_t)fsp->fsp_name->st.st_ex_size);
SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
SSVAL(req->outbuf,smb_vwv11,smb_action);
connection_struct *conn = req->conn;
struct smb_filename *smb_fname = NULL;
char *fname = NULL;
- uint32 fattr = 0;
+ uint32_t fattr = 0;
struct smb_file_time ft;
files_struct *fsp;
int oplock_request = 0;
NTSTATUS status;
- uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
- uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
- uint32 create_disposition;
- uint32 create_options = 0;
+ uint32_t access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
+ uint32_t share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
+ uint32_t create_disposition;
+ uint32_t create_options = 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_PREP_CREATEFILE,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
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 */
create_options, /* create_options */
fattr, /* file_attributes */
oplock_request, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- NULL); /* pinfo */
+ NULL, /* pinfo */
+ NULL, NULL); /* create context */
if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(req->sconn, req->mid)) {
+ if (open_was_deferred(req->xconn, req->mid)) {
/* We have re-scheduled this call. */
goto out;
}
struct smb_filename *smb_fname = NULL;
char *wire_name = NULL;
char *fname = NULL;
- uint32 fattr;
+ uint32_t fattr;
files_struct *fsp;
int oplock_request;
char *s;
NTSTATUS status;
int i;
+ 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_PREP_CREATEFILE,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
0, /* create_options */
fattr, /* file_attributes */
oplock_request, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- NULL); /* pinfo */
+ NULL, /* pinfo */
+ NULL, NULL); /* create context */
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
TALLOC_FREE(fname);
}
if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(req->sconn, req->mid)) {
+ if (open_was_deferred(req->xconn, req->mid)) {
/* We have re-scheduled this call. */
goto out;
}
********************************************************************/
static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
- uint16 dirtype)
+ uint16_t dirtype)
{
if (!CAN_WRITE(conn)) {
return NT_STATUS_MEDIA_WRITE_PROTECTED;
if ((dirtype & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) !=
(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
/* Only bother to read the DOS attribute if we might deny the
- rename on the grounds of attribute missmatch. */
+ rename on the grounds of attribute mismatch. */
uint32_t fmode = dos_mode(conn, fsp->fsp_name);
if ((fmode & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
return NT_STATUS_NO_SUCH_FILE;
}
if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
- if (fsp->posix_open) {
+ if (fsp->posix_flags & FSP_POSIX_FLAGS_RENAME) {
return NT_STATUS_OK;
}
/* If no pathnames are open below this
directory, allow the rename. */
- if (file_find_subpath(fsp)) {
+ if (lp_strict_rename(SNUM(conn))) {
+ /*
+ * Strict rename, check open file db.
+ */
+ if (have_file_open_below(fsp->conn, fsp->fsp_name)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ } else if (file_find_subpath(fsp)) {
+ /*
+ * No strict rename, just look in local process.
+ */
return NT_STATUS_ACCESS_DENIED;
}
return NT_STATUS_OK;
static NTSTATUS do_unlink(connection_struct *conn,
struct smb_request *req,
struct smb_filename *smb_fname,
- uint32 dirtype)
+ uint32_t dirtype)
{
- uint32 fattr;
+ uint32_t fattr;
files_struct *fsp;
- uint32 dirtype_orig = dirtype;
+ 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),
posix_paths ? FILE_FLAG_POSIX_SEMANTICS|0777 :
FILE_ATTRIBUTE_NORMAL,
0, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- NULL); /* pinfo */
+ NULL, /* pinfo */
+ NULL, NULL); /* create context */
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n",
****************************************************************************/
NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
- uint32 dirtype, struct smb_filename *smb_fname,
+ uint32_t dirtype, struct smb_filename *smb_fname,
bool has_wild)
{
char *fname_dir = NULL;
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 = NT_STATUS_OBJECT_NAME_INVALID;
goto out;
}
+ if (dirtype == 0) {
+ dirtype = FILE_ATTRIBUTE_NORMAL;
+ }
if (strequal(fname_mask,"????????.???")) {
TALLOC_FREE(fname_mask);
}
}
- 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;
connection_struct *conn = req->conn;
char *name = NULL;
struct smb_filename *smb_fname = NULL;
- uint32 dirtype;
+ uint32_t dirtype;
NTSTATUS status;
bool path_contains_wcard = False;
+ uint32_t ucf_flags = UCF_COND_ALLOW_WCARD_LCOMP |
+ 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_COND_ALLOW_WCARD_LCOMP,
+ ucf_flags,
&path_contains_wcard,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
status = unlink_internals(conn, req, dirtype, smb_fname,
path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(req->sconn, req->mid)) {
+ if (open_was_deferred(req->xconn, req->mid)) {
/* We have re-scheduled this call. */
goto out;
}
Fake (read/write) sendfile. Returns -1 on read or write fail.
****************************************************************************/
-ssize_t fake_sendfile(files_struct *fsp, off_t startpos, size_t nread)
+ssize_t fake_sendfile(struct smbXsrv_connection *xconn, files_struct *fsp,
+ off_t startpos, size_t nread)
{
- struct smbXsrv_connection *xconn = fsp->conn->sconn->conn;
size_t bufsize;
size_t tosend = nread;
char *buf;
ssize_t ret;
size_t cur_read;
- if (tosend > bufsize) {
- cur_read = bufsize;
- } else {
- cur_read = tosend;
- }
+ cur_read = MIN(tosend, bufsize);
ret = read_file(fsp,buf,startpos,cur_read);
if (ret == -1) {
SAFE_FREE(buf);
/****************************************************************************
Deal with the case of sendfile reading less bytes from the file than
- requested. Fill with zeros (all we can do).
+ requested. Fill with zeros (all we can do). Returns 0 on success
****************************************************************************/
-void sendfile_short_send(files_struct *fsp,
- ssize_t nread,
- size_t headersize,
- size_t smb_maxcnt)
+ssize_t sendfile_short_send(struct smbXsrv_connection *xconn,
+ files_struct *fsp,
+ ssize_t nread,
+ size_t headersize,
+ size_t smb_maxcnt)
{
- struct smbXsrv_connection *xconn = fsp->conn->sconn->conn;
-
#define SHORT_SEND_BUFSIZE 1024
if (nread < headersize) {
DEBUG(0,("sendfile_short_send: sendfile failed to send "
"header for file %s (%s). Terminating\n",
fsp_str_dbg(fsp), strerror(errno)));
- exit_server_cleanly("sendfile_short_send failed");
+ return -1;
}
nread -= headersize;
if (nread < smb_maxcnt) {
char *buf = SMB_CALLOC_ARRAY(char, SHORT_SEND_BUFSIZE);
if (!buf) {
- exit_server_cleanly("sendfile_short_send: "
- "malloc failed");
+ DEBUG(0,("sendfile_short_send: malloc failed "
+ "for file %s (%s). Terminating\n",
+ fsp_str_dbg(fsp), strerror(errno)));
+ return -1;
}
DEBUG(0,("sendfile_short_send: filling truncated file %s "
smbXsrv_connection_dbg(xconn),
strerror(saved_errno)));
errno = saved_errno;
- exit_server_cleanly("sendfile_short_send: "
- "write_data failed");
+ return -1;
}
nread += to_write;
}
SAFE_FREE(buf);
}
+
+ return 0;
}
/****************************************************************************
Return a readbraw error (4 bytes of zero).
****************************************************************************/
-static void reply_readbraw_error(struct smbd_server_connection *sconn)
+static void reply_readbraw_error(struct smbXsrv_connection *xconn)
{
- struct smbXsrv_connection *xconn = sconn->conn;
char header[4];
SIVAL(header,0,0);
- smbd_lock_socket(sconn);
+ smbd_lock_socket(xconn);
if (write_data(xconn->transport.sock,header,4) != 4) {
int saved_errno = errno;
/*
fail_readraw();
}
- smbd_unlock_socket(sconn);
+ smbd_unlock_socket(xconn);
}
/****************************************************************************
size_t nread,
ssize_t mincount)
{
- struct smbd_server_connection *sconn = req->sconn;
- struct smbXsrv_connection *xconn = sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
char *outbuf = NULL;
ssize_t ret=0;
set_use_sendfile(SNUM(conn), False);
DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
- if (fake_sendfile(fsp, startpos, nread) == -1) {
+ if (fake_sendfile(xconn, fsp, startpos, nread) == -1) {
DEBUG(0,("send_file_readbraw: "
"fake_sendfile failed for "
"file %s (%s).\n",
/* Deal with possible short send. */
if (sendfile_read != 4+nread) {
- sendfile_short_send(fsp, sendfile_read, 4, nread);
+ ret = sendfile_short_send(xconn, fsp,
+ sendfile_read, 4, nread);
+ if (ret == -1) {
+ fail_readraw();
+ }
}
return;
}
if (!outbuf) {
DEBUG(0,("send_file_readbraw: talloc_array failed for size %u.\n",
(unsigned)(nread+4)));
- reply_readbraw_error(sconn);
+ reply_readbraw_error(xconn);
return;
}
void reply_readbraw(struct smb_request *req)
{
connection_struct *conn = req->conn;
- struct smbd_server_connection *sconn = req->sconn;
- struct smbXsrv_connection *xconn = sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
ssize_t maxcount,mincount;
size_t nread = 0;
off_t startpos;
}
if (req->wct < 8) {
- reply_readbraw_error(sconn);
+ reply_readbraw_error(xconn);
END_PROFILE(SMBreadbraw);
return;
}
if (xconn->smb1.echo_handler.trusted_fde) {
DEBUG(2,("SMBreadbraw rejected with NOT_SUPPORTED because of "
"'async smb echo handler = yes'\n"));
- reply_readbraw_error(sconn);
+ reply_readbraw_error(xconn);
END_PROFILE(SMBreadbraw);
return;
}
DEBUG(3,("reply_readbraw: fnum %d not valid "
"- cache prime?\n",
(int)SVAL(req->vwv+0, 0)));
- reply_readbraw_error(sconn);
+ reply_readbraw_error(xconn);
END_PROFILE(SMBreadbraw);
return;
}
(fsp->access_mask & FILE_EXECUTE)))) {
DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
(int)SVAL(req->vwv+0, 0)));
- reply_readbraw_error(sconn);
+ reply_readbraw_error(xconn);
END_PROFILE(SMBreadbraw);
return;
}
DEBUG(0,("reply_readbraw: negative 64 bit "
"readraw offset (%.0f) !\n",
(double)startpos ));
- reply_readbraw_error(sconn);
+ reply_readbraw_error(xconn);
END_PROFILE(SMBreadbraw);
return;
}
(uint64_t)startpos, (uint64_t)maxcount, READ_LOCK,
&lock);
- if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
- reply_readbraw_error(sconn);
+ 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;
}
files_struct *fsp;
struct byte_range_lock *br_lck = NULL;
char *p = NULL;
- struct smbd_server_connection *sconn = req->sconn;
- struct smbXsrv_connection *xconn = sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
START_PROFILE(SMBlockread);
off_t startpos;
files_struct *fsp;
struct lock_struct lock;
- struct smbd_server_connection *sconn = req->sconn;
- struct smbXsrv_connection *xconn = sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
START_PROFILE(SMBread);
(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;
- outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
+ outsize = srv_set_message(outbuf,12,smb_maxcnt + 1 /* padding byte */,
+ False);
memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
(smb_wct - 4) /* offset from smb header to wct */
+ 1 /* the wct field */
+ 12 * sizeof(uint16_t) /* vwv */
- + 2); /* the buflen field */
+ + 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,(smb_size + 12*2 + smb_maxcnt - 4));
+ _smb_setlen_large(outbuf,
+ smb_size + 12*2 + smb_maxcnt - 4 + 1 /* pad */);
return outsize;
}
files_struct *fsp, off_t startpos,
size_t smb_maxcnt)
{
- struct smbXsrv_connection *xconn = req->sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
ssize_t nread = -1;
struct lock_struct lock;
int saved_errno = 0;
(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;
}
(fsp->base_fsp == NULL) &&
(fsp->wcp == NULL) &&
lp_use_sendfile(SNUM(conn), xconn->smb1.signing_state) ) {
- uint8 headerbuf[smb_size + 12 * 2];
+ uint8_t headerbuf[smb_size + 12 * 2 + 1 /* padding byte */];
DATA_BLOB header;
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);
/* Ensure we don't do this again. */
set_use_sendfile(SNUM(conn), False);
DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
- nread = fake_sendfile(fsp, startpos,
+ nread = fake_sendfile(xconn, fsp, startpos,
smb_maxcnt);
if (nread == -1) {
saved_errno = errno;
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 "
/* Deal with possible short send. */
if (nread != smb_maxcnt + sizeof(headerbuf)) {
- sendfile_short_send(fsp, nread, sizeof(headerbuf), smb_maxcnt);
+ ssize_t ret;
+
+ ret = sendfile_short_send(xconn, fsp, nread,
+ sizeof(headerbuf), smb_maxcnt);
+ if (ret == -1) {
+ const char *r;
+ r = "send_file_readX: sendfile_short_send failed";
+ DEBUG(0,("%s for file %s (%s).\n",
+ r, fsp_str_dbg(fsp), strerror(errno)));
+ exit_server_cleanly(r);
+ }
}
/* 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:
if ((smb_maxcnt & 0xFF0000) > 0x10000) {
- uint8 headerbuf[smb_size + 2*12];
+ 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 sendfile failed");
}
- nread = fake_sendfile(fsp, startpos, smb_maxcnt);
+ nread = fake_sendfile(xconn, fsp, startpos, smb_maxcnt);
if (nread == -1) {
saved_errno = errno;
DEBUG(0,("send_file_readX: fake_sendfile failed for file "
errno = saved_errno;
exit_server_cleanly("send_file_readX: fake_sendfile failed");
}
- goto strict_unlock;
+ goto out;
}
nosendfile_read:
- reply_outbuf(req, 12, smb_maxcnt);
+ reply_outbuf(req, 12, smb_maxcnt + 1 /* padding byte */);
SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
- nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
+ nread = read_file(fsp, smb_buf(req->outbuf) + 1 /* padding byte */,
+ 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;
}
static size_t calc_max_read_pdu(const struct smb_request *req)
{
- struct smbXsrv_connection *xconn = req->sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
- if (req->sconn->conn->protocol < PROTOCOL_NT1) {
+ if (xconn->protocol < PROTOCOL_NT1) {
return xconn->smb1.sessions.max_send;
}
size_t upper_size,
size_t lower_size)
{
+ struct smbXsrv_connection *xconn = req->xconn;
size_t max_pdu = calc_max_read_pdu(req);
size_t total_size = 0;
size_t hdr_len = MIN_SMB_SIZE + VWV(12);
- size_t max_len = max_pdu - hdr_len;
+ size_t max_len = max_pdu - hdr_len - 1 /* padding byte */;
/*
* Windows explicitly ignores upper size of 0xFFFF.
upper_size = 0;
}
- if (req->sconn->conn->protocol < PROTOCOL_NT1) {
+ if (xconn->protocol < PROTOCOL_NT1) {
upper_size = 0;
}
/* NT_STATUS_RETRY - fall back to sync read. */
}
- smbd_lock_socket(req->sconn);
+ smbd_lock_socket(req->xconn);
send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
- smbd_unlock_socket(req->sconn);
+ smbd_unlock_socket(req->xconn);
out:
END_PROFILE(SMBreadX);
void error_to_writebrawerr(struct smb_request *req)
{
- uint8 *old_outbuf = req->outbuf;
+ uint8_t *old_outbuf = req->outbuf;
reply_outbuf(req, 1, 0);
void reply_writebraw(struct smb_request *req)
{
connection_struct *conn = req->conn;
- struct smbXsrv_connection *xconn = req->sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
char *buf = NULL;
ssize_t nwritten=0;
ssize_t total_written=0;
(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
SCVAL(buf,smb_com,SMBwritebraw);
SSVALS(buf,smb_vwv0,0xFFFF);
show_msg(buf);
- if (!srv_send_smb(req->sconn,
+ if (!srv_send_smb(req->xconn,
buf,
false, 0, /* no signing */
IS_CONN_ENCRYPTED(conn),
(int)tcount,(int)nwritten,(int)numtowrite));
}
- status = read_data(xconn->transport.sock, buf+4, numtowrite);
+ status = read_data_ntstatus(xconn->transport.sock, buf+4,
+ numtowrite);
if (!NT_STATUS_IS_OK(status)) {
/* Try and give an error message
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;
}
(2*14) + /* word count (including bcc) */ \
1 /* pad byte */)
-bool is_valid_writeX_buffer(struct smbd_server_connection *sconn,
+bool is_valid_writeX_buffer(struct smbXsrv_connection *xconn,
const uint8_t *inbuf)
{
size_t numtowrite;
struct files_struct *fsp = NULL;
NTSTATUS status;
- if (is_encrypted_packet(sconn, inbuf)) {
+ if (is_encrypted_packet(inbuf)) {
/* Can't do this on encrypted
* connections. */
return false;
}
fnum = SVAL(inbuf, smb_vwv2);
- status = smb1srv_open_lookup(sconn->conn,
+ status = smb1srv_open_lookup(xconn,
fnum,
0, /* now */
&op);
void reply_write_and_X(struct smb_request *req)
{
connection_struct *conn = req->conn;
- struct smbXsrv_connection *xconn = req->sconn->conn;
+ struct smbXsrv_connection *xconn = req->xconn;
files_struct *fsp;
struct lock_struct lock;
off_t startpos;
(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) {
void reply_flush(struct smb_request *req)
{
connection_struct *conn = req->conn;
- uint16 fnum;
+ uint16_t fnum;
files_struct *fsp;
START_PROFILE(SMBflush);
} else {
reply_nterror(smbreq, status);
}
- if (!srv_send_smb(smbreq->sconn,
+ if (!srv_send_smb(smbreq->xconn,
(char *)smbreq->outbuf,
true,
smbreq->seqnum+1,
(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);
/*
SSVAL(req->outbuf,smb_vwv0,seq_num);
show_msg((char *)req->outbuf);
- if (!srv_send_smb(req->sconn,
+ if (!srv_send_smb(req->xconn,
(char *)req->outbuf,
true, req->seqnum+1,
IS_CONN_ENCRYPTED(conn)||req->encrypted,
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)) {
char *p = blob;
time_t qtime = spoolss_Time_to_time_t(&info[i].info2.submitted);
int qstatus;
+ size_t len = 0;
uint16_t qrapjobid = pjobid_to_rap(sharename,
info[i].info2.job_id);
SSVAL(p, 5, qrapjobid);
SIVAL(p, 7, info[i].info2.size);
SCVAL(p, 11, 0);
- srvstr_push(blob, req->flags2, p+12,
- info[i].info2.notify_name, 16, STR_ASCII);
-
+ status = srvstr_push(blob, req->flags2, p+12,
+ info[i].info2.notify_name, 16, STR_ASCII, &len);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
if (message_push_blob(
&req->outbuf,
data_blob_const(
struct smb_filename *smb_dname = NULL;
char *directory = NULL;
NTSTATUS status;
+ 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_PREP_CREATEFILE,
+ ucf_flags,
NULL,
&smb_dname);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_CTX *ctx = talloc_tos();
files_struct *fsp = NULL;
int info = 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,
- 0,
+ ucf_flags,
NULL,
&smb_dname);
if (!NT_STATUS_IS_OK(status)) {
FILE_DIRECTORY_FILE, /* create_options */
FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
0, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- &info); /* pinfo */
+ &info, /* pinfo */
+ NULL, NULL); /* create context */
if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(req->sconn, req->mid)) {
+ if (open_was_deferred(req->xconn, req->mid)) {
/* We have re-scheduled this call. */
goto out;
}
{
char *parent_dir_src = NULL;
char *parent_dir_dst = NULL;
- uint32 mask;
+ uint32_t mask;
mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
: FILE_NOTIFY_CHANGE_FILE_NAME;
NTSTATUS rename_internals_fsp(connection_struct *conn,
files_struct *fsp,
const struct smb_filename *smb_fname_dst_in,
- uint32 attrs,
+ uint32_t attrs,
bool replace_if_exists)
{
TALLOC_CTX *ctx = talloc_tos();
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;
}
/*
* Check for special case with case preserving and not
- * case sensitive. If the old last component differs from the original
+ * case sensitive. If the new last component differs from the original
* last component only by case, then we should allow
* the rename (user is trying to change the case of the
* filename).
*/
- if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
+ 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_ASSERT(lck != NULL);
if(SMB_VFS_RENAME(conn, fsp->fsp_name, smb_fname_dst) == 0) {
- uint32 create_options = fsp->fh->private_options;
+ uint32_t create_options = fsp->fh->private_options;
DEBUG(3, ("rename_internals_fsp: succeeded doing rename on "
"%s -> %s\n", smb_fname_str_dbg(fsp->fsp_name),
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
struct smb_request *req,
struct smb_filename *smb_fname_src,
struct smb_filename *smb_fname_dst,
- uint32 attrs,
+ uint32_t attrs,
bool replace_if_exists,
bool src_has_wild,
bool dest_has_wild,
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;
/*
create_options, /* create_options */
posix_pathnames ? FILE_FLAG_POSIX_SEMANTICS|0777 : 0, /* file_attributes */
0, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- NULL); /* pinfo */
+ NULL, /* pinfo */
+ NULL, NULL); /* create context */
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Could not open rename source %s: %s\n",
}
}
- 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);
create_options, /* create_options */
posix_pathnames ? FILE_FLAG_POSIX_SEMANTICS|0777 : 0, /* file_attributes */
0, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- NULL); /* pinfo */
+ NULL, /* pinfo */
+ NULL, NULL); /* create context */
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("rename_internals: SMB_VFS_CREATE_FILE "
out:
TALLOC_FREE(talloced);
+ TALLOC_FREE(smb_fname_src_dir);
TALLOC_FREE(fname_src_dir);
TALLOC_FREE(fname_src_mask);
return status;
char *name = NULL;
char *newname = NULL;
const char *p;
- uint32 attrs;
+ uint32_t attrs;
NTSTATUS status;
bool src_has_wcard = False;
bool dest_has_wcard = False;
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_COND_ALLOW_WCARD_LCOMP;
- uint32_t dst_ucf_flags = UCF_SAVE_LCOMP | (lp_posix_pathnames() ? 0 : 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,
attrs, False, src_has_wcard, dest_has_wcard,
DELETE_ACCESS);
if (!NT_STATUS_IS_OK(status)) {
- if (open_was_deferred(req->sconn, req->mid)) {
+ if (open_was_deferred(req->xconn, req->mid)) {
/* We have re-scheduled this call. */
goto out;
}
struct smb_filename *smb_fname_dst_tmp = NULL;
off_t ret=-1;
files_struct *fsp1,*fsp2;
- uint32 dosattrs;
- uint32 new_create_disposition;
+ uint32_t dosattrs;
+ uint32_t new_create_disposition;
NTSTATUS status;
0, /* create_options */
FILE_ATTRIBUTE_NORMAL, /* file_attributes */
INTERNAL_OPEN_ONLY, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp1, /* result */
- NULL); /* psbuf */
+ NULL, /* psbuf */
+ NULL, NULL); /* create context */
if (!NT_STATUS_IS_OK(status)) {
goto out;
0, /* create_options */
dosattrs, /* file_attributes */
INTERNAL_OPEN_ONLY, /* oplock_request */
+ NULL, /* lease */
0, /* allocation_size */
0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp2, /* result */
- NULL); /* psbuf */
+ NULL, /* psbuf */
+ NULL, NULL); /* create context */
if (!NT_STATUS_IS_OK(status)) {
close_file(NULL, fsp1, ERROR_CLOSE);
{
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 source_has_wild = False;
bool dest_has_wild = False;
NTSTATUS status;
+ uint32_t ucf_flags_src = UCF_COND_ALLOW_WCARD_LCOMP |
+ ucf_flags_from_smb_request(req);
+ uint32_t ucf_flags_dst = UCF_COND_ALLOW_WCARD_LCOMP |
+ 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_COND_ALLOW_WCARD_LCOMP,
+ ucf_flags_src,
&source_has_wild,
&smb_fname_src);
if (!NT_STATUS_IS_OK(status)) {
}
status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
fname_dst,
- UCF_COND_ALLOW_WCARD_LCOMP,
+ ucf_flags_dst,
&dest_has_wild,
&smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
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);
files_struct *fsp;
unsigned char locktype;
unsigned char oplocklevel;
- uint16 num_ulocks;
- uint16 num_locks;
- int32 lock_timeout;
+ uint16_t num_ulocks;
+ uint16_t num_locks;
+ int32_t lock_timeout;
int i;
const uint8_t *data;
bool large_file_format;
SIVAL(req->outbuf, smb_vwv6, 0);
SIVAL(req->outbuf, smb_vwv8, 0);
} else {
- uint32 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp, &fsp->fsp_name->st);
- SIVAL(req->outbuf, smb_vwv6, (uint32)fsp->fsp_name->st.st_ex_size);
+ uint32_t allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp, &fsp->fsp_name->st);
+ SIVAL(req->outbuf, smb_vwv6, (uint32_t)fsp->fsp_name->st.st_ex_size);
SIVAL(req->outbuf, smb_vwv8, allocation_size);
}
SSVAL(req->outbuf,smb_vwv10, mode);