Annotation of researchv9/cmd/login.c, revision 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 <setjmp.h>
        !            13: #include <pwd.h>
        !            14: #include <grp.h>
        !            15: #include <stdio.h>
        !            16: #include <sys/stat.h>
        !            17: #include <sys/lnode.h>
        !            18: #include <sys/share.h>
        !            19: #include <shares.h>
        !            20: #include <errno.h>
        !            21: 
        !            22: #define        DEFSHARES       1       /* Default number of shares for a group 0 user */
        !            23: #define        SYSERROR        (-1)
        !            24: #define        MINUSAGE        1e6
        !            25: #ifndef        ETOOMANYU
        !            26: #define        ETOOMANYU       ENOSPC  /* Must go in errno.h or lnode.h */
        !            27: #endif
        !            28: #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
        !            29: 
        !            30: #define ISIZE 32
        !            31: #define POSTMKSIZ sizeof "From  Sun Jan 00 00:00:00 1979"
        !            32: char   maildir[30] =   "/usr/spool/mail/";
        !            33: struct passwd nouser = {"", "nope"};
        !            34: struct utmp utmp;
        !            35: char   minusnam[16] = "-";
        !            36: char   homedir[64] = "HOME=";
        !            37: char   path[] = "PATH=:/bin:/usr/bin";
        !            38: char   **env;
        !            39: int    nenv = 0;
        !            40: char   nolog[] = "/etc/nologin";
        !            41: struct passwd *pwd;
        !            42: struct passwd *pwdecode();
        !            43: char   *cmd;
        !            44: 
        !            45: struct passwd *getpwnam();
        !            46: char   *strcat();
        !            47: int    setpwent();
        !            48: char   *ttyname();
        !            49: char   *crypt();
        !            50: char   *getpass();
        !            51: char   *strrchr(), *strchr();
        !            52: extern char **environ;
        !            53: 
        !            54: main(argc, argv)
        !            55: char **argv;
        !            56: {
        !            57:        register char *namep;
        !            58:        char input[ISIZE];
        !            59:        char pwline[128];
        !            60:        int t, f, c;
        !            61:        char *ttyn;
        !            62:        int neednopass = 0;
        !            63:        int hangitup = 0;
        !            64:        int ntries = 0;
        !            65:        FILE *nlfd;
        !            66:        int i;
        !            67:        struct ttydevb tb;
        !            68: 
        !            69:        alarm(60);
        !            70:        signal(SIGQUIT, SIG_IGN);
        !            71:        signal(SIGINT, SIG_IGN);
        !            72:        signal(SIGHUP, SIG_IGN);
        !            73:        nice(-100);
        !            74:        nice(20);
        !            75:        nice(0);
        !            76: #define        ONOFILE 20
        !            77:        for (t=NSYSFILE; t<ONOFILE; t++)
        !            78:                close(t);
        !            79:        ttyn = ttyname(0);
        !            80:        if (ttyn==0)
        !            81:                ttyn = "/dev/tty??";
        !            82:        SCPYN(input, "");
        !            83:        switch(argc) {
        !            84: 
        !            85:        case 0:
        !            86:        case 1:
        !            87:                break;
        !            88: 
        !            89:        case 2:
        !            90:                SCPYN(input, argv[1]);
        !            91:                break;
        !            92: 
        !            93:        default:
        !            94:                if (strcmp(argv[1], "-f")==0 || strcmp(argv[1], "-p")==0) {
        !            95:                        if (getuid()!=0) {
        !            96:                                printf("login: not super-user\n");
        !            97:                                exit(1);
        !            98:                        }
        !            99:                        neednopass++;
        !           100:                        if (strcmp(argv[1], "-f")==0)
        !           101:                                SCPYN(input, argv[2]);
        !           102:                        else {
        !           103:                                SCPYN(pwline, argv[2]);
        !           104:                                pwd = pwdecode(pwline);
        !           105:                                SCPYN(input, pwd->pw_name);
        !           106:                        }
        !           107:                        if (argc>3)
        !           108:                                cmd = argv[3];
        !           109:                } else
        !           110:                        exit(1);
        !           111:        }
        !           112:     loop:
        !           113:        if (ntries) {
        !           114:                if (ntries > 5 || hangitup) {
        !           115:                        ioctl(0, TIOCGDEV, &tb);
        !           116:                        tb.ispeed = tb.ospeed = 0;
        !           117:                        ioctl(0, TIOCSDEV, &tb);
        !           118:                        sleep(5);
        !           119:                        exit(1);
        !           120:                }
        !           121:                neednopass = 0;
        !           122:                pwd = NULL;
        !           123:                SCPYN(input, "");
        !           124:        }
        !           125:        ntries++;
        !           126:        while (input[0] == '\0') {
        !           127:                namep = input;
        !           128:                printf("login: ");
        !           129:                while ((c = getchar()) != '\n') {
        !           130:                        if(c == ' ')
        !           131:                                c = '_';
        !           132:                        if (c == EOF)
        !           133:                                exit(0);
        !           134:                        if (namep < input + ISIZE - 1)
        !           135:                                *namep++ = c;
        !           136:                }
        !           137:                *namep = NULL;
        !           138:        }
        !           139:        SCPYN(utmp.ut_name, input);
        !           140:        utmp.ut_time = 0;
        !           141:        if (pwd == NULL) {
        !           142:                setpwent();
        !           143:                if ((pwd = getpwnam(input)) == NULL)
        !           144:                        pwd = &nouser;
        !           145:                endpwent();
        !           146:        }
        !           147:        if (namep = strchr(utmp.ut_name, '\001'))
        !           148:                if (namep[1]=='L' && namep[2]=='\002')  /* loopback? */
        !           149:                        hangitup++;
        !           150:        time(&utmp.ut_time);
        !           151:        SCPYN(utmp.ut_line, strchr(ttyn+1, '/')+1);
        !           152:        if (*pwd->pw_passwd != '\0' && !neednopass) {
        !           153:                namep = crypt(getpass("Password:"), pwd->pw_passwd);
        !           154:                if (strcmp(namep, pwd->pw_passwd)) {
        !           155:                        /* magic string detects loopbacks */
        !           156:                        printf("\001L\002ogin incorrect\n");
        !           157:                        f = open("/usr/adm/xtmp", 1);
        !           158:                        if (f > 0) {
        !           159:                                lseek(f, 0L, 2);
        !           160:                                write(f, (char *)&utmp, sizeof(utmp));
        !           161:                                close(f);
        !           162:                        }
        !           163:                        goto loop;
        !           164:                }
        !           165:        }
        !           166:        if(pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) != NULL){
        !           167:                while((c = getc(nlfd)) != EOF)
        !           168:                        putchar(c);
        !           169:                exit(0);
        !           170:        }
        !           171:        if(setuplimits(pwd) < 0)
        !           172:                goto loop;
        !           173:        (void)setupgroups(pwd);
        !           174:        if(chdir(pwd->pw_dir) < 0) {
        !           175:                printf("No directory\n");
        !           176:                if(pwd->pw_uid != 0 || (access(nolog, 0) < 0))
        !           177:                        goto loop;
        !           178:        }
        !           179:        setlogname(utmp.ut_name);
        !           180:        if (cmd) {              /* remote exec */
        !           181:                t = strlen(utmp.ut_name);
        !           182:                if (t < sizeof(utmp.ut_name))
        !           183:                        utmp.ut_name[t] = '*';
        !           184:        }
        !           185:        t = ttyslot();
        !           186:        if (t>0 && (f = open("/etc/utmp", 1)) >= 0) {
        !           187:                lseek(f, (long)(t*sizeof(utmp)), 0);
        !           188:                write(f, (char *)&utmp, sizeof(utmp));
        !           189:                close(f);
        !           190:        }
        !           191:        if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) {
        !           192:                lseek(f, 0L, 2);
        !           193:                write(f, (char *)&utmp, sizeof(utmp));
        !           194:                close(f);
        !           195:        }
        !           196:        chown(ttyn, pwd->pw_uid, pwd->pw_gid);
        !           197:        chmod(ttyn, 0622);
        !           198:        setgid(pwd->pw_gid);
        !           199:        setuid(pwd->pw_uid);
        !           200:        if (*pwd->pw_shell == '\0')
        !           201:                pwd->pw_shell = "/bin/sh";
        !           202:        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
        !           203:        nenv = 0;
        !           204:        for(i = 0; environ[i]; i++)
        !           205:                ;
        !           206:        env = (char **) malloc(sizeof(char *) * (i + 10));
        !           207:        if (env == NULL) {
        !           208:                printf("No memory for environment.\n");
        !           209:                exit(1);
        !           210:        }
        !           211:        for (i = 0; environ[i]; i++) {
        !           212:                if (strncmp(environ[i], "HOME=", 5) == 0)
        !           213:                        continue;
        !           214:                if (strncmp(environ[i], "PATH=", 5) == 0)
        !           215:                        continue;
        !           216:                env[nenv++] = environ[i];
        !           217:        }
        !           218:        if(homedir[0])
        !           219:                env[nenv++] = homedir;
        !           220:        if(path[0])
        !           221:                env[nenv++] = path;
        !           222:        env[nenv] = NULL;
        !           223:        if ((namep = strrchr(pwd->pw_shell, '/')) == NULL)
        !           224:                namep = pwd->pw_shell;
        !           225:        else
        !           226:                namep++;
        !           227:        strcat(minusnam, namep);
        !           228:        alarm(0);
        !           229:        umask(02);
        !           230:        if (cmd==NULL) {
        !           231:                showmotd();
        !           232:                strcat(maildir, pwd->pw_name);
        !           233:                if(access(maildir,4)==0) {
        !           234:                        struct stat statb;
        !           235:                        stat(maildir, &statb);
        !           236:                        if (statb.st_size > POSTMKSIZ)
        !           237:                                printf("You have mail.\n");
        !           238:                }
        !           239:        }
        !           240:        signal(SIGQUIT, SIG_DFL);
        !           241:        signal(SIGINT, SIG_DFL);
        !           242:        signal(SIGHUP, SIG_DFL);
        !           243:        environ = env;
        !           244:        if (cmd==NULL)
        !           245:                execlp(pwd->pw_shell, minusnam, 0);
        !           246:        else {
        !           247:                env[nenv++] = "REXEC=1";
        !           248:                ioctl(0, TIOCEXCL, (void *)NULL);
        !           249:                env[nenv] = 0;
        !           250:                execlp(pwd->pw_shell, minusnam, "-c", cmd, (char *)0);
        !           251:        }
        !           252:        printf("No shell\n");
        !           253:        exit(0);
        !           254: }
        !           255: 
        !           256: int    stopmotd;
        !           257: catch()
        !           258: {
        !           259:        signal(SIGINT, SIG_IGN);
        !           260:        stopmotd++;
        !           261: }
        !           262: 
        !           263: showmotd()
        !           264: {
        !           265:        FILE *mf;
        !           266:        register c;
        !           267: 
        !           268:        signal(SIGINT, catch);
        !           269:        if((mf = fopen("/etc/motd","r")) != NULL) {
        !           270:                while((c = getc(mf)) != EOF && stopmotd == 0)
        !           271:                        putchar(c);
        !           272:                fclose(mf);
        !           273:        }
        !           274:        signal(SIGINT, SIG_IGN);
        !           275: }
        !           276: 
        !           277: /*
        !           278: **     Set up parameters for share scheduler
        !           279: */
        !           280: 
        !           281: int    catchsys();
        !           282: jmp_buf        Sigsysbuf;
        !           283: 
        !           284: int
        !           285: setuplimits(pwd)
        !           286:        register struct passwd *pwd;
        !           287: {
        !           288:        register int            (*oldsig)();
        !           289:        register unsigned long  extime;
        !           290:        struct sh_consts        shconsts;
        !           291:        struct lnode            share;
        !           292: 
        !           293:        if ( pwd->pw_uid == 0 )
        !           294:                return 0;       /* root needs no set-up */
        !           295: 
        !           296:        oldsig = signal(SIGSYS, catchsys);
        !           297: 
        !           298:        if
        !           299:        (
        !           300:                setjmp(Sigsysbuf)
        !           301:                ||
        !           302:                limits((struct lnode *)&shconsts, L_GETCOSTS) == SYSERROR
        !           303:                ||
        !           304:                (Shareflags & NOSHARE)
        !           305:        )
        !           306:        {
        !           307:                (void)signal(SIGSYS, oldsig);
        !           308:                return 0;       /* Share not installed/active */
        !           309:        }
        !           310: 
        !           311:        (void)signal(SIGSYS, oldsig);
        !           312: 
        !           313:        if ( (extime = getshares(&share, pwd->pw_uid, 0)) == 0 )
        !           314:        {
        !           315:                share.l_shares = DEFSHARES;
        !           316:                share.l_usage = MINUSAGE;
        !           317:        }
        !           318:        else
        !           319:        if ( limits(&share, L_OTHLIM) == SYSERROR )
        !           320:        {
        !           321:                /*
        !           322:                **      Decay usage by time since last access.
        !           323:                */
        !           324: 
        !           325:                if ( (extime = (utmp.ut_time - extime) / Delta) > 0 )
        !           326:                {
        !           327:                        extern double   pow();
        !           328: 
        !           329:                        share.l_usage *= pow(DecayUsage, (float)extime);
        !           330:                        if ( share.l_usage < MINUSAGE )
        !           331:                                share.l_usage = MINUSAGE;
        !           332:                }
        !           333:        }
        !           334: 
        !           335:        if ( setlimits(&share) == SYSERROR )
        !           336:        {
        !           337:                if ( errno == ETOOMANYU )
        !           338:                {
        !           339:                        char * cp = "other";
        !           340: 
        !           341:                        share.l_uid = OTHERUID;
        !           342: 
        !           343:                        if ( limits(&share, L_OTHLIM) != SYSERROR )
        !           344:                                (void)setlimits(&share);
        !           345:                        else
        !           346:                                cp = "root";
        !           347: 
        !           348:                        printf("Warning: system out of share structures, using \"%s\".\n", cp);
        !           349:                }
        !           350:                else
        !           351:                        perror("setlimits");
        !           352:        }
        !           353: 
        !           354:        closeshares();
        !           355: 
        !           356:        return 0;
        !           357: }
        !           358: 
        !           359: int
        !           360: catchsys(sig)
        !           361: {
        !           362:        longjmp(Sigsysbuf, 1);
        !           363:        perror("longjmp");
        !           364:        abort();
        !           365: }
        !           366: 
        !           367: /*
        !           368: **     Set up access groups.
        !           369: */
        !           370: 
        !           371: int
        !           372: setupgroups(pwd)
        !           373:        register struct passwd *pwd;
        !           374: {
        !           375:        register char **        cpp;
        !           376:        register short *        gp;
        !           377:        register struct group * grp;
        !           378:        register int            n;
        !           379:        short                   groups[NGROUPS];
        !           380: 
        !           381:        if ( getgroups(NGROUPS, groups) == SYSERROR )
        !           382:                return; /* Not installed */
        !           383: 
        !           384:        (void)setgrent();
        !           385: 
        !           386:        gp = groups;
        !           387: 
        !           388:        while ( gp < &groups[NGROUPS] && (grp = getgrent()) != (struct group *)0 )
        !           389:                for ( cpp = grp->gr_mem ; *cpp != (char *)0 ; cpp++ )
        !           390:                        if ( strcmp(*cpp, pwd->pw_name) == 0 && grp->gr_gid != pwd->pw_gid )
        !           391:                        {
        !           392:                                *gp++ = grp->gr_gid;
        !           393:                                break;
        !           394:                        }
        !           395: 
        !           396:        (void)endgrent();
        !           397: 
        !           398:        if ( (n = gp-groups) == 0 )
        !           399:                return;
        !           400: 
        !           401:        if ( setgroups(n, groups) == SYSERROR )
        !           402:                perror("setgroups");
        !           403: }

unix.superglobalmegacorp.com

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