mirror of
https://github.com/samba-team/samba.git
synced 2025-08-08 13:49:29 +03:00
Wrap calls to change_oem_password() in become_root()/unbecome_root() pairs
to allow UNIX password change scripts to work correctly. This is safe as
the old password has been checked as correct before invoking this.
Jeremy.
(This used to be commit 1734d43eb5
)
This commit is contained in:
@ -1517,17 +1517,17 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
|
||||
|
||||
NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
|
||||
{
|
||||
fstring user_name;
|
||||
fstring wks;
|
||||
fstring user_name;
|
||||
fstring wks;
|
||||
|
||||
DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
|
||||
DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
|
||||
|
||||
r_u->status = NT_STATUS_OK;
|
||||
r_u->status = NT_STATUS_OK;
|
||||
|
||||
rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
|
||||
rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
|
||||
rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
|
||||
rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
|
||||
|
||||
DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
|
||||
DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
|
||||
|
||||
/*
|
||||
* Pass the user through the NT -> unix user mapping
|
||||
@ -1541,14 +1541,14 @@ NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_
|
||||
* is case insensitive.
|
||||
*/
|
||||
|
||||
r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
|
||||
q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
|
||||
r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
|
||||
q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
|
||||
|
||||
init_samr_r_chgpasswd_user(r_u, r_u->status);
|
||||
init_samr_r_chgpasswd_user(r_u, r_u->status);
|
||||
|
||||
DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
|
||||
DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
|
||||
|
||||
return r_u->status;
|
||||
return r_u->status;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -674,6 +674,8 @@ BOOL check_lanman_password(char *user, uchar * pass1,
|
||||
Code to change the lanman hashed password.
|
||||
It nulls out the NT hashed password as it will
|
||||
no longer be valid.
|
||||
NOTE this function is designed to be called as root. Check the old password
|
||||
is correct before calling. JRA.
|
||||
************************************************************/
|
||||
|
||||
BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2)
|
||||
@ -730,9 +732,7 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2)
|
||||
}
|
||||
|
||||
/* Now flush the sam_passwd struct to persistent storage */
|
||||
become_root();
|
||||
ret = pdb_update_sam_account (sampass);
|
||||
unbecome_root();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -740,6 +740,7 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2)
|
||||
/***********************************************************
|
||||
Code to check and change the OEM hashed password.
|
||||
************************************************************/
|
||||
|
||||
NTSTATUS pass_oem_change(char *user,
|
||||
uchar * lmdata, uchar * lmhash,
|
||||
uchar * ntdata, uchar * nthash)
|
||||
@ -747,8 +748,7 @@ NTSTATUS pass_oem_change(char *user,
|
||||
fstring new_passwd;
|
||||
const char *unix_user;
|
||||
SAM_ACCOUNT *sampass = NULL;
|
||||
NTSTATUS nt_status
|
||||
= check_oem_password(user, lmdata, lmhash, ntdata, nthash,
|
||||
NTSTATUS nt_status = check_oem_password(user, lmdata, lmhash, ntdata, nthash,
|
||||
&sampass, new_passwd, sizeof(new_passwd));
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status))
|
||||
@ -765,7 +765,10 @@ NTSTATUS pass_oem_change(char *user,
|
||||
|
||||
unix_user = pdb_get_username(sampass);
|
||||
|
||||
/* We've already checked the old password here.... */
|
||||
become_root();
|
||||
nt_status = change_oem_password(sampass, NULL, new_passwd);
|
||||
unbecome_root();
|
||||
|
||||
memset(new_passwd, 0, sizeof(new_passwd));
|
||||
|
||||
@ -942,6 +945,8 @@ static NTSTATUS check_oem_password(const char *user,
|
||||
/***********************************************************
|
||||
Code to change the oem password. Changes both the lanman
|
||||
and NT hashes. Old_passwd is almost always NULL.
|
||||
NOTE this function is designed to be called as root. Check the old password
|
||||
is correct before calling. JRA.
|
||||
************************************************************/
|
||||
|
||||
NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd)
|
||||
@ -997,9 +1002,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
|
||||
}
|
||||
|
||||
/* Now write it into the file. */
|
||||
become_root();
|
||||
ret = pdb_update_sam_account (hnd);
|
||||
unbecome_root();
|
||||
|
||||
if (!ret) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
|
@ -1897,76 +1897,78 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
|
||||
char **rdata,char **rparam,
|
||||
int *rdata_len,int *rparam_len)
|
||||
{
|
||||
char *p = skip_string(param+2,2);
|
||||
fstring user;
|
||||
fstring pass1,pass2;
|
||||
char *p = skip_string(param+2,2);
|
||||
fstring user;
|
||||
fstring pass1,pass2;
|
||||
|
||||
pull_ascii_fstring(user,p);
|
||||
pull_ascii_fstring(user,p);
|
||||
|
||||
p = skip_string(p,1);
|
||||
p = skip_string(p,1);
|
||||
|
||||
memset(pass1,'\0',sizeof(pass1));
|
||||
memset(pass2,'\0',sizeof(pass2));
|
||||
memcpy(pass1,p,16);
|
||||
memcpy(pass2,p+16,16);
|
||||
memset(pass1,'\0',sizeof(pass1));
|
||||
memset(pass2,'\0',sizeof(pass2));
|
||||
memcpy(pass1,p,16);
|
||||
memcpy(pass2,p+16,16);
|
||||
|
||||
*rparam_len = 4;
|
||||
*rparam = REALLOC(*rparam,*rparam_len);
|
||||
*rparam_len = 4;
|
||||
*rparam = REALLOC(*rparam,*rparam_len);
|
||||
|
||||
*rdata_len = 0;
|
||||
*rdata_len = 0;
|
||||
|
||||
SSVAL(*rparam,0,NERR_badpass);
|
||||
SSVAL(*rparam,2,0); /* converter word */
|
||||
SSVAL(*rparam,0,NERR_badpass);
|
||||
SSVAL(*rparam,2,0); /* converter word */
|
||||
|
||||
DEBUG(3,("Set password for <%s>\n",user));
|
||||
DEBUG(3,("Set password for <%s>\n",user));
|
||||
|
||||
/*
|
||||
* Attempt to verify the old password against smbpasswd entries
|
||||
* Win98 clients send old and new password in plaintext for this call.
|
||||
*/
|
||||
/*
|
||||
* Attempt to verify the old password against smbpasswd entries
|
||||
* Win98 clients send old and new password in plaintext for this call.
|
||||
*/
|
||||
|
||||
{
|
||||
auth_serversupplied_info *server_info = NULL;
|
||||
DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
|
||||
if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
|
||||
{
|
||||
auth_serversupplied_info *server_info = NULL;
|
||||
DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
|
||||
|
||||
if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2)))
|
||||
{
|
||||
SSVAL(*rparam,0,NERR_Success);
|
||||
}
|
||||
|
||||
free_server_info(&server_info);
|
||||
}
|
||||
data_blob_clear_free(&password);
|
||||
}
|
||||
if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
|
||||
|
||||
/*
|
||||
* If the plaintext change failed, attempt
|
||||
* the old encrypted method. NT will generate this
|
||||
* after trying the samr method. Note that this
|
||||
* method is done as a last resort as this
|
||||
* password change method loses the NT password hash
|
||||
* and cannot change the UNIX password as no plaintext
|
||||
* is received.
|
||||
*/
|
||||
become_root();
|
||||
if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2))) {
|
||||
SSVAL(*rparam,0,NERR_Success);
|
||||
}
|
||||
unbecome_root();
|
||||
|
||||
if(SVAL(*rparam,0) != NERR_Success)
|
||||
{
|
||||
SAM_ACCOUNT *hnd = NULL;
|
||||
free_server_info(&server_info);
|
||||
}
|
||||
data_blob_clear_free(&password);
|
||||
}
|
||||
|
||||
if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd) &&
|
||||
change_lanman_password(hnd,pass2))
|
||||
{
|
||||
SSVAL(*rparam,0,NERR_Success);
|
||||
}
|
||||
pdb_free_sam(&hnd);
|
||||
}
|
||||
/*
|
||||
* If the plaintext change failed, attempt
|
||||
* the old encrypted method. NT will generate this
|
||||
* after trying the samr method. Note that this
|
||||
* method is done as a last resort as this
|
||||
* password change method loses the NT password hash
|
||||
* and cannot change the UNIX password as no plaintext
|
||||
* is received.
|
||||
*/
|
||||
|
||||
if(SVAL(*rparam,0) != NERR_Success) {
|
||||
SAM_ACCOUNT *hnd = NULL;
|
||||
|
||||
memset((char *)pass1,'\0',sizeof(fstring));
|
||||
memset((char *)pass2,'\0',sizeof(fstring));
|
||||
if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd)) {
|
||||
become_root();
|
||||
if (change_lanman_password(hnd,pass2)) {
|
||||
SSVAL(*rparam,0,NERR_Success);
|
||||
}
|
||||
unbecome_root();
|
||||
pdb_free_sam(&hnd);
|
||||
}
|
||||
}
|
||||
|
||||
memset((char *)pass1,'\0',sizeof(fstring));
|
||||
memset((char *)pass2,'\0',sizeof(fstring));
|
||||
|
||||
return(True);
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
Reference in New Issue
Block a user