diff options
author | Jeremy Allison <jra@samba.org> | 1998-03-18 19:07:53 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 1998-03-18 19:07:53 +0000 |
commit | da050244c305c1e03e2f3fb2ac02f6bc93ad47ca (patch) | |
tree | e6da7d243fd00f8fd4e9ade3fbbc191dfdd39cec /source3 | |
parent | 002176a37597b51b4f5e482d9c5e6a8f6b39257f (diff) | |
download | samba-da050244c305c1e03e2f3fb2ac02f6bc93ad47ca.tar.gz samba-da050244c305c1e03e2f3fb2ac02f6bc93ad47ca.tar.bz2 samba-da050244c305c1e03e2f3fb2ac02f6bc93ad47ca.zip |
Added SamOEMChangePassword functionality.
Jeremy.
(This used to be commit e02e3bcbbd4333113dde7bef47763fb229148007)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/proto.h | 5 | ||||
-rw-r--r-- | source3/libsmb/smbdes.c | 40 | ||||
-rw-r--r-- | source3/smbd/chgpasswd.c | 114 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 60 |
4 files changed, 219 insertions, 0 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 54f833a93e..e980bcacc9 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -38,6 +38,10 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass); BOOL check_lanman_password(char *user, unsigned char *pass1, unsigned char *pass2, struct smb_passwd **psmbpw); BOOL change_lanman_password(struct smb_passwd *smbpw, unsigned char *pass1, unsigned char *pass2); +BOOL check_oem_password(char *user, unsigned char *data, + struct smb_passwd **psmbpw, char *new_passwd, + int new_passwd_size); +BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd); /*The following definitions come from client.c */ @@ -1664,6 +1668,7 @@ void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); +void SamOEMhash( unsigned char *data, unsigned char *key); /*The following definitions come from smbencrypt.c */ diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index c345d051bd..8f95a5a297 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -341,3 +341,43 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) smbhash(out, buf, key2, 1); } +void SamOEMhash( unsigned char *data, unsigned char *key) +{ + unsigned char s_box[256]; + unsigned char index_i = 0; + unsigned char index_j = 0; + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + s_box[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (s_box[ind] + key[ind%16]); + + tc = s_box[ind]; + s_box[ind] = s_box[j]; + s_box[j] = tc; + } + + for( ind = 0; ind < 516; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += s_box[index_i]; + + tc = s_box[index_i]; + s_box[index_i] = s_box[index_j]; + s_box[index_j] = tc; + + t = s_box[index_i] + s_box[index_j]; + data[ind] = data[ind] ^ s_box[t]; + } +} diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index c83ff1911c..57d81ad756 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -493,3 +493,117 @@ BOOL change_lanman_password(struct smb_passwd *smbpw, unsigned char *pass1, unsi return ret; } + +/*********************************************************** + Code to check the OEM hashed password. +************************************************************/ + +BOOL check_oem_password(char *user, unsigned char *data, + struct smb_passwd **psmbpw, char *new_passwd, + int new_passwd_size) +{ + struct smb_passwd *smbpw = NULL; + int new_pw_len; + fstring upper_case_new_passwd; + unsigned char new_p16[16]; + unsigned char unenc_old_pw[16]; + + become_root(0); + *psmbpw = smbpw = get_smbpwd_entry(user, 0); + unbecome_root(0); + + if(smbpw == NULL) + { + DEBUG(0,("check_oem_password: get_smbpwd_entry returned NULL\n")); + return False; + } + + if(smbpw->acct_ctrl & ACB_DISABLED) + { + DEBUG(0,("check_lanman_password: account %s disabled.\n", user)); + return False; + } + + if(smbpw->smb_passwd == NULL) + { + DEBUG(0,("check_oem_password: no lanman password !\n")); + return False; + } + + /* + * Call the hash function to get the new password. + */ + SamOEMhash( (unsigned char *)data, (unsigned char *)smbpw->smb_passwd); + + /* + * The length of the new password is in the last 4 bytes of + * the data buffer. + */ + new_pw_len = IVAL(data,512); + if(new_pw_len < 0 || new_pw_len > new_passwd_size - 1) { + DEBUG(0,("check_oem_password: incorrect password length.\n")); + return False; + } + + memcpy(new_passwd, &data[512-new_pw_len], new_pw_len); + new_passwd[new_pw_len] = '\0'; + + /* + * To ensure we got the correct new password, hash it and + * use it as a key to test the passed old password. + */ + + memset(upper_case_new_passwd, '\0', sizeof(upper_case_new_passwd)); + fstrcpy(upper_case_new_passwd, new_passwd); + strupper(upper_case_new_passwd); + + E_P16((uchar *)upper_case_new_passwd, new_p16); + + /* + * Now use new_p16 as the key to see if the old + * password matches. + */ + D_P16(new_p16, &data[516], unenc_old_pw); + + if(memcmp(smbpw->smb_passwd, unenc_old_pw, 16)) { + DEBUG(0,("check_oem_password: old password doesn't match.\n")); + return False; + } + + memset(upper_case_new_passwd, '\0', strlen(upper_case_new_passwd)); + + return True; +} + +/*********************************************************** + Code to change the oem password. Changes both the lanman + and NT hashes. +************************************************************/ + +BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd) +{ + int ret; + fstring upper_case_new_passwd; + unsigned char new_nt_p16[16]; + unsigned char new_p16[16]; + + fstrcpy(upper_case_new_passwd, new_passwd); + strupper(upper_case_new_passwd); + + E_P16((uchar *)upper_case_new_passwd, new_p16); + + smbpw->smb_passwd = new_p16; + + E_md4hash((uchar *) new_passwd, new_nt_p16); + smbpw->smb_nt_passwd = new_nt_p16; + + /* Now write it into the file. */ + become_root(0); + ret = mod_smbpwd_entry(smbpw); + unbecome_root(0); + + memset(upper_case_new_passwd, '\0', strlen(upper_case_new_passwd)); + memset(new_passwd, '\0', strlen(new_passwd)); + + return ret; +} diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index bbeeb21e96..89b3e36f52 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -1663,6 +1663,65 @@ static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data, } /**************************************************************************** + Set the user password (SamOEM version - gets plaintext). +****************************************************************************/ + +static BOOL api_SamOEMChangePassword(int cnum,uint16 vuid, char *param,char *data, + int mdrcnt,int mprcnt, + char **rdata,char **rparam, + int *rdata_len,int *rparam_len) +{ + fstring user; + fstring new_passwd; + struct smb_passwd *smbpw = NULL; + char *p = param + 2; + + *rparam_len = 2; + *rparam = REALLOC(*rparam,*rparam_len); + + *rdata_len = 0; + + SSVAL(*rparam,0,NERR_badpass); + + /* + * Check the parameter definition is correct. + */ + if(!strequal(param + 2, "zsT")) { + DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %sn\n", param + 2)); + return False; + } + p = skip_string(p, 1); + + if(!strequal(p, "B516B16")) { + DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %sn\n", p)); + return False; + } + p = skip_string(p,1); + + fstrcpy(user,p); + p = skip_string(p,1); + + if(check_oem_password( user, data, &smbpw, new_passwd, sizeof(new_passwd)) == False) { + return True; + } + + /* + * At this point we have the new case-sensitive plaintext + * password in the fstring new_passwd. If we wanted to synchronise + * with UNIX passwords we would call a UNIX password changing + * function here. However it would have to be done as root + * as the plaintext of the old users password is not + * available. JRA. + */ + + if(change_oem_password( smbpw, new_passwd)) { + SSVAL(*rparam,0,NERR_Success); + } + + return(True); +} + +/**************************************************************************** delete a print job Form: <W> <> ****************************************************************************/ @@ -3410,6 +3469,7 @@ struct {"WPrintDriverEnum", 205, (BOOL (*)())api_WPrintDriverEnum,0}, {"WPrintQProcEnum", 206, (BOOL (*)())api_WPrintQProcEnum,0}, {"WPrintPortEnum", 207, (BOOL (*)())api_WPrintPortEnum,0}, + {"SamOEMChangePassword", 214, (BOOL (*)())api_SamOEMChangePassword,0}, {NULL, -1, (BOOL (*)())api_Unsupported,0}}; |