summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/auth.h1
-rw-r--r--source4/auth/auth_sam.c7
-rw-r--r--source4/auth/ntlm_check.c27
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c3
-rw-r--r--source4/torture/rpc/samlogon.c23
5 files changed, 52 insertions, 9 deletions
diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index 55168a5beb..9f2e0b6a07 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -39,6 +39,7 @@
#define USER_INFO_CASE_INSENSITIVE_USERNAME 0x01 /* username may be in any case */
#define USER_INFO_CASE_INSENSITIVE_PASSWORD 0x02 /* password may be in any case */
#define USER_INFO_DONT_CHECK_UNIX_ACCOUNT 0x04 /* dont check unix account status */
+#define USER_INFO_INTERACTIVE_LOGON 0x08 /* dont check unix account status */
enum auth_password_state {
AUTH_PASSWORD_RESPONSE,
diff --git a/source4/auth/auth_sam.c b/source4/auth/auth_sam.c
index e17eea8087..44609bb7f8 100644
--- a/source4/auth/auth_sam.c
+++ b/source4/auth/auth_sam.c
@@ -370,6 +370,13 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
return NT_STATUS_ACCOUNT_LOCKED_OUT;
}
+ /* You can only do an interactive login to normal accounts */
+ if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) {
+ if (!(acct_flags & ACB_NORMAL)) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+ }
+
nt_status = samdb_result_passwords(mem_ctx, msgs[0], &lm_pwd, &nt_pwd);
NT_STATUS_NOT_OK_RETURN(nt_status);
diff --git a/source4/auth/ntlm_check.c b/source4/auth/ntlm_check.c
index 0856b82856..fc2a45efad 100644
--- a/source4/auth/ntlm_check.c
+++ b/source4/auth/ntlm_check.c
@@ -245,6 +245,9 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
username));
return NT_STATUS_WRONG_PASSWORD;
}
+ if (strchr_m(username, '@')) {
+ return NT_STATUS_NOT_FOUND;
+ }
if (memcmp(client_lanman->hash, stored_lanman->hash, sizeof(stored_lanman->hash)) == 0) {
return NT_STATUS_OK;
@@ -254,6 +257,9 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
return NT_STATUS_WRONG_PASSWORD;
}
}
+ if (strchr_m(username, '@')) {
+ return NT_STATUS_NOT_FOUND;
+ }
return NT_STATUS_WRONG_PASSWORD;
}
@@ -304,20 +310,27 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
&& (memcmp(challenge->data, zeros, challenge->length) == 0 )) {
struct samr_Password client_nt;
struct samr_Password client_lm;
- uint8_t dospwd[14];
+ uint8_t dospwd[15];
+ char *unix_pw;
DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n",
username));
mdfour(client_nt.hash, nt_response->data, nt_response->length);
ZERO_STRUCT(dospwd);
- memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd)));
+ convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX,
+ lm_response->data, lm_response->length,
+ (void **)&unix_pw);
+
/* Only the fisrt 14 chars are considered, password need not be null terminated. */
+ push_ascii(dospwd, unix_pw, sizeof(dospwd), STR_UPPER);
/* we *might* need to upper-case the string here */
E_P16((const uint8_t *)dospwd, client_lm.hash);
- return hash_password_check(mem_ctx, &client_lm, &client_nt,
+ return hash_password_check(mem_ctx,
+ lm_response->length ? &client_lm : NULL,
+ nt_response->length ? &client_nt : NULL,
username,
stored_lanman, stored_nt);
}
@@ -424,6 +437,9 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
} else if (!stored_lanman) {
DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n",
username));
+ } else if (strchr_m(username, '@')) {
+ DEBUG(3,("ntlm_password_check: NO LanMan password allowed for username@realm logins (user: %s)\n",
+ username));
} else {
DEBUG(4,("ntlm_password_check: Checking LM password\n"));
if (smb_pwd_check_ntlmv1(mem_ctx,
@@ -572,6 +588,11 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
} else {
DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username));
}
+
+ /* Try and match error codes */
+ if (strchr_m(username, '@')) {
+ return NT_STATUS_NOT_FOUND;
+ }
return NT_STATUS_WRONG_PASSWORD;
}
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 6366a58f4a..63c211baec 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -417,6 +417,9 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
return NT_STATUS_NO_MEMORY;
}
*user_info->password.hash.nt = r->in.logon.password->ntpassword;
+
+ user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
+
break;
case 2:
case 6:
diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c
index 1094c2886e..36201aa210 100644
--- a/source4/torture/rpc/samlogon.c
+++ b/source4/torture/rpc/samlogon.c
@@ -304,6 +304,8 @@ static BOOL test_lm_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm
return True;
}
return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
+ } else if (NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, nt_status) && strchr_m(samlogon_state->account_name, '@')) {
+ return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH) || (break_which == NO_NT));
} else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
SAFE_FREE(*error_string);
asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
@@ -633,6 +635,8 @@ static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state,
return True;
}
return break_which == BREAK_BOTH;
+ } else if (NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, nt_status) && strchr_m(samlogon_state->account_name, '@')) {
+ return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH) || (break_which == NO_NT));
} else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
SAFE_FREE(*error_string);
asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
@@ -799,6 +803,8 @@ static BOOL test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state,
return True;
}
return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
+ } else if (NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, nt_status) && strchr_m(samlogon_state->account_name, '@')) {
+ return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
} else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
SAFE_FREE(*error_string);
asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
@@ -1181,6 +1187,8 @@ static BOOL test_plaintext(struct samlogon_state *samlogon_state, enum ntlm_brea
return True;
}
return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
+ } else if (NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, nt_status) && strchr_m(samlogon_state->account_name, '@')) {
+ return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH) || (break_which == NO_NT));
} else if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
SAFE_FREE(*error_string);
asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
@@ -1387,7 +1395,8 @@ BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
const char *comment,
const char *workstation_name,
const char *account_domain, const char *account_name,
- const char *plain_pass, NTSTATUS expected_error)
+ const char *plain_pass, uint32_t parameter_control,
+ NTSTATUS expected_error)
{
NTSTATUS status;
TALLOC_CTX *fn_ctx = talloc_named(mem_ctx, 0, "test_InteractiveLogon function-level context");
@@ -1411,7 +1420,7 @@ BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.flags = 0;
pinfo.identity_info.domain_name.string = account_domain;
- pinfo.identity_info.parameter_control = 0;
+ pinfo.identity_info.parameter_control = parameter_control;
pinfo.identity_info.logon_id_low = 0;
pinfo.identity_info.logon_id_high = 0;
pinfo.identity_info.account_name.string = account_name;
@@ -1581,7 +1590,7 @@ BOOL torture_rpc_samlogon(void)
cli_credentials_get_domain(cmdline_credentials)
),
.password = cli_credentials_get_password(cmdline_credentials),
- .network_login = False,
+ .network_login = False, /* works for some things, but not NTLMv2. Odd */
.expected_interactive_error = NT_STATUS_OK,
.expected_network_error = NT_STATUS_OK
},
@@ -1634,7 +1643,7 @@ BOOL torture_rpc_samlogon(void)
cli_credentials_get_domain(machine_credentials)
),
.password = cli_credentials_get_password(machine_credentials),
- .network_login = False,
+ .network_login = False, /* works for some things, but not NTLMv2. Odd */
.expected_interactive_error = NT_STATUS_NO_SUCH_USER,
.parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
},
@@ -1680,7 +1689,7 @@ BOOL torture_rpc_samlogon(void)
TEST_USER_NAME,
userdomain),
.password = user_password,
- .network_login = False,
+ .network_login = False, /* works for some things, but not NTLMv2. Odd */
.expected_interactive_error = NT_STATUS_OK,
.expected_network_error = NT_STATUS_OK
},
@@ -1706,6 +1715,7 @@ BOOL torture_rpc_samlogon(void)
usercreds[ci].domain,
usercreds[ci].username,
usercreds[ci].password,
+ usercreds[ci].parameter_control,
usercreds[ci].expected_interactive_error)) {
ret = False;
}
@@ -1736,6 +1746,7 @@ BOOL torture_rpc_samlogon(void)
usercreds[0].domain,
usercreds[0].username,
usercreds[0].password,
+ usercreds[0].parameter_control,
usercreds[0].expected_interactive_error)) {
ret = False;
}
@@ -1748,7 +1759,7 @@ BOOL torture_rpc_samlogon(void)
usercreds[0].password,
usercreds[0].parameter_control,
usercreds[0].expected_network_error,
- usercreds[ci].old_password,
+ usercreds[0].old_password,
1)) {
ret = False;
}