From 652dc40f0d535b333f8dd6a15fe699438176c53b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 23 Apr 2009 16:17:18 +0200 Subject: Add missing prototypes --- source3/include/proto.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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); -- cgit From 176302dc05cd67d013f3d153b9816329a175167e Mon Sep 17 00:00:00 2001 From: Sam Liddicott Date: Thu, 23 Apr 2009 13:47:59 +0100 Subject: Add async support for reply_tcon* and ntvfs_connect smbsrv_tcon_backend no longer creates the ntvfs_request wrapper, so smbsrv_reply_tcon* can now do this and then invoke ntvfs_connect in the typical manner using SMBSRV_SETUP_NTVFS_REQUEST and SMBSRV_CALL_NTVFS_BACKEND Previously smbsrv_tcon_backend has been responsible for instantiating the ntvfs_module_context to service a tree-connect request, and then create an ntvfs_request wrapper around the smbsrv_request and pass this to ntvfs_connect for the newly created ntvfs. These actions could not be invoked asynchronously. This meant that any client requests made while instantiating the ntvfs module, including any composite's used during authentication (or related client connections for the case of proxy modules) would block other ntvfs modules and requests in the current process as they executed a nested event loop to await completion. Signed-off-by: Sam Liddicott Signed-off-by: Stefan Metzmacher --- source4/smb_server/smb/reply.c | 154 ++++++++++++++++++++++++++------------- source4/smb_server/smb/service.c | 21 +----- 2 files changed, 105 insertions(+), 70 deletions(-) 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 @@ -43,115 +43,169 @@ 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; -- cgit