chsh-chfn: Move pam auth to its own function, factoring out common code

This makes it easier to add support for libuser, which needs the same PAM
authentication. Also removes duplicate code between chsh and chfn.

Signed-off-by: Cody Maloney <cmaloney@theoreticalchaos.com>
This commit is contained in:
Cody Maloney 2013-02-06 23:22:19 -07:00 committed by Karel Zak
parent 7e4714f22b
commit d91ad6ab3c
5 changed files with 68 additions and 60 deletions

View File

@ -62,6 +62,8 @@ dist_man_MANS += \
chfn_chsh_sources = \
login-utils/islocal.c \
login-utils/islocal.h \
login-utils/auth.c \
login-utils/auth.h \
login-utils/setpwnam.c \
login-utils/setpwnam.h
chfn_chsh_cflags = $(SUID_CFLAGS) $(AM_CFLAGS)

47
login-utils/auth.c Normal file
View File

@ -0,0 +1,47 @@
/*
* auth.c -- PAM authorization code, common between chsh and chfn
* (c) 2012 by Cody Maloney <cmaloney@theoreticalchaos.com>
*
* this program is free software. you can redistribute it and
* modify it under the terms of the gnu general public license.
* there is no warranty.
*
*/
#include "auth.h"
#include "pamfail.h"
int auth_pam(const char *service_name, uid_t uid, const char *username) {
#ifdef REQUIRE_PASSWORD
if (uid != 0) {
pam_handle_t *pamh = NULL;
struct pam_conv conv = { misc_conv, NULL };
int retcode;
retcode = pam_start(service_name, username, &conv, &pamh);
if (pam_fail_check(pamh, retcode))
return FALSE;
retcode = pam_authenticate(pamh, 0);
if (pam_fail_check(pamh, retcode))
return FALSE;
retcode = pam_acct_mgmt(pamh, 0);
if (retcode == PAM_NEW_AUTHTOK_REQD)
retcode =
pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
if (pam_fail_check(pamh, retcode))
return FALSE;
retcode = pam_setcred(pamh, 0);
if (pam_fail_check(pamh, retcode))
return FALSE;
pam_end(pamh, 0);
/* no need to establish a session; this isn't a
* session-oriented activity... */
}
return TRUE;
#endif /* REQUIRE_PASSWORD */
}

13
login-utils/auth.h Normal file
View File

@ -0,0 +1,13 @@
/*
* auth.h -- PAM authorization code, common between chsh and chfn
* (c) 2012 by Cody Maloney <cmaloney@theoreticalchaos.com>
*
* this program is free software. you can redistribute it and
* modify it under the terms of the gnu general public license.
* there is no warranty.
*
*/
#include <sys/types.h>
extern int auth_pam(const char *service_name, uid_t uid, const char *username);

View File

@ -31,12 +31,12 @@
#include <sys/types.h>
#include <unistd.h>
#include "auth.h"
#include "c.h"
#include "env.h"
#include "closestream.h"
#include "islocal.h"
#include "nls.h"
#include "pamfail.h"
#include "setpwnam.h"
#include "strutils.h"
#include "xalloc.h"
@ -157,36 +157,9 @@ int main(int argc, char **argv)
printf(_("Changing finger information for %s.\n"), oldf.username);
#ifdef REQUIRE_PASSWORD
if (uid != 0) {
pam_handle_t *pamh = NULL;
struct pam_conv conv = { misc_conv, NULL };
int retcode;
retcode = pam_start("chfn", oldf.username, &conv, &pamh);
if (pam_fail_check(pamh, retcode))
return EXIT_FAILURE;
retcode = pam_authenticate(pamh, 0);
if (pam_fail_check(pamh, retcode))
return EXIT_FAILURE;
retcode = pam_acct_mgmt(pamh, 0);
if (retcode == PAM_NEW_AUTHTOK_REQD)
retcode =
pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
if (pam_fail_check(pamh, retcode))
return EXIT_FAILURE;
retcode = pam_setcred(pamh, 0);
if (pam_fail_check(pamh, retcode))
return EXIT_FAILURE;
pam_end(pamh, 0);
/* no need to establish a session; this isn't a
* session-oriented activity... */
if(!auth_pam("chfn", uid, oldf.username)) {
return EXIT_FAILURE;
}
#endif /* REQUIRE_PASSWORD */
if (interactive)
ask_info(&oldf, &newf);

View File

@ -32,12 +32,12 @@
#include <sys/types.h>
#include <unistd.h>
#include "auth.h"
#include "c.h"
#include "env.h"
#include "closestream.h"
#include "islocal.h"
#include "nls.h"
#include "pamfail.h"
#include "pathnames.h"
#include "setpwnam.h"
#include "xalloc.h"
@ -147,36 +147,9 @@ int main(int argc, char **argv)
printf(_("Changing shell for %s.\n"), pw->pw_name);
#ifdef REQUIRE_PASSWORD
if (uid != 0) {
pam_handle_t *pamh = NULL;
struct pam_conv conv = { misc_conv, NULL };
int retcode;
retcode = pam_start("chsh", pw->pw_name, &conv, &pamh);
if (pam_fail_check(pamh, retcode))
return EXIT_FAILURE;
retcode = pam_authenticate(pamh, 0);
if (pam_fail_check(pamh, retcode))
return EXIT_FAILURE;
retcode = pam_acct_mgmt(pamh, 0);
if (retcode == PAM_NEW_AUTHTOK_REQD)
retcode =
pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
if (pam_fail_check(pamh, retcode))
return EXIT_FAILURE;
retcode = pam_setcred(pamh, 0);
if (pam_fail_check(pamh, retcode))
return EXIT_FAILURE;
pam_end(pamh, 0);
/* no need to establish a session; this isn't a
* session-oriented activity... */
if(!auth_pam("chsh", uid, pw->pw_name)) {
return EXIT_FAILURE;
}
#endif /* REQUIRE_PASSWORD */
if (!shell) {
shell = prompt(_("New shell"), oldshell);