diff -ru busybox-1.00/Makefile busybox-1.00-mod/Makefile --- busybox-1.00/Makefile 2004-10-08 09:45:08.000000000 +0200 +++ busybox-1.00-mod/Makefile 2004-12-07 12:49:43.000000000 +0100 @@ -51,6 +51,10 @@ LIBRARIES += -lsecure endif +ifeq ($(strip $(CONFIG_PAM)),y) +LIBRARIES += -lpam -lpam_misc +endif + CONFIG_CONFIG_IN = $(top_srcdir)/sysdeps/$(TARGET_OS)/Config.in CONFIG_DEFCONFIG = $(top_srcdir)/sysdeps/$(TARGET_OS)/defconfig diff -ru busybox-1.00/loginutils/Config.in busybox-1.00-mod/loginutils/Config.in --- busybox-1.00/loginutils/Config.in 2004-08-27 01:12:59.000000000 +0200 +++ busybox-1.00-mod/loginutils/Config.in 2004-12-07 12:41:37.000000000 +0100 @@ -76,6 +76,13 @@ Note that Busybox binary must be setuid root for this applet to work properly. +config CONFIG_PAM + bool " Support for PAM (Pluggable Authentication Modules)" + default n + depends on CONFIG_LOGIN + help + Include support for PAM in /bin/login. + config CONFIG_FEATURE_SECURETTY bool " Support for /etc/securetty" default y Only in busybox-1.00-mod/loginutils: l.patch diff -ru busybox-1.00/loginutils/login.c busybox-1.00-mod/loginutils/login.c --- busybox-1.00/loginutils/login.c 2004-08-27 00:26:26.000000000 +0200 +++ busybox-1.00-mod/loginutils/login.c 2004-12-07 12:37:52.000000000 +0100 @@ -23,6 +23,16 @@ #include #endif +#ifdef CONFIG_PAM +#include +#include + +static struct pam_conv conv = { + misc_conv, + NULL +}; +#endif + #ifdef CONFIG_FEATURE_U_W_TMP // import from utmp.c static void checkutmp(int picky); @@ -153,6 +163,10 @@ openlog ( "login", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH ); while ( 1 ) { +#ifdef CONFIG_PAM + pam_handle_t *pamh; + int pamret; +#endif failed = 0; if ( !username[0] ) @@ -174,6 +188,54 @@ pw = &pw_copy; +#ifdef CONFIG_PAM + /* PAM authentication goes before (and instead of) all the + * other stuff. The reason we initialize the pw struct + * before going on with PAM is that the pw struct is used + * later on, and this way saved us some changing of that code. + */ + if ( ( pamret = pam_start( "login", + username, + &conv, + &pamh ) ) != + PAM_SUCCESS ) { + /* pam_start() failed. We failed to initialize the PAM + * structures, and should probably carry on with login, + * so we avoid locking people out. + */ + fprintf( stderr, "PAM initialization failed: %s\n", + pam_strerror( pamh, pamret ) ); + } else { + /* Continuing with PAM authentication. */ + if ( ( pamret = pam_authenticate( pamh, 0 ) ) == PAM_SUCCESS ) { + /* Then check that the account is healthy. */ + if ( ( pamret = pam_acct_mgmt( pamh, 0 ) ) != PAM_SUCCESS ) { + /* No, it isn't. */ + fprintf( stderr, "User not allowed access: %s\n", + pam_strerror( pamh, pamret ) ); + } + } + /* If we get here, the user was authenticated, and is + * granted access. + */ + if ( pam_end( pamh, pamret ) != PAM_SUCCESS ) { + fprintf( stderr, "PAM cleaning up failed\n" ); + } + if ( pamret == PAM_SUCCESS ) { + failed = 0; + } else { + failed = 1; + } + goto auth_ok; + } + /* Everything from here to auth_ok: is skipped when running + * PAM. This is all PAM's responsibility anyway. The exception + * is if pam_start() failed, which would indicate a more serious + * error in the PAM library. In that case, we carry on with + * standard procedure. + */ +#endif /* CONFIG_PAM */ + if (( pw-> pw_passwd [0] == '!' ) || ( pw-> pw_passwd[0] == '*' )) failed = 1;