aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Wienand <ianw@vmware.com>2011-09-14 08:41:38 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-09-14 08:41:38 +0200
commit378ab6819907fa9e439e93ed081c73c2351b4330 (patch)
tree2dff596f174929de10472a36a452462118613980
parenta221bc5f9909a6914ec6f4d14f76bb28c4a4cddf (diff)
downloadbusybox-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.c3
-rw-r--r--loginutils/Config.src11
-rw-r--r--loginutils/login.c53
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
70enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 }; 71enum { 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
208config 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
208config PAM 219config 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
44static char* short_tty;
45
46#if ENABLE_FEATURE_NOLOGIN 44#if ENABLE_FEATURE_NOLOGIN
47static void die_if_nologin(void) 45static 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
77static int check_securetty(void) 75static 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
92static ALWAYS_INLINE int check_securetty(void) { return 1; } 90static 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)
142void run_login_script(struct passwd *pw, char *full_tty); 140void run_login_script(struct passwd *pw, char *full_tty);
143#endif 141#endif
144 142
143#if ENABLE_LOGIN_SESSION_AS_CHILD && ENABLE_PAM
144static 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
145static void get_username_or_die(char *buf, int size_buf) 166static 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); */