Annotation of 43BSD/bin/su.c, revision 1.1.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.