# 2.11BSD#431 - /usr/src/bin/su.c

##### Functions

    getenv            X
    main              X
    setenv            X

##### Variables

    cleanenv          X
    copyright         X
    fastlogin         X
    fulllogin         X
    homebuf           X
    pathbuf           X
    pwd               X
    shell             X
    shellbuf          X
    user              X
    userbuf           X

##### Macros

    Getlogin          X

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

#### Defined functions

getenv defined in line 169; used 1 times

- in line 125

main defined in line 38; never used
setenv defined in line 149; used 3 times

- in line 129-131(3)

#### Defined variables

cleanenv defined in line 29; used 2 times

- in line 125-126(2)

copyright defined in line 8; never used
fastlogin defined in line 33; used 2 times

- in line 51, 133

fulllogin defined in line 32; used 3 times

- in line 56, 124, 136

homebuf defined in line 26; used 2 times

- in line 29, 131

pathbuf defined in line 28; used 1 times

- in line 29

pwd defined in line 36; used 18 times

- in line 64-69(3), 76, 93-98(4), 106-123(7), 129-131(2), 137

sccsid defined in line 12; never used
shell defined in line 31; used 3 times

- in line 123, 130, 144

shellbuf defined in line 27; used 2 times

- in line 29, 130

user defined in line 30; used 6 times

- in line 61, 69-70(2), 85, 114, 128

userbuf defined in line 25; used 2 times

- in line 29, 129

#### Defined macros

Getlogin defined in line 92; used 2 times

- in line 100, 107

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1374 |