Patchset: async cli_session_setup
Volker Lendecke
Volker.Lendecke at SerNet.DE
Thu Apr 4 03:35:06 MDT 2013
Hi!
Attached find a patchset that makes cli_session_setup in
source3/libsmb more async. It does not handle the kinit
process, but all non-kerberos variants should be properly
async now.
Please review & potentially 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 23210496618e8ee08154249dec7bda337beed24d 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 1/8] libsmbclient: Fix a leak on talloc_tos()
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index ec5c273..d0e67db 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.0.4
From f2eefe52a429c16c36c071eed033922a2381e248 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 2/8] 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 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index d0e67db..a67d25f 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.0.4
From b71a0177cba67034da86a1c497c2c2a649f31706 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 3/8] libsmbclient: Factor out cli_session_setup_get_principal
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 85 +++++++++++++++++++++++++------------------
1 files changed, 49 insertions(+), 36 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index a67d25f..742921d 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.0.4
From 653dcca03abce989b09a3f0c0d8a27eb77f6a106 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 4/8] libsmbclient: Slightly simplify cli_session_setup_spnego
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 742921d..253cc70 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.0.4
From 454ad4de265efff1a61c5e1eee95f5bcb30e5d03 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 5/8] libsmbclient: Factor out cli_session_setup_get_account
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 26 +++++++++++++++++---------
1 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 253cc70..212cc3e 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.0.4
From a4f23eb70e83e8b1a81cef344287f290385fc8d3 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 6/8] libsmbclient: Add async cli_session_setup_ntlmssp
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/cliconnect.c | 169 +++++++++++++++++++++++++++++++++++++------
1 files changed, 146 insertions(+), 23 deletions(-)
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 212cc3e..09694be 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;