summaryrefslogtreecommitdiff
path: root/debian/patches-applied/049_pam_unix_sane_locking
blob: 3baced2fb67809f74b8587aa7ee7be77a00d0cdc (plain)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
Delta from 1.12 to 1.13 from Linux-PAM pam_unix_passwd.c
made to work with our changes.  Not sure this is actually relevant, as
other changes seem to have been made upstream.  This patch was
specifically reverted in upstream CVS revision 1.18 as introducing a
"race".

Index: Linux-PAM/modules/pam_unix/pam_unix_passwd.c
===================================================================
--- Linux-PAM/modules/pam_unix/pam_unix_passwd.c.orig
+++ Linux-PAM/modules/pam_unix/pam_unix_passwd.c
@@ -749,8 +749,7 @@
 		       char *towhat, unsigned int ctrl, int remember)
 {
 	struct passwd *pwd = NULL;
-	int retval = 0;
-	int unlocked = 0;
+	int retval = 0, i = 0;
 	char *master = NULL;
 
 	D(("called"));
@@ -770,12 +769,6 @@
 		int status;
 		enum clnt_stat err;
 
-		/* Unlock passwd file to avoid deadlock */
-#ifdef USE_LCKPWDF
-		ulckpwdf();
-#endif
-		unlocked = 1;
-
 		/* Initialize password information */
 		yppwd.newpw.pw_passwd = pwd->pw_passwd;
 		yppwd.newpw.pw_name = pwd->pw_name;
@@ -833,29 +826,28 @@
 	}
 
 	if (_unix_comesfromsource(pamh, forwho, 1, 0)) {
-#ifdef USE_LCKPWDF
-		if(unlocked) {
-			int i = 0;
-			/* These values for the number of attempts and the sleep time
-			   are, of course, completely arbitrary.
-			   My reading of the PAM docs is that, once pam_chauthtok() has been
-			   called with PAM_UPDATE_AUTHTOK, we are obliged to take any
-			   reasonable steps to make sure the token is updated; so retrying
-			   for 1/10 sec. isn't overdoing it. */
-			while((retval = lckpwdf()) != 0 && i < 100) {
-				usleep(1000);
-				i++;
-			}
-			if(retval != 0) {
-				return PAM_AUTHTOK_LOCK_BUSY;
-			}
-		}
-#endif
 		/* first, save old password */
 		if (save_old_password(pamh, forwho, fromwhat, remember)) {
 			retval = PAM_AUTHTOK_ERR;
 			goto done;
 		}
+
+#ifdef USE_LCKPWDF
+		/* These values for the number of attempts and the sleep time
+		   are, of course, completely arbitrary.
+		   My reading of the PAM docs is that, once pam_chauthtok() has been
+		   called with PAM_UPDATE_AUTHTOK, we are obliged to take any
+		   reasonable steps to make sure the token is updated; so retrying
+		   for 1/10 sec. isn't overdoing it. */
+		while((retval = lckpwdf()) != 0 && i < 100) {
+			usleep(1000);
+			i++;
+		}
+		if(retval != 0) {
+			retval = PAM_AUTHTOK_LOCK_BUSY;
+			goto done;
+		}
+#endif
 		if (on(UNIX_SHADOW, ctrl) || _unix_shadowed(pwd)) {
 			retval = _update_shadow(pamh, forwho, towhat);
 #ifdef WITH_SELINUX
@@ -1024,7 +1016,7 @@
 				int argc, const char **argv)
 {
 	unsigned int ctrl, lctrl;
-	int retval, i;
+	int retval;
 	int remember = -1;
 
 	/* <DO NOT free() THESE> */
@@ -1255,30 +1247,11 @@
 			pass_new = pass_old = NULL;	/* tidy up */
 			return retval;
 		}
-#ifdef USE_LCKPWDF
-		/* These values for the number of attempts and the sleep time
-		   are, of course, completely arbitrary.
-		   My reading of the PAM docs is that, once pam_chauthtok() has been
-		   called with PAM_UPDATE_AUTHTOK, we are obliged to take any
-		   reasonable steps to make sure the token is updated; so retrying
-		   for 1/10 sec. isn't overdoing it. */
-		i=0;
-		while((retval = lckpwdf()) != 0 && i < 100) {
-			usleep(1000);
-			i++;
-		}
-		if(retval != 0) {
-			return PAM_AUTHTOK_LOCK_BUSY;
-		}
-#endif
 
 		if (pass_old) {
 			retval = _unix_verify_password(pamh, user, pass_old, ctrl);
 			if (retval != PAM_SUCCESS) {
 				pam_syslog(pamh, LOG_NOTICE, "user password changed by another process");
-#ifdef USE_LCKPWDF
-				ulckpwdf();
-#endif
 				return retval;
 			}
 		}
@@ -1286,9 +1259,6 @@
 		retval = _unix_verify_shadow(pamh, user, ctrl);
 		if (retval != PAM_SUCCESS) {
 			pam_syslog(pamh, LOG_NOTICE, "user not authenticated 2");
-#ifdef USE_LCKPWDF
-			ulckpwdf();
-#endif
 			return retval;
 		}
 
@@ -1297,9 +1267,6 @@
 			pam_syslog(pamh, LOG_NOTICE,
 			         "new password not acceptable 2");
 			pass_new = pass_old = NULL;	/* tidy up */
-#ifdef USE_LCKPWDF
-			ulckpwdf();
-#endif
 			return retval;
 		}
 
@@ -1341,9 +1308,6 @@
 					pam_syslog(pamh, LOG_CRIT,
 					         "out of memory for password");
 					pass_new = pass_old = NULL;	/* tidy up */
-#ifdef USE_LCKPWDF
-					ulckpwdf();
-#endif
 					return PAM_BUF_ERR;
 				}
 				/* copy first 8 bytes of password */