diff options
author | Luke Leighton <lkcl@samba.org> | 2000-03-15 23:47:51 +0000 |
---|---|---|
committer | Luke Leighton <lkcl@samba.org> | 2000-03-15 23:47:51 +0000 |
commit | e3c8ac198cb84764d4f9dea9f7c07afd37c2235e (patch) | |
tree | 3367925749794795daa6f9128d223ff46d24c129 | |
parent | 946f93e15d590f7f1cec0ea56d15e4cbbcafb507 (diff) | |
download | samba-e3c8ac198cb84764d4f9dea9f7c07afd37c2235e.tar.gz samba-e3c8ac198cb84764d4f9dea9f7c07afd37c2235e.tar.xz samba-e3c8ac198cb84764d4f9dea9f7c07afd37c2235e.zip |
fixed word-order issue in password set and password change.
-rw-r--r-- | source/samrd/srv_samr_passdb.c | 18 | ||||
-rw-r--r-- | source/smbd/chgpasswd.c | 874 |
2 files changed, 503 insertions, 389 deletions
diff --git a/source/samrd/srv_samr_passdb.c b/source/samrd/srv_samr_passdb.c index 63d9077e965..5ab81bd36d2 100644 --- a/source/samrd/srv_samr_passdb.c +++ b/source/samrd/srv_samr_passdb.c @@ -1937,6 +1937,8 @@ static BOOL set_user_info_24(const SAM_USER_INFO_24 * id24, uint32 rid) static uchar lm_hash[16]; UNISTR2 new_pw; uint32 len; + pstring buf; + int i; if (pwd == NULL) { @@ -1946,7 +1948,7 @@ static BOOL set_user_info_24(const SAM_USER_INFO_24 * id24, uint32 rid) pwdb_init_sam(&new_pwd); copy_sam_passwd(&new_pwd, pwd); - if (!decode_pw_buffer(id24->pass, (char *)new_pw.buffer, 256, &len)) + if (!decode_pw_buffer(id24->pass, buf, 256, &len)) { return False; } @@ -1954,6 +1956,11 @@ static BOOL set_user_info_24(const SAM_USER_INFO_24 * id24, uint32 rid) new_pw.uni_max_len = len / 2; new_pw.uni_str_len = len / 2; + for (i = 0; i < new_pw.uni_str_len; i++) + { + new_pw.buffer[i] = SVAL(buf, i*2); + } + nt_lm_owf_genW(&new_pw, nt_hash, lm_hash); new_pwd.smb_passwd = lm_hash; @@ -1972,7 +1979,9 @@ static BOOL set_user_info_23(const SAM_USER_INFO_23 * id23, uint32 rid) static uchar nt_hash[16]; static uchar lm_hash[16]; UNISTR2 new_pw; + pstring buf; uint32 len; + int i; if (id23 == NULL) { @@ -1988,7 +1997,7 @@ static BOOL set_user_info_23(const SAM_USER_INFO_23 * id23, uint32 rid) copy_sam_passwd(&new_pwd, pwd); copy_id23_to_sam_passwd(&new_pwd, id23); - if (!decode_pw_buffer(id23->pass, (char *)new_pw.buffer, 256, &len)) + if (!decode_pw_buffer(id23->pass, buf, 256, &len)) { return False; } @@ -1996,6 +2005,11 @@ static BOOL set_user_info_23(const SAM_USER_INFO_23 * id23, uint32 rid) new_pw.uni_max_len = len / 2; new_pw.uni_str_len = len / 2; + for (i = 0; i < new_pw.uni_str_len; i++) + { + new_pw.buffer[i] = SVAL(buf, i*2); + } + nt_lm_owf_genW(&new_pw, nt_hash, lm_hash); new_pwd.smb_passwd = lm_hash; diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c index 6e50c3acb69..f2c7f29f312 100644 --- a/source/smbd/chgpasswd.c +++ b/source/smbd/chgpasswd.c @@ -57,405 +57,483 @@ extern int DEBUGLEVEL; static int findpty(char **slave) { - int master; + int master; #ifndef HAVE_GRANTPT - static fstring line; - DIR *dirp; - struct dirent *dentry; - char *dpname; + static fstring line; + DIR *dirp; + struct dirent *dentry; + char *dpname; #endif /* !HAVE_GRANTPT */ - + #if defined(HAVE_GRANTPT) - if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 1) { - grantpt(master); - unlockpt(master); - *slave = ptsname(master); - if (*slave == NULL) { - DEBUG(0,("findpty: Unable to create master/slave pty pair.\n")); - /* Stop fd leak on error. */ - close(master); - return -1; - } else { - DEBUG(10, ("findpty: Allocated slave pty %s\n", *slave)); - return (master); - } - } + if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 1) + { + grantpt(master); + unlockpt(master); + *slave = ptsname(master); + if (*slave == NULL) + { + DEBUG(0, + ("findpty: Unable to create master/slave pty pair.\n")); + /* Stop fd leak on error. */ + close(master); + return -1; + } + else + { + DEBUG(10, + ("findpty: Allocated slave pty %s\n", *slave)); + return (master); + } + } #else /* HAVE_GRANTPT */ - fstrcpy( line, "/dev/ptyXX" ); - - dirp = opendir("/dev"); - if (!dirp) - return(-1); - while ((dentry = readdir(dirp)) != NULL) { - dpname = dentry->d_name; - if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) { - DEBUG(3,("pty: try to open %s, line was %s\n", dpname, line ) ); - line[8] = dpname[3]; - line[9] = dpname[4]; - if ((master = sys_open(line, O_RDWR, 0)) >= 0) { - DEBUG(3,("pty: opened %s\n", line ) ); - line[5] = 't'; - *slave = line; - closedir(dirp); - return (master); - } - } - } - closedir(dirp); + fstrcpy(line, "/dev/ptyXX"); + + dirp = opendir("/dev"); + if (!dirp) + return (-1); + while ((dentry = readdir(dirp)) != NULL) + { + dpname = dentry->d_name; + if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) + { + DEBUG(3, + ("pty: try to open %s, line was %s\n", dpname, + line)); + line[8] = dpname[3]; + line[9] = dpname[4]; + if ((master = sys_open(line, O_RDWR, 0)) >= 0) + { + DEBUG(3, ("pty: opened %s\n", line)); + line[5] = 't'; + *slave = line; + closedir(dirp); + return (master); + } + } + } + closedir(dirp); #endif /* HAVE_GRANTPT */ - return (-1); + return (-1); } -static int dochild(int master,char *slavedev, const char *_name, char *passwordprogram, BOOL as_root) +static int dochild(int master, char *slavedev, const char *_name, + char *passwordprogram, BOOL as_root) { - int slave; - struct termios stermios; - const struct passwd *pass; - int gid; - int uid; + int slave; + struct termios stermios; + const struct passwd *pass; + int gid; + int uid; fstring name; fstrcpy(name, _name); - pass = Get_Pwnam(name,True); + pass = Get_Pwnam(name, True); - if (pass == NULL) { - DEBUG(0,("dochild: user name %s doesn't exist in the UNIX password database.\n", - name)); - return False; - } + if (pass == NULL) + { + DEBUG(0, + ("dochild: user name %s doesn't exist in the UNIX password database.\n", + name)); + return False; + } - gid = pass->pw_gid; - uid = pass->pw_uid; + gid = pass->pw_gid; + uid = pass->pw_uid; #ifdef HAVE_SETRESUID - setresuid(0,0,0); -#else - setuid(0); + setresuid(0, 0, 0); +#else + setuid(0); #endif - /* Start new session - gets rid of controlling terminal. */ - if (setsid() < 0) { - DEBUG(3,("Weirdness, couldn't let go of controlling terminal\n")); - return(False); - } - - /* Open slave pty and acquire as new controlling terminal. */ - if ((slave = sys_open(slavedev, O_RDWR, 0)) < 0) { - DEBUG(3,("More weirdness, could not open %s\n", - slavedev)); - return(False); - } + /* Start new session - gets rid of controlling terminal. */ + if (setsid() < 0) + { + DEBUG(3, + ("Weirdness, couldn't let go of controlling terminal\n")); + return (False); + } + + /* Open slave pty and acquire as new controlling terminal. */ + if ((slave = sys_open(slavedev, O_RDWR, 0)) < 0) + { + DEBUG(3, ("More weirdness, could not open %s\n", slavedev)); + return (False); + } #ifdef I_PUSH - ioctl(slave, I_PUSH, "ptem"); - ioctl(slave, I_PUSH, "ldterm"); + ioctl(slave, I_PUSH, "ptem"); + ioctl(slave, I_PUSH, "ldterm"); #elif defined(TIOCSCTTY) - if (ioctl(slave,TIOCSCTTY,0) <0) { - DEBUG(3,("Error in ioctl call for slave pty\n")); - /* return(False); */ - } -#endif - - /* Close master. */ - close(master); - - /* Make slave stdin/out/err of child. */ - - if (dup2(slave, STDIN_FILENO) != STDIN_FILENO) { - DEBUG(3,("Could not re-direct stdin\n")); - return(False); - } - if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO) { - DEBUG(3,("Could not re-direct stdout\n")); - return(False); - } - if (dup2(slave, STDERR_FILENO) != STDERR_FILENO) { - DEBUG(3,("Could not re-direct stderr\n")); - return(False); - } - if (slave > 2) close(slave); - - /* Set proper terminal attributes - no echo, canonical input processing, - no map NL to CR/NL on output. */ - - if (tcgetattr(0, &stermios) < 0) { - DEBUG(3,("could not read default terminal attributes on pty\n")); - return(False); - } - stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); - stermios.c_lflag |= ICANON; - stermios.c_oflag &= ~(ONLCR); - if (tcsetattr(0, TCSANOW, &stermios) < 0) { - DEBUG(3,("could not set attributes of pty\n")); - return(False); - } - - /* make us completely into the right uid */ - if (!as_root) { + if (ioctl(slave, TIOCSCTTY, 0) < 0) + { + DEBUG(3, ("Error in ioctl call for slave pty\n")); + /* return(False); */ + } +#endif + + /* Close master. */ + close(master); + + /* Make slave stdin/out/err of child. */ + + if (dup2(slave, STDIN_FILENO) != STDIN_FILENO) + { + DEBUG(3, ("Could not re-direct stdin\n")); + return (False); + } + if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO) + { + DEBUG(3, ("Could not re-direct stdout\n")); + return (False); + } + if (dup2(slave, STDERR_FILENO) != STDERR_FILENO) + { + DEBUG(3, ("Could not re-direct stderr\n")); + return (False); + } + if (slave > 2) + close(slave); + + /* Set proper terminal attributes - no echo, canonical input processing, + no map NL to CR/NL on output. */ + + if (tcgetattr(0, &stermios) < 0) + { + DEBUG(3, + ("could not read default terminal attributes on pty\n")); + return (False); + } + stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + stermios.c_lflag |= ICANON; + stermios.c_oflag &= ~(ONLCR); + if (tcsetattr(0, TCSANOW, &stermios) < 0) + { + DEBUG(3, ("could not set attributes of pty\n")); + return (False); + } + + /* make us completely into the right uid */ + if (!as_root) + { #ifdef HAVE_SETRESUID - setresgid(0,0,0); - setresuid(0,0,0); - setresgid(gid,gid,gid); - setresuid(uid,uid,uid); -#else - setuid(0); - seteuid(0); - setgid(gid); - setegid(gid); - setuid(uid); - seteuid(uid); + setresgid(0, 0, 0); + setresuid(0, 0, 0); + setresgid(gid, gid, gid); + setresuid(uid, uid, uid); +#else + setuid(0); + seteuid(0); + setgid(gid); + setegid(gid); + setuid(uid); + seteuid(uid); #endif - } + } - DEBUG(10, ("Invoking '%s' as password change program.\n", passwordprogram)); + DEBUG(10, + ("Invoking '%s' as password change program.\n", + passwordprogram)); - /* execl() password-change application */ - if (execl("/bin/sh","sh","-c",passwordprogram,NULL) < 0) { - DEBUG(3,("Bad status returned from %s\n",passwordprogram)); - return(False); - } - return(True); + /* execl() password-change application */ + if (execl("/bin/sh", "sh", "-c", passwordprogram, NULL) < 0) + { + DEBUG(3, ("Bad status returned from %s\n", passwordprogram)); + return (False); + } + return (True); } -static int expect(int master,char *expected,char *buf) +static int expect(int master, char *expected, char *buf) { - int n, m; - - n = 0; - buf[0] = 0; - while (1) { - if (n >= BUFSIZE-1) { - return False; - } - - /* allow 4 seconds for some output to appear */ - m = read_with_timeout(master, buf+n, 1, BUFSIZE-1-n, 4000); - if (m < 0) - return False; - - n += m; - buf[n] = 0; - - { - pstring s1,s2; - pstrcpy(s1,buf); - pstrcpy(s2,expected); - if (do_match(s1, s2, False)) - return(True); - } - } + int n, m; + + n = 0; + buf[0] = 0; + while (1) + { + if (n >= BUFSIZE - 1) + { + return False; + } + + /* allow 4 seconds for some output to appear */ + m = + read_with_timeout(master, buf + n, 1, BUFSIZE - 1 - n, + 4000); + if (m < 0) + return False; + + n += m; + buf[n] = 0; + + { + pstring s1, s2; + pstrcpy(s1, buf); + pstrcpy(s2, expected); + if (do_match(s1, s2, False)) + return (True); + } + } } static void pwd_sub(char *buf) { - string_sub(buf,"\\n","\n"); - string_sub(buf,"\\r","\r"); - string_sub(buf,"\\s"," "); - string_sub(buf,"\\t","\t"); + string_sub(buf, "\\n", "\n"); + string_sub(buf, "\\r", "\r"); + string_sub(buf, "\\s", " "); + string_sub(buf, "\\t", "\t"); } -static void writestring(int fd,char *s) +static void writestring(int fd, char *s) { - int l; - - l = strlen (s); - write (fd, s, l); + int l; + + l = strlen(s); + write(fd, s, l); } static int talktochild(int master, char *chatsequence) { - char buf[BUFSIZE]; - int count=0; - char *ptr=chatsequence; - fstring chatbuf; - - *buf = 0; - sleep(1); - - while (next_token(&ptr,chatbuf,NULL,sizeof(chatbuf))) { - BOOL ok=True; - count++; - pwd_sub(chatbuf); - if (!strequal(chatbuf,".")) - ok = expect(master,chatbuf,buf); + char buf[BUFSIZE]; + int count = 0; + char *ptr = chatsequence; + fstring chatbuf; - if (lp_passwd_chat_debug()) - DEBUG(100,("talktochild: chatbuf=[%s] responsebuf=[%s]\n",chatbuf,buf)); + *buf = 0; + sleep(1); - if (!ok) { - DEBUG(3,("response %d incorrect\n",count)); - return(False); - } + while (next_token(&ptr, chatbuf, NULL, sizeof(chatbuf))) + { + BOOL ok = True; + count++; + pwd_sub(chatbuf); + if (!strequal(chatbuf, ".")) + ok = expect(master, chatbuf, buf); + + if (lp_passwd_chat_debug()) + DEBUG(100, + ("talktochild: chatbuf=[%s] responsebuf=[%s]\n", + chatbuf, buf)); + + if (!ok) + { + DEBUG(3, ("response %d incorrect\n", count)); + return (False); + } - if (!next_token(&ptr,chatbuf,NULL,sizeof(chatbuf))) break; - pwd_sub(chatbuf); - if (!strequal(chatbuf,".")) - writestring(master,chatbuf); + if (!next_token(&ptr, chatbuf, NULL, sizeof(chatbuf))) + break; + pwd_sub(chatbuf); + if (!strequal(chatbuf, ".")) + writestring(master, chatbuf); - if (lp_passwd_chat_debug()) - DEBUG(100,("talktochild: sendbuf=[%s]\n",chatbuf)); - } + if (lp_passwd_chat_debug()) + DEBUG(100, ("talktochild: sendbuf=[%s]\n", chatbuf)); + } - if (count<1) return(False); + if (count < 1) + return (False); - return (True); + return (True); } -static BOOL chat_with_program(char *passwordprogram,const char *name,char *chatsequence, BOOL as_root) +static BOOL chat_with_program(char *passwordprogram, const char *name, + char *chatsequence, BOOL as_root) { - char *slavedev; - int master; - pid_t pid, wpid; - int wstat; - BOOL chstat = False; - - /* allocate a pseudo-terminal device */ - if ((master = findpty (&slavedev)) < 0) { - DEBUG(3,("Cannot Allocate pty for password change: %s\n",name)); - return(False); - } - - if ((pid = fork()) < 0) { - DEBUG(3,("Cannot fork() child for password change: %s\n",name)); - close(master); - 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",name)); - kill(pid, SIGKILL); /* be sure to end this process */ - } - - if ((wpid = sys_waitpid(pid, &wstat, 0)) < 0) { - DEBUG(3,("The process is no longer waiting!\n\n")); - close(master); - return(False); - } - - close(master); - - 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")); - return(False); - } - if (WEXITSTATUS(wstat) != 0) { - DEBUG(3,("The status of the process exiting was %d\n", wstat)); - return(False); - } - - } else { - /* CHILD */ - - /* - * Lose any oplock capabilities. - */ - set_process_capability(KERNEL_OPLOCK_CAPABILITY, False); - set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY, False); - - /* make sure it doesn't freeze */ - alarm(20); - - if (as_root) - become_root(False); - DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,(int)getuid(),(int)getgid())); - chstat = dochild(master, slavedev, name, passwordprogram, as_root); - - if (as_root) - unbecome_root(False); - } - - if (chstat) - DEBUG(3,("Password change %ssuccessful for user %s\n", (chstat?"":"un"), name)); - return (chstat); + char *slavedev; + int master; + pid_t pid, wpid; + int wstat; + BOOL chstat = False; + + /* allocate a pseudo-terminal device */ + if ((master = findpty(&slavedev)) < 0) + { + DEBUG(3, + ("Cannot Allocate pty for password change: %s\n", + name)); + return (False); + } + + if ((pid = fork()) < 0) + { + DEBUG(3, + ("Cannot fork() child for password change: %s\n", + name)); + close(master); + 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", + name)); + kill(pid, SIGKILL); /* be sure to end this process */ + } + + if ((wpid = sys_waitpid(pid, &wstat, 0)) < 0) + { + DEBUG(3, ("The process is no longer waiting!\n\n")); + close(master); + return (False); + } + + close(master); + + 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")); + return (False); + } + if (WEXITSTATUS(wstat) != 0) + { + DEBUG(3, + ("The status of the process exiting was %d\n", + wstat)); + return (False); + } + + } + else + { + /* CHILD */ + + /* + * Lose any oplock capabilities. + */ + set_process_capability(KERNEL_OPLOCK_CAPABILITY, False); + set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY, + False); + + /* make sure it doesn't freeze */ + alarm(20); + + if (as_root) + become_root(False); + DEBUG(3, + ("Dochild for user %s (uid=%d,gid=%d)\n", name, + (int)getuid(), (int)getgid())); + chstat = + dochild(master, slavedev, name, passwordprogram, + as_root); + + if (as_root) + unbecome_root(False); + } + + if (chstat) + DEBUG(3, + ("Password change %ssuccessful for user %s\n", + (chstat ? "" : "un"), name)); + return (chstat); } -BOOL chgpasswd(const char *_name,char *oldpass,char *newpass, BOOL as_root) +BOOL chgpasswd(const char *_name, char *oldpass, char *newpass, BOOL as_root) { - pstring passwordprogram; - pstring chatsequence; - int i; - int len; + pstring passwordprogram; + pstring chatsequence; + int i; + int len; fstring name; fstrcpy(name, _name); - strlower(name); - DEBUG(3,("Password change for user: %s\n",name)); + strlower(name); + DEBUG(3, ("Password change for user: %s\n", name)); #if DEBUG_PASSWORD - DEBUG(100,("Passwords: old=%s new=%s\n",oldpass,newpass)); + DEBUG(100, ("Passwords: old=%s new=%s\n", oldpass, newpass)); #endif - /* Take the passed information and test it for minimum criteria */ - /* Minimum password length */ - if (strlen(newpass) < MINPASSWDLENGTH) /* too short, must be at least MINPASSWDLENGTH */ - { - DEBUG(2,("Password Change: %s, New password is shorter than MINPASSWDLENGTH\n",name)); - return (False); /* inform the user */ - } - - /* Password is same as old password */ - if (strcmp(oldpass,newpass) == 0) /* don't allow same password */ - { - DEBUG(2,("Password Change: %s, New password is same as old\n",name)); /* log the attempt */ - return (False); /* inform the user */ - } - - pstrcpy(passwordprogram,lp_passwd_program()); - pstrcpy(chatsequence,lp_passwd_chat()); - - if (!*chatsequence) { - DEBUG(2,("Null chat sequence - no password changing\n")); - return(False); - } - - if (!*passwordprogram) { - DEBUG(2,("Null password program - no password changing\n")); - return(False); - } - - /* - * Check the old and new passwords don't contain any control - * characters. - */ + /* Take the passed information and test it for minimum criteria */ + /* Minimum password length */ + if (strlen(newpass) < MINPASSWDLENGTH) /* too short, must be at least MINPASSWDLENGTH */ + { + DEBUG(2, + ("Password Change: %s, New password is shorter than MINPASSWDLENGTH\n", + name)); + return (False); /* inform the user */ + } + + /* Password is same as old password */ + if (strcmp(oldpass, newpass) == 0) /* don't allow same password */ + { + DEBUG(2, + ("Password Change: %s, New password is same as old\n", name)); /* log the attempt */ + return (False); /* inform the user */ + } + + pstrcpy(passwordprogram, lp_passwd_program()); + pstrcpy(chatsequence, lp_passwd_chat()); + + if (!*chatsequence) + { + DEBUG(2, ("Null chat sequence - no password changing\n")); + return (False); + } - 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")); - return False; - } - } - - 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")); - return False; - } - } - - string_sub(passwordprogram,"%u",name); - all_string_sub(passwordprogram,"%o",oldpass, 0); - all_string_sub(passwordprogram,"%n",newpass, 0); - - string_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,name,chatsequence, as_root)); + if (!*passwordprogram) + { + DEBUG(2, ("Null password program - no password changing\n")); + return (False); + } + + /* + * Check the old and new passwords don't contain any control + * characters. + */ + + 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")); + return False; + } + } + + 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")); + return False; + } + } + + string_sub(passwordprogram, "%u", name); + all_string_sub(passwordprogram, "%o", oldpass, 0); + all_string_sub(passwordprogram, "%n", newpass, 0); + + string_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, name, chatsequence, as_root)); } #else /* ALLOW_CHANGE_PASSWORD */ -BOOL chgpasswd(const char *name,char *oldpass,char *newpass, BOOL as_root) +BOOL chgpasswd(const char *name, char *oldpass, char *newpass, BOOL as_root) { - DEBUG(0,("Password changing not compiled in (user=%s)\n",name)); - return(False); + DEBUG(0, ("Password changing not compiled in (user=%s)\n", name)); + return (False); } #endif /* ALLOW_CHANGE_PASSWORD */ @@ -467,9 +545,10 @@ BOOL chgpasswd(const char *name,char *oldpass,char *newpass, BOOL as_root) ************************************************************/ static BOOL check_oem_password(const char *user, - const uchar *_lmdata, const uchar *lmhash, - const uchar *_ntdata, const uchar *nthash, - struct smb_passwd **psmbpw, UNISTR2 *new_passwd) + const uchar * _lmdata, const uchar * lmhash, + const uchar * _ntdata, const uchar * nthash, + struct smb_passwd **psmbpw, + UNISTR2 * new_passwd) { static uchar null_pw[16]; static uchar null_ntpw[16]; @@ -482,6 +561,7 @@ static BOOL check_oem_password(const char *user, uint32 len; uchar lmdata[516]; uchar ntdata[516]; + pstring buf; BOOL nt_pass_set = (_ntdata != NULL && nthash != NULL); @@ -501,13 +581,15 @@ static BOOL check_oem_password(const char *user, if (smbpw == NULL) { - DEBUG(0,("check_oem_password: getsmbpwnam returned NULL\n")); + DEBUG(0, ("check_oem_password: getsmbpwnam returned NULL\n")); return False; } if (IS_BITS_SET_ALL(smbpw->acct_ctrl, ACB_DISABLED)) { - DEBUG(0,("check_lanman_password: account %s disabled.\n", user)); + DEBUG(0, + ("check_lanman_password: account %s disabled.\n", + user)); return False; } @@ -523,9 +605,10 @@ static BOOL check_oem_password(const char *user, { smbpw->smb_passwd = null_pw; } - else + else { - DEBUG(0,("check_oem_password: no lanman password !\n")); + DEBUG(0, + ("check_oem_password: no lanman password !\n")); return False; } } @@ -536,9 +619,10 @@ static BOOL check_oem_password(const char *user, { smbpw->smb_nt_passwd = null_pw; } - else + else { - DEBUG(0,("check_oem_password: no ntlm password !\n")); + DEBUG(0, + ("check_oem_password: no ntlm password !\n")); return False; } } @@ -546,9 +630,9 @@ static BOOL check_oem_password(const char *user, /* * Call the hash function to get the new password. */ - SamOEMhash( (uchar *)lmdata, (uchar *)smbpw->smb_passwd, True); + SamOEMhash((uchar *) lmdata, (uchar *) smbpw->smb_passwd, True); - if (!decode_pw_buffer(lmdata, (char*)new_passwd->buffer, 256, &len)) + if (!decode_pw_buffer(lmdata, buf, 256, &len)) { return False; } @@ -560,31 +644,42 @@ static BOOL check_oem_password(const char *user, if (!nt_pass_set) { - DEBUG(10,("check_oem_password: non-unicode\n")); - nt_lm_owf_gen((char*)new_passwd->buffer, new_ntp16, new_p16); + DEBUG(10, ("check_oem_password: non-unicode\n")); + nt_lm_owf_gen(buf, new_ntp16, new_p16); + + make_unistr2(new_passwd, buf, strlen(buf) + 1); /* * Now use new_p16 as the key to see if the old * password matches. */ - D_P16(new_p16 , lmhash, unenc_old_pw); + D_P16(new_p16, lmhash, unenc_old_pw); if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16)) { - DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); + DEBUG(0, + ("check_oem_password: old lm password doesn't match.\n")); return False; } #ifdef DEBUG_PASSWORD - DEBUG(100,("check_oem_password: password %s ok\n", - (char*)new_passwd->buffer)); + DEBUG(100, ("check_oem_password: password %s ok\n", + (char *)new_passwd->buffer)); #endif return True; } else { + int i; + new_passwd->uni_max_len = len / 2; new_passwd->uni_str_len = len / 2; + + for (i = 0; i < new_passwd->uni_str_len; i++) + { + new_passwd->buffer[i] = SVAL(buf, i * 2); + } + nt_lm_owf_genW(new_passwd, new_ntp16, new_p16); } @@ -603,17 +698,19 @@ static BOOL check_oem_password(const char *user, #endif if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16)) { - DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); + DEBUG(0, + ("check_oem_password: old lm password doesn't match.\n")); return False; } if (memcmp(smbpw->smb_nt_passwd, unenc_old_ntpw, 16)) { - DEBUG(0,("check_oem_password: old nt password doesn't match.\n")); + DEBUG(0, + ("check_oem_password: old nt password doesn't match.\n")); return False; } #ifdef DEBUG_PASSWORD - DEBUG(100,("check_oem_password: password ok\n")); + DEBUG(100, ("check_oem_password: password ok\n")); #endif return True; } @@ -622,34 +719,35 @@ static BOOL check_oem_password(const char *user, Code to check and change the OEM hashed password. ************************************************************/ BOOL pass_oem_change(const char *user, - const uchar *lmdata, const uchar *lmhash, - const uchar *ntdata, const uchar *nthash) + const uchar * lmdata, const uchar * lmhash, + const uchar * ntdata, const uchar * nthash) { UNISTR2 new_passwd; struct smb_passwd *sampw = NULL; - BOOL ret = check_oem_password( user, lmdata, lmhash, ntdata, nthash, - &sampw, - &new_passwd); + BOOL ret = check_oem_password(user, lmdata, lmhash, ntdata, nthash, + &sampw, + &new_passwd); /* now we check to see if we are actually allowed to change the password. */ - + if (ret && (sampw == NULL || - IS_BITS_SET_ALL(sampw->acct_ctrl,ACB_PWLOCK))) + IS_BITS_SET_ALL(sampw->acct_ctrl, ACB_PWLOCK))) { if (sampw == NULL) { - DEBUG(3,("pass_oem_change: account %s not known\n", - user)); + DEBUG(3, ("pass_oem_change: account %s not known\n", + user)); } else { - DEBUG(3,("pass_oem_change: account %s disabled (%x)\n", - user, sampw->acct_ctrl)); + DEBUG(3, + ("pass_oem_change: account %s disabled (%x)\n", + user, sampw->acct_ctrl)); } ret = False; } - + /* * At this point we have the new case-sensitive plaintext * password in the fstring new_passwd. If we wanted to synchronise @@ -659,15 +757,15 @@ BOOL pass_oem_change(const char *user, * available. JRA. */ - if ( ret && lp_unix_password_sync()) + if (ret && lp_unix_password_sync()) { - ret = chgpasswd(user,"", (char*)new_passwd.buffer, True); + ret = chgpasswd(user, "", (char *)new_passwd.buffer, True); } if (ret) { - ret = change_oem_password( sampw, &new_passwd, - ntdata != NULL, False ); + ret = change_oem_password(sampw, &new_passwd, + ntdata != NULL, False); } ZERO_STRUCT(new_passwd); @@ -682,14 +780,14 @@ BOOL pass_oem_change(const char *user, override = True, override XXXXXXXXXX'd password ************************************************************/ -BOOL change_oem_password(struct smb_passwd *smbpw, UNISTR2 *new_passwd, - BOOL unicode, BOOL override) +BOOL change_oem_password(struct smb_passwd *smbpw, UNISTR2 * new_passwd, + BOOL unicode, BOOL override) { int ret; uchar new_nt_p16[16]; uchar new_p16[16]; - DEBUG(100,("change_oem_password: %d\n", __LINE__)); + DEBUG(100, ("change_oem_password: %d\n", __LINE__)); if (unicode) { @@ -697,21 +795,22 @@ BOOL change_oem_password(struct smb_passwd *smbpw, UNISTR2 *new_passwd, } else { - nt_lm_owf_gen((char*)new_passwd->buffer, new_nt_p16, new_p16); + nt_lm_owf_gen((char *)new_passwd->buffer, new_nt_p16, + new_p16); } - DEBUG(100,("change_oem_password: %d\n", __LINE__)); + DEBUG(100, ("change_oem_password: %d\n", __LINE__)); dbgflush(); smbpw->smb_passwd = new_p16; smbpw->smb_nt_passwd = new_nt_p16; - DEBUG(100,("change_oem_password: %d\n", __LINE__)); + DEBUG(100, ("change_oem_password: %d\n", __LINE__)); dbgflush(); /* Now write it into the file. */ become_root(0); - ret = mod_smbpwd_entry(smbpw,override); + ret = mod_smbpwd_entry(smbpw, override); unbecome_root(0); ZERO_STRUCTP(new_passwd); @@ -727,25 +826,26 @@ BOOL update_smbpassword_file(const char *user, const char *password) struct smb_passwd *smbpw; UNISTR2 newpw; BOOL ret; - + become_root(0); smbpw = getsmbpwnam(user); unbecome_root(0); - if(smbpw == NULL) + if (smbpw == NULL) { - DEBUG(0,("getsmbpwnam returned NULL\n")); + DEBUG(0, ("getsmbpwnam returned NULL\n")); return False; } - - make_unistr2(&newpw, password, password != NULL ? strlen(password) : 0); + + make_unistr2(&newpw, password, + password != NULL ? strlen(password) : 0); /* Here, the flag is one, because we want to ignore the - XXXXXXX'd out password */ - ret = change_oem_password( smbpw, &newpw, True, True); + XXXXXXX'd out password */ + ret = change_oem_password(smbpw, &newpw, True, True); if (!ret) { - DEBUG(3,("change_oem_password returned False\n")); + DEBUG(3, ("change_oem_password returned False\n")); } ZERO_STRUCT(newpw); |