aboutsummaryrefslogtreecommitdiff
path: root/toys/other/login.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/other/login.c')
-rw-r--r--toys/other/login.c286
1 files changed, 134 insertions, 152 deletions
diff --git a/toys/other/login.c b/toys/other/login.c
index a9e7562c..72d7063e 100644
--- a/toys/other/login.c
+++ b/toys/other/login.c
@@ -1,6 +1,4 @@
-/* vi: set sw=4 ts=4:
- *
- * login.c - Start a session on the system.
+/* login.c - Start a session on the system.
*
* Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com>
*
@@ -10,15 +8,15 @@
USE_LOGIN(NEWTOY(login, ">1fph:", TOYFLAG_BIN))
config LOGIN
- bool "login"
- default y
- help
- usage: login [-p] [-h host] [[-f] username]
-
- Establish a new session with the system.
- -p Preserve environment
- -h The name of the remote host for this login
- -f Do not perform authentication
+ bool "login"
+ default y
+ help
+ usage: login [-p] [-h host] [[-f] username]
+
+ Establish a new session with the system.
+ -p Preserve environment
+ -h The name of the remote host for this login
+ -f Do not perform authentication
*/
#define FOR_login
@@ -30,215 +28,199 @@ config LOGIN
#define HOSTNAME_SIZE 32
GLOBALS(
- char *hostname;
+ char *hostname;
)
static void login_timeout_handler(int sig __attribute__((unused)))
{
- printf("\nLogin timed out after %d seconds.\n", LOGIN_TIMEOUT);
- exit(0);
+ printf("\nLogin timed out after %d seconds.\n", LOGIN_TIMEOUT);
+ exit(0);
}
static char *forbid[] = {
- "BASH_ENV",
- "ENV",
- "HOME",
- "IFS",
- "LD_LIBRARY_PATH",
- "LD_PRELOAD",
- "LD_TRACE_LOADED_OBJECTS",
- "LD_BIND_NOW",
- "LD_AOUT_LIBRARY_PATH",
- "LD_AOUT_PRELOAD",
- "LD_NOWARN",
- "LD_KEEPDIR",
- "SHELL",
- NULL
+ "BASH_ENV", "ENV", "HOME", "IFS", "LD_LIBRARY_PATH", "LD_PRELOAD",
+ "LD_TRACE_LOADED_OBJECTS", "LD_BIND_NOW", "LD_AOUT_LIBRARY_PATH",
+ "LD_AOUT_PRELOAD", "LD_NOWARN", "LD_KEEPDIR", "SHELL", NULL
};
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 && !strcmp(pass, pwd)) return 0;
+ pass = crypt(toybuf, pwd);
+ if (pass && !strcmp(pass, pwd)) return 0;
- return 1;
+ return 1;
}
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);
-
- fputs(" login: ", stdout);
- fflush(stdout);
-
- do {
- buff[0] = getchar();
- if (buff[0] == EOF)
- exit(EXIT_FAILURE);
- } while (isblank(buff[0]));
-
- if (buff[0] != '\n')
- if(!fgets(&buff[1], HOSTNAME_SIZE-1, stdin))
- _exit(1);
-
- while(i<HOSTNAME_SIZE-1 && isgraph(buff[i])) i++;
- buff[i] = 0;
+ char hostname[HOSTNAME_SIZE+1];
+ int i = 0;
+ hostname[HOSTNAME_SIZE] = 0;
+ if(!gethostname(hostname, HOSTNAME_SIZE)) fputs(hostname, stdout);
+
+ fputs(" login: ", stdout);
+ fflush(stdout);
+
+ do {
+ buff[0] = getchar();
+ if (buff[0] == EOF) exit(EXIT_FAILURE);
+ } while (isblank(buff[0]));
+
+ if (buff[0] != '\n') if(!fgets(&buff[1], HOSTNAME_SIZE-1, stdin)) _exit(1);
+
+ while(i<HOSTNAME_SIZE-1 && isgraph(buff[i])) i++;
+ buff[i] = 0;
}
void handle_nologin(void)
{
- int fd = open("/etc/nologin", O_RDONLY);
- int size;
- 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);
-
- close(fd);
- fflush(stdout);
- exit(EXIT_FAILURE);
+ int fd = open("/etc/nologin", O_RDONLY);
+ int size;
+ 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);
+
+ close(fd);
+ fflush(stdout);
+ exit(EXIT_FAILURE);
}
void handle_motd(void)
{
- int fd = open("/etc/motd", O_RDONLY);
- int size;
- if (fd == -1) return;
+ int fd = open("/etc/motd", O_RDONLY);
+ int size;
+ if (fd == -1) return;
- size = readall(fd, toybuf,sizeof(toybuf)-1);
- toybuf[size] = 0;
- puts(toybuf);
+ size = readall(fd, toybuf,sizeof(toybuf)-1);
+ toybuf[size] = 0;
+ puts(toybuf);
- close(fd);
- fflush(stdout);
+ close(fd);
+ fflush(stdout);
}
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;
+ return 0;
}
void spawn_shell(const char *shell)
{
- const char * exec_name = strrchr(shell,'/');
- if (exec_name) exec_name++;
- else exec_name = shell;
+ const char * exec_name = strrchr(shell,'/');
+ if (exec_name) exec_name++;
+ else exec_name = shell;
- snprintf(toybuf,sizeof(toybuf)-1, "-%s", shell);
- execl(shell, toybuf, NULL);
- error_exit("Failed to spawn shell");
+ snprintf(toybuf,sizeof(toybuf)-1, "-%s", shell);
+ execl(shell, toybuf, NULL);
+ error_exit("Failed to spawn shell");
}
void setup_environment(const struct passwd *pwd, int clear_env)
{
- if (chdir(pwd->pw_dir)) printf("bad home dir: %s\n", pwd->pw_dir);
-
- 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);
+ if (chdir(pwd->pw_dir)) printf("bad home dir: %s\n", pwd->pw_dir);
+
+ 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);
}
void login_main(void)
{
- int f_flag = toys.optflags & FLAG_f;
- int h_flag = toys.optflags & FLAG_h;
- char username[USER_NAME_MAX_SIZE+1], *pass = NULL, **ss;
- struct passwd * pwd = NULL;
- struct spwd * spwd = NULL;
- int auth_fail_cnt = 0;
+ int f_flag = toys.optflags & FLAG_f;
+ int h_flag = toys.optflags & FLAG_h;
+ char username[USER_NAME_MAX_SIZE+1], *pass = NULL, **ss;
+ struct passwd * pwd = NULL;
+ struct spwd * spwd = NULL;
+ int auth_fail_cnt = 0;
- if (f_flag && toys.optc != 1)
- error_exit("-f requires username");
+ if (f_flag && toys.optc != 1) error_exit("-f requires username");
- if (geteuid()) error_exit("not root");
+ if (geteuid()) error_exit("not root");
- if (!isatty(0) || !isatty(1) || !isatty(2)) error_exit("no 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);
+ openlog("login", LOG_PID | LOG_CONS, LOG_AUTH);
+ signal(SIGALRM, login_timeout_handler);
+ alarm(LOGIN_TIMEOUT);
- for (ss = forbid; *ss; ss++) unsetenv(*ss);
+ for (ss = forbid; *ss; ss++) unsetenv(*ss);
- while (1) {
- tcflush(0, TCIFLUSH);
+ while (1) {
+ tcflush(0, TCIFLUSH);
- username[USER_NAME_MAX_SIZE] = 0;
- if (toys.optargs[0])
- strncpy(username, toys.optargs[0], USER_NAME_MAX_SIZE);
- else {
- read_user(username, USER_NAME_MAX_SIZE+1);
- if (username[0] == 0) continue;
- }
+ username[USER_NAME_MAX_SIZE] = 0;
+ if (toys.optargs[0]) strncpy(username, toys.optargs[0], USER_NAME_MAX_SIZE);
+ else {
+ read_user(username, USER_NAME_MAX_SIZE+1);
+ if (username[0] == 0) continue;
+ }
- pwd = getpwnam(username);
- if (!pwd) goto query_pass; // Non-existing user
+ pwd = getpwnam(username);
+ if (!pwd) goto query_pass; // Non-existing user
- if (pwd->pw_passwd[0] == '!' || pwd->pw_passwd[0] == '*')
- goto query_pass; // Locked account
+ 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]) 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;
- }
+ pass = pwd->pw_passwd;
+ if (pwd->pw_passwd[0] == 'x') {
+ spwd = getspnam (username);
+ if (spwd) pass = spwd->sp_pwdp;
+ }
query_pass:
- if (!verify_password(pass)) break;
+ 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:"");
+ f_flag = 0;
+ syslog(LOG_WARNING, "invalid password for '%s' on %s %s %s", username,
+ ttyname(0), h_flag?"from":"", h_flag?TT.hostname:"");
- sleep(LOGIN_FAIL_TIMEOUT);
- puts("Login incorrect");
+ sleep(LOGIN_FAIL_TIMEOUT);
+ puts("Login incorrect");
- if (++auth_fail_cnt == 3)
- error_exit("Maximum number of tries exceeded (%d)\n", auth_fail_cnt);
+ if (++auth_fail_cnt == 3)
+ error_exit("Maximum number of tries exceeded (%d)\n", auth_fail_cnt);
- username[0] = 0;
- pwd = NULL;
- spwd = NULL;
- }
+ username[0] = 0;
+ pwd = NULL;
+ spwd = NULL;
+ }
- alarm(0);
+ 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, !(toys.optflags & FLAG_p));
+ setup_environment(pwd, !(toys.optflags & FLAG_p));
- handle_motd();
+ handle_motd();
- syslog(LOG_INFO, "%s logged in on %s %s %s", pwd->pw_name,
- ttyname(0), h_flag?"from":"", h_flag?TT.hostname:"");
+ syslog(LOG_INFO, "%s logged in on %s %s %s", pwd->pw_name,
+ ttyname(0), h_flag?"from":"", h_flag?TT.hostname:"");
- spawn_shell(pwd->pw_shell);
+ spawn_shell(pwd->pw_shell);
}