--- yp-tools-2.8/src/yppasswd.c.orig 2002-12-05 08:49:20.000000000 -0500 +++ yp-tools-2.8/src/yppasswd.c 2003-04-23 14:58:13.000000000 -0400 @@ -49,6 +49,8 @@ #include #include #include +#include +#include #include #include #include @@ -436,11 +438,44 @@ verifypassword (struct passwd *pwd, char #endif +#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') + +static void +create_random_salt (char *salt, int num_chars) +{ + int fd; + unsigned char c; + int i; + int res; + + fd = open("/dev/urandom", O_RDONLY); + + for (i = 0; i < num_chars; i++) + { + res = 0; + + if (fd != 0) + res = read (fd, &c, 1); + + if (res != 1) + c = random(); + + salt[i] = bin_to_ascii(c & 0x3f); + } + + salt[num_chars] = 0; + + if (fd != 0) + close (fd); +} + + int main (int argc, char **argv) { char *s, *progname, *domainname = NULL, *user = NULL, *master = NULL; int f_flag = 0, l_flag = 0, p_flag = 0, error, status; + int has_md5_passwd = 0; struct yppasswd yppwd; struct passwd *pwd; CLIENT *clnt; @@ -451,6 +486,8 @@ main (int argc, char **argv) bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + srandom (time (NULL)); + if ((s = strrchr (argv[0], '/')) != NULL) progname = s + 1; else @@ -642,6 +679,9 @@ main (int argc, char **argv) cp = stpcpy (hashpass, "##"); strcpy (cp, pwd->pw_name); + if (strncmp(pwd->pw_passwd, "$1$", 3) == 0) + has_md5_passwd = 1; + /* We can't check the password with shadow passwords enabled. We * leave the checking to yppasswdd */ if (uid != 0 && strcmp (pwd->pw_passwd, "x") != 0 && @@ -676,13 +716,11 @@ main (int argc, char **argv) if (p_flag) { -#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') #ifdef USE_CRACKLIB char *error_msg; #endif /* USE_CRACKLIB */ - char *buf, salt[2], *p = NULL; + char *buf, salt[12], *p = NULL; int tries = 0; - time_t tm; buf = (char *) malloc (129); @@ -733,9 +771,15 @@ main (int argc, char **argv) } } - time (&tm); - salt[0] = bin_to_ascii (tm & 0x3f); - salt[1] = bin_to_ascii ((tm >> 6) & 0x3f); + if (!has_md5_passwd) + create_random_salt (salt, 2); + else + { + /* The user already had a MD5 password, so it's safe to + * use a MD5 password again */ + strcpy (salt, "$1$"); + create_random_salt (salt+3, 8); + } yppwd.newpw.pw_passwd = strdup (crypt (buf, salt)); }