Annotation of 40BSD/cmd/login.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)login.c     4.6 (Berkeley) 11/11/80";
                      2: /*
                      3:  * login [ name ]
                      4:  */
                      5: 
                      6: #include <sys/types.h>
                      7: #include <sgtty.h>
                      8: #include <utmp.h>
                      9: #include <signal.h>
                     10: #include <pwd.h>
                     11: #include <stdio.h>
                     12: #include <sys/stat.h>
                     13: #include <lastlog.h>
                     14: #include <whoami.h>
                     15: #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
                     16: 
                     17: #define NMAX sizeof(utmp.ut_name)
                     18: #define LMAX sizeof(utmp.ut_line)
                     19: 
                     20: char   user[20];
                     21: char   maildir[30] =   "/usr/spool/mail/";
                     22: char   lastlog[] =     "/usr/adm/lastlog";
                     23: struct passwd nouser = {"", "nope"};
                     24: struct sgttyb ttyb;
                     25: struct utmp utmp;
                     26: char   minusnam[16] = "-";
                     27: char   homedir[64] = "HOME=";
                     28: char   shell[64] = "SHELL=";
                     29: char   term[64] = "TERM=";
                     30: char   *envinit[] = {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", term, user,0};
                     31: struct passwd *pwd;
                     32: 
                     33: struct passwd *getpwnam();
                     34: char   *strcat();
                     35: int    setpwent();
                     36: char   *ttyname();
                     37: char   *crypt();
                     38: char   *getpass();
                     39: char   *rindex();
                     40: char   *stypeof();
                     41: extern char **environ;
                     42: 
                     43: #define        CTRL(c) ('c'&037)
                     44: #define        CERASE  '#'
                     45: #define        CEOT    CTRL(d)
                     46: #define        CKILL   '@'
                     47: #define        CQUIT   034             /* FS, cntl shift L */
                     48: #define        CINTR   0177            /* DEL */
                     49: #define        CSTOP   CTRL(s)
                     50: #define        CSTART  CTRL(q)
                     51: #define        CBRK    0377
                     52: struct tchars tc = {
                     53:        CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
                     54: };
                     55: struct ltchars ltc = {
                     56:        CTRL(z), CTRL(y), CTRL(r), CTRL(o), CTRL(w), CTRL(v)
                     57: };
                     58: 
                     59: main(argc, argv)
                     60: char **argv;
                     61: {
                     62:        register char *namep;
                     63:        int t, f, c;
                     64:        char *ttyn;
                     65:        int ldisc = 0;
                     66: 
                     67:        alarm(60);
                     68:        signal(SIGQUIT, SIG_IGN);
                     69:        signal(SIGINT, SIG_IGN);
                     70:        nice(-100);
                     71:        nice(20);
                     72:        nice(0);
                     73:        ioctl(0, TIOCLSET, 0);
                     74:        ioctl(0, TIOCNXCL, 0);
                     75:        gtty(0, &ttyb);
                     76:        ttyb.sg_erase = '#';
                     77:        ttyb.sg_kill = '@';
                     78:        stty(0, &ttyb);
                     79:        ioctl(0, TIOCSETC, &tc);
                     80:        ioctl(0, TIOCSLTC, &ltc);
                     81:        for (t=3; t<20; t++)
                     82:                close(t);
                     83:        ttyn = ttyname(0);
                     84:        if (ttyn==0)
                     85:                ttyn = "/dev/tty??";
                     86: 
                     87:     loop:
                     88:        ldisc = 0;
                     89:        ioctl(0, TIOCSETD, &ldisc);
                     90:        SCPYN(utmp.ut_name, "");
                     91:        if (argc>1) {
                     92:                SCPYN(utmp.ut_name, argv[1]);
                     93:                argc = 0;
                     94:        }
                     95:        while (utmp.ut_name[0] == '\0') {
                     96:                namep = utmp.ut_name;
                     97:                printf("login: ");
                     98:                while ((c = getchar()) != '\n') {
                     99:                        if(c == ' ')
                    100:                                c = '_';
                    101:                        if (c == EOF)
                    102:                                exit(0);
                    103:                        if (namep < utmp.ut_name+NMAX)
                    104:                                *namep++ = c;
                    105:                }
                    106:        }
                    107:        setpwent();
                    108:        if ((pwd = getpwnam(utmp.ut_name)) == NULL)
                    109:                pwd = &nouser;
                    110:        endpwent();
                    111:        if (!strcmp(pwd->pw_shell, "/bin/csh")) {
                    112:                ldisc = NTTYDISC;
                    113:                ioctl(0, TIOCSETD, &ldisc);
                    114:        }
                    115:        if (*pwd->pw_passwd != '\0') {
                    116:                nice(-4);
                    117:                namep = crypt(getpass("Password:"),pwd->pw_passwd);
                    118:                nice(4);
                    119:                if (strcmp(namep, pwd->pw_passwd)) {
                    120: bad:
                    121:                        printf("Login incorrect\n");
                    122:                        if (ttyn[LMAX] == 'd') {
                    123:                                FILE *console = fopen("/dev/console", "w");
                    124:                                if (console != NULL) {
                    125:                                        fprintf(console, "\r\nBADDIALUP %s %s\r\n", ttyn+5, utmp.ut_name);
                    126:                                        fclose(console);
                    127:                                }
                    128:                        }
                    129:                        goto loop;
                    130:                }
                    131:        }
                    132:        sprintf(user, "USER=%.*s", NMAX, pwd->pw_name);
                    133: #ifdef ERNIE
                    134:        if (pwd->pw_uid == 0 && ttyn[5] != 'c')
                    135:                goto bad;
                    136: #endif
                    137:        if (ttyn[LMAX] == 'd') {
                    138:                FILE *console = fopen("/dev/console", "w");
                    139:                if (console != NULL) {
                    140:                        fprintf(console, "\r\nDIALUP %s %s\r\n", ttyn+5, pwd->pw_name);
                    141:                        fclose(console);
                    142:                }
                    143:        }
                    144:        if((f = open(lastlog, 2)) >= 0) {
                    145:                struct lastlog ll;
                    146: 
                    147:                lseek(f, (long) pwd->pw_uid * sizeof (struct lastlog), 0);
                    148:                if (read(f, (char *) &ll, sizeof ll) == sizeof ll && ll.ll_time != 0) {
                    149:                        register char *ep = (char *) ctime(&ll.ll_time);
                    150:                        printf("Last login: ");
                    151:                        ep[24 - 5] = 0;
                    152:                        printf("%s on %.*s\n", ep, LMAX, ll.ll_line);
                    153:                }
                    154:                lseek(f, (long) pwd->pw_uid * sizeof (struct lastlog), 0);
                    155:                time(&ll.ll_time);
                    156:                strcpyn(ll.ll_line, ttyn+5, LMAX);
                    157:                write(f, (char *) &ll, sizeof ll);
                    158:                close(f);
                    159:        }
                    160:        if(chdir(pwd->pw_dir) < 0) {
                    161:                printf("No directory\n");
                    162:                goto loop;
                    163:        }
                    164:        time(&utmp.ut_time);
                    165:        t = ttyslot();
                    166:        if (t>0 && (f = open("/etc/utmp", 1)) >= 0) {
                    167:                lseek(f, (long)(t*sizeof(utmp)), 0);
                    168:                SCPYN(utmp.ut_line, rindex(ttyn, '/')+1);
                    169:                write(f, (char *)&utmp, sizeof(utmp));
                    170:                close(f);
                    171:        }
                    172:        if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) {
                    173:                lseek(f, 0L, 2);
                    174:                write(f, (char *)&utmp, sizeof(utmp));
                    175:                close(f);
                    176:        }
                    177:        chown(ttyn, pwd->pw_uid, pwd->pw_gid);
                    178:        setgid(pwd->pw_gid);
                    179:        setuid(pwd->pw_uid);
                    180:        if (*pwd->pw_shell == '\0')
                    181:                pwd->pw_shell = "/bin/sh";
                    182:        environ = envinit;
                    183:        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
                    184:        strncat(shell, pwd->pw_shell, sizeof(shell)-7);
                    185:        strncat(term, stypeof(ttyn), sizeof(term)-6);
                    186:        if ((namep = rindex(pwd->pw_shell, '/')) == NULL)
                    187:                namep = pwd->pw_shell;
                    188:        else
                    189:                namep++;
                    190:        strcat(minusnam, namep);
                    191:        alarm(0);
                    192:        umask(022);
                    193:        showmotd();
                    194:        strcat(maildir, pwd->pw_name);
                    195:        if(access(maildir,4)==0) {
                    196:                struct stat statb;
                    197:                stat(maildir, &statb);
                    198:                if (statb.st_size)
                    199:                        printf("You have mail.\n");
                    200:        }
                    201:        signal(SIGQUIT, SIG_DFL);
                    202:        signal(SIGINT, SIG_DFL);
                    203:        execlp(pwd->pw_shell, minusnam, 0);
                    204:        printf("No shell\n");
                    205:        exit(0);
                    206: }
                    207: 
                    208: int    stopmotd;
                    209: catch()
                    210: {
                    211:        signal(SIGINT, SIG_IGN);
                    212:        stopmotd++;
                    213: }
                    214: 
                    215: showmotd()
                    216: {
                    217:        FILE *mf;
                    218:        register c;
                    219: 
                    220:        signal(SIGINT, catch);
                    221:        if((mf = fopen("/etc/motd","r")) != NULL) {
                    222:                while((c = getc(mf)) != EOF && stopmotd == 0)
                    223:                        putchar(c);
                    224:                fclose(mf);
                    225:        }
                    226:        signal(SIGINT, SIG_IGN);
                    227: }
                    228: 
                    229: #define UNKNOWN "su"
                    230: 
                    231: char *
                    232: stypeof(ttyid)
                    233: char   *ttyid;
                    234: {
                    235:        static char     typebuf[16];
                    236:        char            buf[50];
                    237:        register FILE   *f;
                    238:        register char   *p, *t, *q;
                    239: 
                    240:        if (ttyid == NULL)
                    241:                return (UNKNOWN);
                    242:        f = fopen("/etc/ttytype", "r");
                    243:        if (f == NULL)
                    244:                return (UNKNOWN);
                    245:        /* split off end of name */
                    246:        for (p = q = ttyid; *p != 0; p++)
                    247:                if (*p == '/')
                    248:                        q = p + 1;
                    249: 
                    250:        /* scan the file */
                    251:        while (fgets(buf, sizeof buf, f) != NULL)
                    252:        {
                    253:                for (t=buf; *t!=' '; t++)
                    254:                        ;
                    255:                *t++ = 0;
                    256:                for (p=t; *p>' '; p++)
                    257:                        ;
                    258:                *p = 0;
                    259:                if (strcmp(q,t)==0) {
                    260:                        strcpy(typebuf, buf);
                    261:                        fclose(f);
                    262:                        return (typebuf);
                    263:                }
                    264:        }
                    265:        fclose (f);
                    266:        return (UNKNOWN);
                    267: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.