summaryrefslogtreecommitdiffstats
path: root/source/libsmb
diff options
context:
space:
mode:
authorCVS Import User <samba-bugs@samba.org>2004-04-04 11:27:30 +0000
committerCVS Import User <samba-bugs@samba.org>2004-04-04 11:27:30 +0000
commitf8db8e0ae8fa16894a5eb6367ca325e530ff506b (patch)
tree753894e0b091990464ef5ce274cb149e4fd9cf0d /source/libsmb
parent139b1658ca30692835c1a7203c7cd003e587ac12 (diff)
downloadsamba-f8db8e0ae8fa16894a5eb6367ca325e530ff506b.tar.gz
samba-f8db8e0ae8fa16894a5eb6367ca325e530ff506b.tar.xz
samba-f8db8e0ae8fa16894a5eb6367ca325e530ff506b.zip
r4: merge in the SAMBA_3_0 branch from cvs
to checkout try this: svn co svn+ssh://svn.samba.org/home/svn/samba/branches/SAMBA_3_0 samba-3_0-work metze
Diffstat (limited to 'source/libsmb')
-rw-r--r--source/libsmb/cliconnect.c20
-rw-r--r--source/libsmb/ntlm_check.c74
-rw-r--r--source/libsmb/ntlmssp.c15
-rw-r--r--source/libsmb/smb_signing.c33
-rw-r--r--source/libsmb/smbencrypt.c10
5 files changed, 115 insertions, 37 deletions
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index c39044e10af..cdf58c5b913 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -358,7 +358,9 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
}
p += clistr_push(cli, p, user, -1, STR_TERMINATE);
- p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE);
+
+ /* Upper case here might help some NTLMv2 implementations */
+ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
@@ -874,7 +876,7 @@ BOOL cli_send_tconX(struct cli_state *cli,
if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) {
if (!lp_client_lanman_auth()) {
- DEBUG(1, ("Server requested LANMAN password but 'client use lanman auth'"
+ DEBUG(1, ("Server requested LANMAN password (share-level security) but 'client use lanman auth'"
" is disabled\n"));
return False;
}
@@ -1091,7 +1093,7 @@ BOOL cli_negprot(struct cli_state *cli)
}
cli->sign_info.negotiated_smb_signing = True;
cli->sign_info.mandatory_signing = True;
- } else if (cli->sign_info.allow_smb_signing && cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
+ } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
cli->sign_info.negotiated_smb_signing = True;
}
@@ -1610,8 +1612,8 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring workgroup, struct user_auth_info *user_info)
{
static fstring name;
- struct cli_state *cli;
- struct in_addr server_ip;
+ struct cli_state *cli;
+ struct in_addr server_ip;
DEBUG(99, ("Looking up name of master browser %s\n",
inet_ntoa(mb_ip->ip)));
@@ -1640,14 +1642,14 @@ struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring w
return NULL;
}
- pstrcpy(workgroup, name);
+ pstrcpy(workgroup, name);
- DEBUG(4, ("found master browser %s, %s\n",
+ DEBUG(4, ("found master browser %s, %s\n",
name, inet_ntoa(mb_ip->ip)));
- cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info);
+ cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info);
- return cli;
+ return cli;
}
diff --git a/source/libsmb/ntlm_check.c b/source/libsmb/ntlm_check.c
index 362b640f913..a7764f9e986 100644
--- a/source/libsmb/ntlm_check.c
+++ b/source/libsmb/ntlm_check.c
@@ -85,6 +85,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
const uchar *part_passwd,
const DATA_BLOB *sec_blob,
const char *user, const char *domain,
+ BOOL upper_case_domain, /* should the domain be transformed into upper case? */
DATA_BLOB *user_sess_key)
{
/* Finish the encryption of part_passwd. */
@@ -122,7 +123,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
memcpy(client_response, ntv2_response->data, sizeof(client_response));
- if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
+ if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
return False;
}
@@ -169,6 +170,8 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
const DATA_BLOB *challenge,
const DATA_BLOB *lm_response,
const DATA_BLOB *nt_response,
+ const DATA_BLOB *lm_interactive_pwd,
+ const DATA_BLOB *nt_interactive_pwd,
const char *username,
const char *client_username,
const char *client_domain,
@@ -182,6 +185,47 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
username));
}
+ if (nt_interactive_pwd && nt_interactive_pwd->length && nt_pw) {
+ if (nt_interactive_pwd->length != 16) {
+ DEBUG(3,("ntlm_password_check: Interactive logon: Invalid NT password length (%d) supplied for user %s\n", (int)nt_interactive_pwd->length,
+ username));
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ if (memcmp(nt_interactive_pwd->data, nt_pw, 16) == 0) {
+ if (user_sess_key) {
+ *user_sess_key = data_blob(NULL, 16);
+ SMBsesskeygen_ntv1(nt_pw, NULL, user_sess_key->data);
+ }
+ return NT_STATUS_OK;
+ } else {
+ DEBUG(3,("ntlm_password_check: Interactive logon: NT password check failed for user %s\n",
+ username));
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ } else if (lm_interactive_pwd && lm_interactive_pwd->length && lm_pw) {
+ if (lm_interactive_pwd->length != 16) {
+ DEBUG(3,("ntlm_password_check: Interactive logon: Invalid LANMAN password length (%d) supplied for user %s\n", (int)lm_interactive_pwd->length,
+ username));
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ if (!lp_lanman_auth()) {
+ DEBUG(3,("ntlm_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n",
+ username));
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ if (memcmp(lm_interactive_pwd->data, lm_pw, 16) == 0) {
+ return NT_STATUS_OK;
+ } else {
+ DEBUG(3,("ntlm_password_check: Interactive logon: LANMAN password check failed for user %s\n",
+ username));
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+ }
+
/* Check for cleartext netlogon. Used by Exchange 5.5. */
if (challenge->length == sizeof(zeros) &&
(memcmp(challenge->data, zeros, challenge->length) == 0 )) {
@@ -235,13 +279,24 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
if (nt_response->length >= 24 && nt_pw) {
if (nt_response->length > 24) {
/* We have the NT MD4 hash challenge available - see if we can
- use it (ie. does it exist in the smbpasswd file).
+ use it
*/
DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain));
if (smb_pwd_check_ntlmv2( nt_response,
nt_pw, challenge,
- client_username,
+ client_username,
+ client_domain,
+ False,
+ user_sess_key)) {
+ return NT_STATUS_OK;
+ }
+
+ DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n", client_domain));
+ if (smb_pwd_check_ntlmv2( nt_response,
+ nt_pw, challenge,
+ client_username,
client_domain,
+ True,
user_sess_key)) {
return NT_STATUS_OK;
}
@@ -251,6 +306,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
nt_pw, challenge,
client_username,
"",
+ False,
user_sess_key)) {
return NT_STATUS_OK;
} else {
@@ -334,6 +390,17 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
nt_pw, challenge,
client_username,
client_domain,
+ False,
+ NULL)) {
+ return NT_STATUS_OK;
+ }
+
+ DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n", client_domain));
+ if (smb_pwd_check_ntlmv2( lm_response,
+ nt_pw, challenge,
+ client_username,
+ client_domain,
+ True,
NULL)) {
return NT_STATUS_OK;
}
@@ -343,6 +410,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
nt_pw, challenge,
client_username,
"",
+ False,
NULL)) {
return NT_STATUS_OK;
}
diff --git a/source/libsmb/ntlmssp.c b/source/libsmb/ntlmssp.c
index 60523ddf9d0..ddc2e0325fd 100644
--- a/source/libsmb/ntlmssp.c
+++ b/source/libsmb/ntlmssp.c
@@ -168,7 +168,9 @@ NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password
*/
NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain)
{
- ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain);
+ /* Possibly make our NTLMv2 client more robust by always having
+ an uppercase domain */
+ ntlmssp_state->domain = talloc_strdup_upper(ntlmssp_state->mem_ctx, domain);
if (!ntlmssp_state->domain) {
return NT_STATUS_NO_MEMORY;
}
@@ -1020,16 +1022,19 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
/* Key exchange encryptes a new client-generated session key with
the password-derived key */
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
+ /* Make up a new session key */
uint8 client_session_key[16];
-
- generate_random_buffer(client_session_key, sizeof(client_session_key), False);
+ generate_random_buffer(client_session_key, sizeof(client_session_key), False);
+
+ /* Encrypt the new session key with the old one */
encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
-
SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
+ dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
+
+ /* Mark the new session key as the 'real' session key */
data_blob_free(&session_key);
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
- dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
}
/* this generates the actual auth packet */
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
index 28ff0e0c2e9..7130453c0c9 100644
--- a/source/libsmb/smb_signing.c
+++ b/source/libsmb/smb_signing.c
@@ -150,7 +150,7 @@ static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
SMB signing - NULL implementation - check a MAC sent by server.
************************************************************/
-static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok)
+static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
{
return True;
}
@@ -197,7 +197,7 @@ static void free_signing_context(struct smb_sign_info *si)
}
-static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL expected_ok)
+static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL must_be_ok)
{
if (good) {
@@ -212,18 +212,18 @@ static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint3
} else {
if (!si->mandatory_signing && !si->seen_valid) {
- if (!expected_ok) {
+ if (!must_be_ok) {
return True;
}
/* Non-mandatory signing - just turn off if this is the first bad packet.. */
- DEBUG(5, ("signing_good: signing negotiated but not required and the other side \
-isn't sending correct signatures. Turning signatures off.\n"));
+ DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n"
+ "isn't sending correct signatures. Turning off.\n"));
si->negotiated_smb_signing = False;
si->allow_smb_signing = False;
si->doing_signing = False;
free_signing_context(si);
return True;
- } else if (!expected_ok) {
+ } else if (!must_be_ok) {
/* This packet is known to be unsigned */
return True;
} else {
@@ -337,7 +337,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
SMB signing - Client implementation - check a MAC sent by server.
************************************************************/
-static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok)
+static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
{
BOOL good;
uint32 reply_seq_number;
@@ -395,7 +395,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq ));
DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
dump_data(10, (const char *)server_sent_mac, 8);
}
- return signing_good(inbuf, si, good, saved_seq, expected_ok);
+ return signing_good(inbuf, si, good, saved_seq, must_be_ok);
}
/***********************************************************
@@ -549,7 +549,7 @@ static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
SMB signing - TEMP implementation - check a MAC sent by server.
************************************************************/
-static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok)
+static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL foo)
{
return True;
}
@@ -611,9 +611,9 @@ void cli_calculate_sign_mac(struct cli_state *cli)
* which had a bad checksum, True otherwise.
*/
-BOOL cli_check_sign_mac(struct cli_state *cli, BOOL expected_ok)
+BOOL cli_check_sign_mac(struct cli_state *cli, BOOL must_be_ok)
{
- if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, expected_ok)) {
+ if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, must_be_ok)) {
free_signing_context(&cli->sign_info);
return False;
}
@@ -702,7 +702,7 @@ static BOOL is_oplock_break(char *inbuf)
SMB signing - Server implementation - check a MAC sent by server.
************************************************************/
-static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok)
+static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok)
{
BOOL good;
struct smb_basic_signing_context *data = si->signing_context;
@@ -776,7 +776,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq ));
dump_data(10, (const char *)server_sent_mac, 8);
}
- return (signing_good(inbuf, si, good, saved_seq, expected_ok));
+ return (signing_good(inbuf, si, good, saved_seq, must_be_ok));
}
/***********************************************************
@@ -809,13 +809,13 @@ BOOL srv_oplock_set_signing(BOOL onoff)
Called to validate an incoming packet from the client.
************************************************************/
-BOOL srv_check_sign_mac(char *inbuf, BOOL expected_ok)
+BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok)
{
/* Check if it's a session keepalive. */
if(CVAL(inbuf,0) == SMBkeepalive)
return True;
- return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, expected_ok);
+ return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok);
}
/***********************************************************
@@ -915,8 +915,7 @@ BOOL srv_is_signing_negotiated(void)
}
/***********************************************************
- Returns whether signing is negotiated. We can't use it unless it was
- in the negprot.
+ Returns whether signing is actually happening
************************************************************/
BOOL srv_signing_started(void)
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index c5acedae51c..270a659e57f 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -127,7 +127,9 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16])
/* Does both the NTLMv2 owfs of a user's password */
BOOL ntv2_owf_gen(const uchar owf[16],
- const char *user_in, const char *domain_in, uchar kr_buf[16])
+ const char *user_in, const char *domain_in,
+ BOOL upper_case_domain, /* Transform the domain into UPPER case */
+ uchar kr_buf[16])
{
smb_ucs2_t *user;
smb_ucs2_t *domain;
@@ -150,7 +152,9 @@ BOOL ntv2_owf_gen(const uchar owf[16],
}
strupper_w(user);
- strupper_w(domain);
+
+ if (upper_case_domain)
+ strupper_w(domain);
SMB_ASSERT(user_byte_len >= 2);
SMB_ASSERT(domain_byte_len >= 2);
@@ -426,7 +430,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password
the username and domain.
This prevents username swapping during the auth exchange
*/
- if (!ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash)) {
+ if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) {
return False;
}