Annotation of 43BSD/bin/su.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)su.c       5.4 (Berkeley) 1/13/86";
        !            15: #endif not lint
        !            16: 
        !            17: #include <stdio.h>
        !            18: #include <pwd.h>
        !            19: #include <grp.h>
        !            20: #include <syslog.h>
        !            21: #include <sys/types.h>
        !            22: #include <sys/time.h>
        !            23: #include <sys/resource.h>
        !            24: 
        !            25: char   userbuf[16]     = "USER=";
        !            26: char   homebuf[128]    = "HOME=";
        !            27: char   shellbuf[128]   = "SHELL=";
        !            28: char   pathbuf[128]    = "PATH=:/usr/ucb:/bin:/usr/bin";
        !            29: char   *cleanenv[] = { userbuf, homebuf, shellbuf, pathbuf, 0, 0 };
        !            30: char   *user = "root";
        !            31: char   *shell = "/bin/sh";
        !            32: int    fulllogin;
        !            33: int    fastlogin;
        !            34: 
        !            35: extern char    **environ;
        !            36: struct passwd *pwd;
        !            37: char   *crypt();
        !            38: char   *getpass();
        !            39: char   *getenv();
        !            40: char   *getlogin();
        !            41: 
        !            42: main(argc,argv)
        !            43:        int argc;
        !            44:        char *argv[];
        !            45: {
        !            46:        char *password;
        !            47:        char buf[1000];
        !            48:        FILE *fp;
        !            49:        register char *p;
        !            50: 
        !            51:        openlog("su", LOG_ODELAY, LOG_AUTH);
        !            52: 
        !            53: again:
        !            54:        if (argc > 1 && strcmp(argv[1], "-f") == 0) {
        !            55:                fastlogin++;
        !            56:                argc--, argv++;
        !            57:                goto again;
        !            58:        }
        !            59:        if (argc > 1 && strcmp(argv[1], "-") == 0) {
        !            60:                fulllogin++;
        !            61:                argc--, argv++;
        !            62:                goto again;
        !            63:        }
        !            64:        if (argc > 1 && argv[1][0] != '-') {
        !            65:                user = argv[1];
        !            66:                argc--, argv++;
        !            67:        }
        !            68:        if ((pwd = getpwuid(getuid())) == NULL) {
        !            69:                fprintf(stderr, "Who are you?\n");
        !            70:                exit(1);
        !            71:        }
        !            72:        strcpy(buf, pwd->pw_name);
        !            73:        if ((pwd = getpwnam(user)) == NULL) {
        !            74:                fprintf(stderr, "Unknown login: %s\n", user);
        !            75:                exit(1);
        !            76:        }
        !            77:        /*
        !            78:         * Only allow those in group zero to su to root.
        !            79:         */
        !            80:        if (pwd->pw_uid == 0) {
        !            81:                struct  group *gr;
        !            82:                int i;
        !            83: 
        !            84:                if ((gr = getgrgid(0)) != NULL) {
        !            85:                        for (i = 0; gr->gr_mem[i] != NULL; i++)
        !            86:                                if (strcmp(buf, gr->gr_mem[i]) == 0)
        !            87:                                        goto userok;
        !            88:                        fprintf(stderr, "You do not have permission to su %s\n",
        !            89:                                user);
        !            90:                        exit(1);
        !            91:                }
        !            92:        userok:
        !            93:                setpriority(PRIO_PROCESS, 0, -2);
        !            94:        }
        !            95: 
        !            96: #define Getlogin()  (((p = getlogin()) && *p) ? p : buf)
        !            97:        if (pwd->pw_passwd[0] == '\0' || getuid() == 0)
        !            98:                goto ok;
        !            99:        password = getpass("Password:");
        !           100:        if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {
        !           101:                fprintf(stderr, "Sorry\n");
        !           102:                if (pwd->pw_uid == 0) {
        !           103:                        syslog(LOG_CRIT, "BAD SU %s on %s",
        !           104:                                        Getlogin(), ttyname(2));
        !           105:                }
        !           106:                exit(2);
        !           107:        }
        !           108: ok:
        !           109:        endpwent();
        !           110:        if (pwd->pw_uid == 0) {
        !           111:                syslog(LOG_NOTICE, "%s on %s", Getlogin(), ttyname(2));
        !           112:                closelog();
        !           113:        }
        !           114:        if (setgid(pwd->pw_gid) < 0) {
        !           115:                perror("su: setgid");
        !           116:                exit(3);
        !           117:        }
        !           118:        if (initgroups(user, pwd->pw_gid)) {
        !           119:                fprintf(stderr, "su: initgroups failed\n");
        !           120:                exit(4);
        !           121:        }
        !           122:        if (setuid(pwd->pw_uid) < 0) {
        !           123:                perror("su: setuid");
        !           124:                exit(5);
        !           125:        }
        !           126:        if (pwd->pw_shell && *pwd->pw_shell)
        !           127:                shell = pwd->pw_shell;
        !           128:        if (fulllogin) {
        !           129:                cleanenv[4] = getenv("TERM");
        !           130:                environ = cleanenv;
        !           131:        }
        !           132:        if (strcmp(user, "root"))
        !           133:                setenv("USER", pwd->pw_name, userbuf);
        !           134:        setenv("SHELL", shell, shellbuf);
        !           135:        setenv("HOME", pwd->pw_dir, homebuf);
        !           136:        setpriority(PRIO_PROCESS, 0, 0);
        !           137:        if (fastlogin) {
        !           138:                *argv-- = "-f";
        !           139:                *argv = "su";
        !           140:        } else if (fulllogin) {
        !           141:                if (chdir(pwd->pw_dir) < 0) {
        !           142:                        fprintf(stderr, "No directory\n");
        !           143:                        exit(6);
        !           144:                }
        !           145:                *argv = "-su";
        !           146:        } else
        !           147:                *argv = "su";
        !           148:        execv(shell, argv);
        !           149:        fprintf(stderr, "No shell\n");
        !           150:        exit(7);
        !           151: }
        !           152: 
        !           153: setenv(ename, eval, buf)
        !           154:        char *ename, *eval, *buf;
        !           155: {
        !           156:        register char *cp, *dp;
        !           157:        register char **ep = environ;
        !           158: 
        !           159:        /*
        !           160:         * this assumes an environment variable "ename" already exists
        !           161:         */
        !           162:        while (dp = *ep++) {
        !           163:                for (cp = ename; *cp == *dp && *cp; cp++, dp++)
        !           164:                        continue;
        !           165:                if (*cp == 0 && (*dp == '=' || *dp == 0)) {
        !           166:                        strcat(buf, eval);
        !           167:                        *--ep = buf;
        !           168:                        return;
        !           169:                }
        !           170:        }
        !           171: }
        !           172: 
        !           173: char *
        !           174: getenv(ename)
        !           175:        char *ename;
        !           176: {
        !           177:        register char *cp, *dp;
        !           178:        register char **ep = environ;
        !           179: 
        !           180:        while (dp = *ep++) {
        !           181:                for (cp = ename; *cp == *dp && *cp; cp++, dp++)
        !           182:                        continue;
        !           183:                if (*cp == 0 && (*dp == '=' || *dp == 0))
        !           184:                        return (*--ep);
        !           185:        }
        !           186:        return ((char *)0);
        !           187: }

unix.superglobalmegacorp.com

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