summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-11-12 23:07:21 +0100
committerVolker Lendecke <vl@samba.org>2009-11-13 09:30:30 +0100
commitf9ad5cd133b57b66a3b71ede7829ef8c226f2224 (patch)
tree65599c9901d82872b2a60278cf4bdb52e0adec9c /source3/libsmb
parent3732798008f26052c030e8a8fc9c9404fd6f5669 (diff)
downloadsamba-f9ad5cd133b57b66a3b71ede7829ef8c226f2224.tar.gz
samba-f9ad5cd133b57b66a3b71ede7829ef8c226f2224.tar.bz2
samba-f9ad5cd133b57b66a3b71ede7829ef8c226f2224.zip
s3: Convert cli_unix_extensions_version to async
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clidfs.c6
-rw-r--r--source3/libsmb/clifsinfo.c164
2 files changed, 127 insertions, 43 deletions
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 33529595a2..0afb75975e 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -322,8 +322,10 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
if (referring_cli && referring_cli->posix_capabilities) {
uint16 major, minor;
uint32 caplow, caphigh;
- if (cli_unix_extensions_version(cli, &major,
- &minor, &caplow, &caphigh)) {
+ NTSTATUS status;
+ status = cli_unix_extensions_version(cli, &major, &minor,
+ &caplow, &caphigh);
+ if (NT_STATUS_IS_OK(status)) {
cli_set_unix_extensions_capabilities(cli,
major, minor,
caplow, caphigh);
diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c
index 308a6f7215..03ec54ab8c 100644
--- a/source3/libsmb/clifsinfo.c
+++ b/source3/libsmb/clifsinfo.c
@@ -25,59 +25,136 @@
Get UNIX extensions version info.
****************************************************************************/
-bool cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor,
- uint32 *pcaplow, uint32 *pcaphigh)
+struct cli_unix_extensions_version_state {
+ uint16_t setup[1];
+ uint8_t param[2];
+ uint16_t major, minor;
+ uint32_t caplow, caphigh;
+};
+
+static void cli_unix_extensions_version_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_unix_extensions_version_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli)
{
- bool ret = False;
- uint16 setup;
- char param[2];
- char *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
-
- setup = TRANSACT2_QFSINFO;
-
- SSVAL(param,0,SMB_QUERY_CIFS_UNIX_INFO);
+ struct tevent_req *req, *subreq;
+ struct cli_unix_extensions_version_state *state;
- if (!cli_send_trans(cli, SMBtrans2,
- NULL,
- 0, 0,
- &setup, 1, 0,
- param, 2, 0,
- NULL, 0, 560)) {
- goto cleanup;
+ req = tevent_req_create(mem_ctx, &state,
+ struct cli_unix_extensions_version_state);
+ if (req == NULL) {
+ return NULL;
}
+ SSVAL(state->setup, 0, TRANSACT2_QFSINFO);
+ SSVAL(state->param, 0, SMB_QUERY_CIFS_UNIX_INFO);
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &rparam_count,
- &rdata, &rdata_count)) {
- goto cleanup;
+ subreq = cli_trans_send(state, ev, cli, SMBtrans2,
+ NULL, 0, 0, 0,
+ state->setup, 1, 0,
+ state->param, 2, 0,
+ NULL, 0, 560);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
+ tevent_req_set_callback(subreq, cli_unix_extensions_version_done, req);
+ return req;
+}
- if (cli_is_error(cli)) {
- ret = False;
- goto cleanup;
- } else {
- ret = True;
+static void cli_unix_extensions_version_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_unix_extensions_version_state *state = tevent_req_data(
+ req, struct cli_unix_extensions_version_state);
+ uint8_t *data;
+ uint32_t num_data;
+ NTSTATUS status;
+
+ status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
+ &data, &num_data);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ if (num_data < 12) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return;
}
- if (rdata_count < 12) {
- goto cleanup;
+ state->major = SVAL(data, 0);
+ state->minor = SVAL(data, 2);
+ state->caplow = IVAL(data, 4);
+ state->caphigh = IVAL(data, 8);
+ TALLOC_FREE(data);
+ tevent_req_done(req);
+}
+
+NTSTATUS cli_unix_extensions_version_recv(struct tevent_req *req,
+ uint16_t *pmajor, uint16_t *pminor,
+ uint32_t *pcaplow,
+ uint32_t *pcaphigh)
+{
+ struct cli_unix_extensions_version_state *state = tevent_req_data(
+ req, struct cli_unix_extensions_version_state);
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ *pmajor = state->major;
+ *pminor = state->minor;
+ *pcaplow = state->caplow;
+ *pcaphigh = state->caphigh;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor,
+ uint16 *pminor, uint32 *pcaplow,
+ uint32 *pcaphigh)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
}
- *pmajor = SVAL(rdata,0);
- *pminor = SVAL(rdata,2);
- cli->posix_capabilities = *pcaplow = IVAL(rdata,4);
- *pcaphigh = IVAL(rdata,8);
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
- /* todo: but not yet needed
- * return the other stuff
- */
+ req = cli_unix_extensions_version_send(frame, ev, cli);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
-cleanup:
- SAFE_FREE(rparam);
- SAFE_FREE(rdata);
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
- return ret;
+ status = cli_unix_extensions_version_recv(req, pmajor, pminor, pcaplow,
+ pcaphigh);
+ if (NT_STATUS_IS_OK(status)) {
+ cli->posix_capabilities = *pcaplow;
+ }
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
@@ -789,12 +866,17 @@ NTSTATUS cli_force_encryption(struct cli_state *c,
{
uint16 major, minor;
uint32 caplow, caphigh;
+ NTSTATUS status;
if (!SERVER_HAS_UNIX_CIFS(c)) {
return NT_STATUS_NOT_SUPPORTED;
}
- if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
+ status = cli_unix_extensions_version(c, &major, &minor, &caplow,
+ &caphigh);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("cli_force_encryption: cli_unix_extensions_version "
+ "returned %s\n", nt_errstr(status)));
return NT_STATUS_UNKNOWN_REVISION;
}