diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-21 10:58:18 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-21 10:58:18 +0000 |
commit | d6e81c7762e20e3df4d12c5515354e4da3a451a8 (patch) | |
tree | 67a7709e486fa51eeabe2c1f038f55d5564a274f | |
parent | 18f2a6bc5efa762c6bdfe4199f2067e6c35fa111 (diff) | |
download | busybox-w32-d6e81c7762e20e3df4d12c5515354e4da3a451a8.tar.gz busybox-w32-d6e81c7762e20e3df4d12c5515354e4da3a451a8.tar.bz2 busybox-w32-d6e81c7762e20e3df4d12c5515354e4da3a451a8.zip |
login: optional support for PAM
-rw-r--r-- | Makefile.flags | 8 | ||||
-rw-r--r-- | loginutils/Config.in | 7 | ||||
-rw-r--r-- | loginutils/login.c | 66 |
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 | |||
60 | endif | 60 | endif |
61 | 61 | ||
62 | BBOX_LIB_LIST = m crypt | 62 | BBOX_LIB_LIST = m crypt |
63 | |||
64 | ifeq ($(CONFIG_PAM),y) | ||
65 | BBOX_LIB_LIST += pam pam_misc | ||
66 | endif | ||
67 | |||
63 | ifeq ($(CONFIG_SELINUX),y) | 68 | ifeq ($(CONFIG_SELINUX),y) |
64 | #LDLIBS += -lselinux -lsepol | ||
65 | BBOX_LIB_LIST += selinux sepol | 69 | BBOX_LIB_LIST += selinux sepol |
66 | endif | 70 | endif |
67 | 71 | ||
68 | ifeq ($(CONFIG_EFENCE),y) | 72 | ifeq ($(CONFIG_EFENCE),y) |
69 | #LDLIBS += -lefence | ||
70 | BBOX_LIB_LIST += efence | 73 | BBOX_LIB_LIST += efence |
71 | endif | 74 | endif |
72 | 75 | ||
73 | ifeq ($(CONFIG_DMALLOC),y) | 76 | ifeq ($(CONFIG_DMALLOC),y) |
74 | #LDLIBS += -ldmalloc | ||
75 | BBOX_LIB_LIST += dmalloc | 77 | BBOX_LIB_LIST += dmalloc |
76 | endif | 78 | endif |
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 | ||
131 | config 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 | |||
131 | config LOGIN_SCRIPTS | 138 | config 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> | ||
20 | static const struct pam_conv conv = { | ||
21 | misc_conv, | ||
22 | NULL | ||
23 | }; | ||
24 | #endif | ||
25 | |||
17 | enum { | 26 | enum { |
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) | |||
125 | static ALWAYS_INLINE void die_if_nologin_and_non_root(int amroot) {} | 134 | static 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 |
129 | static int check_securetty(void) | 138 | static 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); |