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

unix.superglobalmegacorp.com

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