4 * This is an AFS-aware login.
6 * Machine/os specific code is surrounded by #ifdef <system>
8 * The Q_SETUID and Q_DOWARN #ifdefs are for IBM's AOS which doesn't
9 * define them if NFS is configured. Like that matters anymore
13 * Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
14 * All rights reserved.
16 * Redistribution and use in source and binary forms are permitted
17 * provided that the above copyright notice and this paragraph are
18 * duplicated in all such forms and that any documentation,
19 * advertising materials, and other materials related to such
20 * distribution and use acknowledge that the software was developed
21 * by the University of California, Berkeley. The name of the
22 * University may not be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
26 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
31 * login -h hostname (for telnetd, etc.)
32 * login -f name (for pre-authenticated login: datakit, xterm, etc.)
35 #if !defined(UT_NAMESIZE)
39 #include <afsconfig.h>
40 #include <afs/param.h>
48 #include <afs/kautils.h>
50 #include <sys/fs/ufs_quota.h>
52 #if !defined(AFS_HPUX_ENV) && !defined(AFS_AIX_ENV)
53 #if defined(AFS_SUN_ENV) || (defined(AFS_ATHENA_STDENV) && !defined(AFS_DEC_ENV)) || defined(AFS_OSF_ENV)
54 #include <ufs/quota.h>
55 #elif defined(AFS_FBSD_ENV)
56 #include <ufs/ufs/quota.h>
58 #include <sys/quota.h>
64 #include <sys/resource.h>
67 #include <sys/termios.h>
68 #include <sys/ttychars.h>
69 /* hack to get it to build */
71 #include <sys/ttydev.h>
72 #include <sys/ttold.h>
73 #include <sys/filio.h>
77 #include <sys/ttydefaults.h>
79 #include <sys/ioctl.h>
87 #if !defined(AIX) && !defined(AFS_HPUX_ENV) && !defined(AFS_AIX32_ENV) && !defined(AFS_FBSD_ENV)
96 #include <sys/termio.h>
97 #include <sys/syslog.h>
100 #if !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV)
103 #if defined(AFS_HPUX_ENV)
105 #include <sys/bsdtty.h>
116 #define TTYGRPNAME "tty" /* name of group to own ttys */
118 #define MOTDFILE "/etc/motd"
120 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX100_ENV)
123 #define MAILDIR "/var/mail/"
125 #define MAILDIR "/usr/mail/"
127 static char mail[30];
129 #else /* AFS_SUN5_ENV || AFS_HPUX100_ENV */
130 #define MAILDIR "/usr/spool/mail"
131 #endif /* AFS_SUN5_ENV || AFS_HPUX100_ENV */
133 #define NOLOGIN "/etc/nologin"
134 #define HUSHLOGIN ".hushlogin"
135 #define LASTLOG "/usr/adm/lastlog"
136 #define BSHELL "/bin/sh"
137 #define SECURETTY_FILE "/etc/securetty"
140 * This bounds the time given to login. Not a define so it can
141 * be patched on machines where it's too small.
145 struct passwd *pwd, *getpwnam();
147 char term[64], *hostname, *username, *tty;
151 struct sgttyb sgttyb;
155 extern char *defread(), *strdup();
156 static void defaults();
157 static char *Pndefault = "/etc/default/login";
158 static char *Altshell = NULL;
159 static char *Console = NULL;
160 static int Idleweeks = -1;
161 static char *Passreq = NULL;
163 static mode_t Umask = DEFUMASK;
164 static char *Def_tz = NULL;
165 static char *tmp_tz = NULL;
166 static char *Def_hertz = NULL;
167 #define SET_FSIZ 2 /* ulimit() command arg */
168 static long Def_ulimit = 0;
169 #define MAX_TIMEOUT (15 * 60)
170 #define DEF_TIMEOUT 5*60
171 static unsigned Def_timeout = DEF_TIMEOUT;
172 static char *Def_path = NULL;
173 static char *Def_supath = NULL;
174 #define DEF_PATH "/usr/bin:" /* same as PATH */
175 #define DEF_SUPATH "/usr/sbin:/usr/bin" /* same as ROOTPATH */
177 * Intervals to sleep after failed login
180 # define SLEEPTIME 4 /* sleeptime before login incorrect msg */
182 static int Sleeptime = SLEEPTIME;
185 /* This is for Solaris's shadow pass struc */
186 static struct spwd *spwd;
190 static int authenticated_remote_user = 0;
191 static char rhost[64], rusername[10], lusername[10];
197 /* For setting of TZ environment on HPUX */
199 #define MAX_TZ_LEN 256
200 static char TZ[MAX_TZ_LEN];
201 #endif /* AFS_HPUX_ENV */
203 #ifdef AFS_KERBEROS_ENV
204 extern char *ktc_tkt_string();
207 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
209 /* CINTR, CQUIT, CSTART, CSTOP, 000, 000 */
210 CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
213 struct ltchars ltc = {
214 CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
221 SIAENTITY *entity = NULL;
224 #include <sys/security.h>
230 #define NOPAG 0xffffffff
233 /* For avoiding making an osi_audit call when non-root */
242 fprintf(stderr, "Login timed out after %d seconds\n", timeout);
249 register unsigned long aval;
251 register char *tp = ttp;
267 #include "AFS_component_version_number.c"
276 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
277 /* the following utmp field is used for user counting: */
278 #define how_to_count ut_exit.e_exit
280 #define SUBLOGIN "<!sublogin>"
282 main(argc, argv, renvp)
290 extern int errno, optind;
291 extern char *optarg, **environ;
292 struct group *gr, *getgrnam();
295 int ask, fflag, hflag, rflag, pflag, cnt, locl, zero = 0, dflag =
297 int quietlog, passwd_req, ioctlval;
298 char *domain, *salt, *envinit[2], *ttyn = 0, *pp;
299 char tbuf[MAXPATHLEN + 2];
300 char *ttyname(), *stypeof(), *crypt(), *getpass();
301 extern off_t lseek();
303 char *lcell; /* local cellname */
304 char realm[MAXKTCREALMLEN];
305 char buf1[256], **envp;
306 afs_int32 j, pagval = NOPAG, ngroups, groups[NGROUPS_MAX];
307 long password_expires = -1;
308 extern char *AFSVersion; /* generated version */
309 int afsLoginFail = 0;
312 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
313 char retry_chdir = 0;
314 #endif /* AFS_SUN5_ENV || AFS_HPUX_ENV */
317 char tname[sizeof(_PATH_TTY) + 10], *loginname = NULL;
324 defaults(); /* Set up Defaults and flags */
325 if (Umask < 0 || ((mode_t) 0777) < Umask) /* Set up default umask */
329 if (Def_timeout > MAX_TIMEOUT) /* Set up default timeouts and delays */
330 Def_timeout = MAX_TIMEOUT;
331 if (Sleeptime < 0 || Sleeptime > 5)
332 Sleeptime = SLEEPTIME;
333 (void)alarm(Def_timeout);
335 (void)alarm((u_int) timeout);
337 (void)signal(SIGALRM, timedout);
339 (void)signal(SIGQUIT, SIG_IGN);
340 (void)signal(SIGINT, SIG_IGN);
341 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
342 (void)setpriority(PRIO_PROCESS, 0, 0);
345 (void)quota(Q_SETUID, 0, 0, 0);
346 #endif /* Q_SETUID */
349 * -p is used by getty to tell login not to destroy the environment
350 * -f is used to skip a second login authentication
351 * -h is used by other servers to pass the name of the remote
352 * host to login so that it may be placed in utmp and wtmp
354 (void)gethostname(tbuf, sizeof(tbuf));
355 domain = strchr(tbuf, '.');
359 * Set flag to disable the pid check if you find that you are
363 if (*renvp && strcmp(*renvp, SUBLOGIN) == 0)
366 fflag = hflag = pflag = rflag = 0;
367 memset(&utmp, '\0', sizeof(utmp));
371 while ((ch = getopt(argc, argv, "fh:prd")) != -1) {
373 while ((ch = getopt(argc, argv, "fh:pr")) != -1) {
376 while ((ch = getopt(argc, argv, "fh:p")) != EOF) {
378 /*printf("ch='%c'\n", ch);*/
385 if (hflag || rflag) {
386 fprintf(stderr, "Only one of -r and -h allowed\n");
391 fprintf(stderr, "login: -h for super-user only.\n");
397 if (domain && (p = strchr(optarg, '.'))
398 && strcasecmp(p, domain) == 0)
404 if (hflag || rflag) {
405 fprintf(stderr, "Only one of -r and -h allowed\n");
415 usererr = doremotelogin(argv[2]);
416 strncpy(utmp.ut_host, argv[2], sizeof(utmp.ut_host));
424 case 'd': /* Ignode the '-d device' option for now!!! */
436 fprintf(stderr, "usage: login [-fp] [username]\n");
444 strcpy(rhost, *argv++);
446 if (argv[0] && (*argv[0] != '-')) {
447 if ((!strncmp(*argv, "TERM=", strlen("TERM=")))) {
448 strncpy(term, &((*argv)[strlen("TERM=")]), sizeof(term));
454 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
455 if (!rflag && *argv) {
460 memset(ousername, '\0', sizeof(ousername));
461 strcpy(ousername, *argv);
462 loginname = ousername;
469 ttypmt = getenv("TTYPROMPT");
470 if (ttypmt && (*ttypmt != '\0')) {
471 extern char **getargs();
473 * if ttyprompt is set, there should be data on the stream already.
475 if ((envp = getargs(buf1)) != (char **)NULL) {
490 #if !defined(AIX) && !defined(AFS_HPUX_ENV) && !defined(AFS_OSF_ENV)
491 (void)ioctl(0, TIOCLSET, &ioctlval);
493 (void)ioctl(0, TIOCNXCL, 0);
495 (void)fcntl(0, F_SETFL, ioctlval);
496 (void)ioctl(0, TIOCGETP, &sgttyb);
498 (void)ioctl(0, FIONBIO, &zero);
499 (void)ioctl(0, FIOASYNC, &zero);
500 (void)ioctl(0, TIOCLGET, &locl);
502 * If talking to an rlogin process,
503 * propagate the terminal type and
504 * baud rate across the network.
511 doremoteterm(term, &sgttyb);
515 locl |= LCRTBS | LCTLECH | LDECCTQ;
516 if (sgttyb.sg_ospeed >= B1200)
517 locl |= LCRTERA | LCRTKIL;
518 (void)ioctl(0, TIOCLSET, &locl);
520 sgttyb.sg_erase = CERASE;
521 sgttyb.sg_kill = CKILL;
522 (void)ioctl(0, TIOCSLTC, <c);
523 (void)ioctl(0, TIOCSETC, &tc);
527 (void)ioctl(0, TIOCSETP, &sgttyb);
529 for (cnt = getdtablesize(); cnt > 2; cnt--)
538 if (ttyn == NULL || *ttyn == '\0') {
540 (void)sprintf(tname, "%s??", _PATH_TTY);
549 ttyntail = ttyn + sizeof("/dev/") - 1;
551 if (tty = strrchr(ttyn, '/'))
556 openlog("login", LOG_ODELAY, LOG_AUTH);
559 #define _PATH_HUSHLOGIN ".hushlogin"
560 #define _PATH_MAILDIR "/var/spool/mail"
561 #ifndef _PATH_DEFPATH
562 #define _PATH_DEFPATH "/usr/bin:."
566 int authret = 0, doafs = 0;
567 char shell[PATH_MAX + 1] = _PATH_BSHELL, *pass, user[40], ouser[40];
568 int (*sia_collect) () = sia_collect_trm;
569 int getloginp(), uid;
572 /*printf("loginname=%s, ttyn=%s, fflag=%d\n", loginname, ttyn, fflag);*/
575 (&entity, oargc, oargv, hostname, loginname, ttyn, 1,
576 NULL)) == SIASUCCESS) {
577 static int useGetPass = 0;
578 int cnt1 = 0, first = 0;
579 char *prompt, *reason, pword[BUFSIZ];
580 /***** SIA SESSION AUTHENTICATION *****/
582 for (cnt = 5; cnt; cnt--) {
584 if (first++ || !entity->name) {
585 clean_entity_pwd(entity);
586 if (getloginp(entity) < 0) {
587 printf("Illegal login name\n");
592 strcpy(user, entity->name);
593 prompt = "Password:";
594 if ((pwd = getpwnam(user))) {
595 if (!strcmp(pwd->pw_passwd, "X")) {
600 pass = getpass(prompt);
603 ka_UserReadPassword(prompt, pword, sizeof(pword),
607 if (code != KANULLPASSWORD) {
612 "Unable to read password because %s\n",
619 printf("Login incorrect\n");
627 sia_ses_authent(sia_collect, pass,
628 entity)) == SIASUCCESS)) {
631 sia_make_entity_pwd(pwd, entity);
633 uid = entity->pwd->pw_uid;
637 authret = do_afs_auth(pwd, pass, doafs);
640 printf("Login incorrect\n");
645 printf("AFS (R) %s Login\n", AFSVersion);
648 groups[0] = groups[1] = 0;
649 ngroups = getgroups(NGROUPS, groups);
651 get_pag_from_groups(groups[0], groups[1]);
654 } else if (authret & SIASTOP) {
656 } else if (authret == SIAFAIL) {
657 /* why did it fail ? */
661 ** if the "ptys" command does not exist in the
662 ** /etc/securettys file, then root login's are
663 ** allowed only from the console
665 if (!pwd->pw_uid) /* for root */
666 if (((ptr = getttynam("ptys")) == NULL)
667 || !(ptr->ty_status & TTY_SECURE)) {
669 ("root login refused on this terminal\n");
673 if (doafs || (authret != SIASUCCESS)) {
675 sia_make_entity_pwd(pwd, entity);
678 printf("login incorrect\n");
680 if (cnt <= 0 || (doafs == -1)) {
681 sia_ses_release(&entity);
685 /***** SIA SESSION ESTABLISHMENT *****/
686 if (sia_ses_estab(sia_collect, entity) == SIASUCCESS) {
688 * Display and update lastlog file entry. -DAL003
690 quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
692 quietlog = !*entity->pwd->pw_passwd
693 && !usershell(entity->pwd->pw_shell);
697 #ifdef AFS_KERBEROS_ENV
698 (void)chown(ktc_tkt_string(), pwd->pw_uid, pwd->pw_gid);
699 #endif /* AFS_KERBEROS_ENV */
700 /***** SIA LAUNCHING SESSION *****/
701 if (sia_ses_launch(sia_collect, entity) == SIASUCCESS) {
702 ngroups = getgroups(NGROUPS, groups);
703 if ((pagval != NOPAG)
704 && (afs_get_pag_from_groups(groups[0], groups[1])) ==
706 /* we will have to shift grouplist to make room for pag */
707 if (ngroups + 2 > NGROUPS) {
708 perror("Too many groups"); /* XXX */
711 for (j = ngroups - 1; j >= 0; j--) {
712 groups[j + 2] = groups[j];
715 get_groups_from_pag(pagval, &groups[0], &groups[1]);
716 seteuid(0); /* Since the seteuid was set the user already */
717 if (setgroups(ngroups, groups) == -1) {
721 seteuid(entity->pwd->pw_uid); /* Set euid back */
723 /****** Nothing left to fail *******/
724 if (setreuid(geteuid(), geteuid()) < 0) {
725 perror("setreuid()");
728 /****** set up environment *******/
729 /* destroy environment unless user has requested preservation */
730 envinit[0] = envinit[1] = 0;
732 for (cnt = 0; environ[cnt] != NULL; cnt++)
733 if (!strncmp(environ[cnt], "TERM=", 5)) {
734 envinit[0] = environ[cnt];
739 (void)setenv("HOME", entity->pwd->pw_dir, 1);
740 if (entity->pwd->pw_shell && *entity->pwd->pw_shell)
741 strncpy(shell, entity->pwd->pw_shell, sizeof shell);
742 (void)setenv("SHELL", shell, 1);
744 (void)strncpy(term, stypeof(tty), sizeof(term));
745 (void)setenv("TERM", term, 0);
746 (void)setenv("USER", entity->pwd->pw_name, 1);
747 (void)setenv("LOGNAME", entity->pwd->pw_name, 1);
748 (void)setenv("PATH", _PATH_DEFPATH, 0);
749 #ifdef AFS_KERBEROS_ENV
750 (void)setenv("KRBTKFILE", ktc_tkt_string(), 0);
751 #endif /* AFS_KERBEROS_ENV */
756 (void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR,
757 entity->pwd->pw_name);
758 if (stat(tbuf, &st) == 0 && st.st_size != 0)
759 (void)printf("You have %smail.\n",
761 st.st_atime) ? "new " : "");
763 /******* Setup default signals **********/
764 (void)signal(SIGALRM, SIG_DFL);
765 (void)signal(SIGQUIT, SIG_DFL);
766 (void)signal(SIGINT, SIG_DFL);
767 (void)signal(SIGTSTP, SIG_IGN);
770 (void)strcpy(tbuf + 1,
771 (p = strrchr(shell, '/')) ? p + 1 : shell);
772 sia_ses_release(&entity);
773 execlp(shell, tbuf, 0);
774 (void)printf("login: no shell: %s.\n", strerror(errno));
777 /***** SIA session launch failure *****/
779 /***** SIA session establishment failure *****/
781 if (entity != NULL) {
782 sia_ses_release(&entity);
784 syslog(LOG_ERR, " LOGIN FAILURE ");
787 #else /* AFS_OSF_ENV */
789 { /* This block sets TZ environment on HPUX */
790 /* First set TZ environment here, so that
791 * LOGIN FAILURE will get correct time stamp.
792 * For logins from console, -p flag is not set,
793 * the TZ environment set here will be cleared later.
794 * We're gonna set it once again later after it's cleared.
797 char buf[MAX_TZ_LEN];
799 int tz_incorrect = 0;
801 /* set TZ only if tz_incorrect
802 * (*env_p==0 or env_p==0 ) and there is a correct /etc/TIMEZONE
803 * otherwise, just let it be default (US eastern on HP)
805 env_p = getenv("TZ");
812 /* HP UX 10.0 or later has different file format */
813 #ifdef AFS_HPUX100_ENV
814 /* /etc/TIMEZONE file example (HP-UX 10 or later)
818 fp = fopen("/etc/TIMEZONE", "r");
820 if ((fgets(buf, sizeof(buf), fp)) != NULL) {
821 buf[strlen(buf) - 1] = 0;
822 if (!strncmp(buf, "TZ=", 3)) {
823 strncpy(TZ, buf, MAX_TZ_LEN);
829 #else /* AFS_HPUX100_ENV */
830 /* /etc/src.sh file example (HP-UX 9 or earlier)
831 * SYSTEM_NAME=myname; export SYSTEM_NAME
832 * TZ=EST5EDT; export TZ
834 fp = fopen("/etc/src.sh", "r");
836 while ((fgets(buf, sizeof(buf), fp)) != NULL) {
837 buf[strlen(buf) - 1] = 0;
838 if (!strncmp(buf, "TZ=", 3)) {
839 char *p = strchr(buf, ';');
842 strncpy(TZ, buf, MAX_TZ_LEN);
848 #endif /* AFS_HPUX100_ENV */
853 #endif /* AFS_HPUX_ENV */
854 for (cnt = 0;; ask = 1) {
856 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
857 (void)ioctl(0, TIOCSETD, &ioctlval);
858 #endif /* !AIX and !hpux */
860 if (ask | !username) {
865 * Note if trying multiple user names;
866 * log failures for previous user name,
867 * but don't bother logging one failure
868 * for nonexistent name (mistyped username).
870 if (failures && strcmp(tbuf, username)) {
871 if (failures > (pwd ? 0 : 1))
875 (void)strcpy(tbuf, username);
878 if ((pwd = getpwnam(username)) && (spwd = getspnam(username))) {
879 initgroups(username, pwd->pw_gid); /* XXX */
880 salt = spwd->sp_pwdp;
883 if (pwd = getpwnam(username))
884 salt = pwd->pw_passwd;
885 #endif /* else !SUN5 */
887 /* if user not super-user, check for disabled logins */
888 if (pwd == NULL || pwd->pw_uid) {
893 * Disallow automatic login to root; if not invoked by
894 * root, disallow if the uid's differ.
897 uid_t uid = getuid();
900 * allow f flag only if user running login is
901 * same as target user or superuser
903 fflag = (uid == 0) || (uid == pwd->pw_uid);
906 /* passwd_req = pwd->pw_uid == 0 || (uid && uid != pwd->pw_uid);*/
910 * If no pre-authentication and a password exists
911 * for this user, prompt for one and verify it.
913 if (!passwd_req || (pwd && !*pwd->pw_passwd)) {
916 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
920 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
921 setpriority(PRIO_PROCESS, 0, -4);
925 * The basic model for logging in now, is that *if* there
926 * is a kerberos record for this individual user we will
927 * trust kerberos (provided the user really has an account
928 * locally.) If there is no kerberos record (or the password
929 * were typed incorrectly.) we would attempt to authenticate
930 * against the local password file entry. Naturally, if
931 * both fail we use existing failure code.
936 static int useGetPass = 0;
939 pp = getpass("Password:");
940 memcpy(pword, pp, 8);
943 ka_UserReadPassword("Password:", pword, sizeof(pword),
947 if (code != KANULLPASSWORD) {
951 fprintf(stderr, "Unable to read password because %s\n",
957 if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG, pwd->pw_name, /* kerberos name */
961 0, /* default lifetime */
962 &password_expires, 0, /* spare 2 */
963 &reason /* error string */
969 if (strcmp(pwd->pw_passwd, "*"))
970 break; /* out of for loop */
971 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
972 (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL);
977 pp = getpass("Password:");
981 (void)memset(pp, '\0', strlen(pp));
983 if (spwd && !strcmp(p, spwd->sp_pwdp))
985 if (pwd && !strcmp(p, pwd->pw_passwd))
988 /* Only print this if local authentication is successful */
990 printf("Unable to authenticate to AFS because %s\n", reason);
991 printf("proceeding with local authentication...\n");
999 printf("Login incorrect\n");
1001 /* we allow 10 tries, but after 3 we start backing off */
1005 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
1006 (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL);
1014 sleep((u_int) ((cnt - 3) * 5));
1017 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
1018 setpriority(PRIO_PROCESS, 0, 0);
1021 /* Exits if root login not on system console. */
1022 if (pwd->pw_uid == 0) {
1023 if ((Console != NULL) && (strcmp(ttyn, Console) != 0)) {
1024 (void)printf("Not on system console\n");
1027 if (Def_supath != NULL)
1028 Def_path = Def_supath;
1030 Def_path = DEF_SUPATH;
1032 #endif /* AFS_SUN5_ENV */
1034 printf("AFS (R) %s Login\n", AFSVersion); /* generated version */
1036 /* committed to login -- turn off timeout */
1037 (void)alarm((u_int) 0);
1040 * If valid so far and root is logging in, see if root logins on
1041 * this terminal are permitted.
1043 #if !defined(AIX) && !defined(AFS_SUN5_ENV)
1045 /* This is the /etc/securetty feature. We wanted to 1st prompt for a
1046 * password even if we know that this is not a securetty because
1047 * we don't want to give any clue if the potential intruder guesses
1048 * the correct password.
1050 if ((pwd->pw_uid == 0) && !rootterm(ttyn + sizeof("/dev/") - 1)) {
1052 if (pwd->pw_uid == 0 && !rootterm(tty)) {
1055 syslog(LOG_NOTICE, "ROOT LOGIN REFUSED FROM %s", hostname);
1057 syslog(LOG_NOTICE, "ROOT LOGIN REFUSED ON %s", tty);
1058 printf("Login incorrect\n");
1064 (void)chmod(ttyn, 0666);
1068 #endif /* !AIX & !SUN5 */
1070 if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
1074 "Too many users logged on already.\nTry again later.\n");
1077 fprintf(stderr, "You have too many processes running.\n");
1080 perror("quota (Q_SETUID)");
1087 (void)chmod(ttyn, 0666);
1091 #endif /* Q_SETUID */
1093 /* For Solaris and HP, we might want to chdir later for remotely
1094 * mounted home directory because home direcotry may be
1097 if (chdir(pwd->pw_dir) < 0) {
1098 #if !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV)
1099 printf("No directory %s!\n", pwd->pw_dir);
1100 #endif /* !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV) */
1107 (void)chmod(ttyn, 0666);
1111 #if !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV)
1113 printf("Logging in with home = \"/\".\n");
1114 #else /* !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV) */
1116 #endif /* !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV) */
1119 /* nothing else left to fail -- really log in */
1123 struct utmpx *utx, *getutxent(), *pututxline();
1125 #if defined(AFS_HPUX_ENV)
1126 register struct utmp *u = NULL;
1127 extern pid_t getpid();
1131 (void)time(&utmp.ut_tv.tv_sec);
1133 (void)time(&utmp.ut_time);
1135 strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
1136 #if !defined(AIX) /*&& !defined(AFS_SUN5_ENV) */
1138 strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
1140 strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
1141 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV)
1142 utmp.ut_type = USER_PROCESS;
1143 if (!strncmp(ttyn, "/dev/", strlen("/dev/"))) {
1144 strncpy(utmp.ut_line, &(ttyn[strlen("/dev/")]),
1145 sizeof(utmp.ut_line));
1148 utmp.ut_pid = getpid();
1149 if ((!strncmp(tty, "tty", strlen("tty")))
1150 || (!strncmp(tty, "pty", strlen("pty")))) {
1151 strncpy(utmp.ut_id, &(tty[strlen("tty")]), sizeof(utmp.ut_id));
1153 #endif /* AFS_HPUX_ENV */
1156 * Find the entry for this pid (or line if we are a sublogin)
1159 while ((u = getutent()) != NULL) {
1160 if ((u->ut_type == INIT_PROCESS || u->ut_type == LOGIN_PROCESS
1161 || u->ut_type == USER_PROCESS)
1164 && strncmp(u->ut_line, ttyntail, sizeof(u->ut_line)) == 0)
1165 || u->ut_pid == utmp.ut_pid)) {
1168 * Copy in the name of the tty minus the
1169 * "/dev/", the id, and set the type of entry
1172 (void)strncpy(utmp.ut_line, ttyntail, sizeof(utmp.ut_line));
1173 utmp.ut_id[0] = u->ut_id[0];
1174 utmp.ut_id[1] = u->ut_id[1];
1175 utmp.ut_id[2] = u->ut_id[2];
1176 utmp.ut_id[3] = u->ut_id[3];
1177 utmp.ut_type = USER_PROCESS;
1178 utmp.how_to_count = add_count();
1181 * Copy remote host information
1183 strncpy(utmp.ut_host, u->ut_host, sizeof(utmp.ut_host));
1184 utmp.ut_addr = u->ut_addr;
1186 /* Return the new updated utmp file entry. */
1191 endutent(); /* Close utmp file */
1194 utmp.ut_syslen = (tlen =
1195 strlen(utmp.ut_host)) ? min(tlen + 1,
1198 strncpy(utmp.ut_user, username, sizeof(utmp.ut_user));
1199 while ((utx = getutxent()) != NULL) {
1200 if ((utx->ut_type == INIT_PROCESS || utx->ut_type == LOGIN_PROCESS
1201 || utx->ut_type == USER_PROCESS)
1202 && (utx->ut_pid == utmp.ut_pid)) {
1203 strncpy(utmp.ut_line, (ttyn + sizeof("/dev/") - 1),
1204 sizeof(utmp.ut_line));
1205 utmp.ut_id[0] = utx->ut_id[0];
1206 utmp.ut_id[1] = utx->ut_id[1];
1207 utmp.ut_id[2] = utx->ut_id[2];
1208 utmp.ut_id[3] = utx->ut_id[3];
1209 utmp.ut_type = USER_PROCESS;
1214 endutxent(); /* Close utmp file */
1217 ("No utmpx entry. You must exec 'login' from the lowest level 'sh'\n");
1220 updwtmpx(WTMPX_FILE, &utmp);
1226 quietlog = access(HUSHLOGIN, F_OK) == 0;
1227 dolastlog(quietlog);
1229 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
1231 if (!hflag && !rflag) { /* XXX */
1233 if (!hflag) { /* XXX */
1235 static struct winsize win = { 0, 0, 0, 0 };
1237 (void)ioctl(0, TIOCSWINSZ, &win);
1239 #endif /* !AIX and !hpux */
1243 * Set the user's ulimit
1245 if (Def_ulimit > 0L && ulimit(SET_FSIZ, Def_ulimit) < 0L)
1246 (void)printf("Could not set ULIMIT to %ld\n", Def_ulimit);
1249 #if defined(AFS_SUN_ENV)
1251 * Set owner/group/permissions of framebuffer devices
1253 (void)set_fb_attrs(ttyn, pwd->pw_uid, pwd->pw_gid);
1256 (void)chown(ttyn, pwd->pw_uid,
1257 (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
1260 (void)chmod(ttyn, 0620);
1261 (void)setgid(pwd->pw_gid);
1264 if ((pwd->pw_gid < 0) || (pwd->pw_gid > MAXUID)) {
1265 printf("Bad group id.\n");
1268 if ((pwd->pw_uid < 0) || (pwd->pw_uid > MAXUID)) {
1269 printf("Bad user id.\n");
1274 #ifdef AFS_KERBEROS_ENV
1275 (void)chown(ktc_tkt_string(), pwd->pw_uid, pwd->pw_gid);
1279 groups[0] = groups[1] = 0;
1280 ngroups = getgroups(NGROUPS_MAX, groups);
1281 pagval = get_pag_from_groups(groups[0], groups[1]);
1282 initgroups(username, pwd->pw_gid);
1283 ngroups = getgroups(NGROUPS_MAX, groups);
1284 if ((pagval != NOPAG)
1285 && (afs_get_pag_from_groups(groups[0], groups[1])) == NOPAG) {
1286 /* we will have to shift grouplist to make room for pag */
1287 if (ngroups + 2 > NGROUPS_MAX)
1288 return E2BIG; /* XXX */
1289 for (j = ngroups - 1; j >= 0; j--) {
1290 groups[j + 2] = groups[j];
1293 get_groups_from_pag(pagval, &groups[0], &groups[1]);
1294 if (setgroups(ngroups, groups) == -1) {
1295 perror("setgroups");
1300 quota(Q_DOWARN, pwd->pw_uid, (dev_t) - 1, 0);
1301 #endif /* Q_DOWARN */
1303 /* destroy environment unless user has requested preservation */
1309 (void)setuid(pwd->pw_uid);
1311 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
1312 /* This is the time to retry chdir for Solaris and HP
1314 if (retry_chdir && chdir(pwd->pw_dir) < 0) {
1315 printf("No directory %s!\n", pwd->pw_dir);
1316 if (chdir("/") < 0) {
1317 /* reset tty line and exit */
1318 (void)chmod(ttyn, 0666);
1322 printf("Logging with home = \"/\".\n");
1324 #endif /* AFS_SUN5_ENV || AFS_HPUX_ENV */
1326 if (*pwd->pw_shell == '\0')
1327 pwd->pw_shell = BSHELL;
1328 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
1329 /* turn on new line discipline for the csh */
1330 else if (!strcmp(pwd->pw_shell, "/bin/csh")) {
1331 ioctlval = NTTYDISC;
1332 (void)ioctl(0, TIOCSETD, &ioctlval);
1337 if (Altshell != NULL && strcmp(Altshell, "YES") == 0) {
1338 (void)setenv("SHELL", pwd->pw_shell, 1);
1341 if (Def_tz != NULL) {
1344 Def_tz = getenv("TZ");
1346 setenv("TZ", Def_tz, 1);
1350 setenv("TZ", Def_tz, 1);
1353 if (Def_hertz == NULL)
1354 (void)setenv("HZ", HZ, 1);
1356 (void)setenv("HZ", Def_hertz, 1);
1361 /* if pflag is not set
1362 * the TZ environment was cleared moments ago */
1363 if (*TZ && !pflag) {
1364 setenv("TZ", &TZ[3], 1);
1366 #endif /* AFS_HPUX_ENV */
1368 (void)setenv("HOME", pwd->pw_dir, 1);
1369 (void)setenv("SHELL", pwd->pw_shell, 1);
1370 if (term[0] == '\0')
1371 strncpy(term, stypeof(tty), sizeof(term));
1372 (void)setenv("TERM", term, 0);
1373 (void)setenv("USER", pwd->pw_name, 1);
1374 (void)setenv("LOGNAME", pwd->pw_name, 1);
1376 if (Def_path == NULL)
1377 (void)setenv("PATH", DEF_PATH, 0);
1379 (void)setenv("PATH", Def_path, 0);
1381 (void)setenv("PATH", "/usr/ucb:/bin:/usr/bin:", 0);
1384 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX100_ENV)
1386 /* Sol, HP: set MAIL only if NO_MAIL is not set */
1387 sprintf(mail, "%s%s", MAILDIR, pwd->pw_name);
1388 (void)setenv("MAIL", mail, 0);
1389 #endif /* NO_MAIL */
1390 #endif /* AFS_SUN5_ENV || AFS_HPUX100_ENV */
1392 #ifdef AFS_KERBEROS_ENV
1393 (void)setenv("KRBTKFILE", ktc_tkt_string(), 0);
1396 if (password_expires >= 0) {
1398 (void)setenv("PASSWORD_EXPIRES",
1399 cv2string(&sbuffer[100], password_expires), 1);
1402 if (tty[sizeof("tty") - 1] == 'd')
1403 syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
1404 if (pwd->pw_uid == 0)
1406 syslog(LOG_NOTICE, "ROOT LOGIN ON %s FROM %s", tty, hostname);
1408 syslog(LOG_NOTICE, "ROOT LOGIN ON %s", tty);
1413 #if ! defined(AFS_SUN5_ENV) && (! defined(AFS_HPUX_ENV))
1414 /* In Solaris the shell displays motd */
1415 /* On hp700s /etc/profile also does it so it's redundant here too */
1417 /* Don't check email either, should be done in shell */
1418 (void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name);
1419 if (stat(tbuf, &st) == 0 && st.st_size != 0)
1420 printf("You have %smail.\n",
1421 (st.st_mtime > st.st_atime) ? "new " : "");
1425 (void)signal(SIGALRM, SIG_DFL);
1426 (void)signal(SIGQUIT, SIG_DFL);
1427 (void)signal(SIGINT, SIG_DFL);
1428 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
1429 (void)signal(SIGTSTP, SIG_IGN);
1434 (p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell);
1435 execlp(pwd->pw_shell, tbuf, 0);
1436 fprintf(stderr, "login: no shell: ");
1437 perror(pwd->pw_shell);
1439 #endif /* else AFS_OSF_ENV */
1442 getloginname(prompt)
1447 static char nbuf[UT_NAMESIZE + 1];
1454 for (p = nbuf; (ch = getchar()) != '\n';) {
1459 if (p < nbuf + UT_NAMESIZE)
1464 fprintf(stderr, "login names may not start with '-'.\n");
1484 * check to see if /etc/securetty exists, if it does then scan
1485 * file to see if passwd tty is in the file. Return 1 if it is, 0 if not.
1487 if ((fd = fopen(SECURETTY_FILE, "r")) == NULL)
1489 while (fgets(buf, sizeof buf, fd) != NULL) {
1490 buf[strlen(buf) - 1] = '\0';
1491 if (strcmp(tty, buf) == 0) {
1500 #if !defined(AIX) && !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV)
1506 return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
1510 jmp_buf motdinterrupt;
1514 register int fd, nchars;
1519 if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
1521 oldint = signal(SIGINT, sigint);
1522 if (setjmp(motdinterrupt) == 0)
1523 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
1524 (void)write(fileno(stdout), tbuf, nchars);
1525 (void)signal(SIGINT, oldint);
1532 longjmp(motdinterrupt, 1);
1537 register int fd, nchars;
1540 if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) {
1541 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
1542 (void)write(fileno(stdout), tbuf, nchars);
1547 #if defined(AIX) || defined(AFS_HPUX_ENV) || defined(AFS_AIX32_ENV)
1558 #define _PATH_LASTLOG "/var/adm/lastlog"
1564 if ((fd = open(_PATH_LASTLOG, (O_RDWR | O_CREAT), 0666)) < 0)
1565 fprintf(stderr, "Can't open %s", _PATH_LASTLOG);
1567 (void)lseek(fd, (off_t) pwd->pw_uid * sizeof(ll), L_SET);
1569 if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll)
1570 && ll.ll_time != 0) {
1571 (void)printf("Last login: %.*s ", 24 - 5,
1572 (char *)ctime(&ll.ll_time));
1573 if (*ll.ll_host != '\0')
1574 (void)printf("from %.*s\n", sizeof(ll.ll_host),
1577 (void)printf("on %.*s\n", sizeof(ll.ll_line), ll.ll_line);
1590 if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) {
1591 (void)lseek(fd, (off_t) pwd->pw_uid * sizeof(ll), L_SET);
1593 if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll)
1594 && ll.ll_time != 0) {
1595 printf("Last login: %.*s ", 24 - 5,
1596 (char *)ctime(&ll.ll_time));
1597 if (*ll.ll_host != '\0')
1598 printf("from %.*s\n", sizeof(ll.ll_host), ll.ll_host);
1600 printf("on %.*s\n", sizeof(ll.ll_line), ll.ll_line);
1602 (void)lseek(fd, (off_t) pwd->pw_uid * sizeof(ll), L_SET);
1604 memset(&ll, '\0', sizeof(ll));
1605 (void)time(&ll.ll_time);
1606 strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
1608 strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
1609 (void)write(fd, (char *)&ll, sizeof(ll));
1622 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s, %s", failures,
1623 failures > 1 ? "S" : "", hostname, name);
1625 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s, %s", failures,
1626 failures > 1 ? "S" : "", tty, name);
1631 #define UNKNOWN "sun"
1633 #define UNKNOWN "su"
1636 #if defined(AIX) || defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV)
1650 return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
1654 getstr(buf, cnt, err)
1661 if (read(0, &ch, sizeof(ch)) != sizeof(ch))
1664 fprintf(stderr, "%s too long\r\n", err);
1680 get_pag_from_groups(g0, g1)
1683 afs_uint32 h, l, result;
1687 if (g0 < 0xc000 && g1 < 0xc000) {
1688 l = ((g0 & 0x3fff) << 14) | (g1 & 0x3fff);
1690 h = (g1 >> 14) + h + h + h;
1691 result = ((h << 28) | l);
1692 /* Additional testing */
1693 if (((result >> 24) & 0xff) == 'A')
1702 get_groups_from_pag(pag, g0p, g1p)
1704 afs_uint32 *g0p, *g1p;
1706 unsigned short g0, g1;
1709 g0 = 0x3fff & (pag >> 14);
1711 g0 |= ((pag >> 28) / 3) << 14;
1712 g1 |= ((pag >> 28) % 3) << 14;
1718 #if defined(AFS_SUN_ENV)
1720 * set_fb_attrs -- change owner/group/permissions of framebuffers
1721 * listed in /etc/fbtab.
1724 * Exiting from set_fb_attrs upon error is not advisable
1725 * since it would disable logins on console devices.
1728 * console mode device_name[:device_name ...]
1729 * # begins a comment and may appear anywhere on a line.
1732 * /dev/console 0660 /dev/fb:/dev/cgtwo0:/dev/bwtwo0
1733 * /dev/console 0660 /dev/gpone0a:/dev/gpone0b
1736 * The example above sets the owner/group/permissions of the listed
1737 * devices to uid/gid/0660 if ttyn is /dev/console
1740 #define FIELD_DELIMS " \t\n"
1743 #define WILDCARD "/*"
1744 #define WILDCARD_LEN 2
1745 #define MAX_LINELEN 256
1747 #define FBTAB "/etc/logindevperm"
1749 #define FBTAB "/etc/fbtab"
1753 set_fb_attrs(ttyn, uid, gid)
1758 char line[MAX_LINELEN];
1768 if ((fp = fopen(FBTAB, "r")) == NULL)
1770 while (fgets(line, MAX_LINELEN, fp)) {
1771 if (ptr = strchr(line, '#'))
1772 *ptr = '\0'; /* handle comments */
1773 if ((console = strtok(line, FIELD_DELIMS)) == NULL)
1774 continue; /* ignore blank lines */
1775 if (strcmp(console, ttyn) != 0)
1776 continue; /* ignore non-consoles */
1777 mode_str = strtok((char *)NULL, FIELD_DELIMS);
1778 if (mode_str == NULL) {
1779 (void)fprintf(stderr, "%s: invalid entry -- %s\n", FBTAB, line);
1782 /* convert string to octal value */
1783 mode = (int)strtol(mode_str, (char **)NULL, 8);
1784 if (mode < 0 || mode > 0777) {
1785 (void)fprintf(stderr, "%s: invalid mode -- %s\n", FBTAB,
1789 dev_list = strtok((char *)NULL, FIELD_DELIMS);
1790 if (dev_list == NULL) {
1791 (void)fprintf(stderr, "%s: %s -- empty device list\n", FBTAB,
1796 device = strtok(dev_list, COLON);
1798 ptr = strstr(device, WILDCARD);
1799 if (ptr && (strlen(device) - (ptr - &device[0])) == WILDCARD_LEN) {
1800 /* The device was a (legally-specified) directory. */
1802 struct dirent *dir_e;
1803 char dev_file[MAXPATHLEN];
1805 *ptr = '\0'; /* Remove the wildcard from the dir name. */
1806 if ((dev_dir = opendir(device)) == (DIR *) NULL) {
1807 syslog(LOG_ERR, "bad device %s%s in %s, ignored", device,
1812 /* Directory is open; alter its files. */
1813 /* Must link with /usr/lib/libc.a before
1814 * /usr/ucblib/libucb.a or the d_name structs
1815 * miss the first two characters of the filename */
1816 while (dir_e = readdir(dev_dir)) {
1817 if (strcmp(dir_e->d_name, "..")
1818 && strcmp(dir_e->d_name, ".")) {
1819 strcpy(dev_file, device);
1820 strcat(dev_file, "/");
1821 strcat(dev_file, dir_e->d_name);
1822 (void)chown(dev_file, uid, gid);
1823 (void)chmod(dev_file, mode);
1826 (void)closedir(dev_dir);
1828 /* 'device' was not a directory, so we can just do it. */
1829 (void)chown(device, uid, gid);
1830 (void)chmod(device, mode);
1832 device = strtok((char *)NULL, COLON); /* Move thru list. */
1834 device = strtok(dev_list, COLON);
1836 (void)chown(device, uid, gid);
1837 (void)chmod(device, mode);
1838 device = strtok((char *)NULL, COLON);
1851 register int c, i, num;
1853 switch (c = getc(stdin)) {
1880 for (num = 0, i = 0; i < 3; i++) {
1881 num = num * 8 + (c - '0');
1882 if ((c = getc(stdin)) < '0' || c > '7')
1898 static char envbuf[256];
1899 static char *args[63];
1900 register char *ptr, **answer;
1903 extern int quotec();
1905 for (ptr = envbuf; ptr < &envbuf[sizeof(envbuf)];)
1907 for (answer = args; answer < &args[63];)
1908 *answer++ = (char *)NULL;
1909 for (ptr = envbuf, answer = &args[0], state = 0;
1910 (c = getc(stdin)) != EOF;) {
1914 if (ptr == &envbuf[0])
1915 return ((char **)NULL);
1934 if (ptr == &envbuf[sizeof(envbuf) - 1]) {
1935 ungetc('\n', stdin);
1947 static struct passwd nouser = { "", "no:password", ~0 };
1949 getstr(rusername, sizeof(rusername), "remuser");
1950 getstr(lusername, sizeof(lusername), "locuser");
1952 username = lusername;
1953 getstr(term, sizeof(term), "Terminal type");
1959 pwd = getpwnam(lusername);
1973 static char rusername[100], lusername[100];
1974 static struct passwd nouser = { "", "no:password", ~0 };
1976 getstr(rusername, sizeof(rusername), "remuser");
1977 getstr(lusername, sizeof(lusername), "locuser");
1979 username = lusername;
1980 getstr(term, sizeof(term), "Terminal type");
1985 pwd = getpwnam(lusername);
1990 code = ruserok(host, (pwd->pw_uid == 0), rusername, lusername);
1991 /*printf("DOREM=%d, host=%s, uid=%d, ruser=%s, luser=%s\n", code, host, pwd->pw_uid, rusername, lusername);*/
1996 char *speeds[] = { "0", "50", "75", "110", "134", "150", "200", "300",
1997 "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400"
2000 #define NSPEEDS (sizeof (speeds) / sizeof (speeds[0]))
2003 doremoteterm(terminal)
2005 doremoteterm(terminal, tp)
2013 register char *cp = strchr(terminal, '/'), **cpp;
2017 (void)ioctl(0, TCGETS, &tp);
2022 cp = strchr(speed, '/');
2025 for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
2026 if (strcmp(*cpp, speed) == 0) {
2029 ((tp.c_cflag & ~CBAUD) | ((cpp - speeds) & CBAUD));
2031 tp->sg_ispeed = tp->sg_ospeed = cpp - speeds;
2037 tp.c_lflag = ECHO | ICANON | IGNPAR | ICRNL;
2038 (void)ioctl(0, TCSETS, &tp);
2040 tp->sg_flags = ECHO | CRMOD | ANYP | XTABS;
2047 * Check if the specified program is really a shell (e.g. "sh" or "csh").
2053 char *getusershell();
2056 while ((p = getusershell()) != NULL)
2057 if (strcmp(p, shell) == 0)
2064 getlinep(const char *string, int size, FILE * stream)
2071 if (!fgets(string, size, stream) || ferror(stream) || errno == EINTR)
2073 else if (cp = strchr(string, '\n'))
2076 while ((c = getc(stdin)) != '\n' && c != EOF && errno != EINTR);
2080 clean_entity_pwd(SIAENTITY * entity)
2082 if (entity->acctname != NULL) {
2083 free(entity->acctname);
2084 entity->acctname = NULL;
2086 if (entity->pwd != NULL) {
2087 if (entity->pwd->pw_name) {
2088 memset(entity->pwd->pw_name, '\0', strlen(entity->pwd->pw_name));
2089 free(entity->pwd->pw_name);
2090 entity->pwd->pw_name = NULL;
2092 if (entity->pwd->pw_passwd) {
2093 memset(entity->pwd->pw_passwd, '\0',
2094 strlen(entity->pwd->pw_passwd));
2095 free(entity->pwd->pw_passwd);
2096 entity->pwd->pw_passwd = NULL;
2098 if (entity->pwd->pw_comment) {
2099 memset(entity->pwd->pw_comment, '\0',
2100 strlen(entity->pwd->pw_comment));
2101 free(entity->pwd->pw_comment);
2102 entity->pwd->pw_comment = NULL;
2104 if (entity->pwd->pw_gecos) {
2105 memset(entity->pwd->pw_gecos, '\0',
2106 strlen(entity->pwd->pw_gecos));
2107 free(entity->pwd->pw_gecos);
2108 entity->pwd->pw_gecos = NULL;
2110 if (entity->pwd->pw_dir) {
2111 memset(entity->pwd->pw_dir, '\0', strlen(entity->pwd->pw_dir));
2112 free(entity->pwd->pw_dir);
2113 entity->pwd->pw_dir = NULL;
2115 if (entity->pwd->pw_shell) {
2116 memset(entity->pwd->pw_shell, '\0',
2117 strlen(entity->pwd->pw_shell));
2118 free(entity->pwd->pw_shell);
2119 entity->pwd->pw_shell = NULL;
2132 fputs("login: ", stdout);
2133 if (getlinep(result, sizeof result, stdin) == (char *)NULL) {
2136 entity->name = (char *)malloc(SIANAMEMIN + 1);
2137 if (entity->name == NULL)
2139 strcpy((unsigned char *)entity->name, result);
2143 #ifdef AFS_KERBEROS_ENV
2144 extern char *ktc_tkt_string();
2148 do_afs_auth(pwd, pass, doafs)
2154 int code, afsLoginFail = 0;
2155 char *lcell, realm[MAXKTCREALMLEN], *pword, prompt[256];
2156 char *shell, *reason;
2162 sprintf(prompt, "Enter AFS password: ");
2163 pword = getpass(prompt);
2164 if (strlen(pword) == 0) {
2166 ("Unable to read password because zero length password is illegal\n");
2167 printf("Login incorrect\n");
2173 if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG, pwd->pw_name, /* kerberos name */
2174 NULL, /* instance */
2176 pword, /* password */
2177 0, /* default lifetime */
2180 &reason /* error string */ )) {
2185 if (pwd->pw_passwd && strcmp(pwd->pw_passwd, "*"))
2186 return 1; /* Success */
2189 if (!pwd->pw_passwd)
2191 namep = crypt(pword, pwd->pw_passwd);
2192 code = strcmp(namep, pwd->pw_passwd) == 0 ? 1 : 0;
2193 if ((code == 1) && afsLoginFail) {
2194 /* Only print this if local authentication is successful */
2195 printf("Unable to authenticate to AFS because %s\n", reason);
2196 printf("proceeding with local authentication...\n");
2208 extern int defopen(), defcntl();
2212 if (defopen(Pndefault) == 0) {
2216 flags = defcntl(DC_GETFLAGS, 0);
2217 TURNOFF(flags, DC_CASE);
2218 defcntl(DC_SETFLAGS, flags);
2220 if ((Console = defread("CONSOLE=")) != NULL)
2221 Console = strdup(Console);
2222 if ((Altshell = defread("ALTSHELL=")) != NULL)
2223 Altshell = strdup(Altshell);
2224 if ((Passreq = defread("PASSREQ=")) != NULL)
2225 Passreq = strdup(Passreq);
2226 if ((Def_tz = defread("TIMEZONE=")) != NULL)
2227 Def_tz = strdup(Def_tz);
2228 if ((Def_hertz = defread("HZ=")) != NULL)
2229 Def_hertz = strdup(Def_hertz);
2230 if ((Def_path = defread("PATH=")) != NULL)
2231 Def_path = strdup(Def_path);
2232 if ((Def_supath = defread("SUPATH=")) != NULL)
2233 Def_supath = strdup(Def_supath);
2234 if ((ptr = defread("ULIMIT=")) != NULL)
2235 Def_ulimit = atol(ptr);
2236 if ((ptr = defread("TIMEOUT=")) != NULL)
2237 Def_timeout = (unsigned)atoi(ptr);
2238 if ((ptr = defread("UMASK=")) != NULL)
2239 if (sscanf(ptr, "%lo", &Umask) != 1)
2241 if ((ptr = defread("IDLEWEEKS=")) != NULL)
2242 Idleweeks = atoi(ptr);
2243 if ((ptr = defread("SLEEPTIME=")) != NULL)
2244 Sleeptime = atoi(ptr);
2245 (void)defopen(NULL);
2253 * returns 1 if user should be counted as 1 user;
2254 * returns 3 if user should be counted as a pty
2255 * may return other stuff in the future
2270 * returns 1 if user is a pty, 0 otherwise
2272 #define SSTRPTYMAJOR 157 /* major number for Streams slave pty's */
2273 #define SPTYMAJOR 17 /* major number for slave pty's */
2274 #define PTYSC 0x00 /* select code for pty's */
2275 #define select_code(x) (((x) & 0xff0000) >> 16)
2279 static int firsttime = 1;
2284 if (fstat(0, &sbuf) != 0 || /* can't stat */
2285 (sbuf.st_mode & S_IFMT) != S_IFCHR || /* not char special */
2286 major(sbuf.st_rdev) != SPTYMAJOR || /* not pty major num */
2287 select_code(sbuf.st_rdev) != PTYSC) { /* not pty minor num */
2288 /* Check to see if it is a Streams PTY */
2289 if (major(sbuf.st_rdev) == SSTRPTYMAJOR) {
2292 retval = 0; /* neither a BSD nor a Streams PTY */
2296 if (ISB1 && !remote_login)
2297 retval = 0; /* local pty for td tty simulation */
2304 #define NLIOUCOUNT _IO('K',28) /* _IO(K, 28) */
2305 #define NLIOSERV 0x4b33 /* (('K' << 8) + 51 */
2308 * returns 1 if user is an NL server, else returns 0
2312 if (ioctl(0, NLIOUCOUNT) == NLIOSERV)