X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/53b3a5b27d432e7d4cc4793b62be680701efbcd2..133ce0bc0996f2a55c50c673895d981e9c77691b:/usr/src/usr.bin/login/login.c diff --git a/usr/src/usr.bin/login/login.c b/usr/src/usr.bin/login/login.c index 8df6e185a5..d83752a117 100644 --- a/usr/src/usr.bin/login/login.c +++ b/usr/src/usr.bin/login/login.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1980 Regents of the University of California. + * Copyright (c) 1980,1987 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ @@ -11,13 +11,14 @@ char copyright[] = #endif not lint #ifndef lint -static char sccsid[] = "@(#)login.c 5.16 (Berkeley) %G%"; +static char sccsid[] = "@(#)login.c 5.23 (Berkeley) %G%"; #endif not lint /* * login [ name ] - * login -r hostname (for rlogind) - * login -h hostname (for telnetd, etc.) + * login -r hostname (for rlogind) + * login -h hostname (for telnetd, etc.) + * login -f name (for pre-authenticated login: datakit, xterm, etc.) */ #include @@ -58,23 +59,22 @@ struct passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" }; struct sgttyb ttyb; struct utmp utmp; char minusnam[16] = "-"; -char *envinit[] = { 0 }; /* now set by setenv calls */ +char *envinit[1]; /* now set by setenv calls */ /* * This bounds the time given to login. We initialize it here * so it can be patched on machines where it's too small. */ -int timeout = 60; +int timeout = 300; char term[64]; struct passwd *pwd; -char *strcat(), *rindex(), *index(), *malloc(), *realloc(); +char *strcat(), *rindex(), *index(); int timedout(); char *ttyname(); char *crypt(); char *getpass(); char *stypeof(); -extern char **environ; extern int errno; struct tchars tc = { @@ -97,13 +97,13 @@ char *rhost; main(argc, argv) char *argv[]; { + extern char **environ; register char *namep; - int pflag = 0, hflag = 0, t, f, c; + int pflag = 0, hflag = 0, fflag = 0, t, f, c; int invalid, quietlog; FILE *nlfd; char *ttyn, *tty; - int ldisc = 0, zero = 0, i; - char **envnew; + int ldisc = 0, zero = 0; char *p, *domain, *index(); signal(SIGALRM, timedout); @@ -115,6 +115,7 @@ main(argc, argv) /* * -p is used by getty to tell login not to destroy the environment * -r is used by rlogind to cause the autologin protocol; + * -f is used to skip a second login authentication * -h is used by other servers to pass the name of the * remote host to login so that it may be placed in utmp and wtmp */ @@ -122,10 +123,12 @@ main(argc, argv) domain = index(me, '.'); while (argc > 1) { if (strcmp(argv[1], "-r") == 0) { - if (rflag || hflag) { - printf("Only one of -r and -h allowed\n"); + if (rflag || hflag || fflag) { + printf("Other options not allowed with -r\n"); exit(1); } + if (argv[2] == 0) + exit(1); rflag = 1; usererr = doremotelogin(argv[2]); if ((p = index(argv[2], '.')) && strcmp(p, domain) == 0) @@ -135,15 +138,29 @@ main(argc, argv) argv += 2; continue; } - if (strcmp(argv[1], "-h") == 0 && getuid() == 0) { - if (rflag || hflag) { - printf("Only one of -r and -h allowed\n"); + if (strcmp(argv[1], "-h") == 0) { + if (getuid() == 0) { + if (rflag || hflag) { + printf("Only one of -r and -h allowed\n"); + exit(1); + } + hflag = 1; + if ((p = index(argv[2], '.')) && + strcmp(p, domain) == 0) + *p = 0; + SCPYN(utmp.ut_host, argv[2]); + } + argc -= 2; + argv += 2; + continue; + } + if (strcmp(argv[1], "-f") == 0 && argc > 2) { + if (rflag) { + printf("Only one of -r and -f allowed\n"); exit(1); } - hflag = 1; - if ((p = index(argv[2], '.')) && strcmp(p, domain) == 0) - *p = 0; - SCPYN(utmp.ut_host, argv[2]); + fflag = 1; + SCPYN(utmp.ut_name, argv[2]); argc -= 2; argv += 2; continue; @@ -189,7 +206,8 @@ main(argc, argv) do { ldisc = 0; ioctl(0, TIOCSETD, &ldisc); - SCPYN(utmp.ut_name, ""); + if (fflag == 0) + SCPYN(utmp.ut_name, ""); /* * Name specified, take it. */ @@ -203,19 +221,36 @@ main(argc, argv) */ if (rflag && !invalid) SCPYN(utmp.ut_name, lusername); - else + else { getloginname(&utmp); + if (utmp.ut_name[0] == '-') { + puts("login names may not start with '-'."); + invalid = TRUE; + continue; + } + } invalid = FALSE; if (!strcmp(pwd->pw_shell, "/bin/csh")) { ldisc = NTTYDISC; ioctl(0, TIOCSETD, &ldisc); } + if (fflag) { + int uid = getuid(); + + if (uid != 0 && uid != pwd->pw_uid) + fflag = 0; + /* + * Disallow automatic login for root. + */ + if (pwd->pw_uid == 0) + fflag = 0; + } /* * If no remote login authentication and * a password exists for this user, prompt * for one and verify it. */ - if (usererr == -1 && *pwd->pw_passwd != '\0') { + if (usererr == -1 && fflag == 0 && *pwd->pw_passwd != '\0') { char *pp; setpriority(PRIO_PROCESS, 0, -4); @@ -228,7 +263,7 @@ main(argc, argv) /* * If user not super-user, check for logins disabled. */ - if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) { + if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r"))) { while ((c = getc(nlfd)) != EOF) putchar(c); fflush(stdout); @@ -253,13 +288,13 @@ main(argc, argv) printf("Login incorrect\n"); if (++t >= 5) { if (utmp.ut_host[0]) - syslog(LOG_CRIT, - "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s", + syslog(LOG_ERR, + "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s", tty, HMAX, utmp.ut_host, NMAX, utmp.ut_name); else - syslog(LOG_CRIT, - "REPEATED LOGIN FAILURES ON %s, %.*s", + syslog(LOG_ERR, + "REPEATED LOGIN FAILURES ON %s, %.*s", tty, NMAX, utmp.ut_name); ioctl(0, TIOCHPCL, (struct sgttyb *) 0); close(0), close(1), close(2); @@ -302,17 +337,8 @@ main(argc, argv) exit(0); } time(&utmp.ut_time); - t = ttyslot(); - if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) { - lseek(f, (long)(t*sizeof(utmp)), 0); - SCPYN(utmp.ut_line, tty); - write(f, (char *)&utmp, sizeof(utmp)); - close(f); - } - if ((f = open("/usr/adm/wtmp", O_WRONLY|O_APPEND)) >= 0) { - write(f, (char *)&utmp, sizeof(utmp)); - close(f); - } + SCPYN(utmp.ut_line, tty); + login(&utmp); quietlog = access(qlog, F_OK) == 0; if ((f = open(lastlog, O_RDWR)) >= 0) { struct lastlog ll; @@ -346,27 +372,17 @@ main(argc, argv) initgroups(name, pwd->pw_gid); quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); setuid(pwd->pw_uid); + /* destroy environment unless user has asked to preserve it */ if (!pflag) environ = envinit; - - /* set up environment, this time without destruction */ - /* copy the environment before setenving */ - i = 0; - while (environ[i] != NULL) - i++; - envnew = (char **) malloc(sizeof (char *) * (i + 1)); - for (; i >= 0; i--) - envnew[i] = environ[i]; - environ = envnew; - - setenv("HOME=", pwd->pw_dir, 1); - setenv("SHELL=", pwd->pw_shell, 1); + setenv("HOME", pwd->pw_dir, 1); + setenv("SHELL", pwd->pw_shell, 1); if (term[0] == '\0') strncpy(term, stypeof(tty), sizeof(term)); - setenv("TERM=", term, 0); - setenv("USER=", pwd->pw_name, 1); - setenv("PATH=", ":/usr/ucb:/bin:/usr/bin", 0); + setenv("TERM", term, 0); + setenv("USER", pwd->pw_name, 1); + setenv("PATH", ":/usr/ucb:/bin:/usr/bin", 0); if ((namep = rindex(pwd->pw_shell, '/')) == NULL) namep = pwd->pw_shell; @@ -542,43 +558,6 @@ doremoteterm(term, tp) tp->sg_flags = ECHO|CRMOD|ANYP|XTABS; } -/* - * Set the value of var to be arg in the Unix 4.2 BSD environment env. - * Var should end with '='. - * (bindings are of the form "var=value") - * This procedure assumes the memory for the first level of environ - * was allocated using malloc. - */ -setenv(var, value, clobber) - char *var, *value; -{ - extern char **environ; - int index = 0; - int varlen = strlen(var); - int vallen = strlen(value); - - for (index = 0; environ[index] != NULL; index++) { - if (strncmp(environ[index], var, varlen) == 0) { - /* found it */ - if (!clobber) - return; - environ[index] = malloc(varlen + vallen + 1); - strcpy(environ[index], var); - strcat(environ[index], value); - return; - } - } - environ = (char **) realloc(environ, sizeof (char *) * (index + 2)); - if (environ == NULL) { - fprintf(stderr, "login: malloc out of memory\n"); - exit(1); - } - environ[index] = malloc(varlen + vallen + 1); - strcpy(environ[index], var); - strcat(environ[index], value); - environ[++index] = NULL; -} - tty_gid(default_gid) int default_gid; {