Author: abartlet Date: 2004-08-31 20:29:22 +0000 (Tue, 31 Aug 2004) New Revision: 2145
WebSVN: http://websvn.samba.org/websvn/changeset.php?rep=samba&path=/trunk/source/libsmb&rev=2145&nolog=1 Log: Merge LanMan login fixes from Samba 3.0 -> trunk. (Also merge a few indentation changes). Andrew Bartlett Modified: trunk/source/libsmb/cliconnect.c Changeset: Modified: trunk/source/libsmb/cliconnect.c =================================================================== --- trunk/source/libsmb/cliconnect.c 2004-08-31 20:27:36 UTC (rev 2144) +++ trunk/source/libsmb/cliconnect.c 2004-08-31 20:29:22 UTC (rev 2145) @@ -40,6 +40,18 @@ {-1,NULL} }; +/** + * Set the user session key for a connection + * @param cli The cli structure to add it too + * @param session_key The session key used. (A copy of this is taken for the cli struct) + * + */ + +static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) +{ + cli->user_session_key = data_blob(session_key.data, session_key.length); +} + /**************************************************************************** Do an old lanman2 style session setup. ****************************************************************************/ @@ -47,6 +59,8 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, const char *pass, size_t passlen, const char *workgroup) { + DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB lm_response = data_blob(NULL, 0); fstring pword; char *p; @@ -66,14 +80,18 @@ if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ - passlen = 24; - SMBencrypt(pass,cli->secblob.data,(uchar *)pword); + lm_response = data_blob(NULL, 24); + if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) { + DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n")); + return False; + } } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ - memcpy(pword, pass, passlen); + lm_response = data_blob(pass, passlen); } else if (passlen > 0) { /* Plaintext mode needed, assume plaintext supplied. */ passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); + lm_response = data_blob(pass, passlen); } /* send a session setup command */ @@ -87,11 +105,11 @@ SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,1); SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); + SSVAL(cli->outbuf,smb_vwv7,lm_response.length); p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += passlen; + memcpy(p,lm_response.data,lm_response.length); + p += lm_response.length; p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); @@ -111,6 +129,11 @@ cli->vuid = SVAL(cli->inbuf,smb_uid); fstrcpy(cli->user_name, user); + if (session_key.data) { + /* Have plaintext orginal */ + cli_set_session_key(cli, session_key); + } + return True; } @@ -248,18 +271,6 @@ return True; } -/** - * Set the user session key for a connection - * @param cli The cli structure to add it too - * @param session_key The session key used. (A copy of this is taken for the cli struct) - * - */ - -static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) -{ - cli->user_session_key = data_blob(session_key.data, session_key.length); -} - /**************************************************************************** do a NT1 NTLM/LM encrypted session setup - for when extended security is not negotiated. @@ -310,22 +321,39 @@ uchar nt_hash[16]; E_md4hash(pass, nt_hash); +#ifdef LANMAN_ONLY + nt_response = data_blob(NULL, 0); +#else nt_response = data_blob(NULL, 24); SMBNTencrypt(pass,cli->secblob.data,nt_response.data); - +#endif /* non encrypted password supplied. Ignore ntpass. */ if (lp_client_lanman_auth()) { lm_response = data_blob(NULL, 24); - SMBencrypt(pass,cli->secblob.data, lm_response.data); + if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) { + /* Oops, the LM response is invalid, just put + the NT response there instead */ + data_blob_free(&lm_response); + lm_response = data_blob(nt_response.data, nt_response.length); + } } else { /* LM disabled, place NT# in LM field instead */ lm_response = data_blob(nt_response.data, nt_response.length); } session_key = data_blob(NULL, 16); +#ifdef LANMAN_ONLY + E_deshash(pass, session_key.data); + memset(&session_key.data[8], '\0', 8); +#else SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); +#endif } +#ifdef LANMAN_ONLY + cli_simple_set_signing(cli, session_key, lm_response); +#else cli_simple_set_signing(cli, session_key, nt_response); +#endif } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -1616,8 +1644,8 @@ 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))); @@ -1646,14 +1674,14 @@ 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; }