diff -Nurbd samba-3.0.34.orig/source/smbd/chgpasswd.c samba-3.0.34/source/smbd/chgpasswd.c --- samba-3.0.34.orig/source/smbd/chgpasswd.c 2009-01-19 11:40:09.000000000 +0100 +++ samba-3.0.34/source/smbd/chgpasswd.c 2009-05-26 16:57:29.000000000 +0200 @@ -236,18 +236,25 @@ return (True); } -static int expect(int master, char *issue, char *expected) +static int expect(int master, char *issue, char *expected, + const char *oldpass, const char *newpass) { pstring buffer; + pstring issue_password; int attempts, timeout, nread, len; BOOL match = False; + /* replace placeholder by password */ + pstrcpy(issue_password, issue); + all_string_sub(issue_password, "%o", oldpass, sizeof(pstring)); + all_string_sub(issue_password, "%n", newpass, sizeof(pstring)); + for (attempts = 0; attempts < 2; attempts++) { if (!strequal(issue, ".")) { if (lp_passwd_chat_debug()) - DEBUG(100, ("expect: sending [%s]\n", issue)); + DEBUG(100, ("expect: sending [%s]\n", issue_password)); - if ((len = sys_write(master, issue, strlen(issue))) != strlen(issue)) { + if ((len = sys_write(master, issue_password, strlen(issue_password))) != strlen(issue_password)) { DEBUG(2,("expect: (short) write returned %d\n", len )); return False; } @@ -305,7 +312,8 @@ all_string_sub(buf, "\\t", "\t", 0); } -static int talktochild(int master, const char *seq) +static int talktochild(int master, const char *seq, + const char *oldpass, const char *newpass) { int count = 0; fstring issue, expected; @@ -317,7 +325,7 @@ pwd_sub(expected); count++; - if (!expect(master, issue, expected)) + if (!expect(master, issue, expected, oldpass, newpass)) { DEBUG(3, ("Response %d incorrect\n", count)); return False; @@ -331,7 +339,7 @@ if (!strequal(issue, ".")) { /* we have one final issue to send */ fstrcpy(expected, "."); - if (!expect(master, issue, expected)) + if (!expect(master, issue, expected, oldpass, newpass)) return False; } @@ -339,7 +347,8 @@ } static BOOL chat_with_program(char *passwordprogram, const struct passwd *pass, - char *chatsequence, BOOL as_root) + char *chatsequence, BOOL as_root, + const char *oldpass, const char *newpass) { char *slavedev; int master; @@ -374,7 +383,7 @@ /* we now have a pty */ if (pid > 0) { /* This is the parent process */ - if ((chstat = talktochild(master, chatsequence)) == False) { + if ((chstat = talktochild(master, chatsequence, oldpass, newpass)) == False) { DEBUG(3, ("chat_with_program: Child failed to change password: %s\n", pass->pw_name)); kill(pid, SIGKILL); /* be sure to end this process */ } @@ -563,10 +572,8 @@ a new password containing shell escape characters */ pstring_sub(chatsequence, "%u", name); - all_string_sub(chatsequence, "%o", oldpass, sizeof(pstring)); - all_string_sub(chatsequence, "%n", newpass, sizeof(pstring)); return (chat_with_program - (passwordprogram, pass, chatsequence, as_root)); + (passwordprogram, pass, chatsequence, as_root, oldpass, newpass)); } #else /* ALLOW_CHANGE_PASSWORD */