Annotation of coherent/d/bin/su.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Rec'd from Lauren Weinstein, 7-16-84.
                      3:  * Substitute user-id temporarily or become super user (as you wish).
                      4:  * Compile -s -n -i.
                      5:  * Hacked by steve 10/4/90 to correct password bug and for clarity.
                      6:  */
                      7: 
                      8: #include <stdio.h>
                      9: #include <pwd.h>
                     10: 
                     11: extern char *getenv();
                     12: extern char *getpass();
                     13: extern char *malloc();
                     14: 
                     15: #define ACCNAME "remacc"       /* Remote access password dummy username */
                     16: #define        DEFSHELL "/bin/sh"      /* Default shell pathname */
                     17: #define PASSLEN 13             /* Encrypted password length */
                     18: 
                     19: #define        bye()   fatal("Sorry")
                     20: 
                     21: /* Forward. */
                     22: extern void    addenviron();
                     23: extern void    fatal();
                     24: extern void    getuname();
                     25: 
                     26: /* Globals. */
                     27: char   *defargs[] = { "su", NULL };
                     28: /* The following are all set by getuname(). */
                     29: short  gid;
                     30: char   *password;
                     31: char   salt[3];
                     32: short  uid;
                     33: 
                     34: main(argc, argv) int argc; char *argv[];
                     35: {
                     36:        register int ouid, ogid;
                     37:        char *command, *prompta, *promptb, *passp;
                     38:        char **args;
                     39: 
                     40:        getuname(argc>1 ? argv[1] : "0");       /* check username */
                     41:        if (password[0] != '\0' && getuid()) {  /* check password if not already su */
                     42:                passp = getpass("Password: ");  /* get input password choice */
                     43:                if ((strlen(password) != PASSLEN)
                     44:                 || (strcmp(crypt(passp, salt), password) != 0)) {
                     45:                        ouid = uid;
                     46:                        ogid = gid;
                     47:                        getuname("0");          /* check root password too */ 
                     48:                        if ((strlen(password) != PASSLEN)
                     49:                         || (strcmp(crypt(passp, salt), password) != 0))
                     50:                                bye();          /* failure */
                     51:                        uid = ouid;
                     52:                        gid = ogid;
                     53:                }
                     54:        }
                     55: 
                     56:        if (argc > 2) {
                     57:                command = argv[2];
                     58:                args = &argv[2];
                     59:        } else {
                     60:                command = getenv("SHELL");
                     61:                if (command == NULL || strlen(command) < 1)
                     62:                        command = DEFSHELL;
                     63:                args = defargs;
                     64:        }
                     65:        setgid(gid);
                     66:        setuid(uid);
                     67:        prompta = getenv("PSN");                /* check for normal prompt */
                     68:        promptb = getenv("PSS");                /* check for desired su prompt */
                     69:        addenviron(uid == 0 ? (promptb ? promptb : "# ")
                     70:                            : (prompta ? prompta : "$ "));
                     71:                                                /* change prompt as appropriate */
                     72:        execvp(command, args);
                     73:        fatal("%s: not found", command);
                     74: }
                     75: 
                     76: /*
                     77:  * Add string 's' to the environment as "PS1".
                     78:  */
                     79: void
                     80: addenviron(s) char *s;
                     81: {
                     82:        extern char **environ;
                     83:        register char **epp1, **epp2;
                     84:        register char **newenv;
                     85:        int n;
                     86:        char *prompt;
                     87:        static char prbuf[50];
                     88: 
                     89:        for (epp1 = environ; *epp1!=NULL; epp1++)
                     90:                ;
                     91:        n = (epp1-environ+2) * sizeof (char *);
                     92:        if ((newenv = (char **)malloc(n)) == NULL)
                     93:                fatal("Out of memory for environments");
                     94:        prompt = prbuf;
                     95:        strcpy(prompt, "PS1=");
                     96:        strcat(prompt, s);
                     97:        for (epp1=environ, epp2=newenv; *epp1 != NULL; epp1++)
                     98:                if (strncmp(*epp1, "PS1=", 4) != 0)
                     99:                        *epp2++ = *epp1;
                    100:                else {
                    101:                        *epp2++ = prompt;
                    102:                        prompt = NULL;
                    103:                }
                    104:        *epp2++ = prompt;
                    105:        *epp2 = NULL;
                    106:        environ = newenv;
                    107: }
                    108: 
                    109: void
                    110: fatal(s) char *s;
                    111: {
                    112:        fprintf(stderr, "%r\n", &s);
                    113:        exit(1);
                    114: }
                    115: 
                    116: /*
                    117:  * Get a user-name from string 's'.
                    118:  * If the string starts with a numeric, use it directly as a uid.
                    119:  * Set globals password, salt[], gid and uid with the user's password info.
                    120:  * Die if not found or illegal.
                    121:  */
                    122: void
                    123: getuname(s) register char *s;
                    124: {
                    125:        register struct passwd *pwp;
                    126: 
                    127:        if (*s >= '0' && *s <= '9') {
                    128:                uid = atoi(s);
                    129:                if ((pwp = getpwuid(uid)) == NULL)
                    130:                        fatal("%d: bad user number", uid);
                    131:        } else if ((pwp = getpwnam(s)) == NULL)
                    132:                fatal("%s: not a user name", s);
                    133:        if (strcmp(pwp->pw_name, ACCNAME) == 0) /* dummy access username? */
                    134:                bye();                          /* yes, sorry */
                    135:        password = pwp->pw_passwd;
                    136:        salt[0] = pwp->pw_passwd[0];
                    137:        salt[1] = pwp->pw_passwd[1];
                    138:        salt[2] = '\0';
                    139:        gid = pwp->pw_gid;
                    140:        uid = pwp->pw_uid;
                    141: }
                    142: 
                    143: /* end of su.c */

unix.superglobalmegacorp.com

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