const char *s = path;
NTSTATUS ret = NT_STATUS_OK;
bool start_of_name_component = True;
+ bool stream_started = false;
*p_last_component_contains_wcard = False;
while (*s) {
- if (IS_PATH_SEP(*s,posix_path)) {
+ if (stream_started) {
+ switch (*s) {
+ case '/':
+ case '\\':
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ case ':':
+ if (s[1] == '\0') {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ if (strchr_m(&s[1], ':')) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ if (StrCaseCmp(s, ":$DATA") != 0) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ break;
+ }
+ }
+
+ if (!stream_started && *s == ':') {
+ if (*p_last_component_contains_wcard) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ /* stream names allow more characters than file names */
+ stream_started = true;
+ start_of_name_component = false;
+ posix_path = true;
+
+ if (s[1] == '\0') {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ }
+
+ if (!stream_started && IS_PATH_SEP(*s,posix_path)) {
/*
* Safe to assume is not the second part of a mb char
* as this is handled below.
if (!(*s & 0x80)) {
if (!posix_path) {
- if (*s <= 0x1f) {
+ if (*s <= 0x1f || *s == '|') {
return NT_STATUS_OBJECT_NAME_INVALID;
}
switch (*s) {
****************************************************************************/
size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
- const char *inbuf,
+ const char *base_ptr,
uint16 smb_flags2,
char **pp_dest,
const char *src,
*pp_dest = NULL;
- if (src_len == 0) {
- ret = srvstr_pull_buf_talloc(ctx,
- inbuf,
- smb_flags2,
- pp_dest,
- src,
- flags);
- } else {
- ret = srvstr_pull_talloc(ctx,
- inbuf,
- smb_flags2,
- pp_dest,
- src,
- src_len,
- flags);
- }
+ ret = srvstr_pull_talloc(ctx, base_ptr, smb_flags2, pp_dest, src,
+ src_len, flags);
if (!*pp_dest) {
*err = NT_STATUS_INVALID_PARAMETER;
****************************************************************************/
size_t srvstr_get_path(TALLOC_CTX *ctx,
- const char *inbuf,
+ const char *base_ptr,
uint16 smb_flags2,
char **pp_dest,
const char *src,
int flags,
NTSTATUS *err)
{
- size_t ret;
-
- *pp_dest = NULL;
-
- if (src_len == 0) {
- ret = srvstr_pull_buf_talloc(ctx,
- inbuf,
- smb_flags2,
- pp_dest,
- src,
- flags);
- } else {
- ret = srvstr_pull_talloc(ctx,
- inbuf,
- smb_flags2,
- pp_dest,
- src,
- src_len,
- flags);
- }
-
- if (!*pp_dest) {
- *err = NT_STATUS_INVALID_PARAMETER;
- return ret;
- }
-
- if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
- /*
- * For a DFS path the function parse_dfs_path()
- * will do the path processing, just make a copy.
- */
- *err = NT_STATUS_OK;
- return ret;
- }
+ bool ignore;
+ return srvstr_get_path_wcard(ctx, base_ptr, smb_flags2, pp_dest, src,
+ src_len, flags, err, &ignore);
+}
- if (lp_posix_pathnames()) {
- *err = check_path_syntax_posix(*pp_dest);
- } else {
- *err = check_path_syntax(*pp_dest);
- }
+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 srvstr_get_path_wcard(mem_ctx, (char *)req->inbuf, req->flags2,
+ pp_dest, src, smbreq_bufrem(req, src),
+ flags, err, contains_wcard);
+}
- return ret;
+size_t srvstr_get_path_req(TALLOC_CTX *mem_ctx, struct smb_request *req,
+ char **pp_dest, const char *src, int flags,
+ NTSTATUS *err)
+{
+ bool ignore;
+ return srvstr_get_path_req_wcard(mem_ctx, req, pp_dest, src,
+ flags, err, &ignore);
}
/****************************************************************************
* header.
*/
char outbuf[smb_size];
-
+
static bool already_got_session = False;
*name1 = *name2 = 0;
-
+
memset(outbuf, '\0', sizeof(outbuf));
smb_setlen(outbuf,0);
-
+
switch (msg_type) {
case 0x81: /* session request */
-
+
if (already_got_session) {
exit_server_cleanly("multiple session request not permitted");
}
-
+
SCVAL(outbuf,0,0x82);
SCVAL(outbuf,3,0);
if (name_len(inbuf+4) > 50 ||
already_got_session = True;
break;
-
+
case 0x89: /* session keepalive request
(some old clients produce this?) */
SCVAL(outbuf,0,SMBkeepalive);
SCVAL(outbuf,3,0);
break;
-
+
case 0x82: /* positive session response */
case 0x83: /* negative session response */
case 0x84: /* retarget session response */
DEBUG(0,("Unexpected session response\n"));
break;
-
+
case SMBkeepalive: /* session keepalive */
default:
return;
}
-
+
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
msg_type, msg_flags));
char *dev = NULL;
int pwlen=0;
NTSTATUS nt_status;
- char *p;
+ const char *p;
DATA_BLOB password_blob;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBtcon);
- if (smb_buflen(req->inbuf) < 4) {
+ if (req->buflen < 4) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBtcon);
return;
}
- p = smb_buf(req->inbuf)+1;
- p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
- &service_buf, p, STR_TERMINATE) + 1;
- pwlen = srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
- &password, p, STR_TERMINATE) + 1;
- p += pwlen;
- p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
- &dev, p, STR_TERMINATE) + 1;
+ p = (const char *)req->buf + 1;
+ p += srvstr_pull_req_talloc(ctx, req, &service_buf, p, STR_TERMINATE);
+ p += 1;
+ pwlen = srvstr_pull_req_talloc(ctx, req, &password, p, STR_TERMINATE);
+ p += pwlen+1;
+ p += srvstr_pull_req_talloc(ctx, req, &dev, p, STR_TERMINATE);
+ p += 1;
if (service_buf == NULL || password == NULL || dev == NULL) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
void reply_tcon_and_X(struct smb_request *req)
{
connection_struct *conn = req->conn;
- char *service = NULL;
+ const char *service = NULL;
DATA_BLOB password;
TALLOC_CTX *ctx = talloc_tos();
/* what the cleint thinks the device is */
NTSTATUS nt_status;
int passlen;
char *path = NULL;
- char *p, *q;
+ const char *p, *q;
uint16 tcon_flags;
START_PROFILE(SMBtconX);
return;
}
- passlen = SVAL(req->inbuf,smb_vwv3);
- tcon_flags = SVAL(req->inbuf,smb_vwv2);
+ passlen = SVAL(req->vwv+3, 0);
+ tcon_flags = SVAL(req->vwv+2, 0);
/* we might have to close an old one */
if ((tcon_flags & 0x1) && conn) {
conn = NULL;
}
- if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
+ if ((passlen > MAX_PASS_LEN) || (passlen >= req->buflen)) {
reply_doserror(req, ERRDOS, ERRbuftoosmall);
END_PROFILE(SMBtconX);
return;
}
if (global_encrypted_passwords_negotiated) {
- password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
- passlen);
+ password = data_blob_talloc(talloc_tos(), req->buf, passlen);
if (lp_security() == SEC_SHARE) {
/*
* Security = share always has a pad byte
* after the password.
*/
- p = smb_buf(req->inbuf) + passlen + 1;
+ p = (const char *)req->buf + passlen + 1;
} else {
- p = smb_buf(req->inbuf) + passlen;
+ p = (const char *)req->buf + passlen;
}
} else {
- password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
- passlen+1);
+ password = data_blob_talloc(talloc_tos(), req->buf, passlen+1);
/* Ensure correct termination */
password.data[passlen]=0;
- p = smb_buf(req->inbuf) + passlen + 1;
+ p = (const char *)req->buf + passlen + 1;
}
- p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p,
- STR_TERMINATE);
+ p += srvstr_pull_req_talloc(ctx, req, &path, p, STR_TERMINATE);
if (path == NULL) {
data_blob_clear_free(&password);
p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
&client_devicetype, p,
- MIN(6,smb_bufrem(req->inbuf, p)), STR_ASCII);
+ MIN(6, smbreq_bufrem(req, p)), STR_ASCII);
if (client_devicetype == NULL) {
data_blob_clear_free(&password);
return;
}
- device = SVAL(req->inbuf,smb_vwv1);
- function = SVAL(req->inbuf,smb_vwv2);
+ device = SVAL(req->vwv+1, 0);
+ function = SVAL(req->vwv+2, 0);
ioctl_code = (device << 16) + function;
DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
case IOCTL_QUERY_JOB_INFO:
{
files_struct *fsp = file_fsp(
- req, SVAL(req->inbuf, smb_vwv0));
+ req, SVAL(req->vwv+0, 0));
if (!fsp) {
reply_doserror(req, ERRDOS, ERRbadfid);
END_PROFILE(SMBioctl);
Strange checkpath NTSTATUS mapping.
****************************************************************************/
-static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
+static NTSTATUS map_checkpath_error(uint16_t flags2, NTSTATUS status)
{
/* Strange DOS error code semantics only for checkpath... */
- if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
+ if (!(flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
/* We need to map to ERRbadpath */
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
START_PROFILE(SMBcheckpath);
- srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &name, (const char *)req->buf + 1,
+ STR_TERMINATE, &status);
+
if (!NT_STATUS_IS_OK(status)) {
- status = map_checkpath_error((char *)req->inbuf, status);
+ status = map_checkpath_error(req->flags2, status);
reply_nterror(req, status);
END_PROFILE(SMBcheckpath);
return;
goto path_err;
}
- DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
+ DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0)));
status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
one at a time - if a component fails it expects
ERRbadpath, not ERRbadfile.
*/
- status = map_checkpath_error((char *)req->inbuf, status);
+ status = map_checkpath_error(req->flags2, status);
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
/*
* Windows returns different error codes if
int mode=0;
SMB_OFF_T size=0;
time_t mtime=0;
- char *p;
+ const char *p;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBgetatr);
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
- 0, STR_TERMINATE, &status);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBgetatr);
SSVAL(req->outbuf, smb_flg2,
SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
}
-
+
DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
END_PROFILE(SMBgetatr);
int mode;
time_t mtime;
SMB_STRUCT_STAT sbuf;
- char *p;
+ const char *p;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
return;
}
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
- 0, STR_TERMINATE, &status);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBsetatr);
return;
}
- mode = SVAL(req->inbuf,smb_vwv0);
- mtime = srv_make_unix_date3(req->inbuf+smb_vwv1);
+ mode = SVAL(req->vwv+0, 0);
+ mtime = srv_make_unix_date3(req->vwv+1);
ts[1] = convert_time_t_to_timespec(mtime);
status = smb_set_file_time(conn, NULL, fname,
}
reply_outbuf(req, 0, 0);
-
+
DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
-
+
END_PROFILE(SMBsetatr);
return;
}
}
reply_outbuf(req, 5, 0);
-
+
if (Protocol <= PROTOCOL_LANMAN2) {
double total_space, free_space;
/* we need to scale this to a number that DOS6 can handle. We
dsize = (uint64_t)((total_space+63*512) / (64*512));
dfree = (uint64_t)((free_space+63*512) / (64*512));
-
+
if (dsize > 0xFFFF) dsize = 0xFFFF;
if (dfree > 0xFFFF) dfree = 0xFFFF;
void reply_search(struct smb_request *req)
{
connection_struct *conn = req->conn;
- char *mask = NULL;
+ const char *mask = NULL;
char *directory = NULL;
char *fname = NULL;
SMB_OFF_T size;
unsigned int numentries = 0;
unsigned int maxentries = 0;
bool finished = False;
- char *p;
+ const char *p;
int status_len;
char *path = NULL;
char status[21];
}
if (lp_posix_pathnames()) {
- reply_unknown_new(req, CVAL(req->inbuf, smb_com));
+ reply_unknown_new(req, req->cmd);
END_PROFILE(SMBsearch);
return;
}
/* If we were called as SMBffirst then we must expect close. */
- if(CVAL(req->inbuf,smb_com) == SMBffirst) {
+ if(req->cmd == SMBffirst) {
expect_close = True;
}
reply_outbuf(req, 1, 3);
- maxentries = SVAL(req->inbuf,smb_vwv0);
- dirtype = SVAL(req->inbuf,smb_vwv1);
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path_wcard(ctx,
- (char *)req->inbuf,
- req->flags2,
- &path,
- p,
- 0,
- STR_TERMINATE,
- &nt_status,
- &mask_contains_wcard);
+ maxentries = SVAL(req->vwv+0, 0);
+ dirtype = SVAL(req->vwv+1, 0);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
+ &nt_status, &mask_contains_wcard);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
END_PROFILE(SMBsearch);
}
p = strrchr_m(directory,'/');
- if (!p) {
+ if ((p != NULL) && (*directory != '/')) {
+ mask = p + 1;
+ directory = talloc_strndup(ctx, directory,
+ PTR_DIFF(p, directory));
+ } else {
mask = directory;
directory = talloc_strdup(ctx,".");
- if (!directory) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
- }
- } else {
- *p = 0;
- mask = p+1;
}
- if (*directory == '\0') {
- directory = talloc_strdup(ctx,".");
- if (!directory) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
- }
+ if (!directory) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBsearch);
+ return;
}
+
memset((char *)status,'\0',21);
SCVAL(status,0,(dirtype & 0x1F));
}
/* If we were called as SMBfunique, then we can close the dirptr now ! */
- if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) {
+ if(dptr_num >= 0 && req->cmd == SMBfunique) {
dptr_close(&dptr_num);
}
}
DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
- smb_fn_name(CVAL(req->inbuf,smb_com)),
+ smb_fn_name(req->cmd),
mask,
directory ? directory : "./",
dirtype,
int status_len;
char status[21];
int dptr_num= -2;
- char *p;
+ const char *p;
char *path = NULL;
NTSTATUS err;
bool path_contains_wcard = False;
START_PROFILE(SMBfclose);
if (lp_posix_pathnames()) {
- reply_unknown_new(req, CVAL(req->inbuf, smb_com));
+ reply_unknown_new(req, req->cmd);
END_PROFILE(SMBfclose);
return;
}
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path_wcard(ctx,
- (char *)req->inbuf,
- req->flags2,
- &path,
- p,
- 0,
- STR_TERMINATE,
- &err,
- &path_contains_wcard);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
+ &err, &path_contains_wcard);
if (!NT_STATUS_IS_OK(err)) {
reply_nterror(req, err);
END_PROFILE(SMBfclose);
}
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
- deny_mode = SVAL(req->inbuf,smb_vwv0);
- dos_attr = SVAL(req->inbuf,smb_vwv1);
+ deny_mode = SVAL(req->vwv+0, 0);
+ dos_attr = SVAL(req->vwv+1, 0);
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf)+1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBopen);
return;
}
- status = create_file(conn, /* conn */
- req, /* req */
- 0, /* root_dir_fid */
- fname, /* fname */
- access_mask, /* access_mask */
- share_mode, /* share_access */
- create_disposition, /* create_disposition*/
- create_options, /* create_options */
- dos_attr, /* file_attributes */
- oplock_request, /* oplock_request */
- 0, /* allocation_size */
- NULL, /* sd */
- NULL, /* ea_list */
- &fsp, /* result */
- &info, /* pinfo */
- &sbuf); /* psbuf */
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ true, /* is_dos_path */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ dos_attr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ &info, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
SCVAL(req->outbuf,smb_flg,
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
-
+
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
SCVAL(req->outbuf,smb_flg,
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
int core_oplock_request;
int oplock_request;
#if 0
- int smb_sattr = SVAL(req->inbuf,smb_vwv4);
- uint32 smb_time = make_unix_date3(req->inbuf+smb_vwv6);
+ int smb_sattr = SVAL(req->vwv+4, 0);
+ uint32 smb_time = make_unix_date3(req->vwv+6);
#endif
int smb_ofun;
uint32 fattr=0;
return;
}
- open_flags = SVAL(req->inbuf,smb_vwv2);
- deny_mode = SVAL(req->inbuf,smb_vwv3);
- smb_attr = SVAL(req->inbuf,smb_vwv5);
+ open_flags = SVAL(req->vwv+2, 0);
+ deny_mode = SVAL(req->vwv+3, 0);
+ smb_attr = SVAL(req->vwv+5, 0);
ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
oplock_request = ex_oplock_request | core_oplock_request;
- smb_ofun = SVAL(req->inbuf,smb_vwv8);
- allocation_size = (uint64_t)IVAL(req->inbuf,smb_vwv9);
+ smb_ofun = SVAL(req->vwv+8, 0);
+ allocation_size = (uint64_t)IVAL(req->vwv+9, 0);
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(conn)) {
}
/* XXXX we need to handle passed times, sattr and flags */
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf), 0, STR_TERMINATE,
- &status);
+ srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBopenX);
return;
}
- status = create_file(conn, /* conn */
- req, /* req */
- 0, /* root_dir_fid */
- fname, /* fname */
- access_mask, /* access_mask */
- share_mode, /* share_access */
- create_disposition, /* create_disposition*/
- create_options, /* create_options */
- smb_attr, /* file_attributes */
- oplock_request, /* oplock_request */
- 0, /* allocation_size */
- NULL, /* sd */
- NULL, /* ea_list */
- &fsp, /* result */
- &smb_action, /* pinfo */
- &sbuf); /* psbuf */
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ true, /* is_dos_path */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ smb_attr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ &smb_action, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBopenX);
{
connection_struct *conn = req->conn;
char *fname = NULL;
- int com;
uint32 fattr = 0;
struct timespec ts[2];
files_struct *fsp;
return;
}
- fattr = SVAL(req->inbuf,smb_vwv0);
+ fattr = SVAL(req->vwv+0, 0);
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
- com = SVAL(req->inbuf,smb_com);
- ts[1] =convert_time_t_to_timespec(
- srv_make_unix_date3(req->inbuf + smb_vwv1));
+ ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1));
/* mtime. */
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBcreate);
"please report this\n", fname));
}
- if(com == SMBmknew) {
+ if(req->cmd == SMBmknew) {
/* We should fail if file exists. */
create_disposition = FILE_CREATE;
} else {
create_disposition = FILE_OVERWRITE_IF;
}
- status = create_file(conn, /* conn */
- req, /* req */
- 0, /* root_dir_fid */
- fname, /* fname */
- access_mask, /* access_mask */
- share_mode, /* share_access */
- create_disposition, /* create_disposition*/
- create_options, /* create_options */
- fattr, /* file_attributes */
- oplock_request, /* oplock_request */
- 0, /* allocation_size */
- NULL, /* sd */
- NULL, /* ea_list */
- &fsp, /* result */
- NULL, /* pinfo */
- &sbuf); /* psbuf */
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ true, /* is_dos_path */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ fattr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ NULL, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
return;
}
- fattr = SVAL(req->inbuf,smb_vwv0);
+ fattr = SVAL(req->vwv+0, 0);
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf)+1, 0, STR_TERMINATE,
- &status);
+ srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBctemp);
SCVAL(req->outbuf, smb_flg,
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
-
+
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
SCVAL(req->outbuf, smb_flg,
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
/* On open checks the open itself will check the share mode, so
don't do it here as we'll get it wrong. */
- status = create_file_unixpath
+ status = SMB_VFS_CREATE_FILE
(conn, /* conn */
req, /* req */
+ 0, /* root_dir_fid */
fname, /* fname */
+ false, /* is_dos_path */
DELETE_ACCESS, /* access_mask */
FILE_SHARE_NONE, /* share_access */
FILE_OPEN, /* create_disposition*/
&sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("create_file_unixpath failed: %s\n",
+ DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n",
nt_errstr(status)));
return status;
}
return;
}
- dirtype = SVAL(req->inbuf,smb_vwv0);
+ dirtype = SVAL(req->vwv+0, 0);
- srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status, &path_contains_wcard);
+ srvstr_get_path_req_wcard(ctx, req, &name, (const char *)req->buf + 1,
+ STR_TERMINATE, &status,
+ &path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBunlink);
* return a zero length response here.
*/
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
/*
* We have to do a check_fsp by hand here, as
*/
DEBUG(3,("reply_readbraw: fnum %d not valid "
"- cache prime?\n",
- (int)SVAL(req->inbuf,smb_vwv0)));
+ (int)SVAL(req->vwv+0, 0)));
reply_readbraw_error();
END_PROFILE(SMBreadbraw);
return;
((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
(fsp->access_mask & FILE_EXECUTE)))) {
DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
- (int)SVAL(req->inbuf,smb_vwv0)));
+ (int)SVAL(req->vwv+0, 0)));
reply_readbraw_error();
END_PROFILE(SMBreadbraw);
return;
flush_write_cache(fsp, READRAW_FLUSH);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+1, 0);
if(req->wct == 10) {
/*
* This is a large offset (64 bit) read.
*/
#ifdef LARGE_SMB_OFF_T
- startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(req->vwv+8, 0)) << 32);
#else /* !LARGE_SMB_OFF_T */
* Ensure we haven't been sent a >32 bit offset.
*/
- if(IVAL(req->inbuf,smb_vwv8) != 0) {
+ if(IVAL(req->vwv+8, 0) != 0) {
DEBUG(0,("reply_readbraw: large offset "
"(%x << 32) used and we don't support "
"64 bit offsets.\n",
- (unsigned int)IVAL(req->inbuf,smb_vwv8) ));
+ (unsigned int)IVAL(req->vwv+8, 0) ));
reply_readbraw_error();
END_PROFILE(SMBreadbraw);
return;
}
}
- maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
- mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
+ maxcount = (SVAL(req->vwv+3, 0) & 0xFFFF);
+ mincount = (SVAL(req->vwv+4, 0) & 0xFFFF);
/* ensure we don't overrun the packet size */
maxcount = MIN(65535,maxcount);
if (nread < mincount)
nread = 0;
#endif
-
+
DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
"min=%lu nread=%lu\n",
fsp->fnum, (double)startpos,
(unsigned long)maxcount,
(unsigned long)mincount,
(unsigned long)nread ) );
-
+
send_file_readbraw(conn, fsp, startpos, nread, mincount);
DEBUG(5,("reply_readbraw finished\n"));
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBlockread);
return;
}
- if (!CHECK_READ(fsp,req->inbuf)) {
+ if (!CHECK_READ(fsp,req)) {
reply_doserror(req, ERRDOS, ERRbadaccess);
END_PROFILE(SMBlockread);
return;
release_level_2_oplocks_on_change(fsp);
- numtoread = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
+ numtoread = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
reply_outbuf(req, 5, numtoread + 3);
data = smb_buf(req->outbuf) + 3;
-
+
/*
* NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
* protocol request that predates the read/write lock concept.
* for a write lock. JRA.
* Note that the requested lock size is unaffected by max_recv.
*/
-
+
br_lck = do_lock(smbd_messaging_context(),
fsp,
req->smbpid,
END_PROFILE(SMBlockread);
return;
}
-
+
srv_set_message((char *)req->outbuf, 5, nread+3, False);
SSVAL(req->outbuf,smb_vwv0,nread);
p = smb_buf(req->outbuf);
SCVAL(p,0,0); /* pad byte. */
SSVAL(p,1,nread);
-
+
DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
fsp->fnum, (int)numtoread, (int)nread));
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBread);
return;
}
- if (!CHECK_READ(fsp,req->inbuf)) {
+ if (!CHECK_READ(fsp,req)) {
reply_doserror(req, ERRDOS, ERRbadaccess);
END_PROFILE(SMBread);
return;
}
- numtoread = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
+ numtoread = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
reply_outbuf(req, 5, numtoread+3);
data = smb_buf(req->outbuf) + 3;
-
+
if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtoread,
(uint64_t)startpos, READ_LOCK)) {
reply_doserror(req, ERRDOS,ERRlock);
SSVAL(req->outbuf,smb_vwv5,nread+3);
SCVAL(smb_buf(req->outbuf),0,1);
SSVAL(smb_buf(req->outbuf),1,nread);
-
+
DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
fsp->fnum, (int)numtoread, (int)nread ) );
* on a train in Germany :-). JRA.
*/
- if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
+ if ((chain_size == 0) && (CVAL(req->vwv+0, 0) == 0xFF) &&
!is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
uint8 headerbuf[smb_size + 12 * 2];
header = data_blob_const(headerbuf, sizeof(headerbuf));
- construct_reply_common((char *)req->inbuf, (char *)headerbuf);
+ construct_reply_common_req(req, (char *)headerbuf);
setup_readX_header((char *)headerbuf, smb_maxcnt);
if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
if ((smb_maxcnt & 0xFF0000) > 0x10000) {
uint8 headerbuf[smb_size + 2*12];
- construct_reply_common((char *)req->inbuf, (char *)headerbuf);
+ construct_reply_common_req(req, (char *)headerbuf);
setup_readX_header((char *)headerbuf, smb_maxcnt);
/* Send out the header. */
size_t smb_maxcnt;
bool big_readX = False;
#if 0
- size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
+ size_t smb_mincnt = SVAL(req->vwv+6, 0);
#endif
START_PROFILE(SMBreadX);
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
- smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
+ fsp = file_fsp(req, SVAL(req->vwv+2, 0));
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0);
+ smb_maxcnt = SVAL(req->vwv+5, 0);
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(conn)) {
return;
}
- if (!CHECK_READ(fsp,req->inbuf)) {
+ if (!CHECK_READ(fsp,req)) {
reply_doserror(req, ERRDOS,ERRbadaccess);
END_PROFILE(SMBreadX);
return;
}
if (global_client_caps & CAP_LARGE_READX) {
- size_t upper_size = SVAL(req->inbuf,smb_vwv7);
+ size_t upper_size = SVAL(req->vwv+7, 0);
smb_maxcnt |= (upper_size<<16);
if (upper_size > 1) {
/* Can't do this on a chained packet. */
- if ((CVAL(req->inbuf,smb_vwv0) != 0xFF)) {
+ if ((CVAL(req->vwv+0, 0) != 0xFF)) {
reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
END_PROFILE(SMBreadX);
return;
/*
* This is a large offset (64 bit) read.
*/
- startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv10)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(req->vwv+10, 0)) << 32);
#else /* !LARGE_SMB_OFF_T */
* Ensure we haven't been sent a >32 bit offset.
*/
- if(IVAL(req->inbuf,smb_vwv10) != 0) {
+ if(IVAL(req->vwv+10, 0) != 0) {
DEBUG(0,("reply_read_and_X - large offset (%x << 32) "
"used and we don't support 64 bit offsets.\n",
- (unsigned int)IVAL(req->inbuf,smb_vwv10) ));
+ (unsigned int)IVAL(req->vwv+10, 0) ));
END_PROFILE(SMBreadX);
reply_doserror(req, ERRDOS, ERRbadaccess);
return;
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
error_to_writebrawerr(req);
END_PROFILE(SMBwritebraw);
return;
}
- tcount = IVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
- write_through = BITSETW(req->inbuf+smb_vwv7,0);
+ tcount = IVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0);
+ write_through = BITSETW(req->vwv+7,0);
/* We have to deal with slightly different formats depending
on whether we are using the core+ or lanman1.0 protocol */
numtowrite = SVAL(smb_buf(req->inbuf),-2);
data = smb_buf(req->inbuf);
} else {
- numtowrite = SVAL(req->inbuf,smb_vwv10);
- data = smb_base(req->inbuf) + SVAL(req->inbuf, smb_vwv11);
+ numtowrite = SVAL(req->vwv+10, 0);
+ data = smb_base(req->inbuf) + SVAL(req->vwv+11, 0);
}
/* Ensure we don't write bytes past the end of this packet. */
ssize_t nwritten = -1;
size_t numtowrite;
SMB_OFF_T startpos;
- char *data;
+ const char *data;
NTSTATUS status = NT_STATUS_OK;
files_struct *fsp;
END_PROFILE(SMBwriteunlock);
return;
}
-
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwriteunlock);
return;
}
- numtowrite = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
- data = smb_buf(req->inbuf) + 3;
-
+ numtowrite = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
+ data = (const char *)req->buf + 3;
+
if (numtowrite
&& is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
(uint64_t)startpos, WRITE_LOCK)) {
} else {
nwritten = write_file(req,fsp,data,startpos,numtowrite);
}
-
+
status = sync_file(conn, fsp, False /* write through */);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
}
reply_outbuf(req, 1, 0);
-
+
SSVAL(req->outbuf,smb_vwv0,nwritten);
-
+
DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
fsp->fnum, (int)numtowrite, (int)nwritten));
-
+
END_PROFILE(SMBwriteunlock);
return;
}
size_t numtowrite;
ssize_t nwritten = -1;
SMB_OFF_T startpos;
- char *data;
+ const char *data;
files_struct *fsp;
NTSTATUS status;
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwrite);
return;
}
- numtowrite = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
- data = smb_buf(req->inbuf) + 3;
-
+ numtowrite = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
+ data = (const char *)req->buf + 3;
+
if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
(uint64_t)startpos, WRITE_LOCK)) {
reply_doserror(req, ERRDOS, ERRlock);
}
reply_outbuf(req, 1, 0);
-
+
SSVAL(req->outbuf,smb_vwv0,nwritten);
if (nwritten < (ssize_t)numtowrite) {
SCVAL(req->outbuf,smb_rcls,ERRHRD);
SSVAL(req->outbuf,smb_err,ERRdiskfull);
}
-
+
DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
END_PROFILE(SMBwrite);
return;
}
- numtowrite = SVAL(req->inbuf,smb_vwv10);
- smb_doff = SVAL(req->inbuf,smb_vwv11);
+ numtowrite = SVAL(req->vwv+10, 0);
+ smb_doff = SVAL(req->vwv+11, 0);
smblen = smb_len(req->inbuf);
if (req->unread_bytes > 0xFFFF ||
(smblen > smb_doff &&
smblen - smb_doff > 0xFFFF)) {
- numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16);
+ numtowrite |= (((size_t)SVAL(req->vwv+9, 0))<<16);
}
if (req->unread_bytes) {
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
- write_through = BITSETW(req->inbuf+smb_vwv7,0);
+ fsp = file_fsp(req, SVAL(req->vwv+2, 0));
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0);
+ write_through = BITSETW(req->vwv+7,0);
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwriteX);
/*
* This is a large offset (64 bit) write.
*/
- startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv12)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(req->vwv+12, 0)) << 32);
#else /* !LARGE_SMB_OFF_T */
* Ensure we haven't been sent a >32 bit offset.
*/
- if(IVAL(req->inbuf,smb_vwv12) != 0) {
+ if(IVAL(req->vwv+12, 0) != 0) {
DEBUG(0,("reply_write_and_X - large offset (%x << 32) "
"used and we don't support 64 bit offsets.\n",
- (unsigned int)IVAL(req->inbuf,smb_vwv12) ));
+ (unsigned int)IVAL(req->vwv+12, 0) ));
reply_doserror(req, ERRDOS, ERRbadaccess);
END_PROFILE(SMBwriteX);
return;
END_PROFILE(SMBwriteX);
return;
}
-
+
nwritten = write_file(req,fsp,data,startpos,numtowrite);
}
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
return;
flush_write_cache(fsp, SEEK_FLUSH);
- mode = SVAL(req->inbuf,smb_vwv1) & 3;
+ mode = SVAL(req->vwv+1, 0) & 3;
/* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
- startpos = (SMB_OFF_T)IVALS(req->inbuf,smb_vwv2);
+ startpos = (SMB_OFF_T)IVALS(req->vwv+2, 0);
switch (mode) {
case 0:
reply_outbuf(req, 2, 0);
SIVAL(req->outbuf,smb_vwv0,res);
-
+
DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
fsp->fnum, (double)startpos, (double)res, mode));
return;
}
- fnum = SVAL(req->inbuf,smb_vwv0);
+ fnum = SVAL(req->vwv+0, 0);
fsp = file_fsp(req, fnum);
if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp)) {
return;
}
-
+
if (!fsp) {
file_sync_all(conn);
} else {
return;
}
}
-
+
reply_outbuf(req, 0, 0);
DEBUG(3,("flush\n"));
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
/*
* We can only use check_fsp if we know it's not a directory.
DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
fsp->fh->fd, fsp->fnum,
conn->num_files_open));
-
+
/*
* Take care of any time sent in the close.
*/
- t = srv_make_unix_date3(req->inbuf+smb_vwv1);
+ t = srv_make_unix_date3(req->vwv+1);
set_close_write_time(fsp, convert_time_t_to_timespec(t));
/*
* was detected on close - normally this is due to
* a disk full error. If not then it was probably an I/O error.
*/
-
+
status = close_file(req, fsp, NORMAL_CLOSE);
}
ssize_t nwritten = -1;
NTSTATUS close_status = NT_STATUS_OK;
SMB_OFF_T startpos;
- char *data;
+ const char *data;
struct timespec mtime;
files_struct *fsp;
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwriteclose);
return;
}
- numtowrite = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
- mtime = convert_time_t_to_timespec(srv_make_unix_date3(
- req->inbuf+smb_vwv4));
- data = smb_buf(req->inbuf) + 1;
-
+ numtowrite = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
+ mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
+ data = (const char *)req->buf + 1;
+
if (numtowrite
&& is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
(uint64_t)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteclose);
return;
}
-
+
nwritten = write_file(req,fsp,data,startpos,numtowrite);
set_close_write_time(fsp, mtime);
DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
fsp->fnum, (int)numtowrite, (int)nwritten,
conn->num_files_open));
-
+
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
reply_doserror(req, ERRHRD, ERRdiskfull);
END_PROFILE(SMBwriteclose);
return;
}
-
+
if(!NT_STATUS_IS_OK(close_status)) {
reply_nterror(req, close_status);
END_PROFILE(SMBwriteclose);
}
reply_outbuf(req, 1, 0);
-
+
SSVAL(req->outbuf,smb_vwv0,nwritten);
END_PROFILE(SMBwriteclose);
return;
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBlock);
release_level_2_oplocks_on_change(fsp);
- count = (uint64_t)IVAL(req->inbuf,smb_vwv1);
- offset = (uint64_t)IVAL(req->inbuf,smb_vwv3);
+ count = (uint64_t)IVAL(req->vwv+1, 0);
+ offset = (uint64_t)IVAL(req->vwv+3, 0);
DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBunlock);
return;
}
-
- count = (uint64_t)IVAL(req->inbuf,smb_vwv1);
- offset = (uint64_t)IVAL(req->inbuf,smb_vwv3);
-
+
+ count = (uint64_t)IVAL(req->vwv+1, 0);
+ offset = (uint64_t)IVAL(req->vwv+3, 0);
+
status = do_unlock(smbd_messaging_context(),
fsp,
req->smbpid,
connection_struct *conn = req->conn;
int smb_reverb;
int seq_num;
- unsigned int data_len = smb_buflen(req->inbuf);
START_PROFILE(SMBecho);
return;
}
- if (data_len > BUFFER_SIZE) {
- DEBUG(0,("reply_echo: data_len too large.\n"));
- reply_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES);
- END_PROFILE(SMBecho);
- return;
- }
-
- smb_reverb = SVAL(req->inbuf,smb_vwv0);
+ smb_reverb = SVAL(req->vwv+0, 0);
- reply_outbuf(req, 1, data_len);
+ reply_outbuf(req, 1, req->buflen);
/* copy any incoming data back out */
- if (data_len > 0) {
- memcpy(smb_buf(req->outbuf),smb_buf(req->inbuf),data_len);
+ if (req->buflen > 0) {
+ memcpy(smb_buf(req->outbuf), req->buf, req->buflen);
}
if (smb_reverb > 100) {
connection_struct *conn = req->conn;
files_struct *fsp;
NTSTATUS status;
-
+
START_PROFILE(SMBsplopen);
if (req->wct < 2) {
return;
}
+ status = file_new(req, conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ END_PROFILE(SMBsplopen);
+ return;
+ }
+
/* Open for exclusive use, write only. */
- status = print_fsp_open(req, conn, NULL, req->vuid, &fsp);
+ status = print_fsp_open(req, conn, NULL, req->vuid, fsp);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
reply_outbuf(req, 1, 0);
SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
-
+
DEBUG(3,("openprint fd=%d fnum=%d\n",
fsp->fh->fd, fsp->fnum));
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBsplclose);
END_PROFILE(SMBsplclose);
return;
}
-
+
DEBUG(3,("printclose fd=%d fnum=%d\n",
fsp->fh->fd,fsp->fnum));
-
+
status = close_file(req, fsp, NORMAL_CLOSE);
if(!NT_STATUS_IS_OK(status)) {
return;
}
- max_count = SVAL(req->inbuf,smb_vwv0);
- start_index = SVAL(req->inbuf,smb_vwv1);
+ max_count = SVAL(req->vwv+0, 0);
+ start_index = SVAL(req->vwv+1, 0);
/* we used to allow the client to get the cnum wrong, but that
is really quite gross and only worked when there was only
SSVAL(req->outbuf,smb_vwv1,0);
SCVAL(smb_buf(req->outbuf),0,1);
SSVAL(smb_buf(req->outbuf),1,0);
-
+
DEBUG(3,("printqueue start_index=%d max_count=%d\n",
start_index, max_count));
num_to_get = 0;
else
num_to_get = MIN(num_to_get,count-first);
-
+
for (i=first;i<first+num_to_get;i++) {
char blob[28];
}
SAFE_FREE(queue);
-
+
DEBUG(3,("%d entries returned in queue\n",count));
}
-
+
END_PROFILE(SMBsplretq);
return;
}
{
connection_struct *conn = req->conn;
int numtowrite;
- char *data;
+ const char *data;
files_struct *fsp;
START_PROFILE(SMBsplwr);
END_PROFILE(SMBsplwr);
return;
}
-
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBsplwr);
return;
}
- numtowrite = SVAL(smb_buf(req->inbuf),1);
+ numtowrite = SVAL(req->buf, 1);
- if (smb_buflen(req->inbuf) < numtowrite + 3) {
+ if (req->buflen < numtowrite + 3) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBsplwr);
return;
}
- data = smb_buf(req->inbuf) + 3;
+ data = (const char *)req->buf + 3;
if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
reply_unixerror(req, ERRHRD, ERRdiskfull);
START_PROFILE(SMBmkdir);
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &directory, (const char *)req->buf + 1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBmkdir);
}
}
- /* We only have veto files/directories. Recursive delete. */
+ /* We only have veto files/directories.
+ * Are we allowed to delete them ? */
+
+ if(!lp_recursive_veto_delete(SNUM(conn))) {
+ TALLOC_FREE(dir_hnd);
+ errno = ENOTEMPTY;
+ goto err;
+ }
+ /* Do a recursive delete. */
RewindDir(dir_hnd,&dirpos);
while ((dname = ReadDirName(dir_hnd,&dirpos))) {
char *fullname = NULL;
break;
}
if(st.st_mode & S_IFDIR) {
- if(lp_recursive_veto_delete(SNUM(conn))) {
- if(!recursive_rmdir(ctx, conn, fullname))
- break;
+ if(!recursive_rmdir(ctx, conn, fullname)) {
+ break;
}
if(SMB_VFS_RMDIR(conn,fullname) != 0) {
break;
START_PROFILE(SMBrmdir);
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &directory, (const char *)req->buf + 1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBrmdir);
char *ext1 = NULL;
char *ext2 = NULL;
char *p,*p2, *pname1, *pname2;
-
+
name2_copy = talloc_strdup(ctx, name2);
if (!name2_copy) {
return False;
if (!pname1 || !pname2) {
return False;
}
-
+
/* Truncate the copy of name2 at the last '/' */
*pname2 = '\0';
return NT_STATUS_OBJECT_NAME_COLLISION;
}
+ if(replace_if_exists && dst_exists) {
+ if (is_ntfs_stream_name(newname)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ }
+
if (dst_exists) {
struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1);
files_struct *dst_fsp = file_find_di_first(fileid);
connection_struct *conn = req->conn;
char *name = NULL;
char *newname = NULL;
- char *p;
+ const char *p;
uint32 attrs;
NTSTATUS status;
bool src_has_wcard = False;
return;
}
- attrs = SVAL(req->inbuf,smb_vwv0);
+ attrs = SVAL(req->vwv+0, 0);
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
- 0, STR_TERMINATE, &status,
- &src_has_wcard);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req_wcard(ctx, req, &name, p, STR_TERMINATE,
+ &status, &src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBmv);
return;
}
p++;
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
- 0, STR_TERMINATE, &status,
- &dest_has_wcard);
+ p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
+ &status, &dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBmv);
char *name = NULL;
char *newname = NULL;
char *directory = NULL;
- char *mask = NULL;
- char *p;
+ const char *mask = NULL;
+ const char mask_star[] = "*";
+ const char *p;
int count=0;
int error = ERRnoaccess;
int err = 0;
return;
}
- tid2 = SVAL(req->inbuf,smb_vwv0);
- ofun = SVAL(req->inbuf,smb_vwv1);
- flags = SVAL(req->inbuf,smb_vwv2);
+ tid2 = SVAL(req->vwv+0, 0);
+ ofun = SVAL(req->vwv+1, 0);
+ flags = SVAL(req->vwv+2, 0);
- p = smb_buf(req->inbuf);
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
- 0, STR_TERMINATE, &status,
- &source_has_wild);
+ p = (const char *)req->buf;
+ p += srvstr_get_path_req_wcard(ctx, req, &name, p, STR_TERMINATE,
+ &status, &source_has_wild);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBcopy);
return;
}
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
- 0, STR_TERMINATE, &status,
- &dest_has_wild);
+ p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
+ &status, &dest_has_wild);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBcopy);
}
p = strrchr_m(name,'/');
- if (!p) {
+ if (p != NULL) {
+ directory = talloc_strndup(ctx, name, PTR_DIFF(p, name));
+ mask = p+1;
+ } else {
directory = talloc_strdup(ctx, "./");
- if (!directory) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBcopy);
- return;
- }
mask = name;
- } else {
- *p = 0;
- directory = talloc_strdup(ctx, name);
- if (!directory) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBcopy);
- return;
- }
- mask = p+1;
+ }
+
+ if (!directory) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBcopy);
+ return;
}
/*
long offset = 0;
if (strequal(mask,"????????.???")) {
- mask[0] = '*';
- mask[1] = '\0';
+ mask = mask_star;
}
status = check_name(conn, directory);
Get a lock pid, dealing with large count requests.
****************************************************************************/
-uint32 get_lock_pid( char *data, int data_offset, bool large_file_format)
+uint32 get_lock_pid(const uint8_t *data, int data_offset,
+ bool large_file_format)
{
if(!large_file_format)
return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
Get a lock count, dealing with large count requests.
****************************************************************************/
-uint64_t get_lock_count( char *data, int data_offset, bool large_file_format)
+uint64_t get_lock_count(const uint8_t *data, int data_offset,
+ bool large_file_format)
{
uint64_t count = 0;
unsigned int i;
uint32 mask = 0;
uint32 highcopy = high;
-
+
/*
* Try and find out how many significant bits there are in high.
*/
-
+
for(i = 0; highcopy; i++)
highcopy >>= 1;
-
+
/*
* We use 31 bits not 32 here as POSIX
* lock offsets may not be negative.
*/
-
+
mask = (~0) << (31 - i);
-
+
if(low & mask)
return 0; /* Fail. */
-
+
high <<= (31 - i);
-
+
return (high|low);
}
#endif /* !defined(HAVE_LONGLONG) */
Get a lock offset, dealing with large offset requests.
****************************************************************************/
-uint64_t get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err)
+uint64_t get_lock_offset(const uint8_t *data, int data_offset,
+ bool large_file_format, bool *err)
{
uint64_t offset = 0;
* negotiated. For boxes without large unsigned ints mangle the
* lock offset by mapping the top 32 bits onto the lower 32.
*/
-
+
if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
uint32 lock_pid;
int32 lock_timeout;
int i;
- char *data;
+ const uint8_t *data;
bool large_file_format;
bool err;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
END_PROFILE(SMBlockingX);
return;
}
-
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
- locktype = CVAL(req->inbuf,smb_vwv3);
- oplocklevel = CVAL(req->inbuf,smb_vwv3+1);
- num_ulocks = SVAL(req->inbuf,smb_vwv6);
- num_locks = SVAL(req->inbuf,smb_vwv7);
- lock_timeout = IVAL(req->inbuf,smb_vwv4);
+
+ fsp = file_fsp(req, SVAL(req->vwv+2, 0));
+ locktype = CVAL(req->vwv+3, 0);
+ oplocklevel = CVAL(req->vwv+3, 1);
+ num_ulocks = SVAL(req->vwv+6, 0);
+ num_locks = SVAL(req->vwv+7, 0);
+ lock_timeout = IVAL(req->vwv+4, 0);
large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBlockingX);
return;
}
-
- data = smb_buf(req->inbuf);
+
+ data = req->buf;
if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
/* we don't support these - and CANCEL_LOCK makes w2k
END_PROFILE(SMBlockingX);
return;
}
-
+
/* Check if this is an oplock break on a file
we have granted an oplock on.
*/
* Make sure we have granted an exclusive or batch oplock on
* this file.
*/
-
+
if (fsp->oplock_type == 0) {
/* The Samba4 nbench simulator doesn't understand
} else {
result = downgrade_oplock(fsp);
}
-
+
if (!result) {
DEBUG(0, ("reply_lockingX: error in removing "
"oplock on file %s\n", fsp->fsp_name));
if (num_locks == 0 && num_ulocks == 0) {
/* Sanity check - ensure a pure oplock break is not a
chained request. */
- if(CVAL(req->inbuf,smb_vwv0) != 0xff)
+ if(CVAL(req->vwv+0, 0) != 0xff)
DEBUG(0,("reply_lockingX: Error : pure oplock "
"break is a chained %d request !\n",
- (unsigned int)CVAL(req->inbuf,
- smb_vwv0) ));
+ (unsigned int)CVAL(req->vwv+0, 0)));
END_PROFILE(SMBlockingX);
return;
}
* We do this check *after* we have checked this is not a oplock break
* response message. JRA.
*/
-
+
release_level_2_oplocks_on_change(fsp);
- if (smb_buflen(req->inbuf) <
+ if (req->buflen <
(num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBlockingX);
return;
}
-
+
/* Data now points at the beginning of the list
of smb_unlkrng structs */
for(i = 0; i < (int)num_ulocks; i++) {
lock_pid = get_lock_pid( data, i, large_file_format);
count = get_lock_count( data, i, large_file_format);
offset = get_lock_offset( data, i, large_file_format, &err);
-
+
/*
* There is no error code marked "stupid client bug".... :-).
*/
DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
"pid %u, file %s\n", (double)offset, (double)count,
(unsigned int)lock_pid, fsp->fsp_name ));
-
+
status = do_unlock(smbd_messaging_context(),
fsp,
lock_pid,
if (!lp_blocking_locks(SNUM(conn))) {
lock_timeout = 0;
}
-
+
/* Now do any requested locks */
data += ((large_file_format ? 20 : 10)*num_ulocks);
-
+
/* Data now points at the beginning of the list
of smb_lkrng structs */
-
+
for(i = 0; i < (int)num_locks; i++) {
enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
READ_LOCK:WRITE_LOCK);
lock_pid = get_lock_pid( data, i, large_file_format);
count = get_lock_count( data, i, large_file_format);
offset = get_lock_offset( data, i, large_file_format, &err);
-
+
/*
* There is no error code marked "stupid client bug".... :-).
*/
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
}
-
+
DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
"%u, file %s timeout = %d\n", (double)offset,
(double)count, (unsigned int)lock_pid,
fsp->fsp_name, (int)lock_timeout ));
-
+
if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
if (lp_blocking_locks(SNUM(conn))) {
return;
}
}
-
+
/* If any of the above locks failed, then we must unlock
all of the previous locks (X/Open spec). */
count = get_lock_count( data, i, large_file_format);
offset = get_lock_offset( data, i, large_file_format,
&err);
-
+
/*
* There is no error code marked "stupid client
* bug".... :-).
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
}
-
+
do_unlock(smbd_messaging_context(),
fsp,
lock_pid,
}
reply_outbuf(req, 2, 0);
-
+
DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
-
+
END_PROFILE(SMBlockingX);
chain_reply(req);
}
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if(!fsp || (fsp->conn != conn)) {
reply_doserror(req, ERRDOS, ERRbadfid);
*/
ts[0] = convert_time_t_to_timespec(
- srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */
+ srv_make_unix_date2(req->vwv+3)); /* atime. */
ts[1] = convert_time_t_to_timespec(
- srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */
-
+ srv_make_unix_date2(req->vwv+5)); /* mtime. */
+
reply_outbuf(req, 0, 0);
/*
END_PROFILE(SMBsetattrE);
return;
}
-
+
DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
fsp->fnum,
(unsigned int)ts[0].tv_sec,
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if(!fsp || (fsp->conn != conn)) {
reply_doserror(req, ERRDOS, ERRbadfid);
END_PROFILE(SMBgetattrE);
return;
}
-
+
mode = dos_mode(conn,fsp->fsp_name,&sbuf);
-
+
/*
* Convert the times into dos times. Set create
* date to be last modify date as UNIX doesn't save
SIVAL(req->outbuf, smb_vwv8, allocation_size);
}
SSVAL(req->outbuf,smb_vwv10, mode);
-
+
DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
-
+
END_PROFILE(SMBgetattrE);
return;
}