summaryrefslogtreecommitdiff
path: root/source4/auth/ntlmssp/ntlmssp_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/auth/ntlmssp/ntlmssp_client.c')
-rw-r--r--source4/auth/ntlmssp/ntlmssp_client.c71
1 files changed, 37 insertions, 34 deletions
diff --git a/source4/auth/ntlmssp/ntlmssp_client.c b/source4/auth/ntlmssp/ntlmssp_client.c
index bbde1d954b..dcd52af1f5 100644
--- a/source4/auth/ntlmssp/ntlmssp_client.c
+++ b/source4/auth/ntlmssp/ntlmssp_client.c
@@ -41,10 +41,13 @@
* @return Errors or NT_STATUS_OK.
*/
-NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
+NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
TALLOC_CTX *out_mem_ctx,
DATA_BLOB in, DATA_BLOB *out)
{
+ struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+ struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
+
if (ntlmssp_state->unicode) {
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
} else {
@@ -62,7 +65,7 @@ NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
NTLMSSP_NEGOTIATE,
ntlmssp_state->neg_flags,
ntlmssp_state->get_domain(),
- ntlmssp_state->workstation);
+ cli_credentials_get_workstation(gensec_security->credentials));
ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
@@ -78,10 +81,12 @@ NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
* @return Errors or NT_STATUS_OK.
*/
-NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
+NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
TALLOC_CTX *out_mem_ctx,
const DATA_BLOB in, DATA_BLOB *out)
{
+ struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+ struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
DATA_BLOB server_domain_blob;
DATA_BLOB challenge_blob;
@@ -97,6 +102,8 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
NTSTATUS nt_status;
+ const char *user, *domain, *password;
+
if (!msrpc_parse(ntlmssp_state,
&in, "CdBd",
"NTLMSSP",
@@ -156,7 +163,21 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
return NT_STATUS_INVALID_PARAMETER;
}
- if (!ntlmssp_state->password) {
+ /* Correctly handle username in the original form of user@REALM, which is valid */
+ if (gensec_security->credentials->realm_obtained
+ > gensec_security->credentials->domain_obtained) {
+ user = talloc_asprintf(out_mem_ctx, "%s@%s",
+ cli_credentials_get_username(gensec_security->credentials),
+ cli_credentials_get_realm(gensec_security->credentials));
+ domain = NULL;
+ } else {
+ user = cli_credentials_get_username(gensec_security->credentials);
+ domain = cli_credentials_get_domain(gensec_security->credentials);
+ }
+
+ password = cli_credentials_get_password(gensec_security->credentials);
+
+ if (!password) {
static const uint8_t zeros[16];
/* do nothing - blobs are zero length */
@@ -177,9 +198,9 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
/* TODO: if the remote server is standalone, then we should replace 'domain'
with the server name as supplied above */
- if (!SMBNTLMv2encrypt(ntlmssp_state->user,
- ntlmssp_state->domain,
- ntlmssp_state->password, &challenge_blob,
+ if (!SMBNTLMv2encrypt(user,
+ domain,
+ password, &challenge_blob,
&struct_blob,
&lm_response, &nt_response,
NULL, &session_key)) {
@@ -197,7 +218,7 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
uint8_t session_nonce[16];
uint8_t session_nonce_hash[16];
uint8_t user_session_key[16];
- E_md4hash(ntlmssp_state->password, nt_hash);
+ E_md4hash(password, nt_hash);
lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
generate_random_buffer(lm_response.data, 8);
@@ -216,7 +237,7 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
dump_data(5, session_nonce_hash, 8);
nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
- SMBNTencrypt(ntlmssp_state->password,
+ SMBNTencrypt(password,
session_nonce_hash,
nt_response.data);
@@ -233,9 +254,9 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
if (ntlmssp_state->use_nt_response) {
nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
- SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
+ SMBNTencrypt(password,challenge_blob.data,
nt_response.data);
- E_md4hash(ntlmssp_state->password, nt_hash);
+ E_md4hash(password, nt_hash);
session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
SMBsesskeygen_ntv1(nt_hash, session_key.data);
dump_data_pw("NT session key:\n", session_key.data, session_key.length);
@@ -244,7 +265,7 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
/* lanman auth is insecure, it may be disabled */
if (lp_client_lanman_auth()) {
lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
- if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
+ if (!SMBencrypt(password,challenge_blob.data,
lm_response.data)) {
/* If the LM password was too long (and therefore the LM hash being
of the first 14 chars only), don't send it */
@@ -253,7 +274,7 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
/* LM Key is incompatible with 'long' passwords */
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
} else {
- E_deshash(ntlmssp_state->password, lm_hash);
+ E_deshash(password, lm_hash);
lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
memcpy(lm_session_key.data, lm_hash, 8);
memset(&lm_session_key.data[8], '\0', 8);
@@ -310,9 +331,9 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
NTLMSSP_AUTH,
lm_response.data, lm_response.length,
nt_response.data, nt_response.length,
- ntlmssp_state->domain,
- ntlmssp_state->user,
- ntlmssp_state->workstation,
+ domain,
+ user,
+ cli_credentials_get_workstation(gensec_security->credentials),
encrypted_session_key.data, encrypted_session_key.length,
ntlmssp_state->neg_flags)) {
@@ -351,7 +372,6 @@ static NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state *
(*ntlmssp_state)->role = NTLMSSP_CLIENT;
- (*ntlmssp_state)->workstation = lp_netbios_name();
(*ntlmssp_state)->get_domain = lp_workgroup;
(*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
@@ -392,7 +412,6 @@ static NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state *
NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
{
struct gensec_ntlmssp_state *gensec_ntlmssp_state;
- const char *password = NULL;
NTSTATUS nt_status;
nt_status = gensec_ntlmssp_start(gensec_security);
@@ -422,22 +441,6 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
}
- nt_status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state,
- cli_credentials_get_domain(gensec_security->credentials));
- NT_STATUS_NOT_OK_RETURN(nt_status);
-
- nt_status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state,
- cli_credentials_get_username(gensec_security->credentials));
- NT_STATUS_NOT_OK_RETURN(nt_status);
-
- password = cli_credentials_get_password(gensec_security->credentials);
-
- nt_status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, password);
- NT_STATUS_NOT_OK_RETURN(nt_status);
-
- nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state->ntlmssp_state,
- cli_credentials_get_workstation(gensec_security->credentials));
-
gensec_security->private_data = gensec_ntlmssp_state;
return NT_STATUS_OK;