diff --git a/appl/login/Makefile.am b/appl/login/Makefile.am index 0ed5888bc..15f9536a7 100644 --- a/appl/login/Makefile.am +++ b/appl/login/Makefile.am @@ -5,7 +5,7 @@ AUTOMAKE_OPTIONS = no-dependencies foreign INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4) bin_PROGRAMS = login -login_SOURCES = login.c read_string.c +login_SOURCES = login.c read_string.c utmp_login.c utmpx_login.c tty.c stty_default.c LDADD = $(top_builddir)/lib/krb5/libkrb5.a \ $(top_builddir)/lib/des/libdes.a \ diff --git a/appl/login/login.c b/appl/login/login.c index c7c41d994..2e980788c 100644 --- a/appl/login/login.c +++ b/appl/login/login.c @@ -71,6 +71,14 @@ add_env(const char *var, const char *value) extend_env(str); } +void +copy_env(void) +{ + char **p; + for(p = environ; *p; p++) + extend_env(*p); +} + void exec_shell(const char *shell, int fallback) { @@ -93,11 +101,61 @@ exec_shell(const char *shell, int fallback) err(1, "%s", shell); } +int f_flag; +int p_flag; +int r_flag; +int version_flag; +int help_flag; +char *remote_host; + +struct getargs args[] = { +#if 0 + { NULL, 'a' }, + { NULL, 'd' }, +#endif + { NULL, 'f', arg_flag, &f_flag, "pre-authenticated" }, + { NULL, 'h', arg_string, &remote_host, "remote host", "hostname" }, + { NULL, 'p', arg_flag, &p_flag, "don't purge environment" }, +#if 0 + { NULL, 'r', arg_flag, &r_flag, "rlogin protocol" }, +#endif + { "version", 0, arg_flag, &version_flag }, + { "help", 'h', arg_flag,&help_flag, } +}; + +int nargs = sizeof(args) / sizeof(args[0]); + +void +update_utmp(const char *username, const char *hostname) +{ + char *tty, *ttyn, ttname[32]; + ttyn = ttyname(STDIN_FILENO); + if(ttyn == NULL){ + snprintf(ttname, sizeof(ttname), "%s??", _PATH_TTY); + ttyn = ttname; + } + if((tty = strrchr(ttyn, '/'))) + tty++; + else + tty = ttyn; + + /* + * Update the utmp files, both BSD and SYSV style. + */ + if (utmpx_login(tty, username, hostname) != 0 && !f_flag) { + printf("No utmpx entry. You must exec \"login\" from the " + "lowest level shell.\n"); + exit(1); + } + utmp_login(ttyn, username, hostname); +} + void do_login(struct passwd *pwd) { int rootlogin = (pwd->pw_uid == 0); - update_utmp(); + + update_utmp(pwd->pw_name, remote_host ? remote_host : ""); #ifdef HAVE_SETLOGIN if(setlogin(pwd->pw_name)){ warn("setlogin(%s)", pwd->pw_name); @@ -135,6 +193,7 @@ do_login(struct passwd *pwd) exec_shell(pwd->pw_shell, rootlogin); } +#ifdef KRB5 int krb5_verify(struct passwd *pwd, const char *password) { @@ -185,6 +244,7 @@ krb5_verify(struct passwd *pwd, const char *password) krb5_free_context(context); return ret; } +#endif int check_password(struct passwd *pwd, const char *password) @@ -209,33 +269,10 @@ check_password(struct passwd *pwd, const char *password) return 1; } -int f_flag; -int p_flag; -int r_flag; -int version_flag; -int help_flag; -char *remote_host; - -struct getargs args[] = { -#if 0 - { NULL, 'a' }, - { NULL, 'd' }, -#endif - { "authenticated", 'f', arg_flag, &f_flag, "don't authenticate" }, - { "host", 'h', arg_string, &remote_host, "remote host", "hostname" }, - { "preserve-environment", 'p', arg_flag, &p_flag, - "don't purge environment" }, - { NULL, 'r', arg_flag, &r_flag, "foo" }, - { "version", 0, arg_flag, &version_flag, "print version" }, - { "help", 0, arg_flag, &help_flag, NULL } -}; - -int nargs = sizeof(args) / sizeof(args[0]); - void usage(int status) { - arg_printusage(args, nargs, ""); + arg_printusage(args, nargs, "[username]"); exit(status); } @@ -254,9 +291,6 @@ main(int argc, char **argv) openlog("login", LOG_ODELAY, LOG_AUTH); - if (geteuid() != 0) - err(1, "only root may use login, use su"); - if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) usage (1); @@ -266,8 +300,17 @@ main(int argc, char **argv) if(help_flag) usage(0); if (version_flag) - errx(0, "(%s-%s)", PACKAGE, VERSION); + errx(0, "%s version %s", PACKAGE, VERSION); + if (geteuid() != 0) + err(1, "only root may use login, use su"); + + /* Default tty settings. */ + stty_default(); + + if(p_flag) + copy_env(); + if(*argv){ if(strchr(*argv, '=') == NULL && strcmp(*argv, "-") != 0){ strncpy(username, *argv, sizeof(username)); @@ -278,12 +321,20 @@ main(int argc, char **argv) for(try = 0; try < max_tries; try++){ struct passwd *pwd; char password[128]; + int ret; if(ask){ - read_string("login: ", username, sizeof(username), 1); f_flag = r_flag = 0; + ret = read_string("login: ", username, sizeof(username), 1); + if(ret == -3) + exit(0); + if(ret == -2) + continue; + } + if(f_flag == 0){ + ret = read_string("Password: ", password, sizeof(password), 0); + if(ret == -3 || ret == -2) + continue; } - if(f_flag == 0) - read_string("Password: ", password, sizeof(password), 0); pwd = getpwnam(username); if(pwd == NULL){ fprintf(stderr, "Login incorrect.\n"); diff --git a/appl/login/login_locl.h b/appl/login/login_locl.h index 1ebc9dcda..127f4cda1 100644 --- a/appl/login/login_locl.h +++ b/appl/login/login_locl.h @@ -55,10 +55,31 @@ #include #include #include +#ifdef HAVE_PATHS_H +#include +#endif +#ifdef HAVE_UTMP_H +#include +#endif +#ifdef HAVE_UTMPX_H +#include +#endif #ifdef KRB5 #include #endif +#ifndef _PATH_WTMP +#ifdef WTMP_FILE +#define _PATH_WTMP WTMP_FILE +#else +#define _PATH_WTMP "/var/adm/wtmp" +#endif +#endif + int read_string(const char*, char*, size_t, int); +char *clean_ttyname (char*); +char *make_id (char*); + + #endif /* __LOGIN_LOCL_H__ */ diff --git a/appl/login/read_string.c b/appl/login/read_string.c index 8ba6277e7..1e8ca127a 100644 --- a/appl/login/read_string.c +++ b/appl/login/read_string.c @@ -86,7 +86,8 @@ read_string(const char *prompt, char *buf, size_t len, int echo) while(intr_flag == 0){ c = getc(tty); if(c == EOF){ - ret = 1; + if(!ferror(tty)) + ret = 1; break; } if(c == '\n') @@ -110,7 +111,13 @@ read_string(const char *prompt, char *buf, size_t len, int echo) for(i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++) sigaction(i, &sigs[i], NULL); - return of || intr_flag || ret; + if(ret) + return -3; + if(intr_flag) + return -2; + if(of) + return -1; + return 0; } diff --git a/appl/login/stty_default.c b/appl/login/stty_default.c index c840cc5b4..1b11cb55e 100644 --- a/appl/login/stty_default.c +++ b/appl/login/stty_default.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. */ -#include "bsd_locl.h" +#include "login_locl.h" RCSID("$Id$"); diff --git a/appl/login/tty.c b/appl/login/tty.c index c2e0c7eeb..c70ffa624 100644 --- a/appl/login/tty.c +++ b/appl/login/tty.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. */ -#include "bsd_locl.h" +#include "login_locl.h" RCSID("$Id$"); diff --git a/appl/login/utmp_login.c b/appl/login/utmp_login.c index 4447e6898..bc74126d4 100644 --- a/appl/login/utmp_login.c +++ b/appl/login/utmp_login.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. */ -#include "bsd_locl.h" +#include "login_locl.h" RCSID("$Id$"); diff --git a/appl/login/utmpx_login.c b/appl/login/utmpx_login.c index e68040494..d0631a6f6 100644 --- a/appl/login/utmpx_login.c +++ b/appl/login/utmpx_login.c @@ -1,6 +1,6 @@ /* Author: Wietse Venema */ -#include "bsd_locl.h" +#include "login_locl.h" RCSID("$Id$");