[PATCH] Make cli_full_connection async
Volker Lendecke
Volker.Lendecke at SerNet.DE
Wed Apr 10 05:11:09 MDT 2013
Hi!
Attached find a patchset to make cli_full_connection async
to a certain extent. Notable exceptions: Name lookup is not
async, so it is only truly async if passed an IP address,
and acquiring Kerberos tickets is not async. It has some
minor cleanup patches embedded.
Please review & push.
Thanks,
Volker
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 9cd691df9e1137f92e0461335edb76b56b47decb Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 5 Apr 2013 14:58:02 +0200
Subject: [PATCH 01/22] libsmbclient: Use tevent_req_poll_ntstatus in
cli_tcon_andx
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index ec5c273..8bfaa2c 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -2530,8 +2530,7 @@ NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
goto fail;
}
- if (!tevent_req_poll(req, ev)) {
- status = map_nt_error_from_unix(errno);
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
goto fail;
}
--
1.7.9.5
From 8336b13297060039abe880aeb7b6d0c8e1165157 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 5 Apr 2013 15:02:51 +0200
Subject: [PATCH 02/22] libsmbclient: Streamline cli_tcon_andx a bit
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 8bfaa2c..fc994dd 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -2508,7 +2508,7 @@ NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
TALLOC_CTX *frame = talloc_stackframe();
struct tevent_context *ev;
struct tevent_req *req;
- NTSTATUS status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
@@ -2520,13 +2520,11 @@ NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
ev = samba_tevent_context_init(frame);
if (ev == NULL) {
- status = NT_STATUS_NO_MEMORY;
goto fail;
}
req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
if (req == NULL) {
- status = NT_STATUS_NO_MEMORY;
goto fail;
}
--
1.7.9.5
From affdad6448d252d3d9463e3bc88fd5565ac89e3b Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 5 Apr 2013 15:08:22 +0200
Subject: [PATCH 03/22] libsmbclient: Use tevent_req_poll_ntstatus in
cli_openx
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/clifile.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 43218bf..a248a46 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -2293,8 +2293,7 @@ NTSTATUS cli_openx(struct cli_state *cli, const char *fname, int flags,
goto fail;
}
- if (!tevent_req_poll(req, ev)) {
- status = map_nt_error_from_unix(errno);
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
goto fail;
}
--
1.7.9.5
From 1f46a857f1157148b92a75d4b8e567e96cb61571 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 5 Apr 2013 15:09:02 +0200
Subject: [PATCH 04/22] libsmbclient: Streamline cli_openx a bit
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/clifile.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index a248a46..4b4e1a0 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -2271,7 +2271,7 @@ NTSTATUS cli_openx(struct cli_state *cli, const char *fname, int flags,
TALLOC_CTX *frame = talloc_stackframe();
struct tevent_context *ev;
struct tevent_req *req;
- NTSTATUS status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
@@ -2283,13 +2283,11 @@ NTSTATUS cli_openx(struct cli_state *cli, const char *fname, int flags,
ev = samba_tevent_context_init(frame);
if (ev == NULL) {
- status = NT_STATUS_NO_MEMORY;
goto fail;
}
req = cli_openx_send(frame, ev, cli, fname, flags, share_mode);
if (req == NULL) {
- status = NT_STATUS_NO_MEMORY;
goto fail;
}
--
1.7.9.5
From b364dbd78dff0bb48e6369992a47393aedf321bc Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 8 Mar 2013 17:40:54 +0100
Subject: [PATCH 05/22] libsmbclient: Fix a leak on talloc_tos()
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index fc994dd..31dd677 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -2015,7 +2015,9 @@ ntlmssp:
account[PTR_DIFF(p,user)] = '\0';
}
- return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
+ status = cli_session_setup_ntlmssp(cli, account, pass, user_domain);
+ TALLOC_FREE(account);
+ return ADS_ERROR_NT(status);
}
/****************************************************************************
--
1.7.9.5
From 57bac714138aa8819bbad15fc2994c98c6fda6d8 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 8 Mar 2013 15:55:51 +0100
Subject: [PATCH 06/22] libsmbclient: Avoid a data copy
spnego_parse_negTokenInit does a asn_load of that blob, which does a data copy
itself. So we don't have to had it a copy as well.
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 31dd677..bfa31d3 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1875,20 +1875,17 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
char *OIDs[ASN1_MAX_OIDS];
int i;
const DATA_BLOB *server_blob;
- DATA_BLOB blob = data_blob_null;
const char *p = NULL;
char *account = NULL;
NTSTATUS status;
server_blob = smbXcli_conn_server_gss_blob(cli->conn);
- if (server_blob) {
- blob = data_blob(server_blob->data, server_blob->length);
- }
- DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob.length));
+ DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
+ (unsigned long)server_blob->length));
/* the server might not even do spnego */
- if (blob.length == 0) {
+ if (server_blob->length == 0) {
DEBUG(3,("server didn't supply a full spnego negprot\n"));
goto ntlmssp;
}
@@ -1901,12 +1898,11 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
* negprot reply. It is WRONG to depend on the principal sent in the
* negprot reply, but right now we do it. If we don't receive one,
* we try to best guess, then fall back to NTLM. */
- if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
+ if (!spnego_parse_negTokenInit(talloc_tos(), *server_blob, OIDs,
+ &principal, NULL) ||
OIDs[0] == NULL) {
- data_blob_free(&blob);
return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- data_blob_free(&blob);
/* make sure the server understands kerberos */
for (i=0;OIDs[i];i++) {
--
1.7.9.5
From 15585b9ef727b603eddde4ce58a61e0f50804581 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 8 Mar 2013 17:21:13 +0100
Subject: [PATCH 07/22] libsmbclient: Factor out
cli_session_setup_get_principal
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 85 +++++++++++++++++++++++++------------------
1 file changed, 49 insertions(+), 36 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index bfa31d3..daaf7e3 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1858,6 +1858,50 @@ fail:
return status;
}
+#ifdef HAVE_KRB5
+
+static char *cli_session_setup_get_principal(
+ TALLOC_CTX *mem_ctx, const char *spnego_principal,
+ const char *remote_name, const char *dest_realm)
+{
+ char *principal = NULL;
+
+ if (!lp_client_use_spnego_principal() ||
+ strequal(principal, ADS_IGNORE_PRINCIPAL)) {
+ spnego_principal = NULL;
+ }
+ if (spnego_principal != NULL) {
+ DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
+ "principal %s\n", spnego_principal));
+ return talloc_strdup(mem_ctx, spnego_principal);
+ }
+ if (is_ipaddress(remote_name) ||
+ strequal(remote_name, STAR_SMBSERVER)) {
+ return NULL;
+ }
+
+ DEBUG(3, ("cli_session_setup_spnego: using target "
+ "hostname not SPNEGO principal\n"));
+
+ if (dest_realm) {
+ char *realm = strupper_talloc(talloc_tos(), dest_realm);
+ if (realm == NULL) {
+ return NULL;
+ }
+ principal = talloc_asprintf(talloc_tos(), "cifs/%s@%s",
+ remote_name, realm);
+ TALLOC_FREE(realm);
+ } else {
+ principal = kerberos_get_principal_from_service_hostname(
+ talloc_tos(), "cifs", remote_name, lp_realm());
+ }
+ DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
+ principal ? principal : "<null>"));
+
+ return principal;
+}
+#endif
+
/****************************************************************************
Do a spnego encrypted session setup.
@@ -1932,6 +1976,7 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) {
ADS_STATUS rc;
const char *remote_name = smbXcli_conn_remote_name(cli->conn);
+ char *tmp;
if (pass && *pass) {
int ret;
@@ -1948,42 +1993,10 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
}
}
- /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
- */
- if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
- TALLOC_FREE(principal);
- }
-
- if (principal == NULL &&
- !is_ipaddress(remote_name) &&
- !strequal(STAR_SMBSERVER,
- remote_name)) {
- DEBUG(3,("cli_session_setup_spnego: using target "
- "hostname not SPNEGO principal\n"));
-
- if (dest_realm) {
- char *realm = strupper_talloc(talloc_tos(), dest_realm);
- if (realm) {
- principal = talloc_asprintf(talloc_tos(),
- "cifs/%s@%s",
- remote_name,
- realm);
- TALLOC_FREE(realm);
- }
- } else {
- principal = kerberos_get_principal_from_service_hostname(talloc_tos(),
- "cifs",
- remote_name,
- lp_realm());
- }
-
- if (!principal) {
- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
- }
- DEBUG(3,("cli_session_setup_spnego: guessed "
- "server principal=%s\n",
- principal ? principal : "<null>"));
- }
+ tmp = cli_session_setup_get_principal(
+ talloc_tos(), principal, remote_name, dest_realm);
+ TALLOC_FREE(principal);
+ principal = tmp;
if (principal) {
rc = cli_session_setup_kerberos(cli, principal);
--
1.7.9.5
From bd1ecec5246b1ad91848fc478d692e736550349a Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 8 Mar 2013 19:41:07 +0100
Subject: [PATCH 08/22] libsmbclient: Slightly simplify
cli_session_setup_spnego
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index daaf7e3..c1b2ec8 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1919,7 +1919,7 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
char *OIDs[ASN1_MAX_OIDS];
int i;
const DATA_BLOB *server_blob;
- const char *p = NULL;
+ char *p;
char *account = NULL;
NTSTATUS status;
@@ -2020,8 +2020,8 @@ ntlmssp:
/* when falling back to ntlmssp while authenticating with a machine
* account strip off the realm - gd */
- if ((p = strchr_m(user, '@')) != NULL) {
- account[PTR_DIFF(p,user)] = '\0';
+ if ((p = strchr_m(account, '@')) != NULL) {
+ *p = '\0';
}
status = cli_session_setup_ntlmssp(cli, account, pass, user_domain);
--
1.7.9.5
From 0ca6675a2e34d30ce31b6615de9d98be3a9df5de Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 9 Mar 2013 09:53:42 +0100
Subject: [PATCH 09/22] libsmbclient: Factor out cli_session_setup_get_account
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index c1b2ec8..77053a7 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1902,6 +1902,22 @@ static char *cli_session_setup_get_principal(
}
#endif
+static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
+ const char *principal)
+{
+ char *account, *p;
+
+ account = talloc_strdup(mem_ctx, principal);
+ if (account == NULL) {
+ return NULL;
+ }
+ p = strchr_m(account, '@');
+ if (p != NULL) {
+ *p = '\0';
+ }
+ return account;
+}
+
/****************************************************************************
Do a spnego encrypted session setup.
@@ -1919,7 +1935,6 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
char *OIDs[ASN1_MAX_OIDS];
int i;
const DATA_BLOB *server_blob;
- char *p;
char *account = NULL;
NTSTATUS status;
@@ -2012,18 +2027,11 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
ntlmssp:
- account = talloc_strdup(talloc_tos(), user);
+ account = cli_session_setup_get_account(talloc_tos(), user);
if (!account) {
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
}
- /* when falling back to ntlmssp while authenticating with a machine
- * account strip off the realm - gd */
-
- if ((p = strchr_m(account, '@')) != NULL) {
- *p = '\0';
- }
-
status = cli_session_setup_ntlmssp(cli, account, pass, user_domain);
TALLOC_FREE(account);
return ADS_ERROR_NT(status);
--
1.7.9.5
From 9f421dcae227df25698553dc0b0aac68f2486210 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 9 Mar 2013 13:07:57 +0100
Subject: [PATCH 10/22] libsmbclient: Add async cli_session_setup_ntlmssp
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 170 +++++++++++++++++++++++++++++++++++++------
1 file changed, 146 insertions(+), 24 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 77053a7..905720e 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1925,19 +1925,53 @@ static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
dest_realm: The realm we're connecting to, if NULL we use our default realm.
****************************************************************************/
-static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
- const char *user,
- const char *pass,
- const char *user_domain,
- const char * dest_realm)
+struct cli_session_setup_spnego_state {
+ struct tevent_context *ev;
+ struct cli_state *cli;
+ const char *user;
+ const char *account;
+ const char *pass;
+ const char *user_domain;
+ const char *dest_realm;
+ ADS_STATUS result;
+};
+
+#ifdef HAVE_KRB5
+static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq);
+#endif
+
+static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq);
+
+static struct tevent_req *cli_session_setup_spnego_send(
+ TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
+ const char *user, const char *pass, const char *user_domain,
+ const char *dest_realm)
{
+ struct tevent_req *req, *subreq;
+ struct cli_session_setup_spnego_state *state;
char *principal = NULL;
char *OIDs[ASN1_MAX_OIDS];
int i;
const DATA_BLOB *server_blob;
- char *account = NULL;
NTSTATUS status;
+ req = tevent_req_create(mem_ctx, &state,
+ struct cli_session_setup_spnego_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->ev = ev;
+ state->cli = cli;
+ state->user = user;
+ state->pass = pass;
+ state->user_domain = user_domain;
+ state->dest_realm = dest_realm;
+
+ state->account = cli_session_setup_get_account(state, user);
+ if (tevent_req_nomem(state->account, req)) {
+ return tevent_req_post(req, ev);
+ }
+
server_blob = smbXcli_conn_server_gss_blob(cli->conn);
DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
@@ -1957,10 +1991,12 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
* negprot reply. It is WRONG to depend on the principal sent in the
* negprot reply, but right now we do it. If we don't receive one,
* we try to best guess, then fall back to NTLM. */
- if (!spnego_parse_negTokenInit(talloc_tos(), *server_blob, OIDs,
+ if (!spnego_parse_negTokenInit(state, *server_blob, OIDs,
&principal, NULL) ||
OIDs[0] == NULL) {
- return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ state->result = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
}
/* make sure the server understands kerberos */
@@ -1980,8 +2016,9 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
status = cli_set_username(cli, user);
if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(principal);
- return ADS_ERROR_NT(status);
+ state->result = ADS_ERROR_NT(status);
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
}
#ifdef HAVE_KRB5
@@ -1989,7 +2026,6 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
* and do not store results */
if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) {
- ADS_STATUS rc;
const char *remote_name = smbXcli_conn_remote_name(cli->conn);
char *tmp;
@@ -2004,7 +2040,9 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
if (cli->fallback_after_kerberos)
goto ntlmssp;
- return ADS_ERROR_KRB5(ret);
+ state->result = ADS_ERROR_KRB5(ret);
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
}
}
@@ -2014,27 +2052,111 @@ static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
principal = tmp;
if (principal) {
- rc = cli_session_setup_kerberos(cli, principal);
- if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
- TALLOC_FREE(principal);
- return rc;
+ subreq = cli_session_setup_kerberos_send(
+ state, ev, cli, principal);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
+ tevent_req_set_callback(
+ subreq, cli_session_setup_spnego_done_krb,
+ req);
+ return req;
}
}
#endif
- TALLOC_FREE(principal);
-
ntlmssp:
+ subreq = cli_session_setup_ntlmssp_send(
+ state, ev, cli, state->account, pass, user_domain);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(
+ subreq, cli_session_setup_spnego_done_ntlmssp, req);
+ return req;
+}
+
+#ifdef HAVE_KRB5
+static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_session_setup_spnego_state *state = tevent_req_data(
+ req, struct cli_session_setup_spnego_state);
- account = cli_session_setup_get_account(talloc_tos(), user);
- if (!account) {
- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ state->result = cli_session_setup_kerberos_recv(subreq);
+ TALLOC_FREE(subreq);
+
+ if (ADS_ERR_OK(state->result) ||
+ !state->cli->fallback_after_kerberos) {
+ tevent_req_done(req);
+ return;
+ }
+
+ subreq = cli_session_setup_ntlmssp_send(
+ state, state->ev, state->cli, state->account, state->pass,
+ state->user_domain);
+ if (tevent_req_nomem(subreq, req)) {
+ return;
}
+ tevent_req_set_callback(subreq, cli_session_setup_spnego_done_ntlmssp,
+ req);
+}
+#endif
+
+static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_session_setup_spnego_state *state = tevent_req_data(
+ req, struct cli_session_setup_spnego_state);
+ NTSTATUS status;
+
+ status = cli_session_setup_ntlmssp_recv(subreq);
+ TALLOC_FREE(subreq);
+ state->result = ADS_ERROR_NT(status);
+ tevent_req_done(req);
+}
+
+static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
+{
+ struct cli_session_setup_spnego_state *state = tevent_req_data(
+ req, struct cli_session_setup_spnego_state);
+
+ return state->result;
+}
+
+static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
+ const char *user,
+ const char *pass,
+ const char *user_domain,
+ const char * dest_realm)
+{
+ struct tevent_context *ev;
+ struct tevent_req *req;
+ ADS_STATUS result = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ NTSTATUS status;
- status = cli_session_setup_ntlmssp(cli, account, pass, user_domain);
- TALLOC_FREE(account);
- return ADS_ERROR_NT(status);
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ ev = samba_tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ goto fail;
+ }
+ req = cli_session_setup_spnego_send(ev, ev, cli, user, pass,
+ user_domain, dest_realm);
+ if (req == NULL) {
+ goto fail;
+ }
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+ result = ADS_ERROR_NT(status);
+ goto fail;
+ }
+ result = cli_session_setup_spnego_recv(req);
+fail:
+ TALLOC_FREE(ev);
+ return result;
}
/****************************************************************************
--
1.7.9.5
From dc665e396b8c05eec2c31310875de6c8b7867b47 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 2 Apr 2013 12:50:43 +0200
Subject: [PATCH 11/22] libsmbclient: Remove unused
cli_session_setup_ntlmssp()
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 29 -----------------------------
1 file changed, 29 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 905720e..6befe5b 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1829,35 +1829,6 @@ static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
return NT_STATUS_OK;
}
-static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
- const char *user,
- const char *pass,
- const char *domain)
-{
- struct tevent_context *ev;
- struct tevent_req *req;
- NTSTATUS status = NT_STATUS_NO_MEMORY;
-
- if (smbXcli_conn_has_async_calls(cli->conn)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
- ev = samba_tevent_context_init(talloc_tos());
- if (ev == NULL) {
- goto fail;
- }
- req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
- if (req == NULL) {
- goto fail;
- }
- if (!tevent_req_poll_ntstatus(req, ev, &status)) {
- goto fail;
- }
- status = cli_session_setup_ntlmssp_recv(req);
-fail:
- TALLOC_FREE(ev);
- return status;
-}
-
#ifdef HAVE_KRB5
static char *cli_session_setup_get_principal(
--
1.7.9.5
From c30a7702ed54548f52409a0f82b3ea8a30f254c5 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 2 Apr 2013 13:37:30 +0200
Subject: [PATCH 12/22] libsmbclient: Add async cli_session_setup
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 257 ++++++++++++++++++++++++++++++++++++-------
source3/libsmb/proto.h | 8 ++
2 files changed, 223 insertions(+), 42 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 6befe5b..ea47662 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -2130,29 +2130,50 @@ fail:
return result;
}
+struct cli_session_setup_state {
+ uint8_t dummy;
+};
+
+static void cli_session_setup_done_lanman2(struct tevent_req *subreq);
+static void cli_session_setup_done_spnego(struct tevent_req *subreq);
+static void cli_session_setup_done_guest(struct tevent_req *subreq);
+static void cli_session_setup_done_plain(struct tevent_req *subreq);
+static void cli_session_setup_done_nt1(struct tevent_req *subreq);
+
/****************************************************************************
Send a session setup. The username and workgroup is in UNIX character
format and must be converted to DOS codepage format before sending. If the
password is in plaintext, the same should be done.
****************************************************************************/
-NTSTATUS cli_session_setup(struct cli_state *cli,
- const char *user,
- const char *pass, int passlen,
- const char *ntpass, int ntpasslen,
- const char *workgroup)
+struct tevent_req *cli_session_setup_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli,
+ const char *user,
+ const char *pass, int passlen,
+ const char *ntpass, int ntpasslen,
+ const char *workgroup)
{
+ struct tevent_req *req, *subreq;
+ struct cli_session_setup_state *state;
char *p;
char *user2;
uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
+ req = tevent_req_create(mem_ctx, &state,
+ struct cli_session_setup_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
if (user) {
- user2 = talloc_strdup(talloc_tos(), user);
+ user2 = talloc_strdup(state, user);
} else {
- user2 = talloc_strdup(talloc_tos(), "");
+ user2 = talloc_strdup(state, "");
}
if (user2 == NULL) {
- return NT_STATUS_NO_MEMORY;
+ tevent_req_oom(req);
+ return tevent_req_post(req, ev);
}
if (!workgroup) {
@@ -2165,13 +2186,15 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
*p = 0;
user = p+1;
if (!strupper_m(user2)) {
- return NT_STATUS_INVALID_PARAMETER;
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
workgroup = user2;
}
if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
- return NT_STATUS_OK;
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
}
/* now work out what sort of session setup we are going to
@@ -2184,44 +2207,68 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
" or 'client ntlmv2 auth = yes'\n"));
- return NT_STATUS_ACCESS_DENIED;
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return tevent_req_post(req, ev);
}
if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
!lp_client_plaintext_auth() && (*pass)) {
DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
" or 'client ntlmv2 auth = yes'\n"));
- return NT_STATUS_ACCESS_DENIED;
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return tevent_req_post(req, ev);
}
- return cli_session_setup_lanman2(cli, user, pass, passlen,
- workgroup);
+ subreq = cli_session_setup_lanman2_send(
+ state, ev, cli, user, p