aboutsummaryrefslogtreecommitdiff
path: root/patches-applied/049_pam_unix_sane_locking
blob: 76d2a3bff0cc6b1805b970199256f04f3516e3f3 (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
Delta from 1.12 to 1.13 from Linux-PAM pam_unix_passwd.c
made to work with our changes.


Index: Linux-PAM/modules/pam_unix/pam_unix_passwd.c
===================================================================
RCS file: /afs/sipb/project/debian/cvs/pam/Linux-PAM/modules/pam_unix/pam_unix_passwd.c,v
retrieving revision 1.10
diff -u -r1.10 pam_unix_passwd.c
--- Linux-PAM/modules/pam_unix/pam_unix_passwd.c	12 Jan 2004 06:43:14 -0000	1.10
+++ Linux-PAM/modules/pam_unix/pam_unix_passwd.c	12 Jan 2004 06:44:03 -0000
@@ -88,7 +88,7 @@
  */
 
 #ifdef NEED_LCKPWDF
-#include "./lckpwdf.-c"
+# include "./lckpwdf.-c"
 #endif
 
 extern char *bigcrypt(const char *key, const char *salt);
@@ -494,10 +494,7 @@
 
 	D(("called"));
 
-	setpwent();
 	pwd = getpwnam(forwho);
-	endpwent();
-
 	if (pwd == NULL)
 		return PAM_AUTHTOK_ERR;
 
@@ -569,6 +566,24 @@
 	if (save_old_password(forwho, fromwhat, remember)) {
 		return PAM_AUTHTOK_ERR;
 	}
+
+#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.
+	 */
+
+	retval = lckpwdf();
+	if (retval != 0) {
+	    return PAM_AUTHTOK_LOCK_BUSY;
+	}
+#endif /* def USE_LCKPWDF */
+	
 	if (on(UNIX_SHADOW, ctrl) || (strcmp(pwd->pw_passwd, "x") == 0)) {
 		retval = _update_shadow(forwho, towhat);
 		if (retval == PAM_SUCCESS)
@@ -580,6 +595,10 @@
 	if (retval == PAM_SUCCESS)
 	    _log_err(LOG_NOTICE, pamh, "Password for %s was changed", forwho);
 
+#ifdef USE_LCKPWDF
+	ulckpwdf();
+#endif /* def USE_LCKPWDF */
+
 	return retval;
 }
 
@@ -708,7 +727,7 @@
 				int argc, const char **argv)
 {
 	unsigned int ctrl, lctrl;
-	int retval, i;
+	int retval;
 	int remember = -1;
 
 	/* <DO NOT free() THESE> */
@@ -718,33 +737,12 @@
 
 	D(("called."));
 
-#ifdef USE_LCKPWDF
-	/* our current locking system requires that we lock the
-	   entire password database.  This avoids both livelock
-	   and deadlock. */
-	/* 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.
-	   The other possibility is to call lckpwdf() on the first
-	   pam_chauthtok() pass, and hold the lock until released in the
-	   second pass--but is this guaranteed to work? -SRL */
-	i=0;
-	while((retval = lckpwdf()) != 0 && i < 100) {
-		usleep(1000);
-	}
-	if(retval != 0) {
-		return PAM_AUTHTOK_LOCK_BUSY;
-	}
-#endif
 	ctrl = _set_ctrl(pamh, flags, &remember, argc, argv);
 
 	/*
 	 * First get the name of a user
 	 */
-	retval = pam_get_user(pamh, &user, "Username: ");
+	retval = pam_get_user(pamh, &user, NULL);
 	if (retval == PAM_SUCCESS) {
 		/*
 		 * Various libraries at various times have had bugs related to
@@ -754,9 +752,6 @@
 		 */
 		if (user == NULL || !isalnum(*user)) {
 			_log_err(LOG_ERR, pamh, "bad username [%s]", user);
-#ifdef USE_LCKPWDF
-			ulckpwdf();
-#endif
 			return PAM_USER_UNKNOWN;
 		}
 		if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
@@ -766,9 +761,6 @@
 		if (on(UNIX_DEBUG, ctrl))
 			_log_err(LOG_DEBUG, pamh,
 			         "password - could not identify user");
-#ifdef USE_LCKPWDF
-		ulckpwdf();
-#endif
 		return retval;
 	}
 
@@ -790,9 +782,6 @@
 		D(("prelim check"));
 
 		if (_unix_blankpasswd(ctrl, user)) {
-#ifdef USE_LCKPWDF
-			ulckpwdf();
-#endif
 			return PAM_SUCCESS;
 		} else if (off(UNIX__IAMROOT, ctrl) || on(UNIX_NIS, ctrl)) {
 
@@ -802,9 +791,6 @@
 			if (Announce == NULL) {
 				_log_err(LOG_CRIT, pamh,
 				         "password - out of memory");
-#ifdef USE_LCKPWDF
-				ulckpwdf();
-#endif
 				return PAM_BUF_ERR;
 			}
 			(void) strcpy(Announce, greeting);
@@ -826,9 +812,6 @@
 			if (retval != PAM_SUCCESS) {
 				_log_err(LOG_NOTICE, pamh
 				 ,"password - (old) token not obtained");
-#ifdef USE_LCKPWDF
-				ulckpwdf();
-#endif
 				return retval;
 			}
 			/* verify that this is the password for this user
@@ -846,9 +829,6 @@
 		if (retval != PAM_SUCCESS) {
 			D(("Authentication failed"));
 			pass_old = NULL;
-#ifdef USE_LCKPWDF
-			ulckpwdf();
-#endif
 			return retval;
 		}
 		retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
@@ -901,17 +881,11 @@
 
 		if (retval != PAM_SUCCESS) {
 			_log_err(LOG_NOTICE, pamh, "user not authenticated");
-#ifdef USE_LCKPWDF
-			ulckpwdf();
-#endif
 			return retval;
 		}
 		retval = _unix_verify_shadow(user, ctrl);
 		if (retval != PAM_SUCCESS) {
 			_log_err(LOG_NOTICE, pamh, "user not authenticated 2");
-#ifdef USE_LCKPWDF
-			ulckpwdf();
-#endif
 			return retval;
 		}
 		D(("get new password now"));
@@ -942,9 +916,6 @@
 						 ,"password - new password not obtained");
 				}
 				pass_old = NULL;	/* tidy up */
-#ifdef USE_LCKPWDF
-				ulckpwdf();
-#endif
 				return retval;
 			}
 			D(("returned to _unix_chauthtok"));
@@ -965,9 +936,6 @@
 			_log_err(LOG_NOTICE, pamh,
 			         "new password not acceptable");
 			pass_new = pass_old = NULL;	/* tidy up */
-#ifdef USE_LCKPWDF
-			ulckpwdf();
-#endif
 			return retval;
 		}
 		/*
@@ -1008,9 +976,6 @@
 					_log_err(LOG_CRIT, pamh,
 					         "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 */
@@ -1032,6 +997,7 @@
 
 		retval = _do_setpass(pamh, user, pass_old, tpass, ctrl,
 		                     remember);
+
 		_pam_delete(tpass);
 		pass_old = pass_new = NULL;
 	} else {		/* something has broken with the module */
@@ -1042,9 +1008,6 @@
 
 	D(("retval was %d", retval));
 
-#ifdef USE_LCKPWDF
-	ulckpwdf();
-#endif
 	return retval;
 }