Annotation of researchv8dc/cmd/login/login.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * login  [ -f  name ] [ -p passwdline ] [ command ]
                      3:  *    -f:  if su, log in with no password
                      4:  *    -p:  if su, use entire password line.
                      5:  *    command: if given, just execute command
                      6:  */
                      7: 
                      8: #include <sys/types.h>
                      9: #include <sgtty.h>
                     10: #include <utmp.h>
                     11: #include <signal.h>
                     12: #include <pwd.h>
                     13: #include <stdio.h>
                     14: #include <sys/stat.h>
                     15: #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
                     16: 
                     17: #define ISIZE 32
                     18: #define POSTMKSIZ sizeof "From  Sun Jan 00 00:00:00 1979"
                     19: char   maildir[30] =   "/usr/spool/mail/";
                     20: struct passwd nouser = {"", "nope"};
                     21: struct sgttyb ttyb;
                     22: struct utmp utmp;
                     23: char   minusnam[16] = "-";
                     24: char   homedir[64] = "HOME=";
                     25: char   path[] = "PATH=:/bin:/usr/bin";
                     26: char   **env;
                     27: int    nenv = 0;
                     28: char   nolog[] = "/etc/nologin";
                     29: struct passwd *pwd;
                     30: struct passwd *pwdecode();
                     31: char   *cmd;
                     32: 
                     33: struct passwd *getpwnam();
                     34: char   *strcat();
                     35: int    setpwent();
                     36: char   *ttyname();
                     37: char   *crypt();
                     38: char   *getpass();
                     39: char   *rindex(), *index();
                     40: extern char **environ;
                     41: 
                     42: main(argc, argv)
                     43: char **argv;
                     44: {
                     45:        register char *namep;
                     46:        char input[ISIZE];
                     47:        char pwline[128];
                     48:        int t, f, c;
                     49:        char *ttyn;
                     50:        int neednopass = 0;
                     51:        int hangitup = 0;
                     52:        int ntries = 0;
                     53:        FILE *nlfd;
                     54:        int i;
                     55: 
                     56:        alarm(60);
                     57:        signal(SIGQUIT, SIG_IGN);
                     58:        signal(SIGINT, SIG_IGN);
                     59:        signal(SIGHUP, SIG_IGN);
                     60:        nice(-100);
                     61:        nice(20);
                     62:        nice(0);
                     63:        gtty(0, &ttyb);
                     64: #define        ONOFILE 20
                     65:        for (t=NSYSFILE; t<ONOFILE; t++)
                     66:                close(t);
                     67:        ttyn = ttyname(0);
                     68:        if (ttyn==0)
                     69:                ttyn = "/dev/tty??";
                     70:        SCPYN(input, "");
                     71:        switch(argc) {
                     72: 
                     73:        case 0:
                     74:        case 1:
                     75:                break;
                     76: 
                     77:        case 2:
                     78:                SCPYN(input, argv[1]);
                     79:                break;
                     80: 
                     81:        default:
                     82:                if (strcmp(argv[1], "-f")==0 || strcmp(argv[1], "-p")==0) {
                     83:                        if (getuid()!=0) {
                     84:                                printf("login: not super-user\n");
                     85:                                exit(1);
                     86:                        }
                     87:                        neednopass++;
                     88:                        if (strcmp(argv[1], "-f")==0)
                     89:                                SCPYN(input, argv[2]);
                     90:                        else {
                     91:                                SCPYN(pwline, argv[2]);
                     92:                                pwd = pwdecode(pwline);
                     93:                                SCPYN(input, pwd->pw_name);
                     94:                        }
                     95:                        if (argc>3)
                     96:                                cmd = argv[3];
                     97:                } else
                     98:                        exit(1);
                     99:        }
                    100:     loop:
                    101:        if (ntries) {
                    102:                if (ntries > 5 || hangitup) {
                    103:                        ttyb.sg_ispeed = ttyb.sg_ospeed = 0;
                    104:                        stty(0, &ttyb);
                    105:                        sleep(5);
                    106:                        exit(1);
                    107:                }
                    108:                neednopass = 0;
                    109:                pwd = NULL;
                    110:                SCPYN(input, "");
                    111:        }
                    112:        ntries++;
                    113:        while (input[0] == '\0') {
                    114:                namep = input;
                    115:                printf("login: ");
                    116:                while ((c = getchar()) != '\n') {
                    117:                        if(c == ' ')
                    118:                                c = '_';
                    119:                        if (c == EOF)
                    120:                                exit(0);
                    121:                        if (namep < input + ISIZE - 1)
                    122:                                *namep++ = c;
                    123:                }
                    124:                *namep = NULL;
                    125:        }
                    126:        SCPYN(utmp.ut_name, input);
                    127:        utmp.ut_time = 0;
                    128:        if (pwd == NULL) {
                    129:                setpwent();
                    130:                if ((pwd = getpwnam(input)) == NULL)
                    131:                        pwd = &nouser;
                    132:                endpwent();
                    133:        }
                    134:        if (namep = index(utmp.ut_name, '\001'))
                    135:                if (namep[1]=='L' && namep[2]=='\002')  /* loopback? */
                    136:                        hangitup++;
                    137:        time(&utmp.ut_time);
                    138:        SCPYN(utmp.ut_line, index(ttyn+1, '/')+1);
                    139:        if (pwd->pw_uid == 0)                           /* root loses */
                    140:                neednopass = 0;
                    141:        if (*pwd->pw_passwd != '\0' && !neednopass) {
                    142:                namep = crypt(getpass("Password:"), pwd->pw_passwd);
                    143:                if (strcmp(namep, pwd->pw_passwd)) {
                    144:                        /* magic string detects loopbacks */
                    145:                        printf("\001L\002ogin incorrect\n");
                    146:                        f = open("/usr/adm/xtmp", 1);
                    147:                        if (f > 0) {
                    148:                                lseek(f, 0L, 2);
                    149:                                write(f, (char *)&utmp, sizeof(utmp));
                    150:                                close(f);
                    151:                        }
                    152:                        goto loop;
                    153:                }
                    154:        }
                    155:        if(pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) != NULL){
                    156:                while((c = getc(nlfd)) != EOF)
                    157:                        putchar(c);
                    158:                exit(0);
                    159:        }
                    160:        if(chdir(pwd->pw_dir) < 0) {
                    161:                printf("No directory\n");
                    162:                if(pwd->pw_uid != 0 || (access(nolog, 0) < 0))
                    163:                        goto loop;
                    164:        }
                    165:        if (cmd) {              /* remote exec */
                    166:                t = strlen(utmp.ut_name);
                    167:                if (t < sizeof(utmp.ut_name))
                    168:                        utmp.ut_name[t] = '*';
                    169:        }
                    170:        t = ttyslot();
                    171:        if (t>0 && (f = open("/etc/utmp", 1)) >= 0) {
                    172:                lseek(f, (long)(t*sizeof(utmp)), 0);
                    173:                write(f, (char *)&utmp, sizeof(utmp));
                    174:                close(f);
                    175:        }
                    176:        if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) {
                    177:                lseek(f, 0L, 2);
                    178:                write(f, (char *)&utmp, sizeof(utmp));
                    179:                close(f);
                    180:        }
                    181:        chown(ttyn, pwd->pw_uid, pwd->pw_gid);
                    182:        chmod(ttyn, 0622);
                    183:        setgid(pwd->pw_gid);
                    184:        setuid(pwd->pw_uid);
                    185:        if (*pwd->pw_shell == '\0')
                    186:                pwd->pw_shell = "/bin/sh";
                    187:        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
                    188:        nenv = 0;
                    189:        for(i = 0; environ[i]; i++)
                    190:                ;
                    191:        env = (char **) malloc(sizeof(char *) * (i + 10));
                    192:        if (env == NULL) {
                    193:                printf("No memory for environment.\n");
                    194:                exit(1);
                    195:        }
                    196:        for (i = 0; environ[i]; i++) {
                    197:                if (strncmp(environ[i], "HOME=", 5) == 0)
                    198:                        continue;
                    199:                if (strncmp(environ[i], "PATH=", 5) == 0)
                    200:                        continue;
                    201:                env[nenv++] = environ[i];
                    202:        }
                    203:        if(homedir[0])
                    204:                env[nenv++] = homedir;
                    205:        if(path[0])
                    206:                env[nenv++] = path;
                    207:        env[nenv] = NULL;
                    208:        if ((namep = rindex(pwd->pw_shell, '/')) == NULL)
                    209:                namep = pwd->pw_shell;
                    210:        else
                    211:                namep++;
                    212:        strcat(minusnam, namep);
                    213:        alarm(0);
                    214:        umask(02);
                    215:        if (cmd==NULL) {
                    216:                showmotd();
                    217:                strcat(maildir, pwd->pw_name);
                    218:                if(access(maildir,4)==0) {
                    219:                        struct stat statb;
                    220:                        stat(maildir, &statb);
                    221:                        if (statb.st_size > POSTMKSIZ)
                    222:                                printf("You have mail.\n");
                    223:                }
                    224:        }
                    225:        signal(SIGQUIT, SIG_DFL);
                    226:        signal(SIGINT, SIG_DFL);
                    227:        signal(SIGHUP, SIG_DFL);
                    228:        environ = env;
                    229:        if (cmd==NULL)
                    230:                execlp(pwd->pw_shell, minusnam, 0);
                    231:        else {
                    232:                env[nenv++] = "REXEC=1";
                    233:                ioctl(0, TIOCEXCL, NULL);
                    234:                env[nenv] = 0;
                    235:                execlp(pwd->pw_shell, minusnam, "-c", cmd, (char *)0);
                    236:        }
                    237:        printf("No shell\n");
                    238:        exit(0);
                    239: }
                    240: 
                    241: int    stopmotd;
                    242: catch()
                    243: {
                    244:        signal(SIGINT, SIG_IGN);
                    245:        stopmotd++;
                    246: }
                    247: 
                    248: showmotd()
                    249: {
                    250:        FILE *mf;
                    251:        register c;
                    252: 
                    253:        signal(SIGINT, catch);
                    254:        if((mf = fopen("/etc/motd","r")) != NULL) {
                    255:                while((c = getc(mf)) != EOF && stopmotd == 0)
                    256:                        putchar(c);
                    257:                fclose(mf);
                    258:        }
                    259:        signal(SIGINT, SIG_IGN);
                    260: }

unix.superglobalmegacorp.com

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