summaryrefslogtreecommitdiffstats
path: root/patches/source/yptools/yp-tools-2.14-glibc217-crypt.diff
blob: 148b066322d392fe2a0dd8dd12f1626182d9810b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
Starting with glibc 2.17 (eglibc 2.17), crypt() fails with EINVAL
(w/ NULL return) if the salt violates specifications. Additionally,
on FIPS-140 enabled Linux systems, DES/MD5-encrypted passwords
passed to crypt() fail with EPERM (w/ NULL return).

If using glibc's crypt(), check return value to avoid a possible
NULL pointer dereference.

Author: mancha

====

--- yp-tools-2.14/src/yppasswd.c.orig	2010-04-21
+++ yp-tools-2.14/src/yppasswd.c	2013-05-22
@@ -423,6 +423,7 @@ static int /* return values: 0 = not ok,
 verifypassword (struct passwd *pwd, char *pwdstr, uid_t uid)
 {
   char *p, *q;
+  char *crypted_pass;
   int ucase, lcase, other, r;
   int passwdlen;
 
@@ -448,12 +449,19 @@ verifypassword (struct passwd *pwd, char
     }
 
   passwdlen = get_passwd_len (pwd->pw_passwd);
-  if (pwd->pw_passwd[0]
-      && !strncmp (pwd->pw_passwd, crypt (pwdstr, pwd->pw_passwd), passwdlen)
-      && uid)
+  if (pwd->pw_passwd[0] && uid)
     {
-      fputs (_("You cannot reuse the old password.\n"), stderr);
-      return 0;
+      crypted_pass = crypt (pwdstr, pwd->pw_passwd);
+      if (crypted_pass == NULL)
+        {
+          fputs (_("crypt() call failed.\n"), stderr);
+          return 0;
+        }
+      if (!strncmp (pwd->pw_passwd, crypted_pass, passwdlen))
+        {
+          fputs (_("You cannot reuse the old password.\n"), stderr);
+          return 0;
+        }
     }
 
   r = 0;
@@ -517,6 +525,7 @@ int
 main (int argc, char **argv)
 {
   char *s, *progname, *domainname = NULL, *user = NULL, *master = NULL;
+  char *crypted_pass;
   int f_flag = 0, l_flag = 0, p_flag = 0, error, status;
   int hash_id = DES;
   char rounds[11] = "\0"; /* max length is '999999999$' */
@@ -738,7 +747,13 @@ main (int argc, char **argv)
 	  char *sane_passwd = alloca (passwdlen + 1);
 	  strncpy (sane_passwd, pwd->pw_passwd, passwdlen);
 	  sane_passwd[passwdlen] = 0;
-	  if (strcmp (crypt (s, sane_passwd), sane_passwd))
+	  crypted_pass = crypt (s, sane_passwd);
+	  if (crypted_pass == NULL)
+	    {
+	      fprintf (stderr, _("crypt() call failed.\n"));
+	      return 1;
+	    }
+	  if (strcmp (crypted_pass, sane_passwd))
 	    {
 	      fprintf (stderr, _("Sorry.\n"));
 	      return 1;
@@ -833,7 +848,14 @@ main (int argc, char **argv)
 	  break;
 	}
 
-      yppwd.newpw.pw_passwd = strdup (crypt (buf, salt));
+      crypted_pass = crypt (buf, salt);
+      if (crypted_pass == NULL)
+        {
+	  printf (_("crypt() call failed - password unchanged.\n"));
+	  return 1;
+        }
+
+      yppwd.newpw.pw_passwd = strdup (crypted_pass);
     }
 
   if (f_flag)