|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.