aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-08-21 10:58:18 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-08-21 10:58:18 +0000
commitd6e81c7762e20e3df4d12c5515354e4da3a451a8 (patch)
tree67a7709e486fa51eeabe2c1f038f55d5564a274f
parent18f2a6bc5efa762c6bdfe4199f2067e6c35fa111 (diff)
downloadbusybox-w32-d6e81c7762e20e3df4d12c5515354e4da3a451a8.tar.gz
busybox-w32-d6e81c7762e20e3df4d12c5515354e4da3a451a8.tar.bz2
busybox-w32-d6e81c7762e20e3df4d12c5515354e4da3a451a8.zip
login: optional support for PAM
-rw-r--r--Makefile.flags8
-rw-r--r--loginutils/Config.in7
-rw-r--r--loginutils/login.c66
3 files changed, 71 insertions, 10 deletions
diff --git a/Makefile.flags b/Makefile.flags
index d8817bed6..c64a5c838 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -60,18 +60,20 @@ LDFLAGS += -static
60endif 60endif
61 61
62BBOX_LIB_LIST = m crypt 62BBOX_LIB_LIST = m crypt
63
64ifeq ($(CONFIG_PAM),y)
65BBOX_LIB_LIST += pam pam_misc
66endif
67
63ifeq ($(CONFIG_SELINUX),y) 68ifeq ($(CONFIG_SELINUX),y)
64#LDLIBS += -lselinux -lsepol
65BBOX_LIB_LIST += selinux sepol 69BBOX_LIB_LIST += selinux sepol
66endif 70endif
67 71
68ifeq ($(CONFIG_EFENCE),y) 72ifeq ($(CONFIG_EFENCE),y)
69#LDLIBS += -lefence
70BBOX_LIB_LIST += efence 73BBOX_LIB_LIST += efence
71endif 74endif
72 75
73ifeq ($(CONFIG_DMALLOC),y) 76ifeq ($(CONFIG_DMALLOC),y)
74#LDLIBS += -ldmalloc
75BBOX_LIB_LIST += dmalloc 77BBOX_LIB_LIST += dmalloc
76endif 78endif
77 79
diff --git a/loginutils/Config.in b/loginutils/Config.in
index 63ae9b4db..6f2702e95 100644
--- a/loginutils/Config.in
+++ b/loginutils/Config.in
@@ -128,6 +128,13 @@ config LOGIN
128 Note that Busybox binary must be setuid root for this applet to 128 Note that Busybox binary must be setuid root for this applet to
129 work properly. 129 work properly.
130 130
131config PAM
132 bool "Support for PAM (Pluggable Authentication Modules)"
133 default n
134 depends on LOGIN
135 help
136 Use PAM in login(1) instead of direct access to password database.
137
131config LOGIN_SCRIPTS 138config LOGIN_SCRIPTS
132 bool "Support for login scripts" 139 bool "Support for login scripts"
133 depends on LOGIN 140 depends on LOGIN
diff --git a/loginutils/login.c b/loginutils/login.c
index 7b60fd017..b633a7feb 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -14,6 +14,15 @@
14#include <selinux/flask.h> /* for security class definitions */ 14#include <selinux/flask.h> /* for security class definitions */
15#endif 15#endif
16 16
17#if ENABLE_PAM
18#include <pam/pam_appl.h>
19#include <pam/pam_misc.h>
20static const struct pam_conv conv = {
21 misc_conv,
22 NULL
23};
24#endif
25
17enum { 26enum {
18 TIMEOUT = 60, 27 TIMEOUT = 60,
19 EMPTY_USERNAME_COUNT = 10, 28 EMPTY_USERNAME_COUNT = 10,
@@ -125,7 +134,7 @@ static void die_if_nologin_and_non_root(int amroot)
125static ALWAYS_INLINE void die_if_nologin_and_non_root(int amroot) {} 134static ALWAYS_INLINE void die_if_nologin_and_non_root(int amroot) {}
126#endif 135#endif
127 136
128#if ENABLE_FEATURE_SECURETTY 137#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM
129static int check_securetty(void) 138static int check_securetty(void)
130{ 139{
131 FILE *fp; 140 FILE *fp;
@@ -214,7 +223,7 @@ int login_main(int argc, char **argv)
214 LOGIN_OPT_h = (1<<1), 223 LOGIN_OPT_h = (1<<1),
215 LOGIN_OPT_p = (1<<2), 224 LOGIN_OPT_p = (1<<2),
216 }; 225 };
217 char fromhost[512]; 226 char *fromhost;
218 char username[USERNAME_SIZE]; 227 char username[USERNAME_SIZE];
219 const char *tmp; 228 const char *tmp;
220 int amroot; 229 int amroot;
@@ -226,6 +235,9 @@ int login_main(int argc, char **argv)
226 char full_tty[TTYNAME_SIZE]; 235 char full_tty[TTYNAME_SIZE];
227 USE_SELINUX(security_context_t user_sid = NULL;) 236 USE_SELINUX(security_context_t user_sid = NULL;)
228 USE_FEATURE_UTMP(struct utmp utent;) 237 USE_FEATURE_UTMP(struct utmp utent;)
238 USE_PAM(pam_handle_t *pamh;)
239 USE_PAM(int pamret;)
240 USE_PAM(const char *failed_msg;)
229 241
230 short_tty = full_tty; 242 short_tty = full_tty;
231 username[0] = '\0'; 243 username[0] = '\0';
@@ -265,13 +277,12 @@ int login_main(int argc, char **argv)
265 USE_FEATURE_UTMP( 277 USE_FEATURE_UTMP(
266 safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host)); 278 safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));
267 ) 279 )
268 snprintf(fromhost, sizeof(fromhost)-1, " on '%.100s' from " 280 fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host);
269 "'%.200s'", short_tty, opt_host);
270 } else 281 } else
271 snprintf(fromhost, sizeof(fromhost)-1, " on '%.100s'", short_tty); 282 fromhost = xasprintf(" on '%s'", short_tty);
272 283
273 // Was breaking "login <username>" from shell command line: 284 /* Was breaking "login <username>" from shell command line: */
274 // bb_setpgrp(); 285 /*bb_setpgrp();*/
275 286
276 openlog(applet_name, LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH); 287 openlog(applet_name, LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
277 288
@@ -279,6 +290,46 @@ int login_main(int argc, char **argv)
279 if (!username[0]) 290 if (!username[0])
280 get_username_or_die(username, sizeof(username)); 291 get_username_or_die(username, sizeof(username));
281 292
293#if ENABLE_PAM
294 pamret = pam_start("login", username, &conv, &pamh);
295 if (pamret != PAM_SUCCESS) {
296 failed_msg = "pam_start";
297 goto pam_auth_failed;
298 }
299 /* set TTY (so things like securetty work) */
300 pamret = pam_set_item(pamh, PAM_TTY, short_tty);
301 if (pamret != PAM_SUCCESS) {
302 failed_msg = "pam_set_item(TTY)";
303 goto pam_auth_failed;
304 }
305 pamret = pam_authenticate(pamh, 0);
306 if (pamret == PAM_SUCCESS) {
307 char *pamuser;
308 /* check that the account is healthy. */
309 pamret = pam_acct_mgmt(pamh, 0);
310 if (pamret != PAM_SUCCESS) {
311 failed_msg = "account setup";
312 goto pam_auth_failed;
313 }
314 /* read user back */
315 /* gcc: "dereferencing type-punned pointer breaks aliasing rules..."
316 * thus we use double cast */
317 if (pam_get_item(pamh, PAM_USER, (const void **)(void*)&pamuser) != PAM_SUCCESS) {
318 failed_msg = "pam_get_item(USER)";
319 goto pam_auth_failed;
320 }
321 safe_strncpy(username, pamuser, sizeof(username));
322 }
323 /* If we get here, the user was authenticated, and is
324 * granted access. */
325 pw = getpwnam(username);
326 if (pw)
327 break;
328 goto auth_failed;
329 pam_auth_failed:
330 bb_error_msg("%s failed: %s", failed_msg, pam_strerror(pamh, pamret));
331 safe_strncpy(username, "UNKNOWN", sizeof(username));
332#else /* not PAM */
282 pw = getpwnam(username); 333 pw = getpwnam(username);
283 if (!pw) { 334 if (!pw) {
284 strcpy(username, "UNKNOWN"); 335 strcpy(username, "UNKNOWN");
@@ -301,6 +352,7 @@ int login_main(int argc, char **argv)
301 /* authorization takes place here */ 352 /* authorization takes place here */
302 if (correct_password(pw)) 353 if (correct_password(pw))
303 break; 354 break;
355#endif /* ENABLE_PAM */
304 auth_failed: 356 auth_failed:
305 opt &= ~LOGIN_OPT_f; 357 opt &= ~LOGIN_OPT_f;
306 bb_do_delay(FAIL_DELAY); 358 bb_do_delay(FAIL_DELAY);