mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
Fix UNIX passwd sync properly. I've finally understood
the as_root parameter has bugger all to do with who you *currently* are, and everything to do with who you run the script as. Doh ! Jeremy. (This used to be commit 17a241d9f788b63fec091001cb72d34c09cf32a4)
This commit is contained in:
parent
d5bd98dd9a
commit
3c1c2ddf9a
@ -333,19 +333,14 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
|
||||
int wstat;
|
||||
BOOL chstat = False;
|
||||
|
||||
if (pass == NULL)
|
||||
{
|
||||
DEBUG(0,
|
||||
("chat_with_program: user doesn't exist in the UNIX password database.\n"));
|
||||
if (pass == NULL) {
|
||||
DEBUG(0, ("chat_with_program: user doesn't exist in the UNIX password database.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* allocate a pseudo-terminal device */
|
||||
if ((master = findpty(&slavedev)) < 0)
|
||||
{
|
||||
DEBUG(3,
|
||||
("Cannot Allocate pty for password change: %s\n",
|
||||
pass->pw_name));
|
||||
if ((master = findpty(&slavedev)) < 0) {
|
||||
DEBUG(3, ("Cannot Allocate pty for password change: %s\n", pass->pw_name));
|
||||
return (False);
|
||||
}
|
||||
|
||||
@ -356,39 +351,29 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
|
||||
|
||||
CatchChildLeaveStatus();
|
||||
|
||||
if ((pid = sys_fork()) < 0)
|
||||
{
|
||||
DEBUG(3,
|
||||
("Cannot fork() child for password change: %s\n",
|
||||
pass->pw_name));
|
||||
if ((pid = sys_fork()) < 0) {
|
||||
DEBUG(3, ("Cannot fork() child for password change: %s\n", pass->pw_name));
|
||||
close(master);
|
||||
CatchChild();
|
||||
return (False);
|
||||
}
|
||||
|
||||
/* we now have a pty */
|
||||
if (pid > 0)
|
||||
{ /* This is the parent process */
|
||||
if ((chstat = talktochild(master, chatsequence)) == False)
|
||||
{
|
||||
DEBUG(3,
|
||||
("Child failed to change password: %s\n",
|
||||
pass->pw_name));
|
||||
if (pid > 0) { /* This is the parent process */
|
||||
if ((chstat = talktochild(master, chatsequence)) == False) {
|
||||
DEBUG(3, ("Child failed to change password: %s\n", pass->pw_name));
|
||||
kill(pid, SIGKILL); /* be sure to end this process */
|
||||
}
|
||||
|
||||
while ((wpid = sys_waitpid(pid, &wstat, 0)) < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
while ((wpid = sys_waitpid(pid, &wstat, 0)) < 0) {
|
||||
if (errno == EINTR) {
|
||||
errno = 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (wpid < 0)
|
||||
{
|
||||
if (wpid < 0) {
|
||||
DEBUG(3, ("The process is no longer waiting!\n\n"));
|
||||
close(master);
|
||||
CatchChild();
|
||||
@ -402,29 +387,21 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
|
||||
|
||||
close(master);
|
||||
|
||||
if (pid != wpid)
|
||||
{
|
||||
DEBUG(3,
|
||||
("We were waiting for the wrong process ID\n"));
|
||||
if (pid != wpid) {
|
||||
DEBUG(3, ("We were waiting for the wrong process ID\n"));
|
||||
return (False);
|
||||
}
|
||||
if (WIFEXITED(wstat) == 0)
|
||||
{
|
||||
DEBUG(3,
|
||||
("The process exited while we were waiting\n"));
|
||||
if (WIFEXITED(wstat) == 0) {
|
||||
DEBUG(3, ("The process exited while we were waiting\n"));
|
||||
return (False);
|
||||
}
|
||||
if (WEXITSTATUS(wstat) != 0)
|
||||
{
|
||||
DEBUG(3,
|
||||
("The status of the process exiting was %d\n",
|
||||
if (WEXITSTATUS(wstat) != 0) {
|
||||
DEBUG(3, ("The status of the process exiting was %d\n",
|
||||
wstat));
|
||||
return (False);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* CHILD */
|
||||
|
||||
/*
|
||||
@ -438,12 +415,9 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
|
||||
if (as_root)
|
||||
become_root();
|
||||
|
||||
DEBUG(3,
|
||||
("Dochild for user %s (uid=%d,gid=%d)\n", pass->pw_name,
|
||||
(int)getuid(), (int)getgid()));
|
||||
chstat =
|
||||
dochild(master, slavedev, pass, passwordprogram,
|
||||
as_root);
|
||||
DEBUG(3, ("Dochild for user %s (uid=%d,gid=%d) (as_root = %s)\n", pass->pw_name,
|
||||
(int)getuid(), (int)getgid(), BOOLSTR(as_root) ));
|
||||
chstat = dochild(master, slavedev, pass, passwordprogram, as_root);
|
||||
|
||||
if (as_root)
|
||||
unbecome_root();
|
||||
@ -452,20 +426,16 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
|
||||
* The child should never return from dochild() ....
|
||||
*/
|
||||
|
||||
DEBUG(0,
|
||||
("chat_with_program: Error: dochild() returned %d\n",
|
||||
chstat));
|
||||
DEBUG(0, ("chat_with_program: Error: dochild() returned %d\n", chstat));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (chstat)
|
||||
DEBUG(3,
|
||||
("Password change %ssuccessful for user %s\n",
|
||||
DEBUG(3, ("Password change %ssuccessful for user %s\n",
|
||||
(chstat ? "" : "un"), pass->pw_name));
|
||||
return (chstat);
|
||||
}
|
||||
|
||||
|
||||
BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root)
|
||||
{
|
||||
pstring passwordprogram;
|
||||
@ -489,7 +459,7 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL
|
||||
oldpass = "";
|
||||
}
|
||||
|
||||
DEBUG(3, ("Password change for user: %s\n", name));
|
||||
DEBUG(3, ("Password change (as_root=%s) for user: %s\n", BOOLSTR(as_root), name));
|
||||
|
||||
#if DEBUG_PASSWORD
|
||||
DEBUG(100, ("Passwords: old=%s new=%s\n", oldpass, newpass));
|
||||
@ -519,8 +489,7 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL
|
||||
len = strlen(oldpass);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (iscntrl((int)oldpass[i])) {
|
||||
DEBUG(0,
|
||||
("chat_with_program: oldpass contains control characters (disallowed).\n"));
|
||||
DEBUG(0, ("chat_with_program: oldpass contains control characters (disallowed).\n"));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
@ -528,8 +497,7 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL
|
||||
len = strlen(newpass);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (iscntrl((int)newpass[i])) {
|
||||
DEBUG(0,
|
||||
("chat_with_program: newpass contains control characters (disallowed).\n"));
|
||||
DEBUG(0, ("chat_with_program: newpass contains control characters (disallowed).\n"));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
@ -556,11 +524,8 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL
|
||||
|
||||
/* A non-PAM password change just doen't make sense without a valid local user */
|
||||
|
||||
if (pass == NULL)
|
||||
{
|
||||
DEBUG(0,
|
||||
("chgpasswd: user %s doesn't exist in the UNIX password database.\n",
|
||||
name));
|
||||
if (pass == NULL) {
|
||||
DEBUG(0, ("chgpasswd: user %s doesn't exist in the UNIX password database.\n", name));
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -755,7 +720,7 @@ NTSTATUS pass_oem_change(char *user,
|
||||
|
||||
/* We've already checked the old password here.... */
|
||||
become_root();
|
||||
nt_status = change_oem_password(sampass, NULL, new_passwd);
|
||||
nt_status = change_oem_password(sampass, NULL, new_passwd, True);
|
||||
unbecome_root();
|
||||
|
||||
memset(new_passwd, 0, sizeof(new_passwd));
|
||||
@ -937,7 +902,7 @@ static NTSTATUS check_oem_password(const char *user,
|
||||
is correct before calling. JRA.
|
||||
************************************************************/
|
||||
|
||||
NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd)
|
||||
NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd, BOOL as_root)
|
||||
{
|
||||
BOOL ret;
|
||||
uint32 min_len;
|
||||
@ -981,7 +946,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
|
||||
*/
|
||||
|
||||
if(lp_unix_password_sync() &&
|
||||
!chgpasswd(pdb_get_username(hnd), old_passwd, new_passwd, False)) {
|
||||
!chgpasswd(pdb_get_username(hnd), old_passwd, new_passwd, as_root)) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
|
@ -1984,7 +1984,7 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
|
||||
if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
|
||||
|
||||
become_root();
|
||||
if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2))) {
|
||||
if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2, False))) {
|
||||
SSVAL(*rparam,0,NERR_Success);
|
||||
}
|
||||
unbecome_root();
|
||||
@ -2032,47 +2032,46 @@ static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *
|
||||
char **rdata,char **rparam,
|
||||
int *rdata_len,int *rparam_len)
|
||||
{
|
||||
fstring user;
|
||||
char *p = param + 2;
|
||||
*rparam_len = 2;
|
||||
*rparam = REALLOC(*rparam,*rparam_len);
|
||||
fstring user;
|
||||
char *p = param + 2;
|
||||
*rparam_len = 2;
|
||||
*rparam = REALLOC(*rparam,*rparam_len);
|
||||
|
||||
*rdata_len = 0;
|
||||
*rdata_len = 0;
|
||||
|
||||
SSVAL(*rparam,0,NERR_badpass);
|
||||
SSVAL(*rparam,0,NERR_badpass);
|
||||
|
||||
/*
|
||||
* Check the parameter definition is correct.
|
||||
*/
|
||||
if(!strequal(param + 2, "zsT")) {
|
||||
DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
|
||||
return False;
|
||||
}
|
||||
p = skip_string(p, 1);
|
||||
/*
|
||||
* Check the parameter definition is correct.
|
||||
*/
|
||||
|
||||
if(!strequal(p, "B516B16")) {
|
||||
DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
|
||||
return False;
|
||||
}
|
||||
p = skip_string(p,1);
|
||||
if(!strequal(param + 2, "zsT")) {
|
||||
DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
|
||||
return False;
|
||||
}
|
||||
p = skip_string(p, 1);
|
||||
|
||||
p += pull_ascii_fstring(user,p);
|
||||
if(!strequal(p, "B516B16")) {
|
||||
DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
|
||||
return False;
|
||||
}
|
||||
p = skip_string(p,1);
|
||||
p += pull_ascii_fstring(user,p);
|
||||
|
||||
DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
|
||||
DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
|
||||
|
||||
/*
|
||||
* Pass the user through the NT -> unix user mapping
|
||||
* function.
|
||||
*/
|
||||
/*
|
||||
* Pass the user through the NT -> unix user mapping
|
||||
* function.
|
||||
*/
|
||||
|
||||
(void)map_username(user);
|
||||
(void)map_username(user);
|
||||
|
||||
if (NT_STATUS_IS_OK(pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL)))
|
||||
{
|
||||
SSVAL(*rparam,0,NERR_Success);
|
||||
}
|
||||
if (NT_STATUS_IS_OK(pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))) {
|
||||
SSVAL(*rparam,0,NERR_Success);
|
||||
}
|
||||
|
||||
return(True);
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
x
Reference in New Issue
Block a user