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>
47 #include <afs/kautils.h>
49 #include <sys/fs/ufs_quota.h>
51 #if !defined(AFS_HPUX_ENV) && !defined(AFS_AIX_ENV)
52 #if defined(AFS_SUN_ENV) || (defined(AFS_ATHENA_STDENV) && !defined(AFS_DEC_ENV)) || defined(AFS_OSF_ENV)
53 #include <ufs/quota.h>
54 #elif defined(AFS_FBSD_ENV)
55 #include <ufs/ufs/quota.h>
57 #include <sys/quota.h>
63 #include <sys/resource.h>
66 #include <sys/termios.h>
67 #include <sys/ttychars.h>
68 /* hack to get it to build */
70 #include <sys/ttydev.h>
71 #include <sys/ttold.h>
72 #include <sys/filio.h>
76 #include <sys/ttydefaults.h>
78 #include <sys/ioctl.h>
86 #if !defined(AIX) && !defined(AFS_HPUX_ENV) && !defined(AFS_AIX32_ENV) && !defined(AFS_FBSD_ENV)
95 #include <sys/termio.h>
96 #include <sys/syslog.h>
99 #if !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV)
102 #if defined(AFS_HPUX_ENV)
104 #include <sys/bsdtty.h>
115 #define TTYGRPNAME "tty" /* name of group to own ttys */
117 #define MOTDFILE "/etc/motd"
119 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX100_ENV)
122 #define MAILDIR "/var/mail/"
124 #define MAILDIR "/usr/mail/"
126 static char mail[30];
128 #else /* AFS_SUN5_ENV || AFS_HPUX100_ENV */
129 #define MAILDIR "/usr/spool/mail"
130 #endif /* AFS_SUN5_ENV || AFS_HPUX100_ENV */
132 #define NOLOGIN "/etc/nologin"
133 #define HUSHLOGIN ".hushlogin"
134 #define LASTLOG "/usr/adm/lastlog"
135 #define BSHELL "/bin/sh"
136 #define SECURETTY_FILE "/etc/securetty"
139 * This bounds the time given to login. Not a define so it can
140 * be patched on machines where it's too small.
144 struct passwd *pwd, *getpwnam();
146 char term[64], *hostname, *username, *tty;
150 struct sgttyb sgttyb;
154 extern char *defread(), *strdup();
155 static void defaults();
156 static char *Pndefault = "/etc/default/login";
157 static char *Altshell = NULL;
158 static char *Console = NULL;
159 static int Idleweeks = -1;
160 static char *Passreq = NULL;
162 static mode_t Umask = DEFUMASK;
163 static char *Def_tz = NULL;
164 static char *tmp_tz = NULL;
165 static char *Def_hertz = NULL;
166 #define SET_FSIZ 2 /* ulimit() command arg */
167 static long Def_ulimit = 0;
168 #define MAX_TIMEOUT (15 * 60)
169 #define DEF_TIMEOUT 5*60
170 static unsigned Def_timeout = DEF_TIMEOUT;
171 static char *Def_path = NULL;
172 static char *Def_supath = NULL;
173 #define DEF_PATH "/usr/bin:" /* same as PATH */
174 #define DEF_SUPATH "/usr/sbin:/usr/bin" /* same as ROOTPATH */
176 * Intervals to sleep after failed login
179 # define SLEEPTIME 4 /* sleeptime before login incorrect msg */
181 static int Sleeptime = SLEEPTIME;
184 /* This is for Solaris's shadow pass struc */
185 static struct spwd *spwd;
189 static int authenticated_remote_user = 0;
190 static char rhost[64], rusername[10], lusername[10];
196 /* For setting of TZ environment on HPUX */
198 #define MAX_TZ_LEN 256
199 static char TZ[MAX_TZ_LEN];
200 #endif /* AFS_HPUX_ENV */
202 #ifdef AFS_KERBEROS_ENV
203 extern char *ktc_tkt_string();
206 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
208 /* CINTR, CQUIT, CSTART, CSTOP, 000, 000 */
209 CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
212 struct ltchars ltc = {
213 CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
220 SIAENTITY *entity=NULL;
223 #include <sys/security.h>
229 #define NOPAG 0xffffffff
232 /* For avoiding making an osi_audit call when non-root */
241 fprintf(stderr, "Login timed out after %d seconds\n", timeout);
245 char *cv2string(ttp, aval)
247 register unsigned long aval;
249 register char *tp = ttp;
265 #include "AFS_component_version_number.c"
274 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
275 /* the following utmp field is used for user counting: */
276 #define how_to_count ut_exit.e_exit
278 #define SUBLOGIN "<!sublogin>"
280 main(argc, argv, renvp)
288 extern int errno, optind;
289 extern char *optarg, **environ;
290 struct group *gr, *getgrnam();
293 int ask, fflag, hflag, rflag, pflag, cnt, locl, zero = 0, dflag=0, rlog=0;
294 int quietlog, passwd_req, ioctlval;
295 char *domain, *salt, *envinit[2], *ttyn=0, *pp;
296 char tbuf[MAXPATHLEN + 2];
297 char *ttyname(), *stypeof(), *crypt(), *getpass();
298 extern off_t lseek();
300 char *lcell; /* local cellname */
301 char realm[MAXKTCREALMLEN];
302 char buf1[256], **envp;
303 afs_int32 j, pagval = NOPAG, ngroups, groups[NGROUPS_MAX];
304 long password_expires = -1;
305 extern char* AFSVersion; /* generated version */
309 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
310 char retry_chdir = 0;
311 #endif /* AFS_SUN5_ENV || AFS_HPUX_ENV */
314 char tname[sizeof(_PATH_TTY) + 10], *loginname=NULL;
321 defaults(); /* Set up Defaults and flags */
322 if (Umask < 0 || ((mode_t) 0777) < Umask) /* Set up default umask */
326 if (Def_timeout > MAX_TIMEOUT) /* Set up default timeouts and delays */
327 Def_timeout = MAX_TIMEOUT;
328 if (Sleeptime < 0 || Sleeptime > 5)
329 Sleeptime = SLEEPTIME;
330 (void) alarm(Def_timeout);
332 (void)alarm((u_int)timeout);
334 (void)signal(SIGALRM, timedout);
336 (void)signal(SIGQUIT, SIG_IGN);
337 (void)signal(SIGINT, SIG_IGN);
338 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
339 (void)setpriority(PRIO_PROCESS, 0, 0);
342 (void)quota(Q_SETUID, 0, 0, 0);
343 #endif /* Q_SETUID */
346 * -p is used by getty to tell login not to destroy the environment
347 * -f is used to skip a second login authentication
348 * -h is used by other servers to pass the name of the remote
349 * host to login so that it may be placed in utmp and wtmp
351 (void)gethostname(tbuf, sizeof(tbuf));
352 domain = strchr(tbuf, '.');
356 * Set flag to disable the pid check if you find that you are
360 if (*renvp && strcmp(*renvp,SUBLOGIN) == 0)
363 fflag = hflag = pflag = rflag = 0;
364 memset(&utmp, '\0', sizeof(utmp));
368 while ((ch = getopt(argc, argv, "fh:prd")) != -1) {
370 while ((ch = getopt(argc, argv, "fh:pr")) != -1) {
373 while ((ch = getopt(argc, argv, "fh:p")) != EOF) {
375 /*printf("ch='%c'\n", ch);*/
382 if (hflag || rflag) {
383 fprintf(stderr,"Only one of -r and -h allowed\n");
389 "login: -h for super-user only.\n");
395 if (domain && (p = strchr(optarg, '.')) &&
396 strcasecmp(p, domain) == 0)
402 if (hflag || rflag) {
403 fprintf(stderr,"Only one of -r and -h allowed\n");
413 usererr = doremotelogin(argv[2]);
414 strncpy(utmp.ut_host, argv[2], sizeof(utmp.ut_host));
422 case 'd': /* Ignode the '-d device' option for now!!! */
434 fprintf(stderr, "usage: login [-fp] [username]\n");
442 strcpy(rhost, *argv++);
444 if ( argv[0] && (*argv[0] != '-')) {
445 if ((!strncmp(*argv, "TERM=", strlen("TERM=")))) {
446 strncpy(term, &((*argv)[strlen("TERM=")]), sizeof(term));
452 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
453 if (!rflag && *argv) {
458 memset(ousername,'\0',sizeof(ousername));
459 strcpy(ousername,*argv);
467 ttypmt = getenv("TTYPROMPT");
468 if (ttypmt && (*ttypmt != '\0')) {
469 extern char **getargs();
471 * if ttyprompt is set, there should be data on the stream already.
473 if ((envp = getargs(buf1)) != (char**)NULL) {
488 #if !defined(AIX) && !defined(AFS_HPUX_ENV) && !defined(AFS_OSF_ENV)
489 (void)ioctl(0, TIOCLSET, &ioctlval);
491 (void)ioctl(0, TIOCNXCL, 0);
493 (void)fcntl(0, F_SETFL, ioctlval);
494 (void)ioctl(0, TIOCGETP, &sgttyb);
496 (void)ioctl(0, FIONBIO, &zero);
497 (void)ioctl(0, FIOASYNC, &zero);
498 (void)ioctl(0, TIOCLGET, &locl);
500 * If talking to an rlogin process,
501 * propagate the terminal type and
502 * baud rate across the network.
509 doremoteterm(term, &sgttyb);
513 locl |= LCRTBS|LCTLECH|LDECCTQ;
514 if (sgttyb.sg_ospeed >= B1200)
515 locl |= LCRTERA|LCRTKIL;
516 (void)ioctl(0, TIOCLSET, &locl);
518 sgttyb.sg_erase = CERASE;
519 sgttyb.sg_kill = CKILL;
520 (void)ioctl(0, TIOCSLTC, <c);
521 (void)ioctl(0, TIOCSETC, &tc);
525 (void)ioctl(0, TIOCSETP, &sgttyb);
527 for (cnt = getdtablesize(); cnt > 2; cnt--)
536 if (ttyn == NULL || *ttyn == '\0') {
538 (void)sprintf(tname, "%s??", _PATH_TTY);
547 ttyntail = ttyn + sizeof("/dev/") - 1;
549 if (tty = strrchr(ttyn, '/'))
554 openlog("login", LOG_ODELAY, LOG_AUTH);
557 #define _PATH_HUSHLOGIN ".hushlogin"
558 #define _PATH_MAILDIR "/var/spool/mail"
559 #ifndef _PATH_DEFPATH
560 #define _PATH_DEFPATH "/usr/bin:."
564 int authret=0, doafs=0;
565 char shell[PATH_MAX+1] = _PATH_BSHELL, *pass, user[40], ouser[40];
566 int (*sia_collect)()=sia_collect_trm;
567 int getloginp(), uid;
570 /*printf("loginname=%s, ttyn=%s, fflag=%d\n", loginname, ttyn, fflag);*/
572 if((sia_ses_init(&entity, oargc, oargv, hostname, loginname, ttyn, 1, NULL)) == SIASUCCESS) {
573 static int useGetPass = 0;
574 int cnt1 = 0, first=0;
575 char *prompt, *reason, pword[BUFSIZ];
576 /***** SIA SESSION AUTHENTICATION *****/
578 for(cnt=5; cnt; cnt--) {
580 if (first++ || !entity->name) {
581 clean_entity_pwd(entity);
582 if (getloginp(entity) < 0) {
583 printf("Illegal login name\n");
588 strcpy(user, entity->name);
589 prompt = "Password:";
590 if ((pwd = getpwnam(user))) {
591 if (!strcmp(pwd->pw_passwd, "X")) {
596 pass = getpass(prompt);
598 code = ka_UserReadPassword(prompt, pword, sizeof(pword), &reason);
601 if (code != KANULLPASSWORD) {
605 fprintf(stderr, "Unable to read password because %s\n", reason);
611 printf("Login incorrect\n"); fflush(stdout);
615 if (doafs || ((authret=sia_ses_authent(sia_collect,pass,entity)) == SIASUCCESS)) {
618 sia_make_entity_pwd(pwd, entity);
620 uid = entity->pwd->pw_uid;
624 authret = do_afs_auth(pwd, pass, doafs);
627 printf("Login incorrect\n"); fflush(stdout);
631 printf("AFS (R) %s Login\n", AFSVersion);
634 groups[0] = groups[1] = 0;
635 ngroups = getgroups(NGROUPS, groups);
636 pagval = get_pag_from_groups(groups[0], groups[1]);
639 } else if (authret & SIASTOP) {
642 else if ( authret == SIAFAIL ) {
643 /* why did it fail ? */
647 ** if the "ptys" command does not exist in the
648 ** /etc/securettys file, then root login's are
649 ** allowed only from the console
651 if ( !pwd->pw_uid ) /* for root */
652 if (((ptr=getttynam("ptys"))==NULL) ||
653 !( ptr->ty_status & TTY_SECURE))
655 printf("root login refused on this terminal\n");
659 if (doafs || (authret != SIASUCCESS)) {
661 sia_make_entity_pwd(pwd, entity);
664 printf("login incorrect\n");
666 if(cnt <= 0 || (doafs == -1)) {
667 sia_ses_release(&entity);
671 /***** SIA SESSION ESTABLISHMENT *****/
672 if(sia_ses_estab(sia_collect,entity) == SIASUCCESS) {
674 * Display and update lastlog file entry. -DAL003
676 quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
678 quietlog = !*entity->pwd->pw_passwd && !usershell(entity->pwd->pw_shell);
682 #ifdef AFS_KERBEROS_ENV
683 (void)chown(ktc_tkt_string(), pwd->pw_uid, pwd->pw_gid);
684 #endif /* AFS_KERBEROS_ENV */
685 /***** SIA LAUNCHING SESSION *****/
686 if(sia_ses_launch(sia_collect,entity) == SIASUCCESS) {
687 ngroups = getgroups(NGROUPS, groups);
688 if ((pagval != NOPAG) &&
689 (afs_get_pag_from_groups(groups[0], groups[1])) == NOPAG) {
690 /* we will have to shift grouplist to make room for pag */
691 if (ngroups + 2 > NGROUPS) {
692 perror("Too many groups"); /* XXX */
695 for (j = ngroups - 1; j >= 0; j--) {
696 groups[j + 2] = groups[j];
699 get_groups_from_pag(pagval, &groups[0], &groups[1]);
700 seteuid(0); /* Since the seteuid was set the user already */
701 if (setgroups(ngroups, groups) == -1) {
705 seteuid(entity->pwd->pw_uid); /* Set euid back */
707 /****** Nothing left to fail *******/
708 if(setreuid(geteuid(),geteuid()) < 0) {
709 perror("setreuid()");
712 /****** set up environment *******/
713 /* destroy environment unless user has requested preservation */
714 envinit[0] = envinit[1] = 0;
715 if (environ) for (cnt = 0; environ[cnt] != NULL; cnt++)
716 if (!strncmp(environ[cnt], "TERM=", 5)) {
717 envinit[0] = environ[cnt];
722 (void)setenv("HOME", entity->pwd->pw_dir, 1);
723 if(entity->pwd->pw_shell && *entity->pwd->pw_shell)
724 strncpy(shell, entity->pwd->pw_shell, sizeof shell);
725 (void)setenv("SHELL", shell, 1);
727 (void)strncpy(term, stypeof(tty), sizeof(term));
728 (void)setenv("TERM", term, 0);
729 (void)setenv("USER", entity->pwd->pw_name, 1);
730 (void)setenv("LOGNAME", entity->pwd->pw_name, 1);
731 (void)setenv("PATH", _PATH_DEFPATH, 0);
732 #ifdef AFS_KERBEROS_ENV
733 (void)setenv("KRBTKFILE", ktc_tkt_string(), 0);
734 #endif /* AFS_KERBEROS_ENV */
739 (void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR, entity->pwd->pw_name);
740 if (stat(tbuf, &st) == 0 && st.st_size != 0)
741 (void)printf("You have %smail.\n", (st.st_mtime > st.st_atime) ? "new " : "");
743 /******* Setup default signals **********/
744 (void)signal(SIGALRM, SIG_DFL);
745 (void)signal(SIGQUIT, SIG_DFL);
746 (void)signal(SIGINT, SIG_DFL);
747 (void)signal(SIGTSTP, SIG_IGN);
750 (void)strcpy(tbuf + 1, (p = strrchr(shell, '/')) ? p + 1 : shell);
751 sia_ses_release(&entity);
752 execlp(shell, tbuf, 0);
753 (void)printf("login: no shell: %s.\n", strerror(errno));
756 /***** SIA session launch failure *****/
758 /***** SIA session establishment failure *****/
760 if (entity != NULL) {
761 sia_ses_release(&entity);
763 syslog(LOG_ERR, " LOGIN FAILURE ");
766 #else /* AFS_OSF_ENV */
768 { /* This block sets TZ environment on HPUX */
769 /* First set TZ environment here, so that
770 LOGIN FAILURE will get correct time stamp.
771 For logins from console, -p flag is not set,
772 the TZ environment set here will be cleared later.
773 We're gonna set it once again later after it's cleared.
776 char buf[MAX_TZ_LEN];
780 /* set TZ only if tz_incorrect
781 (*env_p==0 or env_p==0 ) and there is a correct /etc/TIMEZONE
782 otherwise, just let it be default (US eastern on HP)
784 env_p = getenv("TZ");
791 /* HP UX 10.0 or later has different file format */
792 #ifdef AFS_HPUX100_ENV
793 /* /etc/TIMEZONE file example (HP-UX 10 or later)
797 fp = fopen ("/etc/TIMEZONE","r");
799 if ( (fgets (buf, sizeof(buf), fp)) != NULL ) {
800 buf[strlen(buf)-1] = 0;
801 if (!strncmp (buf, "TZ=", 3)) {
802 strncpy (TZ, buf, MAX_TZ_LEN);
808 #else /* AFS_HPUX100_ENV */
809 /* /etc/src.sh file example (HP-UX 9 or earlier)
810 SYSTEM_NAME=myname; export SYSTEM_NAME
811 TZ=EST5EDT; export TZ
813 fp = fopen ("/etc/src.sh","r");
815 while ( (fgets (buf, sizeof(buf), fp)) != NULL ) {
816 buf[strlen(buf)-1] = 0;
817 if (!strncmp (buf, "TZ=", 3)) {
818 char *p = strchr (buf, ';');
820 strncpy (TZ, buf, MAX_TZ_LEN);
826 #endif /* AFS_HPUX100_ENV */
832 #endif /* AFS_HPUX_ENV */
833 for (cnt = 0;; ask = 1) {
835 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
836 (void)ioctl(0, TIOCSETD, &ioctlval);
837 #endif /* !AIX and !hpux */
839 if (ask | !username) {
844 * Note if trying multiple user names;
845 * log failures for previous user name,
846 * but don't bother logging one failure
847 * for nonexistent name (mistyped username).
849 if (failures && strcmp(tbuf, username)) {
850 if (failures > (pwd ? 0 : 1))
854 (void)strcpy(tbuf, username);
857 if ((pwd = getpwnam(username)) && (spwd = getspnam(username))) {
858 initgroups(username, pwd->pw_gid); /* XXX */
859 salt = spwd->sp_pwdp;
862 if (pwd = getpwnam(username))
863 salt = pwd->pw_passwd;
864 #endif /* else !SUN5 */
866 /* if user not super-user, check for disabled logins */
867 if (pwd == NULL || pwd->pw_uid) {
872 * Disallow automatic login to root; if not invoked by
873 * root, disallow if the uid's differ.
876 uid_t uid = getuid();
879 * allow f flag only if user running login is
880 * same as target user or superuser
882 fflag = (uid == 0) || (uid == pwd->pw_uid);
883 if (fflag) passwd_req = 0;
884 /* passwd_req = pwd->pw_uid == 0 || (uid && uid != pwd->pw_uid);*/
888 * If no pre-authentication and a password exists
889 * for this user, prompt for one and verify it.
891 if (!passwd_req || (pwd && !*pwd->pw_passwd)) {
894 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
898 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
899 setpriority(PRIO_PROCESS, 0, -4);
903 * The basic model for logging in now, is that *if* there
904 * is a kerberos record for this individual user we will
905 * trust kerberos (provided the user really has an account
906 * locally.) If there is no kerberos record (or the password
907 * were typed incorrectly.) we would attempt to authenticate
908 * against the local password file entry. Naturally, if
909 * both fail we use existing failure code.
915 static int useGetPass = 0;
918 pp = getpass("Password:");
919 memcpy(pword, pp, 8);
921 code = ka_UserReadPassword("Password:",
927 if (code != KANULLPASSWORD) {
932 "Unable to read password because %s\n",
938 if(ka_UserAuthenticateGeneral(
939 KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG,
940 pwd->pw_name, /* kerberos name */
944 0, /* default lifetime */
947 &reason /* error string */
953 if(strcmp(pwd->pw_passwd,"*"))
954 break; /* out of for loop */
955 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
956 (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL);
961 pp = getpass("Password:");
965 (void) memset(pp, '\0', strlen(pp));
967 if (spwd && !strcmp(p, spwd->sp_pwdp))
969 if (pwd && !strcmp(p, pwd->pw_passwd))
972 /* Only print this if local authentication is successful */
974 printf("Unable to authenticate to AFS because %s\n", reason);
975 printf("proceeding with local authentication...\n");
983 printf("Login incorrect\n");
985 /* we allow 10 tries, but after 3 we start backing off */
989 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
990 (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL);
998 sleep((u_int)((cnt - 3) * 5));
1001 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
1002 setpriority(PRIO_PROCESS, 0, 0);
1005 /* Exits if root login not on system console. */
1006 if (pwd->pw_uid == 0) {
1007 if ((Console != NULL) && (strcmp(ttyn, Console) != 0)) {
1008 (void) printf("Not on system console\n");
1011 if (Def_supath != NULL)
1012 Def_path = Def_supath;
1014 Def_path = DEF_SUPATH;
1016 #endif /* AFS_SUN5_ENV */
1018 printf("AFS (R) %s Login\n", AFSVersion); /* generated version */
1020 /* committed to login -- turn off timeout */
1021 (void)alarm((u_int)0);
1024 * If valid so far and root is logging in, see if root logins on
1025 * this terminal are permitted.
1027 #if !defined(AIX) && !defined(AFS_SUN5_ENV)
1029 /* This is the /etc/securetty feature. We wanted to 1st prompt for a
1030 * password even if we know that this is not a securetty because
1031 * we don't want to give any clue if the potential intruder guesses
1032 * the correct password.
1034 if ((pwd->pw_uid == 0) && !rootterm(ttyn+sizeof("/dev/")-1)) {
1036 if (pwd->pw_uid == 0 && !rootterm(tty)) {
1039 syslog(LOG_NOTICE, "ROOT LOGIN REFUSED FROM %s",
1042 syslog(LOG_NOTICE, "ROOT LOGIN REFUSED ON %s", tty);
1043 printf("Login incorrect\n");
1049 (void)chmod(ttyn,0666);
1053 #endif /* !AIX & !SUN5 */
1055 if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
1059 "Too many users logged on already.\nTry again later.\n");
1063 "You have too many processes running.\n");
1066 perror("quota (Q_SETUID)");
1073 (void)chmod(ttyn,0666);
1077 #endif /* Q_SETUID */
1079 /* For Solaris and HP, we might want to chdir later for remotely
1080 mounted home directory because home direcotry may be
1083 if (chdir(pwd->pw_dir) < 0) {
1084 #if !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV)
1085 printf("No directory %s!\n", pwd->pw_dir);
1086 #endif /* !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV) */
1094 (void)chmod(ttyn,0666);
1099 #if !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV)
1101 printf("Logging in with home = \"/\".\n");
1102 #else /* !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV) */
1104 #endif /* !defined(AFS_SUN5_ENV) && !defined(AFS_HPUX_ENV) */
1107 /* nothing else left to fail -- really log in */
1111 struct utmpx *utx, *getutxent(), *pututxline();
1113 #if defined(AFS_HPUX_ENV)
1114 register struct utmp *u = NULL;
1115 extern pid_t getpid();
1119 (void)time(&utmp.ut_tv.tv_sec);
1121 (void)time(&utmp.ut_time);
1123 strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
1124 #if !defined(AIX) /*&& !defined(AFS_SUN5_ENV)*/
1126 strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
1128 strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
1129 #if defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV)
1130 utmp.ut_type = USER_PROCESS;
1131 if (!strncmp(ttyn, "/dev/", strlen("/dev/"))) {
1132 strncpy(utmp.ut_line, &(ttyn[strlen("/dev/")]), sizeof(utmp.ut_line));
1135 utmp.ut_pid = getpid();
1136 if ((!strncmp(tty, "tty", strlen("tty"))) ||
1137 (!strncmp(tty, "pty", strlen("pty"))) ) {
1138 strncpy(utmp.ut_id, &(tty[strlen("tty")]), sizeof(utmp.ut_id));
1140 #endif /* AFS_HPUX_ENV */
1143 * Find the entry for this pid (or line if we are a sublogin)
1146 while ((u = getutent()) != NULL) {
1147 if ( (u->ut_type == INIT_PROCESS ||
1148 u->ut_type == LOGIN_PROCESS ||
1149 u->ut_type == USER_PROCESS)
1151 strncmp(u->ut_line,ttyntail,sizeof(u->ut_line))==0) ||
1152 u->ut_pid == utmp.ut_pid) ) {
1155 * Copy in the name of the tty minus the
1156 * "/dev/", the id, and set the type of entry
1159 (void) strncpy(utmp.ut_line, ttyntail, sizeof(utmp.ut_line));
1160 utmp.ut_id[0] = u->ut_id[0];
1161 utmp.ut_id[1] = u->ut_id[1];
1162 utmp.ut_id[2] = u->ut_id[2];
1163 utmp.ut_id[3] = u->ut_id[3];
1164 utmp.ut_type = USER_PROCESS;
1165 utmp.how_to_count = add_count();
1168 * Copy remote host information
1170 strncpy(utmp.ut_host, u->ut_host, sizeof(utmp.ut_host));
1171 utmp.ut_addr = u->ut_addr;
1173 /* Return the new updated utmp file entry. */
1178 endutent(); /* Close utmp file */
1181 utmp.ut_syslen = (tlen = strlen(utmp.ut_host)) ? min(tlen+1, sizeof(utmp.ut_host)) : 0;
1182 strncpy(utmp.ut_user, username, sizeof(utmp.ut_user));
1183 while ((utx = getutxent()) != NULL) {
1184 if ((utx->ut_type == INIT_PROCESS || utx->ut_type == LOGIN_PROCESS ||
1185 utx->ut_type == USER_PROCESS) && (utx->ut_pid == utmp.ut_pid)) {
1186 strncpy(utmp.ut_line,(ttyn+sizeof("/dev/")-1), sizeof(utmp.ut_line));
1187 utmp.ut_id[0] = utx->ut_id[0];
1188 utmp.ut_id[1] = utx->ut_id[1];
1189 utmp.ut_id[2] = utx->ut_id[2];
1190 utmp.ut_id[3] = utx->ut_id[3];
1191 utmp.ut_type = USER_PROCESS;
1196 endutxent(); /* Close utmp file */
1198 printf("No utmpx entry. You must exec 'login' from the lowest level 'sh'\n");
1201 updwtmpx(WTMPX_FILE, &utmp);
1207 quietlog = access(HUSHLOGIN, F_OK) == 0;
1208 dolastlog(quietlog);
1210 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
1212 if (!hflag && !rflag) { /* XXX */
1214 if (!hflag) { /* XXX */
1216 static struct winsize win = { 0, 0, 0, 0 };
1218 (void)ioctl(0, TIOCSWINSZ, &win);
1220 #endif /* !AIX and !hpux */
1224 * Set the user's ulimit
1226 if (Def_ulimit > 0L && ulimit(SET_FSIZ, Def_ulimit) < 0L)
1227 (void) printf("Could not set ULIMIT to %ld\n", Def_ulimit);
1230 #if defined(AFS_SUN_ENV)
1232 * Set owner/group/permissions of framebuffer devices
1234 (void) set_fb_attrs(ttyn, pwd->pw_uid, pwd->pw_gid);
1237 (void)chown(ttyn, pwd->pw_uid,
1238 (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
1241 (void)chmod(ttyn, 0620);
1242 (void)setgid(pwd->pw_gid);
1245 if ((pwd->pw_gid < 0) || (pwd->pw_gid > MAXUID)) {
1246 printf("Bad group id.\n");
1249 if ((pwd->pw_uid < 0) || (pwd->pw_uid > MAXUID)) {
1250 printf("Bad user id.\n");
1255 #ifdef AFS_KERBEROS_ENV
1256 (void)chown(ktc_tkt_string(), pwd->pw_uid, pwd->pw_gid);
1260 groups[0] = groups[1] = 0;
1261 ngroups = getgroups(NGROUPS_MAX, groups);
1262 pagval = get_pag_from_groups(groups[0], groups[1]);
1263 initgroups(username, pwd->pw_gid);
1264 ngroups = getgroups(NGROUPS_MAX, groups);
1265 if ((pagval != NOPAG) &&
1266 (afs_get_pag_from_groups(groups[0], groups[1])) == NOPAG) {
1267 /* we will have to shift grouplist to make room for pag */
1268 if (ngroups + 2 > NGROUPS_MAX)
1269 return E2BIG; /* XXX */
1270 for (j = ngroups - 1; j >= 0; j--) {
1271 groups[j + 2] = groups[j];
1274 get_groups_from_pag(pagval, &groups[0], &groups[1]);
1275 if (setgroups(ngroups, groups) == -1) {
1276 perror("setgroups");
1282 quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
1283 #endif /* Q_DOWARN */
1285 /* destroy environment unless user has requested preservation */
1291 (void)setuid(pwd->pw_uid);
1293 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
1294 /* This is the time to retry chdir for Solaris and HP
1296 if (retry_chdir && chdir(pwd->pw_dir)<0) {
1297 printf ("No directory %s!\n", pwd->pw_dir);
1299 /* reset tty line and exit */
1300 (void)chmod(ttyn, 0666);
1304 printf ("Logging with home = \"/\".\n");
1306 #endif /* AFS_SUN5_ENV || AFS_HPUX_ENV */
1308 if (*pwd->pw_shell == '\0')
1309 pwd->pw_shell = BSHELL;
1310 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
1311 /* turn on new line discipline for the csh */
1312 else if (!strcmp(pwd->pw_shell, "/bin/csh")) {
1313 ioctlval = NTTYDISC;
1314 (void)ioctl(0, TIOCSETD, &ioctlval);
1319 if (Altshell != NULL && strcmp(Altshell, "YES") == 0) {
1320 (void)setenv("SHELL", pwd->pw_shell, 1);
1323 if (Def_tz != NULL) {
1326 Def_tz = getenv("TZ");
1328 setenv("TZ", Def_tz, 1);
1332 setenv("TZ", Def_tz, 1);
1335 if (Def_hertz == NULL)
1336 (void)setenv("HZ", HZ, 1);
1338 (void)setenv("HZ", Def_hertz, 1);
1343 /* if pflag is not set
1344 the TZ environment was cleared moments ago */
1345 if (*TZ && !pflag) {
1346 setenv ("TZ", &TZ[3], 1);
1348 #endif /* AFS_HPUX_ENV */
1350 (void)setenv("HOME", pwd->pw_dir, 1);
1351 (void)setenv("SHELL", pwd->pw_shell, 1);
1352 if (term[0] == '\0')
1353 strncpy(term, stypeof(tty), sizeof(term));
1354 (void)setenv("TERM", term, 0);
1355 (void)setenv("USER", pwd->pw_name, 1);
1356 (void)setenv("LOGNAME", pwd->pw_name, 1);
1358 if (Def_path == NULL)
1359 (void)setenv("PATH", DEF_PATH, 0);
1361 (void)setenv("PATH", Def_path, 0);
1363 (void)setenv("PATH", "/usr/ucb:/bin:/usr/bin:", 0);
1366 #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX100_ENV)
1368 /* Sol, HP: set MAIL only if NO_MAIL is not set */
1369 sprintf (mail, "%s%s", MAILDIR, pwd->pw_name);
1370 (void)setenv("MAIL", mail, 0);
1371 #endif /* NO_MAIL */
1372 #endif /* AFS_SUN5_ENV || AFS_HPUX100_ENV */
1374 #ifdef AFS_KERBEROS_ENV
1375 (void)setenv("KRBTKFILE", ktc_tkt_string(), 0);
1378 if (password_expires >= 0) {
1380 (void)setenv("PASSWORD_EXPIRES", cv2string(&sbuffer[100], password_expires), 1);
1383 if (tty[sizeof("tty")-1] == 'd')
1384 syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
1385 if (pwd->pw_uid == 0)
1387 syslog(LOG_NOTICE, "ROOT LOGIN ON %s FROM %s",
1390 syslog(LOG_NOTICE, "ROOT LOGIN ON %s", tty);
1395 #if ! defined(AFS_SUN5_ENV) && (! defined(AFS_HPUX_ENV))
1396 /* In Solaris the shell displays motd */
1397 /* On hp700s /etc/profile also does it so it's redundant here too */
1399 /* Don't check email either, should be done in shell */
1400 (void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name);
1401 if (stat(tbuf, &st) == 0 && st.st_size != 0)
1402 printf("You have %smail.\n",
1403 (st.st_mtime > st.st_atime) ? "new " : "");
1407 (void)signal(SIGALRM, SIG_DFL);
1408 (void)signal(SIGQUIT, SIG_DFL);
1409 (void)signal(SIGINT, SIG_DFL);
1410 #if !defined(AIX) && !defined(AFS_HPUX_ENV)
1411 (void)signal(SIGTSTP, SIG_IGN);
1415 strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ?
1416 p + 1 : pwd->pw_shell);
1417 execlp(pwd->pw_shell, tbuf, 0);
1418 fprintf(stderr, "login: no shell: ");
1419 perror(pwd->pw_shell);
1421 #endif /* else AFS_OSF_ENV */
1424 getloginname(prompt)
1429 static char nbuf[UT_NAMESIZE + 1];
1436 for (p = nbuf; (ch = getchar()) != '\n'; ) {
1441 if (p < nbuf + UT_NAMESIZE)
1447 "login names may not start with '-'.\n");
1466 * check to see if /etc/securetty exists, if it does then scan
1467 * file to see if passwd tty is in the file. Return 1 if it is, 0 if not.
1469 if ((fd = fopen(SECURETTY_FILE, "r")) == NULL)
1471 while (fgets(buf, sizeof buf, fd) != NULL) {
1472 buf[strlen(buf)-1] = '\0';
1473 if (strcmp(tty, buf) == 0) {
1482 #if !defined(AIX) && !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV)
1488 return((t = getttynam(ttyn)) && t->ty_status&TTY_SECURE);
1492 jmp_buf motdinterrupt;
1496 register int fd, nchars;
1501 if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
1503 oldint = signal(SIGINT, sigint);
1504 if (setjmp(motdinterrupt) == 0)
1505 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
1506 (void)write(fileno(stdout), tbuf, nchars);
1507 (void)signal(SIGINT, oldint);
1514 longjmp(motdinterrupt, 1);
1519 register int fd, nchars;
1522 if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) {
1523 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
1524 (void)write(fileno(stdout), tbuf, nchars);
1529 #if defined(AIX) || defined(AFS_HPUX_ENV) || defined(AFS_AIX32_ENV)
1540 #define _PATH_LASTLOG "/var/adm/lastlog"
1546 if ((fd = open(_PATH_LASTLOG, (O_RDWR|O_CREAT), 0666)) < 0)
1547 fprintf(stderr, "Can't open %s", _PATH_LASTLOG);
1549 (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
1551 if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) && ll.ll_time != 0) {
1552 (void)printf("Last login: %.*s ", 24-5, (char *)ctime(&ll.ll_time));
1553 if (*ll.ll_host != '\0')
1554 (void)printf("from %.*s\n", sizeof(ll.ll_host), ll.ll_host);
1556 (void)printf("on %.*s\n", sizeof(ll.ll_line), ll.ll_line);
1569 if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) {
1570 (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
1572 if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
1574 printf("Last login: %.*s ",
1575 24-5, (char *)ctime(&ll.ll_time));
1576 if (*ll.ll_host != '\0')
1577 printf("from %.*s\n",
1578 sizeof(ll.ll_host), ll.ll_host);
1581 sizeof(ll.ll_line), ll.ll_line);
1583 (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
1585 memset(&ll, '\0', sizeof(ll));
1586 (void)time(&ll.ll_time);
1587 strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
1589 strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
1590 (void)write(fd, (char *)&ll, sizeof(ll));
1603 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s, %s",
1604 failures, failures > 1 ? "S" : "", hostname, name);
1606 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s, %s",
1607 failures, failures > 1 ? "S" : "", tty, name);
1612 #define UNKNOWN "sun"
1614 #define UNKNOWN "su"
1617 #if defined(AIX) || defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV)
1631 return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
1635 getstr(buf, cnt, err)
1642 if (read(0, &ch, sizeof(ch)) != sizeof(ch))
1645 fprintf(stderr, "%s too long\r\n", err);
1660 int get_pag_from_groups(g0, g1)
1663 afs_uint32 h, l, result;
1667 if (g0 < 0xc000 && g1 < 0xc000) {
1668 l = ((g0 & 0x3fff) << 14) | (g1 & 0x3fff);
1670 h = (g1 >> 14) + h + h + h;
1671 result = ((h << 28) | l);
1672 /* Additional testing */
1673 if (((result >> 24) & 0xff) == 'A')
1682 get_groups_from_pag(pag, g0p, g1p)
1684 afs_uint32 *g0p, *g1p;
1686 unsigned short g0, g1;
1689 g0 = 0x3fff & (pag >> 14);
1691 g0 |= ((pag >> 28) / 3) << 14;
1692 g1 |= ((pag >> 28) % 3) << 14;
1698 #if defined(AFS_SUN_ENV)
1700 * set_fb_attrs -- change owner/group/permissions of framebuffers
1701 * listed in /etc/fbtab.
1704 * Exiting from set_fb_attrs upon error is not advisable
1705 * since it would disable logins on console devices.
1708 * console mode device_name[:device_name ...]
1709 * # begins a comment and may appear anywhere on a line.
1712 * /dev/console 0660 /dev/fb:/dev/cgtwo0:/dev/bwtwo0
1713 * /dev/console 0660 /dev/gpone0a:/dev/gpone0b
1716 * The example above sets the owner/group/permissions of the listed
1717 * devices to uid/gid/0660 if ttyn is /dev/console
1720 #define FIELD_DELIMS " \t\n"
1723 #define WILDCARD "/*"
1724 #define WILDCARD_LEN 2
1725 #define MAX_LINELEN 256
1727 #define FBTAB "/etc/logindevperm"
1729 #define FBTAB "/etc/fbtab"
1733 set_fb_attrs(ttyn, uid, gid)
1738 char line[MAX_LINELEN];
1748 if ((fp = fopen(FBTAB, "r")) == NULL)
1750 while (fgets(line, MAX_LINELEN, fp)) {
1751 if (ptr = strchr(line, '#'))
1752 *ptr = '\0'; /* handle comments */
1753 if ((console = strtok(line, FIELD_DELIMS)) == NULL)
1754 continue; /* ignore blank lines */
1755 if (strcmp(console, ttyn) != 0)
1756 continue; /* ignore non-consoles */
1757 mode_str = strtok((char *)NULL, FIELD_DELIMS);
1758 if (mode_str == NULL) {
1759 (void) fprintf(stderr, "%s: invalid entry -- %s\n",
1763 /* convert string to octal value */
1764 mode = (int) strtol(mode_str, (char **)NULL, 8);
1765 if (mode < 0 || mode > 0777) {
1766 (void) fprintf(stderr, "%s: invalid mode -- %s\n",
1770 dev_list = strtok((char *)NULL, FIELD_DELIMS);
1771 if (dev_list == NULL) {
1772 (void) fprintf(stderr, "%s: %s -- empty device list\n",
1777 device = strtok(dev_list, COLON);
1779 ptr = strstr(device, WILDCARD);
1781 (strlen(device) - (ptr - &device[0])) == WILDCARD_LEN){
1782 /* The device was a (legally-specified) directory. */
1784 struct dirent *dir_e;
1785 char dev_file[MAXPATHLEN];
1787 *ptr = '\0'; /* Remove the wildcard from the dir name. */
1788 if ((dev_dir = opendir(device)) == (DIR *) NULL) {
1789 syslog(LOG_ERR, "bad device %s%s in %s, ignored",
1790 device, WILDCARD, FBTAB);
1794 /* Directory is open; alter its files. */
1795 /* Must link with /usr/lib/libc.a before
1796 /usr/ucblib/libucb.a or the d_name structs
1797 miss the first two characters of the filename */
1798 while (dir_e = readdir(dev_dir)) {
1799 if (strcmp(dir_e->d_name, "..") &&
1800 strcmp(dir_e->d_name, ".")) {
1801 strcpy(dev_file, device);
1802 strcat(dev_file, "/");
1803 strcat(dev_file, dir_e->d_name);
1804 (void) chown(dev_file, uid, gid);
1805 (void) chmod(dev_file, mode);
1808 (void) closedir(dev_dir);
1810 /* 'device' was not a directory, so we can just do it. */
1811 (void) chown(device, uid, gid);
1812 (void) chmod(device, mode);
1814 device = strtok((char *)NULL, COLON); /* Move thru list. */
1816 device = strtok(dev_list, COLON);
1818 (void) chown(device, uid, gid);
1819 (void) chmod(device, mode);
1820 device = strtok((char *)NULL, COLON);
1832 register int c, i, num;
1834 switch( c = getc(stdin)) {
1861 for( num=0,i=0; i<3; i++ ) {
1862 num = num * 8 + (c - '0');
1863 if ((c = getc(stdin)) < '0' || c > '7')
1875 static char **getargs(inline)
1878 static char envbuf[256];
1879 static char *args[63];
1880 register char *ptr,**answer;
1883 extern int quotec();
1885 for (ptr= envbuf; ptr < &envbuf[sizeof(envbuf)];) *ptr++ = '\0';
1886 for (answer= args; answer < &args[63];) *answer++ = (char *)NULL;
1887 for (ptr= envbuf,answer= &args[0],state = 0; (c = getc(stdin)) != EOF;) {
1891 if (ptr == &envbuf[0]) return((char **)NULL);
1892 else return(&args[0]);
1909 if (ptr == &envbuf[sizeof(envbuf)-1]) {
1922 static struct passwd nouser = { "", "no:password", ~0 };
1924 getstr(rusername, sizeof (rusername), "remuser");
1925 getstr(lusername, sizeof (lusername), "locuser");
1926 if (!username) username = lusername;
1927 getstr(term, sizeof (term), "Terminal type");
1933 pwd = getpwnam(lusername);
1947 static char rusername[100], lusername[100];
1948 static struct passwd nouser = { "", "no:password", ~0 };
1950 getstr(rusername, sizeof (rusername), "remuser");
1951 getstr(lusername, sizeof (lusername), "locuser");
1952 if (!username) username = lusername;
1953 getstr(term, sizeof (term), "Terminal type");
1958 pwd = getpwnam(lusername);
1963 code = ruserok(host, (pwd->pw_uid == 0), rusername, lusername);
1964 /*printf("DOREM=%d, host=%s, uid=%d, ruser=%s, luser=%s\n", code, host, pwd->pw_uid, rusername, lusername);*/
1970 { "0", "50", "75", "110", "134", "150", "200", "300",
1971 "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
1972 #define NSPEEDS (sizeof (speeds) / sizeof (speeds[0]))
1975 doremoteterm(terminal)
1977 doremoteterm(terminal, tp)
1985 register char *cp = strchr(terminal, '/'), **cpp;
1989 (void) ioctl(0, TCGETS, &tp);
1994 cp = strchr(speed, '/');
1997 for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
1998 if (strcmp(*cpp, speed) == 0) {
2000 tp.c_cflag = ((tp.c_cflag & ~CBAUD) | ((cpp-speeds) & CBAUD));
2002 tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
2008 tp.c_lflag = ECHO|ICANON|IGNPAR|ICRNL;
2009 (void) ioctl(0, TCSETS, &tp);
2011 tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
2018 * Check if the specified program is really a shell (e.g. "sh" or "csh").
2024 char *getusershell();
2027 while ((p = getusershell()) != NULL)
2028 if (strcmp(p, shell) == 0)
2034 static char *getlinep(const char *string, int size, FILE *stream) {
2040 if(!fgets(string, size, stream) || ferror(stream) || errno == EINTR)
2043 if(cp=strchr(string, '\n'))
2046 while((c=getc(stdin)) != '\n' && c != EOF && errno != EINTR)
2051 clean_entity_pwd(SIAENTITY *entity)
2053 if (entity->acctname != NULL) {
2054 free(entity->acctname);
2055 entity->acctname = NULL;
2057 if (entity->pwd != NULL) {
2058 if (entity->pwd->pw_name) {
2059 memset(entity->pwd->pw_name,'\0',strlen(entity->pwd->pw_name));
2060 free(entity->pwd->pw_name);
2061 entity->pwd->pw_name = NULL;
2063 if (entity->pwd->pw_passwd) {
2064 memset(entity->pwd->pw_passwd,'\0',strlen(entity->pwd->pw_passwd));
2065 free(entity->pwd->pw_passwd);
2066 entity->pwd->pw_passwd = NULL;
2068 if (entity->pwd->pw_comment) {
2069 memset(entity->pwd->pw_comment,'\0',strlen(entity->pwd->pw_comment));
2070 free(entity->pwd->pw_comment);
2071 entity->pwd->pw_comment = NULL;
2073 if (entity->pwd->pw_gecos) {
2074 memset(entity->pwd->pw_gecos,'\0',strlen(entity->pwd->pw_gecos));
2075 free(entity->pwd->pw_gecos);
2076 entity->pwd->pw_gecos = NULL;
2078 if (entity->pwd->pw_dir) {
2079 memset(entity->pwd->pw_dir,'\0',strlen(entity->pwd->pw_dir));
2080 free(entity->pwd->pw_dir);
2081 entity->pwd->pw_dir = NULL;
2083 if (entity->pwd->pw_shell) {
2084 memset(entity->pwd->pw_shell,'\0',strlen(entity->pwd->pw_shell));
2085 free(entity->pwd->pw_shell);
2086 entity->pwd->pw_shell = NULL;
2093 int getloginp(entity)
2098 fputs("login: ", stdout);
2099 if (getlinep(result,sizeof result,stdin) == (char *) NULL) {
2102 entity->name = (char *)malloc(SIANAMEMIN+1);
2103 if (entity->name == NULL)
2105 strcpy((unsigned char *)entity->name, result);
2109 #ifdef AFS_KERBEROS_ENV
2110 extern char *ktc_tkt_string();
2113 int do_afs_auth(pwd, pass, doafs)
2118 int code, afsLoginFail=0;
2119 char *lcell, realm[MAXKTCREALMLEN], *pword, prompt[256];
2120 char *shell, *reason;
2126 sprintf(prompt, "Enter AFS password: ");
2127 pword = getpass(prompt);
2128 if (strlen(pword) == 0) {
2129 printf("Unable to read password because zero length password is illegal\n");
2130 printf("Login incorrect\n"); fflush(stdout);
2135 if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG,
2136 pwd->pw_name, /* kerberos name */
2137 NULL, /* instance */
2139 pword, /* password */
2140 0, /* default lifetime */
2143 &reason /* error string */)) {
2145 if (doafs) return 0;
2147 if (pwd->pw_passwd && strcmp(pwd->pw_passwd,"*"))
2148 return 1; /* Success */
2151 if (!pwd->pw_passwd) return 0;
2152 namep = crypt(pword, pwd->pw_passwd);
2153 code = strcmp(namep, pwd->pw_passwd) == 0 ? 1 : 0 ;
2154 if ((code == 1) && afsLoginFail) {
2155 /* Only print this if local authentication is successful */
2156 printf("Unable to authenticate to AFS because %s\n", reason);
2157 printf("proceeding with local authentication...\n");
2166 static void defaults()
2168 extern int defopen(), defcntl();
2172 if (defopen(Pndefault) == 0) {
2176 flags = defcntl(DC_GETFLAGS, 0);
2177 TURNOFF(flags, DC_CASE);
2178 defcntl(DC_SETFLAGS, flags);
2180 if ((Console = defread("CONSOLE=")) != NULL)
2181 Console = strdup(Console);
2182 if ((Altshell = defread("ALTSHELL=")) != NULL)
2183 Altshell = strdup(Altshell);
2184 if ((Passreq = defread("PASSREQ=")) != NULL)
2185 Passreq = strdup(Passreq);
2186 if ((Def_tz = defread("TIMEZONE=")) != NULL)
2187 Def_tz = strdup(Def_tz);
2188 if ((Def_hertz = defread("HZ=")) != NULL)
2189 Def_hertz = strdup(Def_hertz);
2190 if ((Def_path = defread("PATH=")) != NULL)
2191 Def_path = strdup(Def_path);
2192 if ((Def_supath = defread("SUPATH=")) != NULL)
2193 Def_supath = strdup(Def_supath);
2194 if ((ptr = defread("ULIMIT=")) != NULL)
2195 Def_ulimit = atol(ptr);
2196 if ((ptr = defread("TIMEOUT=")) != NULL)
2197 Def_timeout = (unsigned) atoi(ptr);
2198 if ((ptr = defread("UMASK=")) != NULL)
2199 if (sscanf(ptr, "%lo", &Umask) != 1)
2201 if ((ptr = defread("IDLEWEEKS=")) != NULL)
2202 Idleweeks = atoi(ptr);
2203 if ((ptr = defread("SLEEPTIME=")) != NULL)
2204 Sleeptime = atoi(ptr);
2205 (void) defopen(NULL);
2213 * returns 1 if user should be counted as 1 user;
2214 * returns 3 if user should be counted as a pty
2215 * may return other stuff in the future
2230 * returns 1 if user is a pty, 0 otherwise
2232 #define SSTRPTYMAJOR 157 /* major number for Streams slave pty's */
2233 #define SPTYMAJOR 17 /* major number for slave pty's */
2234 #define PTYSC 0x00 /* select code for pty's */
2235 #define select_code(x) (((x) & 0xff0000) >> 16)
2239 static int firsttime = 1;
2244 if (fstat(0, &sbuf) != 0 || /* can't stat */
2245 (sbuf.st_mode & S_IFMT) != S_IFCHR || /* not char special */
2246 major(sbuf.st_rdev) != SPTYMAJOR || /* not pty major num */
2247 select_code(sbuf.st_rdev) != PTYSC) { /* not pty minor num */
2248 /* Check to see if it is a Streams PTY */
2249 if (major(sbuf.st_rdev) == SSTRPTYMAJOR) {
2253 retval = 0; /* neither a BSD nor a Streams PTY */
2257 if (ISB1 && !remote_login)
2258 retval=0; /* local pty for td tty simulation */
2265 #define NLIOUCOUNT _IO('K',28) /* _IO(K, 28) */
2266 #define NLIOSERV 0x4b33 /* (('K' << 8) + 51 */
2269 * returns 1 if user is an NL server, else returns 0
2273 if (ioctl(0, NLIOUCOUNT) == NLIOSERV)