diff options
author | CVS Import User <samba-bugs@samba.org> | 2004-04-04 11:27:30 +0000 |
---|---|---|
committer | CVS Import User <samba-bugs@samba.org> | 2004-04-04 11:27:30 +0000 |
commit | f8db8e0ae8fa16894a5eb6367ca325e530ff506b (patch) | |
tree | 753894e0b091990464ef5ce274cb149e4fd9cf0d /source/libsmb | |
parent | 139b1658ca30692835c1a7203c7cd003e587ac12 (diff) | |
download | samba-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.c | 20 | ||||
-rw-r--r-- | source/libsmb/ntlm_check.c | 74 | ||||
-rw-r--r-- | source/libsmb/ntlmssp.c | 15 | ||||
-rw-r--r-- | source/libsmb/smb_signing.c | 33 | ||||
-rw-r--r-- | source/libsmb/smbencrypt.c | 10 |
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; } |