summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h20
-rw-r--r--source4/smb_server/smb/reply.c154
-rw-r--r--source4/smb_server/smb/service.c21
3 files changed, 125 insertions, 70 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 518c3a7e93..de2847b468 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2337,7 +2337,17 @@ bool cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam
bool cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst);
bool cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs);
bool cli_unlink(struct cli_state *cli, const char *fname);
+struct tevent_req *cli_mkdir_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *dname);
+NTSTATUS cli_mkdir_recv(struct tevent_req *req);
NTSTATUS cli_mkdir(struct cli_state *cli, const char *dname);
+struct tevent_req *cli_rmdir_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *dname);
+NTSTATUS cli_rmdir_recv(struct tevent_req *req);
NTSTATUS cli_rmdir(struct cli_state *cli, const char *dname);
int cli_nt_delete_on_close(struct cli_state *cli, int fnum, bool flag);
int cli_nt_create_full(struct cli_state *cli, const char *fname,
@@ -2416,7 +2426,17 @@ bool cli_setattrE(struct cli_state *cli, int fd,
time_t access_time,
time_t write_time);
bool cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t);
+struct tevent_req *cli_chkpath_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname);
+NTSTATUS cli_chkpath_recv(struct tevent_req *req);
NTSTATUS cli_chkpath(struct cli_state *cli, const char *path);
+struct tevent_req *cli_dskattr_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli);
+NTSTATUS cli_dskattr_recv(struct tevent_req *req, int *bsize, int *total,
+ int *avail);
NTSTATUS cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path);
NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *blob);
diff --git a/source4/smb_server/smb/reply.c b/source4/smb_server/smb/reply.c
index 9c4ee993d2..1b309a0c1f 100644
--- a/source4/smb_server/smb/reply.c
+++ b/source4/smb_server/smb/reply.c
@@ -44,114 +44,168 @@ static void reply_simple_send(struct ntvfs_request *ntvfs)
/****************************************************************************
+ Reply to a tcon (async reply)
+****************************************************************************/
+static void reply_tcon_send(struct ntvfs_request *ntvfs)
+{
+ struct smbsrv_request *req;
+ union smb_tcon *con;
+
+ SMBSRV_CHECK_ASYNC_STATUS(con, union smb_tcon);
+
+ if (con->generic.level == RAW_TCON_TCON) {
+ con->tcon.out.max_xmit = req->smb_conn->negotiate.max_recv;
+ con->tcon.out.tid = req->tcon->tid;
+ } else {
+ /* TODO: take a look at tconx.in.flags! */
+ con->tconx.out.tid = req->tcon->tid;
+ con->tconx.out.dev_type = talloc_strdup(req, req->tcon->ntvfs->dev_type);
+ con->tconx.out.fs_type = talloc_strdup(req, req->tcon->ntvfs->fs_type);
+ }
+
+ /* construct reply */
+ smbsrv_setup_reply(req, 2, 0);
+
+ SSVAL(req->out.vwv, VWV(0), con->tcon.out.max_xmit);
+ SSVAL(req->out.vwv, VWV(1), con->tcon.out.tid);
+ SSVAL(req->out.hdr, HDR_TID, req->tcon->tid);
+
+ smbsrv_send_reply(req);
+}
+
+/****************************************************************************
Reply to a tcon.
****************************************************************************/
void smbsrv_reply_tcon(struct smbsrv_request *req)
{
- union smb_tcon con;
+ union smb_tcon *con;
NTSTATUS status;
uint8_t *p;
/* parse request */
SMBSRV_CHECK_WCT(req, 0);
- con.tcon.level = RAW_TCON_TCON;
+ SMBSRV_TALLOC_IO_PTR(con, union smb_tcon);
+
+ con->tcon.level = RAW_TCON_TCON;
p = req->in.data;
- p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.service, p, STR_TERMINATE);
- p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.password, p, STR_TERMINATE);
- p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.dev, p, STR_TERMINATE);
+ p += req_pull_ascii4(&req->in.bufinfo, &con->tcon.in.service, p, STR_TERMINATE);
+ p += req_pull_ascii4(&req->in.bufinfo, &con->tcon.in.password, p, STR_TERMINATE);
+ p += req_pull_ascii4(&req->in.bufinfo, &con->tcon.in.dev, p, STR_TERMINATE);
- if (!con.tcon.in.service || !con.tcon.in.password || !con.tcon.in.dev) {
+ if (!con->tcon.in.service || !con->tcon.in.password || !con->tcon.in.dev) {
smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
return;
}
- /* call backend */
- status = smbsrv_tcon_backend(req, &con);
-
+ /* Instantiate backend */
+ status = smbsrv_tcon_backend(req, con);
if (!NT_STATUS_IS_OK(status)) {
smbsrv_send_error(req, status);
return;
}
- /* construct reply */
- smbsrv_setup_reply(req, 2, 0);
+ SMBSRV_SETUP_NTVFS_REQUEST(reply_tcon_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
- SSVAL(req->out.vwv, VWV(0), con.tcon.out.max_xmit);
- SSVAL(req->out.vwv, VWV(1), con.tcon.out.tid);
- SSVAL(req->out.hdr, HDR_TID, req->tcon->tid);
-
- smbsrv_send_reply(req);
+ /* Invoke NTVFS connection hook */
+ SMBSRV_CALL_NTVFS_BACKEND(ntvfs_connect(req->ntvfs, req->tcon->share_name));
}
/****************************************************************************
+ Reply to a tcon and X (async reply)
+****************************************************************************/
+static void reply_tcon_and_X_send(struct ntvfs_request *ntvfs)
+{
+ struct smbsrv_request *req;
+ union smb_tcon *con;
+
+ SMBSRV_CHECK_ASYNC_STATUS(con, union smb_tcon);
+
+ if (con->generic.level == RAW_TCON_TCON) {
+ con->tcon.out.max_xmit = req->smb_conn->negotiate.max_recv;
+ con->tcon.out.tid = req->tcon->tid;
+ } else {
+ /* TODO: take a look at tconx.in.flags! */
+ con->tconx.out.tid = req->tcon->tid;
+ con->tconx.out.dev_type = talloc_strdup(req, req->tcon->ntvfs->dev_type);
+ con->tconx.out.fs_type = talloc_strdup(req, req->tcon->ntvfs->fs_type);
+ }
+
+ /* construct reply - two variants */
+ if (req->smb_conn->negotiate.protocol < PROTOCOL_NT1) {
+ smbsrv_setup_reply(req, 2, 0);
+
+ SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
+ SSVAL(req->out.vwv, VWV(1), 0);
+
+ req_push_str(req, NULL, con->tconx.out.dev_type, -1, STR_TERMINATE|STR_ASCII);
+ } else {
+ smbsrv_setup_reply(req, 3, 0);
+
+ SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
+ SSVAL(req->out.vwv, VWV(1), 0);
+ SSVAL(req->out.vwv, VWV(2), con->tconx.out.options);
+
+ req_push_str(req, NULL, con->tconx.out.dev_type, -1, STR_TERMINATE|STR_ASCII);
+ req_push_str(req, NULL, con->tconx.out.fs_type, -1, STR_TERMINATE);
+ }
+
+ /* set the incoming and outgoing tid to the just created one */
+ SSVAL(req->in.hdr, HDR_TID, con->tconx.out.tid);
+ SSVAL(req->out.hdr,HDR_TID, con->tconx.out.tid);
+
+ smbsrv_chain_reply(req);
+}
+
+/****************************************************************************
Reply to a tcon and X.
****************************************************************************/
void smbsrv_reply_tcon_and_X(struct smbsrv_request *req)
{
NTSTATUS status;
- union smb_tcon con;
+ union smb_tcon *con;
uint8_t *p;
uint16_t passlen;
- con.tconx.level = RAW_TCON_TCONX;
+ SMBSRV_TALLOC_IO_PTR(con, union smb_tcon);
+
+ con->tconx.level = RAW_TCON_TCONX;
/* parse request */
SMBSRV_CHECK_WCT(req, 4);
- con.tconx.in.flags = SVAL(req->in.vwv, VWV(2));
- passlen = SVAL(req->in.vwv, VWV(3));
+ con->tconx.in.flags = SVAL(req->in.vwv, VWV(2));
+ passlen = SVAL(req->in.vwv, VWV(3));
p = req->in.data;
- if (!req_pull_blob(&req->in.bufinfo, p, passlen, &con.tconx.in.password)) {
+ if (!req_pull_blob(&req->in.bufinfo, p, passlen, &con->tconx.in.password)) {
smbsrv_send_error(req, NT_STATUS_ILL_FORMED_PASSWORD);
return;
}
p += passlen;
- p += req_pull_string(&req->in.bufinfo, &con.tconx.in.path, p, -1, STR_TERMINATE);
- p += req_pull_string(&req->in.bufinfo, &con.tconx.in.device, p, -1, STR_ASCII);
+ p += req_pull_string(&req->in.bufinfo, &con->tconx.in.path, p, -1, STR_TERMINATE);
+ p += req_pull_string(&req->in.bufinfo, &con->tconx.in.device, p, -1, STR_ASCII);
- if (!con.tconx.in.path || !con.tconx.in.device) {
+ if (!con->tconx.in.path || !con->tconx.in.device) {
smbsrv_send_error(req, NT_STATUS_BAD_DEVICE_TYPE);
return;
}
- /* call backend */
- status = smbsrv_tcon_backend(req, &con);
-
+ /* Instantiate backend */
+ status = smbsrv_tcon_backend(req, con);
if (!NT_STATUS_IS_OK(status)) {
smbsrv_send_error(req, status);
return;
}
- /* construct reply - two variants */
- if (req->smb_conn->negotiate.protocol < PROTOCOL_NT1) {
- smbsrv_setup_reply(req, 2, 0);
-
- SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
- SSVAL(req->out.vwv, VWV(1), 0);
-
- req_push_str(req, NULL, con.tconx.out.dev_type, -1, STR_TERMINATE|STR_ASCII);
- } else {
- smbsrv_setup_reply(req, 3, 0);
-
- SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
- SSVAL(req->out.vwv, VWV(1), 0);
- SSVAL(req->out.vwv, VWV(2), con.tconx.out.options);
-
- req_push_str(req, NULL, con.tconx.out.dev_type, -1, STR_TERMINATE|STR_ASCII);
- req_push_str(req, NULL, con.tconx.out.fs_type, -1, STR_TERMINATE);
- }
-
- /* set the incoming and outgoing tid to the just created one */
- SSVAL(req->in.hdr, HDR_TID, con.tconx.out.tid);
- SSVAL(req->out.hdr,HDR_TID, con.tconx.out.tid);
+ SMBSRV_SETUP_NTVFS_REQUEST(reply_tcon_and_X_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
- smbsrv_chain_reply(req);
+ /* Invoke NTVFS connection hook */
+ SMBSRV_CALL_NTVFS_BACKEND(ntvfs_connect(req->ntvfs, req->tcon->share_name));
}
diff --git a/source4/smb_server/smb/service.c b/source4/smb_server/smb/service.c
index 52471c09c9..85d169fc13 100644
--- a/source4/smb_server/smb/service.c
+++ b/source4/smb_server/smb/service.c
@@ -27,6 +27,7 @@
/****************************************************************************
Make a connection, given the snum to connect to, and the vuser of the
connecting user if appropriate.
+ Does note invoke the NTVFS connection hook
****************************************************************************/
static NTSTATUS make_connection_scfg(struct smbsrv_request *req,
struct share_config *scfg,
@@ -88,23 +89,6 @@ static NTSTATUS make_connection_scfg(struct smbsrv_request *req,
goto failed;
}
- req->ntvfs = ntvfs_request_create(req->tcon->ntvfs, req,
- req->session->session_info,
- SVAL(req->in.hdr,HDR_PID),
- req->request_time,
- req, NULL, 0);
- if (!req->ntvfs) {
- status = NT_STATUS_NO_MEMORY;
- goto failed;
- }
-
- /* Invoke NTVFS connection hook */
- status = ntvfs_connect(req->ntvfs, scfg->name);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("make_connection: NTVFS make connection failed!\n"));
- goto failed;
- }
-
return NT_STATUS_OK;
failed:
@@ -204,9 +188,6 @@ NTSTATUS smbsrv_tcon_backend(struct smbsrv_request *req, union smb_tcon *con)
return status;
}
- con->tconx.out.tid = req->tcon->tid;
- con->tconx.out.dev_type = talloc_strdup(req, req->tcon->ntvfs->dev_type);
- con->tconx.out.fs_type = talloc_strdup(req, req->tcon->ntvfs->fs_type);
con->tconx.out.options = SMB_SUPPORT_SEARCH_BITS | (share_int_option(req->tcon->ntvfs->config, SHARE_CSC_POLICY, SHARE_CSC_POLICY_DEFAULT) << 2);
if (share_bool_option(req->tcon->ntvfs->config, SHARE_MSDFS_ROOT, SHARE_MSDFS_ROOT_DEFAULT) && lp_host_msdfs(req->smb_conn->lp_ctx)) {
con->tconx.out.options |= SMB_SHARE_IN_DFS;