diff options
author | Ian Wienand <ianw@vmware.com> | 2011-09-14 08:41:38 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-09-14 08:41:38 +0200 |
commit | 378ab6819907fa9e439e93ed081c73c2351b4330 (patch) | |
tree | 2dff596f174929de10472a36a452462118613980 | |
parent | a221bc5f9909a6914ec6f4d14f76bb28c4a4cddf (diff) | |
download | busybox-w32-378ab6819907fa9e439e93ed081c73c2351b4330.tar.gz busybox-w32-378ab6819907fa9e439e93ed081c73c2351b4330.tar.bz2 busybox-w32-378ab6819907fa9e439e93ed081c73c2351b4330.zip |
login: new option LOGIN_SESSION_AS_CHILD
Signed-off-by: Ian Wienand <ianw@vmware.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | debianutils/run_parts.c | 3 | ||||
-rw-r--r-- | loginutils/Config.src | 11 | ||||
-rw-r--r-- | loginutils/login.c | 53 |
3 files changed, 61 insertions, 6 deletions
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index 65cbfc338..8f08f6dc6 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c | |||
@@ -66,6 +66,7 @@ struct globals { | |||
66 | #define names (G.names) | 66 | #define names (G.names) |
67 | #define cur (G.cur ) | 67 | #define cur (G.cur ) |
68 | #define cmd (G.cmd ) | 68 | #define cmd (G.cmd ) |
69 | #define INIT_G() do { } while (0) | ||
69 | 70 | ||
70 | enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 }; | 71 | enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 }; |
71 | 72 | ||
@@ -143,6 +144,8 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv) | |||
143 | unsigned n; | 144 | unsigned n; |
144 | int ret; | 145 | int ret; |
145 | 146 | ||
147 | INIT_G(); | ||
148 | |||
146 | #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS | 149 | #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS |
147 | applet_long_options = runparts_longopts; | 150 | applet_long_options = runparts_longopts; |
148 | #endif | 151 | #endif |
diff --git a/loginutils/Config.src b/loginutils/Config.src index 0d7f50cf1..14ce53434 100644 --- a/loginutils/Config.src +++ b/loginutils/Config.src | |||
@@ -205,6 +205,17 @@ config LOGIN | |||
205 | Note that Busybox binary must be setuid root for this applet to | 205 | Note that Busybox binary must be setuid root for this applet to |
206 | work properly. | 206 | work properly. |
207 | 207 | ||
208 | config LOGIN_SESSION_AS_CHILD | ||
209 | bool "Run logged in session in a child process" | ||
210 | default y if PAM | ||
211 | depends on LOGIN | ||
212 | help | ||
213 | Run the logged in session in a child process. This allows | ||
214 | login to clean up things such as utmp entries or PAM sessions | ||
215 | when the login session is complete. If you use PAM, you | ||
216 | almost always would want this to be set to Y, else PAM session | ||
217 | will not be cleaned up. | ||
218 | |||
208 | config PAM | 219 | config PAM |
209 | bool "Support for PAM (Pluggable Authentication Modules)" | 220 | bool "Support for PAM (Pluggable Authentication Modules)" |
210 | default n | 221 | default n |
diff --git a/loginutils/login.c b/loginutils/login.c index 2f7b9b212..534343129 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -41,8 +41,6 @@ enum { | |||
41 | TTYNAME_SIZE = 32, | 41 | TTYNAME_SIZE = 32, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static char* short_tty; | ||
45 | |||
46 | #if ENABLE_FEATURE_NOLOGIN | 44 | #if ENABLE_FEATURE_NOLOGIN |
47 | static void die_if_nologin(void) | 45 | static void die_if_nologin(void) |
48 | { | 46 | { |
@@ -74,7 +72,7 @@ static void die_if_nologin(void) | |||
74 | #endif | 72 | #endif |
75 | 73 | ||
76 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM | 74 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM |
77 | static int check_securetty(void) | 75 | static int check_securetty(const char *short_tty) |
78 | { | 76 | { |
79 | char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ | 77 | char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ |
80 | parser_t *parser = config_open2("/etc/securetty", fopen_for_read); | 78 | parser_t *parser = config_open2("/etc/securetty", fopen_for_read); |
@@ -89,7 +87,7 @@ static int check_securetty(void) | |||
89 | return buf != NULL; | 87 | return buf != NULL; |
90 | } | 88 | } |
91 | #else | 89 | #else |
92 | static ALWAYS_INLINE int check_securetty(void) { return 1; } | 90 | static ALWAYS_INLINE int check_securetty(const char *short_tty UNUSED_PARAM) { return 1; } |
93 | #endif | 91 | #endif |
94 | 92 | ||
95 | #if ENABLE_SELINUX | 93 | #if ENABLE_SELINUX |
@@ -142,6 +140,29 @@ static void run_login_script(struct passwd *pw, char *full_tty) | |||
142 | void run_login_script(struct passwd *pw, char *full_tty); | 140 | void run_login_script(struct passwd *pw, char *full_tty); |
143 | #endif | 141 | #endif |
144 | 142 | ||
143 | #if ENABLE_LOGIN_SESSION_AS_CHILD && ENABLE_PAM | ||
144 | static void login_pam_end(pam_handle_t *pamh) | ||
145 | { | ||
146 | int pamret; | ||
147 | |||
148 | pamret = pam_setcred(pamh, PAM_DELETE_CRED); | ||
149 | if (pamret != PAM_SUCCESS) { | ||
150 | bb_error_msg("pam_%s failed: %s (%d)", "setcred", | ||
151 | pam_strerror(pamh, pamret), pamret); | ||
152 | } | ||
153 | pamret = pam_close_session(pamh, 0); | ||
154 | if (pamret != PAM_SUCCESS) { | ||
155 | bb_error_msg("pam_%s failed: %s (%d)", "close_session", | ||
156 | pam_strerror(pamh, pamret), pamret); | ||
157 | } | ||
158 | pamret = pam_end(pamh, pamret); | ||
159 | if (pamret != PAM_SUCCESS) { | ||
160 | bb_error_msg("pam_%s failed: %s (%d)", "end", | ||
161 | pam_strerror(pamh, pamret), pamret); | ||
162 | } | ||
163 | } | ||
164 | #endif /* ENABLE_PAM */ | ||
165 | |||
145 | static void get_username_or_die(char *buf, int size_buf) | 166 | static void get_username_or_die(char *buf, int size_buf) |
146 | { | 167 | { |
147 | int c, cntdown; | 168 | int c, cntdown; |
@@ -214,6 +235,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
214 | char *opt_host = NULL; | 235 | char *opt_host = NULL; |
215 | char *opt_user = opt_user; /* for compiler */ | 236 | char *opt_user = opt_user; /* for compiler */ |
216 | char *full_tty; | 237 | char *full_tty; |
238 | char *short_tty; | ||
217 | IF_SELINUX(security_context_t user_sid = NULL;) | 239 | IF_SELINUX(security_context_t user_sid = NULL;) |
218 | #if ENABLE_PAM | 240 | #if ENABLE_PAM |
219 | int pamret; | 241 | int pamret; |
@@ -224,6 +246,9 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
224 | char pwdbuf[256]; | 246 | char pwdbuf[256]; |
225 | char **pamenv; | 247 | char **pamenv; |
226 | #endif | 248 | #endif |
249 | #if ENABLE_LOGIN_SESSION_AS_CHILD | ||
250 | pid_t child_pid; | ||
251 | #endif | ||
227 | 252 | ||
228 | username[0] = '\0'; | 253 | username[0] = '\0'; |
229 | signal(SIGALRM, alarm_handler); | 254 | signal(SIGALRM, alarm_handler); |
@@ -359,7 +384,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
359 | if (opt & LOGIN_OPT_f) | 384 | if (opt & LOGIN_OPT_f) |
360 | break; /* -f USER: success without asking passwd */ | 385 | break; /* -f USER: success without asking passwd */ |
361 | 386 | ||
362 | if (pw->pw_uid == 0 && !check_securetty()) | 387 | if (pw->pw_uid == 0 && !check_securetty(short_tty)) |
363 | goto auth_failed; | 388 | goto auth_failed; |
364 | 389 | ||
365 | /* Don't check the password if password entry is empty (!) */ | 390 | /* Don't check the password if password entry is empty (!) */ |
@@ -393,7 +418,23 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
393 | if (pw->pw_uid != 0) | 418 | if (pw->pw_uid != 0) |
394 | die_if_nologin(); | 419 | die_if_nologin(); |
395 | 420 | ||
396 | IF_SELINUX(initselinux(username, full_tty, &user_sid)); | 421 | |
422 | #if ENABLE_LOGIN_SESSION_AS_CHILD | ||
423 | child_pid = vfork(); | ||
424 | if (child_pid != 0) { | ||
425 | if (child_pid < 0) | ||
426 | bb_perror_msg("vfork"); | ||
427 | else { | ||
428 | if (safe_waitpid(child_pid, NULL, 0) == -1) | ||
429 | bb_perror_msg("waitpid"); | ||
430 | update_utmp(child_pid, DEAD_PROCESS, NULL, NULL, NULL); | ||
431 | } | ||
432 | IF_PAM(login_pam_end(pamh);) | ||
433 | return 0; | ||
434 | } | ||
435 | #endif | ||
436 | |||
437 | IF_SELINUX(initselinux(username, full_tty, &user_sid);) | ||
397 | 438 | ||
398 | /* Try these, but don't complain if they fail. | 439 | /* Try these, but don't complain if they fail. |
399 | * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */ | 440 | * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */ |