1
0
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:
Jeremy Allison 2003-09-04 18:02:17 +00:00
parent d5bd98dd9a
commit 3c1c2ddf9a
2 changed files with 63 additions and 99 deletions

View File

@ -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;
}

View File

@ -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);
}
/****************************************************************************