diff options
Diffstat (limited to 'loginutils')
-rw-r--r-- | loginutils/getty.c | 61 | ||||
-rw-r--r-- | loginutils/login.c | 112 |
2 files changed, 16 insertions, 157 deletions
diff --git a/loginutils/getty.c b/loginutils/getty.c index 20411b04c..8d1d5254e 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <syslog.h> | 19 | #include <syslog.h> |
20 | 20 | ||
21 | #if ENABLE_FEATURE_UTMP | 21 | #if ENABLE_FEATURE_UTMP |
22 | #include <utmp.h> /* updwtmp() */ | 22 | #include <utmp.h> /* LOGIN_PROCESS */ |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #ifndef IUCLC | 25 | #ifndef IUCLC |
@@ -575,61 +575,6 @@ static void termios_final(struct options *op, struct termios *tp, struct chardat | |||
575 | ioctl_or_perror_and_die(0, TCSETS, tp, "%s: TCSETS", op->tty); | 575 | ioctl_or_perror_and_die(0, TCSETS, tp, "%s: TCSETS", op->tty); |
576 | } | 576 | } |
577 | 577 | ||
578 | #if ENABLE_FEATURE_UTMP | ||
579 | static void touch(const char *filename) | ||
580 | { | ||
581 | if (access(filename, R_OK | W_OK) == -1) | ||
582 | close(open(filename, O_WRONLY | O_CREAT, 0664)); | ||
583 | } | ||
584 | |||
585 | /* update_utmp - update our utmp entry */ | ||
586 | static NOINLINE void update_utmp(const char *line, char *fakehost) | ||
587 | { | ||
588 | struct utmp ut; | ||
589 | struct utmp *utp; | ||
590 | int mypid = getpid(); | ||
591 | |||
592 | /* In case we won't find an entry below... */ | ||
593 | memset(&ut, 0, sizeof(ut)); | ||
594 | safe_strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); | ||
595 | |||
596 | /* | ||
597 | * The utmp file holds miscellaneous information about things started by | ||
598 | * /sbin/init and other system-related events. Our purpose is to update | ||
599 | * the utmp entry for the current process, in particular the process type | ||
600 | * and the tty line we are listening to. Return successfully only if the | ||
601 | * utmp file can be opened for update, and if we are able to find our | ||
602 | * entry in the utmp file. | ||
603 | */ | ||
604 | touch(_PATH_UTMP); | ||
605 | |||
606 | utmpname(_PATH_UTMP); | ||
607 | setutent(); | ||
608 | while ((utp = getutent()) != NULL) { | ||
609 | if (utp->ut_type == INIT_PROCESS && utp->ut_pid == mypid) { | ||
610 | memcpy(&ut, utp, sizeof(ut)); | ||
611 | break; | ||
612 | } | ||
613 | } | ||
614 | |||
615 | strcpy(ut.ut_user, "LOGIN"); | ||
616 | safe_strncpy(ut.ut_line, line, sizeof(ut.ut_line)); | ||
617 | if (fakehost) | ||
618 | safe_strncpy(ut.ut_host, fakehost, sizeof(ut.ut_host)); | ||
619 | ut.ut_tv.tv_sec = time(NULL); | ||
620 | ut.ut_type = LOGIN_PROCESS; | ||
621 | ut.ut_pid = mypid; | ||
622 | |||
623 | pututline(&ut); | ||
624 | endutent(); | ||
625 | |||
626 | #if ENABLE_FEATURE_WTMP | ||
627 | touch(bb_path_wtmp_file); | ||
628 | updwtmp(bb_path_wtmp_file, &ut); | ||
629 | #endif | ||
630 | } | ||
631 | #endif /* CONFIG_FEATURE_UTMP */ | ||
632 | |||
633 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 578 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
634 | int getty_main(int argc UNUSED_PARAM, char **argv) | 579 | int getty_main(int argc UNUSED_PARAM, char **argv) |
635 | { | 580 | { |
@@ -715,10 +660,8 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
715 | tcsetpgrp(0, getpid()); | 660 | tcsetpgrp(0, getpid()); |
716 | #endif | 661 | #endif |
717 | 662 | ||
718 | #if ENABLE_FEATURE_UTMP | ||
719 | /* Update the utmp file. This tty is ours now! */ | 663 | /* Update the utmp file. This tty is ours now! */ |
720 | update_utmp(options.tty, fakehost); | 664 | update_utmp(LOGIN_PROCESS, options.tty, "LOGIN", fakehost); |
721 | #endif | ||
722 | 665 | ||
723 | /* Initialize the termios settings (raw mode, eight-bit, blocking i/o). */ | 666 | /* Initialize the termios settings (raw mode, eight-bit, blocking i/o). */ |
724 | debug("calling termios_init\n"); | 667 | debug("calling termios_init\n"); |
diff --git a/loginutils/login.c b/loginutils/login.c index 256c7c475..4a820379d 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -2,25 +2,26 @@ | |||
2 | /* | 2 | /* |
3 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 3 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
4 | */ | 4 | */ |
5 | |||
6 | #include "libbb.h" | 5 | #include "libbb.h" |
7 | #include <syslog.h> | 6 | #include <syslog.h> |
8 | #include <utmp.h> | 7 | #if ENABLE_FEATURE_UTMP |
8 | # include <utmp.h> /* USER_PROCESS */ | ||
9 | #endif | ||
9 | #include <sys/resource.h> | 10 | #include <sys/resource.h> |
10 | 11 | ||
11 | #if ENABLE_SELINUX | 12 | #if ENABLE_SELINUX |
12 | #include <selinux/selinux.h> /* for is_selinux_enabled() */ | 13 | # include <selinux/selinux.h> /* for is_selinux_enabled() */ |
13 | #include <selinux/get_context_list.h> /* for get_default_context() */ | 14 | # include <selinux/get_context_list.h> /* for get_default_context() */ |
14 | #include <selinux/flask.h> /* for security class definitions */ | 15 | # include <selinux/flask.h> /* for security class definitions */ |
15 | #endif | 16 | #endif |
16 | 17 | ||
17 | #if ENABLE_PAM | 18 | #if ENABLE_PAM |
18 | /* PAM may include <locale.h>. We may need to undefine bbox's stub define: */ | 19 | /* PAM may include <locale.h>. We may need to undefine bbox's stub define: */ |
19 | #undef setlocale | 20 | # undef setlocale |
20 | /* For some obscure reason, PAM is not in pam/xxx, but in security/xxx. | 21 | /* For some obscure reason, PAM is not in pam/xxx, but in security/xxx. |
21 | * Apparently they like to confuse people. */ | 22 | * Apparently they like to confuse people. */ |
22 | #include <security/pam_appl.h> | 23 | # include <security/pam_appl.h> |
23 | #include <security/pam_misc.h> | 24 | # include <security/pam_misc.h> |
24 | static const struct pam_conv conv = { | 25 | static const struct pam_conv conv = { |
25 | misc_conv, | 26 | misc_conv, |
26 | NULL | 27 | NULL |
@@ -36,87 +37,6 @@ enum { | |||
36 | 37 | ||
37 | static char* short_tty; | 38 | static char* short_tty; |
38 | 39 | ||
39 | #if ENABLE_FEATURE_UTMP | ||
40 | /* vv Taken from tinylogin utmp.c vv */ | ||
41 | /* | ||
42 | * read_or_build_utent - see if utmp file is correct for this process | ||
43 | * | ||
44 | * System V is very picky about the contents of the utmp file | ||
45 | * and requires that a slot for the current process exist. | ||
46 | * The utmp file is scanned for an entry with the same process | ||
47 | * ID. If no entry exists the process exits with a message. | ||
48 | * | ||
49 | * The "picky" flag is for network and other logins that may | ||
50 | * use special flags. It allows the pid checks to be overridden. | ||
51 | * This means that getty should never invoke login with any | ||
52 | * command line flags. | ||
53 | */ | ||
54 | |||
55 | static void read_or_build_utent(struct utmp *utptr, int run_by_root) | ||
56 | { | ||
57 | struct utmp *ut; | ||
58 | pid_t pid = getpid(); | ||
59 | |||
60 | setutent(); | ||
61 | |||
62 | /* First, try to find a valid utmp entry for this process. */ | ||
63 | /* If there is one, just use it. */ | ||
64 | while ((ut = getutent()) != NULL) { | ||
65 | if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] | ||
66 | && (ut->ut_type == LOGIN_PROCESS || ut->ut_type == USER_PROCESS) | ||
67 | ) { | ||
68 | *utptr = *ut; /* struct copy */ | ||
69 | if (run_by_root) /* why only for root? */ | ||
70 | memset(utptr->ut_host, 0, sizeof(utptr->ut_host)); | ||
71 | return; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | // Why? Do we require non-root to exec login from another | ||
76 | // former login process (e.g. login shell)? Some login's have | ||
77 | // login shells as children, so it won't work... | ||
78 | // if (!run_by_root) | ||
79 | // bb_error_msg_and_die("no utmp entry found"); | ||
80 | |||
81 | /* Otherwise create a new one. */ | ||
82 | memset(utptr, 0, sizeof(*utptr)); | ||
83 | utptr->ut_type = LOGIN_PROCESS; | ||
84 | utptr->ut_pid = pid; | ||
85 | strncpy(utptr->ut_line, short_tty, sizeof(utptr->ut_line)); | ||
86 | /* This one is only 4 chars wide. Try to fit something | ||
87 | * remotely meaningful by skipping "tty"... */ | ||
88 | strncpy(utptr->ut_id, short_tty + 3, sizeof(utptr->ut_id)); | ||
89 | strncpy(utptr->ut_user, "LOGIN", sizeof(utptr->ut_user)); | ||
90 | utptr->ut_tv.tv_sec = time(NULL); | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * write_utent - put a USER_PROCESS entry in the utmp file | ||
95 | * | ||
96 | * write_utent changes the type of the current utmp entry to | ||
97 | * USER_PROCESS. the wtmp file will be updated as well. | ||
98 | */ | ||
99 | static void write_utent(struct utmp *utptr, const char *username) | ||
100 | { | ||
101 | utptr->ut_type = USER_PROCESS; | ||
102 | strncpy(utptr->ut_user, username, sizeof(utptr->ut_user)); | ||
103 | utptr->ut_tv.tv_sec = time(NULL); | ||
104 | /* other fields already filled in by read_or_build_utent above */ | ||
105 | setutent(); | ||
106 | pututline(utptr); | ||
107 | endutent(); | ||
108 | #if ENABLE_FEATURE_WTMP | ||
109 | if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) { | ||
110 | close(creat(bb_path_wtmp_file, 0664)); | ||
111 | } | ||
112 | updwtmp(bb_path_wtmp_file, utptr); | ||
113 | #endif | ||
114 | } | ||
115 | #else /* !ENABLE_FEATURE_UTMP */ | ||
116 | #define read_or_build_utent(utptr, run_by_root) ((void)0) | ||
117 | #define write_utent(utptr, username) ((void)0) | ||
118 | #endif /* !ENABLE_FEATURE_UTMP */ | ||
119 | |||
120 | #if ENABLE_FEATURE_NOLOGIN | 40 | #if ENABLE_FEATURE_NOLOGIN |
121 | static void die_if_nologin(void) | 41 | static void die_if_nologin(void) |
122 | { | 42 | { |
@@ -144,7 +64,7 @@ static void die_if_nologin(void) | |||
144 | exit(EXIT_FAILURE); | 64 | exit(EXIT_FAILURE); |
145 | } | 65 | } |
146 | #else | 66 | #else |
147 | static ALWAYS_INLINE void die_if_nologin(void) {} | 67 | # define die_if_nologin() ((void)0) |
148 | #endif | 68 | #endif |
149 | 69 | ||
150 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM | 70 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM |
@@ -286,11 +206,10 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
286 | unsigned opt; | 206 | unsigned opt; |
287 | int count = 0; | 207 | int count = 0; |
288 | struct passwd *pw; | 208 | struct passwd *pw; |
289 | char *opt_host = opt_host; /* for compiler */ | 209 | char *opt_host = NULL; |
290 | char *opt_user = opt_user; /* for compiler */ | 210 | char *opt_user = opt_user; /* for compiler */ |
291 | char *full_tty; | 211 | char *full_tty; |
292 | IF_SELINUX(security_context_t user_sid = NULL;) | 212 | IF_SELINUX(security_context_t user_sid = NULL;) |
293 | IF_FEATURE_UTMP(struct utmp utent;) | ||
294 | #if ENABLE_PAM | 213 | #if ENABLE_PAM |
295 | int pamret; | 214 | int pamret; |
296 | pam_handle_t *pamh; | 215 | pam_handle_t *pamh; |
@@ -334,10 +253,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
334 | if (strncmp(full_tty, "/dev/", 5) == 0) | 253 | if (strncmp(full_tty, "/dev/", 5) == 0) |
335 | short_tty += 5; | 254 | short_tty += 5; |
336 | 255 | ||
337 | read_or_build_utent(&utent, run_by_root); | 256 | if (opt_host) { |
338 | |||
339 | if (opt & LOGIN_OPT_h) { | ||
340 | IF_FEATURE_UTMP(safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));) | ||
341 | fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host); | 257 | fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host); |
342 | } else { | 258 | } else { |
343 | fromhost = xasprintf(" on '%s'", short_tty); | 259 | fromhost = xasprintf(" on '%s'", short_tty); |
@@ -461,8 +377,6 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
461 | if (pw->pw_uid != 0) | 377 | if (pw->pw_uid != 0) |
462 | die_if_nologin(); | 378 | die_if_nologin(); |
463 | 379 | ||
464 | write_utent(&utent, username); | ||
465 | |||
466 | IF_SELINUX(initselinux(username, full_tty, &user_sid)); | 380 | IF_SELINUX(initselinux(username, full_tty, &user_sid)); |
467 | 381 | ||
468 | /* Try these, but don't complain if they fail. | 382 | /* Try these, but don't complain if they fail. |
@@ -470,6 +384,8 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
470 | fchown(0, pw->pw_uid, pw->pw_gid); | 384 | fchown(0, pw->pw_uid, pw->pw_gid); |
471 | fchmod(0, 0600); | 385 | fchmod(0, 0600); |
472 | 386 | ||
387 | update_utmp(USER_PROCESS, short_tty, username, run_by_root ? opt_host : NULL); | ||
388 | |||
473 | /* We trust environment only if we run by root */ | 389 | /* We trust environment only if we run by root */ |
474 | if (ENABLE_LOGIN_SCRIPTS && run_by_root) | 390 | if (ENABLE_LOGIN_SCRIPTS && run_by_root) |
475 | run_login_script(pw, full_tty); | 391 | run_login_script(pw, full_tty); |