summaryrefslogtreecommitdiff
path: root/auth/ntlmssp/ntlmssp_client.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-11-27 15:35:40 +0100
committerStefan Metzmacher <metze@samba.org>2016-03-10 06:52:28 +0100
commitb133f66e0da5ed05bbe81098e52c744bac4b48ac (patch)
tree70753f0e40eacb9ba13f1ee5cb47cf465d8b7c74 /auth/ntlmssp/ntlmssp_client.c
parent0a93cad337578a7ba61f12726c9a15ecf869db7b (diff)
downloadsamba-b133f66e0da5ed05bbe81098e52c744bac4b48ac.tar.gz
auth/ntlmssp: implement GENSEC_FEATURE_NTLM_CCACHE
This can used in order to use the WINBINDD_CCACHE_NTLMAUTH code of winbindd to do NTLMSSP authentication with a cached password. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Günther Deschner <gd@samba.org>
Diffstat (limited to 'auth/ntlmssp/ntlmssp_client.c')
-rw-r--r--auth/ntlmssp/ntlmssp_client.c94
1 files changed, 91 insertions, 3 deletions
diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c
index df29aa22552..0823ebeb704 100644
--- a/auth/ntlmssp/ntlmssp_client.c
+++ b/auth/ntlmssp/ntlmssp_client.c
@@ -34,6 +34,7 @@ struct auth_session_info;
#include "auth/ntlmssp/ntlmssp_private.h"
#include "../librpc/gen_ndr/ndr_ntlmssp.h"
#include "../auth/ntlmssp/ntlmssp_ndr.h"
+#include "../nsswitch/libwbclient/wbclient.h"
/*********************************************************************
Client side NTLMSSP
@@ -240,6 +241,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
NTSTATUS nt_status;
int flags = 0;
const char *user = NULL, *domain = NULL, *workstation = NULL;
+ bool is_anonymous = false;
TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
if (!mem_ctx) {
@@ -345,6 +347,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
return NT_STATUS_INVALID_PARAMETER;
}
+ is_anonymous = cli_credentials_is_anonymous(gensec_security->credentials);
cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx,
&user, &domain);
@@ -365,6 +368,87 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
return NT_STATUS_INVALID_PARAMETER;
}
+ if (is_anonymous) {
+ /*
+ * don't use the ccache for anonymous auth
+ */
+ ntlmssp_state->use_ccache = false;
+ }
+ if (ntlmssp_state->use_ccache) {
+ struct samr_Password *nt_hash = NULL;
+
+ /*
+ * If we have a password given we don't
+ * use the ccache
+ */
+ nt_hash = cli_credentials_get_nt_hash(gensec_security->credentials,
+ mem_ctx);
+ if (nt_hash != NULL) {
+ ZERO_STRUCTP(nt_hash);
+ TALLOC_FREE(nt_hash);
+ ntlmssp_state->use_ccache = false;
+ }
+ }
+
+ if (ntlmssp_state->use_ccache) {
+ struct wbcCredentialCacheParams params;
+ struct wbcCredentialCacheInfo *info = NULL;
+ struct wbcAuthErrorInfo *error = NULL;
+ struct wbcNamedBlob auth_blobs[1];
+ const struct wbcBlob *wbc_auth_blob = NULL;
+ const struct wbcBlob *wbc_session_key = NULL;
+ wbcErr wbc_status;
+ int i;
+
+ params.account_name = user;
+ params.domain_name = domain;
+ params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP;
+
+ auth_blobs[0].name = "challenge_blob";
+ auth_blobs[0].flags = 0;
+ auth_blobs[0].blob.data = in.data;
+ auth_blobs[0].blob.length = in.length;
+ params.num_blobs = ARRAY_SIZE(auth_blobs);
+ params.blobs = auth_blobs;
+
+ wbc_status = wbcCredentialCache(&params, &info, &error);
+ wbcFreeMemory(error);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return NT_STATUS_WRONG_CREDENTIAL_HANDLE;
+ }
+
+ for (i=0; i<info->num_blobs; i++) {
+ if (strequal(info->blobs[i].name, "auth_blob")) {
+ wbc_auth_blob = &info->blobs[i].blob;
+ }
+ if (strequal(info->blobs[i].name, "session_key")) {
+ wbc_session_key = &info->blobs[i].blob;
+ }
+ }
+ if ((wbc_auth_blob == NULL) || (wbc_session_key == NULL)) {
+ wbcFreeMemory(info);
+ return NT_STATUS_WRONG_CREDENTIAL_HANDLE;
+ }
+
+ session_key = data_blob_talloc(mem_ctx,
+ wbc_session_key->data,
+ wbc_session_key->length);
+ if (session_key.length != wbc_session_key->length) {
+ wbcFreeMemory(info);
+ return NT_STATUS_NO_MEMORY;
+ }
+ *out = data_blob_talloc(mem_ctx,
+ wbc_auth_blob->data,
+ wbc_auth_blob->length);
+ if (out->length != wbc_auth_blob->length) {
+ wbcFreeMemory(info);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ wbcFreeMemory(info);
+ goto done;
+ }
+
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
flags |= CLI_CRED_NTLM2;
}
@@ -434,9 +518,6 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key));
}
- DEBUG(3, ("NTLMSSP: Set final flags:\n"));
- debug_ntlmssp_flags(ntlmssp_state->neg_flags);
-
/* this generates the actual auth packet */
nt_status = msrpc_gen(mem_ctx,
out, auth_gen_string,
@@ -454,9 +535,13 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
return nt_status;
}
+done:
ntlmssp_state->session_key = session_key;
talloc_steal(ntlmssp_state, session_key.data);
+ DEBUG(3, ("NTLMSSP: Set final flags:\n"));
+ debug_ntlmssp_flags(ntlmssp_state->neg_flags);
+
talloc_steal(out_mem_ctx, out->data);
ntlmssp_state->expected_state = NTLMSSP_DONE;
@@ -565,6 +650,9 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
}
+ if (gensec_security->want_features & GENSEC_FEATURE_NTLM_CCACHE) {
+ ntlmssp_state->use_ccache = true;
+ }
return NT_STATUS_OK;
}