diff options
-rw-r--r-- | toys/login.c | 125 |
1 files changed, 40 insertions, 85 deletions
diff --git a/toys/login.c b/toys/login.c index ac04adbe..c2c9ba38 100644 --- a/toys/login.c +++ b/toys/login.c @@ -30,7 +30,7 @@ config LOGIN #define HOSTNAME_SIZE 32 DEFINE_GLOBALS( - char * hostname; + char *hostname; ) #define TT this.login @@ -40,7 +40,7 @@ static void login_timeout_handler(int sig __attribute__((unused))) exit(0); } -static const char *forbid[] = { +static char *forbid[] = { "BASH_ENV", "ENV", "HOME", @@ -57,30 +57,16 @@ static const char *forbid[] = { NULL }; -// Unset dangerous environment variables. -void sanitize_env() -{ - const char **p = forbid; - do { - unsetenv(*p); - p++; - } while (*p); -} - int verify_password(char * pwd) { - char * pass; + char *pass; - if (read_password(toybuf, sizeof(toybuf), "Password: ")) - return 1; - if (!pwd) - return 1; - if (pwd[0] == '!' || pwd[0] == '*') - return 1; + if (read_password(toybuf, sizeof(toybuf), "Password: ")) return 1; + if (!pwd) return 1; + if (pwd[0] == '!' || pwd[0] == '*') return 1; pass = crypt(toybuf, pwd); - if (pass != NULL && strcmp(pass, pwd)==0) - return 0; + if (pass && !strcmp(pass, pwd)) return 0; return 1; } @@ -90,8 +76,7 @@ void read_user(char * buff, int size) char hostname[HOSTNAME_SIZE+1]; int i = 0; hostname[HOSTNAME_SIZE] = 0; - if(!gethostname(hostname, HOSTNAME_SIZE)) - fputs(hostname, stdout); + if(!gethostname(hostname, HOSTNAME_SIZE)) fputs(hostname, stdout); fputs(" login: ", stdout); fflush(stdout); @@ -106,10 +91,7 @@ void read_user(char * buff, int size) if(!fgets(&buff[1], HOSTNAME_SIZE-1, stdin)) _exit(1); - while(i<HOSTNAME_SIZE-1 && isgraph(buff[i])) - { - i++; - } + while(i<HOSTNAME_SIZE-1 && isgraph(buff[i])) i++; buff[i] = 0; } @@ -117,15 +99,12 @@ void handle_nologin(void) { int fd = open("/etc/nologin", O_RDONLY); int size; - if (fd == -1) - return; + if (fd == -1) return; size = readall(fd, toybuf,sizeof(toybuf)-1); toybuf[size] = 0; - if (!size) - puts("System closed for routine maintenance\n"); - else - puts(toybuf); + if (!size) puts("System closed for routine maintenance\n"); + else puts(toybuf); close(fd); fflush(stdout); @@ -136,8 +115,7 @@ void handle_motd(void) { int fd = open("/etc/motd", O_RDONLY); int size; - if (fd == -1) - return; + if (fd == -1) return; size = readall(fd, toybuf,sizeof(toybuf)-1); toybuf[size] = 0; @@ -149,12 +127,9 @@ void handle_motd(void) int change_identity(const struct passwd *pwd) { - if (initgroups(pwd->pw_name,pwd->pw_gid)) - return 1; - if (setgid(pwd->pw_uid)) - return 1; - if (setuid(pwd->pw_uid)) - return 1; + if (initgroups(pwd->pw_name,pwd->pw_gid)) return 1; + if (setgid(pwd->pw_uid)) return 1; + if (setuid(pwd->pw_uid)) return 1; return 0; } @@ -162,10 +137,8 @@ int change_identity(const struct passwd *pwd) void spawn_shell(const char *shell) { const char * exec_name = strrchr(shell,'/'); - if (exec_name) - exec_name++; - else - exec_name = shell; + if (exec_name) exec_name++; + else exec_name = shell; snprintf(toybuf,sizeof(toybuf)-1, "-%s", shell); execl(shell, toybuf, NULL); @@ -174,20 +147,18 @@ void spawn_shell(const char *shell) void setup_environment(const struct passwd *pwd, int clear_env) { - if (chdir(pwd->pw_dir)) - printf("can't chdir to home directory: %s\n", pwd->pw_dir); + if (chdir(pwd->pw_dir)) printf("bad home dir: %s\n", pwd->pw_dir); - if (clear_env) - { + if (clear_env) { const char * term = getenv("TERM"); clearenv(); if (term) setenv("TERM", term, 1); } - setenv("USER", pwd->pw_name, 1); - setenv("LOGNAME", pwd->pw_name, 1); - setenv("HOME", pwd->pw_dir, 1); - setenv("SHELL", pwd->pw_shell, 1); + setenv("USER", pwd->pw_name, 1); + setenv("LOGNAME", pwd->pw_name, 1); + setenv("HOME", pwd->pw_dir, 1); + setenv("SHELL", pwd->pw_shell, 1); } void login_main(void) @@ -195,25 +166,23 @@ void login_main(void) int f_flag = (toys.optflags & 4) >> 2; int p_flag = (toys.optflags & 2) >> 1; int h_flag = toys.optflags & 1; - char username[USER_NAME_MAX_SIZE+1]; + char username[USER_NAME_MAX_SIZE+1], *pass = NULL, **ss; struct passwd * pwd = NULL; struct spwd * spwd = NULL; - char *pass = NULL; int auth_fail_cnt = 0; if (f_flag && toys.optc != 1) error_exit("-f requires username"); - if (geteuid() != 0 ) - error_exit("Cannot possibly work without effective root"); + if (geteuid()) error_exit("not root"); - if (!isatty(0) || !isatty(1) || !isatty(2)) - error_exit("Not connected to a tty"); + if (!isatty(0) || !isatty(1) || !isatty(2)) error_exit("no tty"); openlog("login", LOG_PID | LOG_CONS, LOG_AUTH); signal(SIGALRM, login_timeout_handler); alarm(LOGIN_TIMEOUT); - sanitize_env(); + + for (ss = forbid; *ss; ss++) unsetenv(*ss); while (1) { tcflush(0, TCIFLUSH); @@ -223,47 +192,37 @@ void login_main(void) strncpy(username, toys.optargs[0], USER_NAME_MAX_SIZE); else { read_user(username, USER_NAME_MAX_SIZE+1); - if (username[0] == 0) - continue; + if (username[0] == 0) continue; } pwd = getpwnam(username); - if (!pwd) - goto query_pass; // Non-existing user + if (!pwd) goto query_pass; // Non-existing user if (pwd->pw_passwd[0] == '!' || pwd->pw_passwd[0] == '*') goto query_pass; // Locked account - if (f_flag) - break; // Pre-authenticated + if (f_flag) break; // Pre-authenticated - if (pwd->pw_passwd[0] == '\0') - break; // Password-less account + if (!pwd->pw_passwd[0]) break; // Password-less account pass = pwd->pw_passwd; if (pwd->pw_passwd[0] == 'x') { spwd = getspnam (username); - if (spwd) - pass = spwd->sp_pwdp; + if (spwd) pass = spwd->sp_pwdp; } - query_pass: - if (!verify_password(pass)) - break; +query_pass: + if (!verify_password(pass)) break; f_flag = 0; syslog(LOG_WARNING, "invalid password for '%s' on %s %s %s", username, - ttyname(0), - (h_flag)?"from":"", - (h_flag)?TT.hostname:""); + ttyname(0), (h_flag)?"from":"", (h_flag)?TT.hostname:""); sleep(LOGIN_FAIL_TIMEOUT); puts("Login incorrect"); if (++auth_fail_cnt == 3) - { error_exit("Maximum number of tries exceeded (%d)\n", auth_fail_cnt); - } username[0] = 0; pwd = NULL; @@ -272,20 +231,16 @@ void login_main(void) alarm(0); - if (pwd->pw_uid) - handle_nologin(); + if (pwd->pw_uid) handle_nologin(); - if (change_identity(pwd)) - error_exit("Failed to change identity"); + if (change_identity(pwd)) error_exit("Failed to change identity"); setup_environment(pwd, !p_flag); handle_motd(); syslog(LOG_INFO, "%s logged in on %s %s %s", pwd->pw_name, - ttyname(0), - (h_flag)?"from":"", - (h_flag)?TT.hostname:""); + ttyname(0), (h_flag)?"from":"", (h_flag)?TT.hostname:""); spawn_shell(pwd->pw_shell); } |