Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 145839 | Differences between
and this patch

Collapse All | Expand All

(-)poppassd-1.8.5/poppassd.c (-37 / +61 lines)
Lines 10-15 Link Here
10
 * Shadow file update code taken from shadow-960810 by John F. Haugh
10
 * Shadow file update code taken from shadow-960810 by John F. Haugh
11
 * II <jfh@rpp386.cactus.org> and Marek Michalkiewicz
11
 * II <jfh@rpp386.cactus.org> and Marek Michalkiewicz
12
 * <marekm@i17linuxb.ists.pwr.wroc.pl>
12
 * <marekm@i17linuxb.ists.pwr.wroc.pl>
13
 * 
14
 * Now getstate() takes care of PAM message interpretation, better handling
15
 * of PAM LDAP and Cracklib modules by Jinesh K J <jinesh_kj@rediffmail.com>
13
 *
16
 *
14
 * See README for more information.
17
 * See README for more information.
15
 */
18
 */
Lines 82-94 Link Here
82
#endif
85
#endif
83
#endif
86
#endif
84
87
85
/* need to be global for poppassd_conv */
86
char oldpass[BUFSIZE];
87
char newpass[BUFSIZE];
88
#define POP_OLDPASS 0
88
#define POP_OLDPASS 0
89
#define POP_NEWPASS 1
89
#define POP_NEWPASS 1
90
#define POP_SKIPASS 2
90
#define POP_SKIPASS 2
91
short int pop_state = POP_OLDPASS;
91
92
/* need to be global for poppassd_conv */
93
char oldpass[BUFSIZE];
94
char newpass[BUFSIZE];
92
95
93
void WriteToClient (char *fmt, ...)
96
void WriteToClient (char *fmt, ...)
94
{
97
{
Lines 104-110 Link Here
104
void ReadFromClient (char *line)
107
void ReadFromClient (char *line)
105
{
108
{
106
	char *sp;
109
	char *sp;
107
	int i;
108
110
109
	bzero(line, BUFSIZE);
111
	bzero(line, BUFSIZE);
110
	fgets (line, BUFSIZE-1, stdin);
112
	fgets (line, BUFSIZE-1, stdin);
Lines 117-165 Link Here
117
	line[BUFSIZE-1] = '\0';
119
	line[BUFSIZE-1] = '\0';
118
}
120
}
119
121
122
static inline int getstate(const char *msg)
123
{
124
	/* Interpret possible PAM messages (not including errors) */
125
	if(!strcmp(msg, "Password: "))
126
		return POP_OLDPASS;
127
	if(!strcmp(msg, "Enter login(LDAP) password: "))
128
		return POP_OLDPASS;
129
130
	if(!strcmp(msg, "New password: "))
131
		return POP_NEWPASS;
132
	if(!strcmp(msg, "Re-enter new password: "))
133
		return POP_NEWPASS;
134
	if(!strcmp(msg, "Enter new UNIX password: "))
135
		return POP_NEWPASS;
136
	if(!strcmp(msg, "Retype new UNIX password: "))
137
		return POP_NEWPASS;
138
	if(!strcmp(msg, "New UNIX password: "))
139
		return POP_NEWPASS;
140
141
	WriteToClient("Unknown PAM Message: %s", msg);  // We should not ever reach here.
142
143
	return POP_SKIPASS;
144
}
145
120
int poppassd_conv(num_msg, msg, resp, appdata_ptr)
146
int poppassd_conv(num_msg, msg, resp, appdata_ptr)
121
    int         num_msg;
147
    int         num_msg;
122
    const struct pam_message **msg;
148
    const struct pam_message **msg;
123
    struct pam_response **resp;
149
    struct pam_response **resp;
124
    void        *appdata_ptr;
150
    void        *appdata_ptr;
151
152
125
{
153
{
126
	int i;
154
	int i;
127
	struct pam_response *r = malloc(sizeof(struct pam_response) * num_msg);
155
	struct pam_response *r;
128
156
129
	if(num_msg <= 0)
157
	if(num_msg <= 0)
130
		return(PAM_CONV_ERR);
158
		return(PAM_CONV_ERR);
131
159
160
	r = malloc(sizeof(struct pam_response) * num_msg);
132
	if(r == NULL)
161
	if(r == NULL)
133
		return(PAM_CONV_ERR);
162
		return(PAM_CONV_ERR);
134
163
135
	for(i=0; i<num_msg; i++) {
164
	for(i = 0; i < num_msg; i++) {
136
		if(msg[i]->msg_style == PAM_ERROR_MSG) {
165
		if(msg[i]->msg_style == PAM_ERROR_MSG) {
137
		       WriteToClient ("500 PAM error: %s", msg[i]->msg);
166
		       WriteToClient ("500 PAM error: %s", msg[i]->msg);
138
		       syslog(LOG_ERR, "PAM error: %s", msg[i]->msg);
167
		       syslog(LOG_ERR, "PAM error: %s", msg[i]->msg);
139
		       /*
168
		       /*
140
		        * If there is an error, we don't want to be sending in
169
		        * If there is an error, we don't want to be sending in
141
		        * anything more, so set pop_state to invalid
170
		        * anything more, so we quit after printing the error message.
142
		        */
171
		        */
143
		       pop_state = POP_SKIPASS;
172
		       exit(1);
144
		}
173
		}
145
174
146
	r[i].resp_retcode = 0;
175
		r[i].resp_retcode = 0;
147
	if(msg[i]->msg_style == PAM_PROMPT_ECHO_OFF ||
176
		if(msg[i]->msg_style == PAM_PROMPT_ECHO_OFF ||
148
			msg[i]->msg_style == PAM_PROMPT_ECHO_ON)
177
			msg[i]->msg_style == PAM_PROMPT_ECHO_ON)
149
	{
178
		{
150
		switch(pop_state) {
179
			switch(getstate(msg[i]->msg))
151
			case POP_OLDPASS: r[i].resp = strdup(oldpass);  
180
			{
152
					  break;
181
			case POP_OLDPASS:
153
			case POP_NEWPASS: r[i].resp = strdup(newpass); 
182
				r[i].resp = strdup(oldpass);  
154
					  break;
183
				break;
155
			case POP_SKIPASS: r[i].resp = NULL;
184
			case POP_NEWPASS:
156
					  break;
185
				r[i].resp = strdup(newpass); 
157
			default: syslog(LOG_ERR, "PAM error: too many switches (state=%d)", pop_state);
186
				break;
187
			case POP_SKIPASS:
188
				r[i].resp = NULL;
189
				break;
190
			default:
191
				syslog(LOG_ERR, "PAM error: unknown state - this should not happen");
192
			}
193
		} else 
194
		{
195
			r[i].resp = strdup("");
158
		}
196
		}
159
	} else 
160
	{
161
		r[i].resp = strdup("");
162
	}
163
	}
197
	}
164
	
198
	
165
	*resp = r;
199
	*resp = r;
Lines 175-190 Link Here
175
{
209
{
176
     char line[BUFSIZE];
210
     char line[BUFSIZE];
177
     char user[BUFSIZE];
211
     char user[BUFSIZE];
178
     char emess[BUFSIZE];
179
     char *slavedev;
180
     struct passwd *pw, *getpwnam();
212
     struct passwd *pw, *getpwnam();
181
     struct spwd *sp;
182
     int c, master;
183
     pid_t pid, wpid;
184
     int wstat;
185
     int ret;
186
     pam_handle_t *pamh=NULL;
213
     pam_handle_t *pamh=NULL;
187
     char *item=oldpass;
188
     
214
     
189
     *user = *oldpass = *newpass = 0;
215
     *user = *oldpass = *newpass = 0;
190
216
Lines 222-227 Link Here
222
	     WriteToClient("500 Password required.");
248
	     WriteToClient("500 Password required.");
223
	     exit(1);
249
	     exit(1);
224
     }
250
     }
251
225
     if(pam_authenticate(pamh, 0) != PAM_SUCCESS)
252
     if(pam_authenticate(pamh, 0) != PAM_SUCCESS)
226
     {
253
     {
227
	  WriteToClient ("500 Old password is incorrect.");
254
	  WriteToClient ("500 Old password is incorrect.");
Lines 233-246 Link Here
233
260
234
     pw=getpwnam(user);
261
     pw=getpwnam(user);
235
262
236
     if(pw->pw_uid<POP_MIN_UID || pw == NULL) {
263
     if(pw == NULL || pw->pw_uid<POP_MIN_UID) {
237
         WriteToClient("500 Old password is incorrect.");
264
         WriteToClient("500 Old password is incorrect.");
238
         syslog(LOG_ERR, "failed attempt to change password for %s", user);
265
         syslog(LOG_ERR, "failed attempt to change password for %s", user);
239
         exit(1);
266
         exit(1);
240
     }
267
     }
241
268
242
     pop_state = POP_NEWPASS;
243
244
     WriteToClient ("200 Your new password please.");
269
     WriteToClient ("200 Your new password please.");
245
     ReadFromClient (line);
270
     ReadFromClient (line);
246
     sscanf (line, "newpass %" MAX_LEN_PASS "c", newpass);
271
     sscanf (line, "newpass %" MAX_LEN_PASS "c", newpass);
Lines 269-273 Link Here
269
     WriteToClient("200 Bye.");
294
     WriteToClient("200 Bye.");
270
     closelog();
295
     closelog();
271
     exit(0);
296
     exit(0);
272
     }
297
}
273

Return to bug 145839