@@ -279,29 +279,29 @@ int _unix_blankpasswd(pam_handle_t *pamh, const char *user)
279279}
280280
281281/*
282- * Verify the password of a user .
282+ * Run a helper binary .
283283 */
284-
285- static int unix_run_helper_binary (const char * user , const char * pass )
284+ int unix_run_helper_binary (const char * user , const char * pass ,
285+ const char * helper_binary , char * const argv [],
286+ const char config [8 ], void * retval_helper ,
287+ size_t retval_size )
286288{
287- int retval = PAM_AUTH_ERR , child , fail = 0 , status , fds [2 ], retpipe [2 ];
289+ int child , retval = 0 , status , fds [2 ], retpipe [2 ];
288290 sighandler_t sigchld , sigpipe ;
289291 int len ;
290- char * argv [] = {CHKPWD_HELPER , NULL };
291292 char * envp [] = {NULL };
292293
293294 D (("called" ));
294295
295- if (!pam_unix_param .helper )
296- return PAM_AUTH_ERR ;
297-
298296 /* create a pipe for the password */
299297 if (pipe (fds )) {
300298 D (("could not make pipe" ));
299+ retval = 1 ;
301300 goto out ;
302301 }
303302 if (pipe (retpipe )) {
304303 D (("could not make pipe" ));
304+ retval = 1 ;
305305 goto out_pipe ;
306306 }
307307
@@ -311,6 +311,7 @@ static int unix_run_helper_binary(const char *user, const char *pass)
311311 switch ((child = fork ())) {
312312 case -1 :
313313 D (("fork failed" ));
314+ retval = 1 ;
314315 goto out_signal ;
315316
316317 case 0 :
@@ -327,7 +328,7 @@ static int unix_run_helper_binary(const char *user, const char *pass)
327328 _exit (1 );
328329
329330 /* exec binary helper */
330- execve (pam_unix_param . helper , argv , envp );
331+ execve (helper_binary , argv , envp );
331332
332333 /* should not get here: exit with error */
333334 D (("helper binary is not available" ));
@@ -337,39 +338,29 @@ static int unix_run_helper_binary(const char *user, const char *pass)
337338 /* wait for child */
338339 close (fds [0 ]);
339340 close (retpipe [1 ]);
340- if (on (UNIX__NULLOK )) {
341- if (write_loop (fds [1 ], "nullok\0\0" , 8 ) != 8 )
342- fail = 1 ;
343- } else {
344- if (write_loop (fds [1 ], "nonull\0\0" , 8 ) != 8 )
345- fail = 1 ;
346- }
341+ if (write_loop (fds [1 ], config , 8 ) != 8 )
342+ retval = 1 ;
347343 len = strlen (user ) + 1 ;
348- if (write_loop (fds [1 ], user , len ) != len )
349- fail = 1 ;
350- else {
344+ if (write_loop (fds [1 ], user , len ) != len ) {
345+ retval = 1 ;
346+ } else {
351347 len = strlen (pass ) + 1 ;
352348 if (write_loop (fds [1 ], pass , len ) != len )
353- fail = 1 ;
349+ retval = 1 ;
354350 }
355351 pass = NULL ;
356352 close (fds [1 ]);
357353 /* wait for helper to complete */
358354 if (waitpid (child , & status , 0 ) != child ) {
359355 status = 0 ;
360- fail = 1 ;
356+ retval = 1 ;
361357 }
362- if (read_loop (retpipe [0 ], (char * )& retval , sizeof ( retval ) ) !=
363- sizeof ( retval ) )
364- fail = 1 ;
358+ if (read_loop (retpipe [0 ], (char * )retval_helper , retval_size ) !=
359+ ( int ) retval_size )
360+ retval = 1 ;
365361 close (retpipe [0 ]);
366362 if (!WIFEXITED (status ) || WEXITSTATUS (status ) != 0 )
367- fail = 1 ;
368- if (fail )
369- retval = PAM_AUTH_ERR ;
370- else
371- retval = (retval == TCB_MAGIC ) ?
372- PAM_SUCCESS : PAM_AUTH_ERR ;
363+ retval = 1 ;
373364 }
374365
375366out_signal :
@@ -387,6 +378,37 @@ static int unix_run_helper_binary(const char *user, const char *pass)
387378 return retval ;
388379}
389380
381+ /*
382+ * Verify the password of a user.
383+ */
384+
385+ static int run_chkpwd_binary (const char * user , const char * pass )
386+ {
387+ char * argv [] = { CHKPWD_HELPER , "chkpwd" , NULL };
388+ char config [8 ];
389+ int retval_helper ;
390+
391+ if (!pam_unix_param .helper )
392+ goto end ;
393+
394+ if (on (UNIX__NULLOK )) {
395+ memcpy (config , "nullok\0\0" , 8 );
396+ } else {
397+ memcpy (config , "nonull\0\0" , 8 );
398+ }
399+
400+ if (unix_run_helper_binary (user , pass , pam_unix_param .helper ,
401+ argv , config , (void * )& retval_helper ,
402+ sizeof (retval_helper )))
403+ goto end ;
404+
405+ if (retval_helper == TCB_MAGIC )
406+ return PAM_SUCCESS ;
407+
408+ end :
409+ return PAM_AUTH_ERR ;
410+ }
411+
390412static int check_crypt (pam_handle_t * pamh , const char * pass ,
391413 const char * stored_hash )
392414{
@@ -478,7 +500,7 @@ static int unix_verify_password_plain(pam_handle_t *pamh,
478500 if (uid == geteuid () && (uid == pw -> pw_uid || uid == 0 )) {
479501 /* We are not privileged enough perhaps this is the reason? */
480502 D (("running helper binary" ));
481- retval = unix_run_helper_binary (user , pass );
503+ retval = run_chkpwd_binary (user , pass );
482504 } else {
483505 D (("user's record unavailable" ));
484506 pam_syslog (pamh , LOG_ALERT ,
0 commit comments