mirror of
https://github.com/samba-team/samba.git
synced 2025-02-04 17:47:26 +03:00
Added SamOEMChangePassword functionality.
Jeremy.
This commit is contained in:
parent
112cf61cb6
commit
e02e3bcbbd
@ -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 */
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1662,6 +1662,65 @@ static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data,
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
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}};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user