summaryrefslogtreecommitdiff
path: root/source3/libsmb/smbencrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb/smbencrypt.c')
-rw-r--r--source3/libsmb/smbencrypt.c80
1 files changed, 63 insertions, 17 deletions
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 858045dc02..caf9256787 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -231,11 +231,18 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
/***********************************************************
decode a password buffer
************************************************************/
-BOOL decode_pw_buffer(char buffer[516], char *new_pwrd,
- int new_pwrd_size, uint32 *new_pw_len)
+BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
+ int new_pwrd_size, uint32 *new_pw_len,
+ uchar nt_p16[16], uchar p16[16])
{
- int uni_pw_len=0;
char *pw;
+
+ int uni_pw_len=0;
+ int byte_len=0;
+ char unicode_passwd[514];
+ char lm_ascii_passwd[514];
+ char passwd[514];
+
/*
Warning !!! : This function is called from some rpc call.
The password IN the buffer is a UNICODE string.
@@ -243,33 +250,72 @@ BOOL decode_pw_buffer(char buffer[516], char *new_pwrd,
If you reuse that code somewhere else check first.
*/
- ZERO_STRUCTP(new_pwrd);
+ ZERO_STRUCT(unicode_passwd);
+ ZERO_STRUCT(lm_ascii_passwd);
+ ZERO_STRUCT(passwd);
- /*
- * The length of the new password is in the last 4 bytes of
- * the data buffer.
- */
+ memset(nt_p16, '\0', 16);
+ memset(p16, '\0', 16);
- *new_pw_len = IVAL(buffer, 512);
+ /* The length of the new password is in the last 4 bytes of the data buffer. */
+
+ byte_len = IVAL(in_buffer, 512);
#ifdef DEBUG_PASSWORD
- dump_data(100, buffer, 516);
+ dump_data(100, in_buffer, 516);
#endif
- if (((int)*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) {
- DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", (*new_pw_len)));
+ /* Password cannot be longer than 128 characters */
+ if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) {
+ DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len));
return False;
}
+
+ uni_pw_len = byte_len/2;
+ pw = dos_unistrn2((uint16 *)(&in_buffer[512 - byte_len]), byte_len);
+ memcpy(passwd, pw, uni_pw_len);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_lm_owf_gen: passwd: "));
+ dump_data(100, (char *)passwd, uni_pw_len);
+ DEBUG(100,("len:%d\n", uni_pw_len));
+#endif
+ memcpy(unicode_passwd, &in_buffer[512 - byte_len], byte_len);
+
+ mdfour(nt_p16, (unsigned char *)unicode_passwd, byte_len);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_lm_owf_gen: nt#:"));
+ dump_data(100, (char *)nt_p16, 16);
+ DEBUG(100,("\n"));
+#endif
+
+ /* Mangle the passwords into Lanman format */
+ memcpy(lm_ascii_passwd, passwd, uni_pw_len);
+ lm_ascii_passwd[14] = '\0';
+ strupper(lm_ascii_passwd);
- uni_pw_len = *new_pw_len;
- *new_pw_len /= 2;
- pw = dos_unistrn2((uint16 *)(&buffer[512 - uni_pw_len]), uni_pw_len);
- memcpy(new_pwrd, pw, *new_pw_len);
+ /* Calculate the SMB (lanman) hash functions of the password */
+ E_P16((uchar *) lm_ascii_passwd, (uchar *)p16);
#ifdef DEBUG_PASSWORD
- dump_data(100, new_pwrd, (*new_pw_len));
+ DEBUG(100,("nt_lm_owf_gen: lm#:"));
+ dump_data(100, (char *)p16, 16);
+ DEBUG(100,("\n"));
#endif
+ /* copy the password and it's length to the return buffer */
+ *new_pw_len=uni_pw_len;
+ memcpy(new_pwrd, passwd, uni_pw_len);
+ new_pwrd[uni_pw_len]='\0';
+
+
+ /* clear out local copy of user's password (just being paranoid). */
+ ZERO_STRUCT(unicode_passwd);
+ ZERO_STRUCT(lm_ascii_passwd);
+ ZERO_STRUCT(passwd);
+
return True;
+
}