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 */
|