Annotation of embedaddon/sudo/plugins/sudoers/set_perms.c, revision 1.1.1.3
1.1 misho 1: /*
2: * Copyright (c) 1994-1996,1998-2011 Todd C. Miller <Todd.Miller@courtesan.com>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: *
16: * Sponsored in part by the Defense Advanced Research Projects
17: * Agency (DARPA) and Air Force Research Laboratory, Air Force
18: * Materiel Command, USAF, under agreement number F39502-99-1-0512.
19: */
20:
21: #include <config.h>
22:
23: #include <sys/types.h>
24: #include <sys/param.h>
25: #include <sys/stat.h>
26: #include <stdio.h>
27: #ifdef STDC_HEADERS
28: # include <stdlib.h>
29: # include <stddef.h>
30: #else
31: # ifdef HAVE_STDLIB_H
32: # include <stdlib.h>
33: # endif
34: #endif /* STDC_HEADERS */
35: #ifdef HAVE_STRING_H
36: # include <string.h>
37: #endif /* HAVE_STRING_H */
38: #ifdef HAVE_STRINGS_H
39: # include <strings.h>
40: #endif /* HAVE_STRINGS_H */
41: #ifdef HAVE_UNISTD_H
42: # include <unistd.h>
43: #endif /* HAVE_UNISTD_H */
1.1.1.2 misho 44: #ifdef _AIX
45: # include <sys/id.h>
46: #endif
1.1 misho 47: #include <pwd.h>
48: #include <errno.h>
49: #include <grp.h>
50:
51: #include "sudoers.h"
52:
53: /*
54: * Prototypes
55: */
1.1.1.2 misho 56: #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
1.1 misho 57: static struct group_list *runas_setgroups(void);
1.1.1.2 misho 58: #endif
1.1 misho 59:
60: /*
61: * We keep track of the current permisstions and use a stack to restore
62: * the old permissions. A depth of 16 is overkill.
63: */
64: struct perm_state {
65: uid_t ruid;
66: uid_t euid;
1.1.1.2 misho 67: #if defined(HAVE_SETRESUID) || defined(ID_SAVED)
1.1 misho 68: uid_t suid;
69: #endif
70: gid_t rgid;
71: gid_t egid;
1.1.1.2 misho 72: #if defined(HAVE_SETRESUID) || defined(ID_SAVED)
1.1 misho 73: gid_t sgid;
74: #endif
75: struct group_list *grlist;
76: };
77:
78: #define PERM_STACK_MAX 16
79: static struct perm_state perm_stack[PERM_STACK_MAX];
80: static int perm_stack_depth = 0;
81:
82: #undef ID
83: #define ID(x) (state->x == ostate->x ? -1 : state->x)
84: #undef OID
85: #define OID(x) (ostate->x == state->x ? -1 : ostate->x)
86:
87: void
88: rewind_perms(void)
89: {
1.1.1.2 misho 90: debug_decl(rewind_perms, SUDO_DEBUG_PERMS)
91:
1.1 misho 92: while (perm_stack_depth > 1)
93: restore_perms();
1.1.1.3 ! misho 94: sudo_grlist_delref(perm_stack[0].grlist);
1.1.1.2 misho 95:
96: debug_return;
1.1 misho 97: }
98:
1.1.1.2 misho 99: #if defined(HAVE_SETRESUID)
100:
101: #define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid || state->suid != ostate->suid)
102: #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid || state->sgid != ostate->sgid)
1.1 misho 103:
104: /*
105: * Set real and effective and saved uids and gids based on perm.
106: * We always retain a saved uid of 0 unless we are headed for an exec().
107: * We only flip the effective gid since it only changes for PERM_SUDOERS.
108: * This version of set_perms() works fine with the "stay_setuid" option.
109: */
110: int
111: set_perms(int perm)
112: {
113: struct perm_state *state, *ostate = NULL;
1.1.1.2 misho 114: char errbuf[1024];
1.1 misho 115: int noexit;
1.1.1.2 misho 116: debug_decl(set_perms, SUDO_DEBUG_PERMS)
1.1 misho 117:
118: noexit = ISSET(perm, PERM_NOEXIT);
119: CLR(perm, PERM_MASK);
120:
121: if (perm_stack_depth == PERM_STACK_MAX) {
1.1.1.2 misho 122: strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
1.1 misho 123: errno = EINVAL;
124: goto bad;
125: }
126:
127: state = &perm_stack[perm_stack_depth];
128: if (perm != PERM_INITIAL) {
129: if (perm_stack_depth == 0) {
1.1.1.2 misho 130: strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
1.1 misho 131: errno = EINVAL;
132: goto bad;
133: }
134: ostate = &perm_stack[perm_stack_depth - 1];
135: }
136:
137: switch (perm) {
138: case PERM_INITIAL:
139: /* Stash initial state */
140: #ifdef HAVE_GETRESUID
141: if (getresuid(&state->ruid, &state->euid, &state->suid)) {
1.1.1.2 misho 142: strlcpy(errbuf, "PERM_INITIAL: getresuid", sizeof(errbuf));
1.1 misho 143: goto bad;
144:
145: }
146: if (getresgid(&state->rgid, &state->egid, &state->sgid)) {
1.1.1.2 misho 147: strlcpy(errbuf, "PERM_INITIAL: getresgid", sizeof(errbuf));
1.1 misho 148: goto bad;
149: }
150: #else
151: state->ruid = getuid();
152: state->euid = geteuid();
153: state->suid = state->euid; /* in case we are setuid */
154:
155: state->rgid = getgid();
156: state->egid = getegid();
157: state->sgid = state->egid; /* in case we are setgid */
158: #endif
159: state->grlist = user_group_list;
1.1.1.3 ! misho 160: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 161: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
162: "ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
163: __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
164: (int)state->rgid, (int)state->egid, (int)state->sgid);
1.1 misho 165: break;
166:
167: case PERM_ROOT:
168: state->ruid = ROOT_UID;
169: state->euid = ROOT_UID;
170: state->suid = ROOT_UID;
1.1.1.2 misho 171: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
172: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
173: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
174: (int)state->ruid, (int)state->euid, (int)state->suid);
175: if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
176: snprintf(errbuf, sizeof(errbuf),
177: "PERM_ROOT: setresuid(%d, %d, %d)",
178: ID(ruid), ID(euid), ID(suid));
1.1 misho 179: goto bad;
180: }
1.1.1.2 misho 181: state->rgid = ostate->rgid;
182: state->egid = ostate->egid;
183: state->sgid = ostate->sgid;
1.1 misho 184: state->grlist = ostate->grlist;
1.1.1.3 ! misho 185: sudo_grlist_addref(state->grlist);
1.1 misho 186: break;
187:
188: case PERM_USER:
1.1.1.2 misho 189: state->rgid = ostate->rgid;
1.1 misho 190: state->egid = user_gid;
1.1.1.2 misho 191: state->sgid = ostate->sgid;
192: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
193: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
194: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
195: (int)state->rgid, (int)state->egid, (int)state->sgid);
196: if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
197: snprintf(errbuf, sizeof(errbuf), "PERM_USER: setresgid(%d, %d, %d)",
198: ID(rgid), ID(egid), ID(sgid));
1.1 misho 199: goto bad;
200: }
201: state->grlist = user_group_list;
1.1.1.3 ! misho 202: sudo_grlist_addref(state->grlist);
1.1 misho 203: if (state->grlist != ostate->grlist) {
204: if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1.1.1.2 misho 205: strlcpy(errbuf, "PERM_USER: setgroups", sizeof(errbuf));
1.1 misho 206: goto bad;
207: }
208: }
209: state->ruid = user_uid;
210: state->euid = user_uid;
211: state->suid = ROOT_UID;
1.1.1.2 misho 212: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
213: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
214: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
215: (int)state->ruid, (int)state->euid, (int)state->suid);
216: if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
217: snprintf(errbuf, sizeof(errbuf), "PERM_USER: setresuid(%d, %d, %d)",
218: ID(ruid), ID(euid), ID(suid));
1.1 misho 219: goto bad;
220: }
221: break;
222:
223: case PERM_FULL_USER:
224: /* headed for exec() */
225: state->rgid = user_gid;
226: state->egid = user_gid;
227: state->sgid = user_gid;
1.1.1.2 misho 228: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
229: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
230: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
231: (int)state->rgid, (int)state->egid, (int)state->sgid);
232: if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
233: snprintf(errbuf, sizeof(errbuf),
234: "PERM_FULL_USER: setresgid(%d, %d, %d)",
235: ID(rgid), ID(egid), ID(sgid));
1.1 misho 236: goto bad;
237: }
238: state->grlist = user_group_list;
1.1.1.3 ! misho 239: sudo_grlist_addref(state->grlist);
1.1 misho 240: if (state->grlist != ostate->grlist) {
241: if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1.1.1.2 misho 242: strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
1.1 misho 243: goto bad;
244: }
245: }
246: state->ruid = user_uid;
247: state->euid = user_uid;
248: state->suid = user_uid;
1.1.1.2 misho 249: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
250: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
251: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
252: (int)state->ruid, (int)state->euid, (int)state->suid);
253: if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
254: snprintf(errbuf, sizeof(errbuf),
255: "PERM_FULL_USER: setresuid(%d, %d, %d)",
256: ID(ruid), ID(euid), ID(suid));
1.1 misho 257: goto bad;
258: }
259: break;
260:
261: case PERM_RUNAS:
1.1.1.2 misho 262: state->rgid = ostate->rgid;
1.1 misho 263: state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
1.1.1.2 misho 264: state->sgid = ostate->sgid;
265: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
266: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
267: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
268: (int)state->rgid, (int)state->egid, (int)state->sgid);
269: if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
270: strlcpy(errbuf, _("unable to change to runas gid"), sizeof(errbuf));
1.1 misho 271: goto bad;
272: }
273: state->grlist = runas_setgroups();
1.1.1.2 misho 274: state->ruid = ostate->ruid;
1.1 misho 275: state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
1.1.1.2 misho 276: state->suid = ostate->suid;
277: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
278: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
279: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
280: (int)state->ruid, (int)state->euid, (int)state->suid);
281: if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
282: strlcpy(errbuf, _("unable to change to runas uid"), sizeof(errbuf));
1.1 misho 283: goto bad;
284: }
285: break;
286:
287: case PERM_SUDOERS:
288: state->grlist = ostate->grlist;
1.1.1.3 ! misho 289: sudo_grlist_addref(state->grlist);
1.1 misho 290:
291: /* assumes euid == ROOT_UID, ruid == user */
1.1.1.2 misho 292: state->rgid = ostate->rgid;
1.1 misho 293: state->egid = sudoers_gid;
1.1.1.2 misho 294: state->sgid = ostate->sgid;
295: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
296: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
297: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
298: (int)state->rgid, (int)state->egid, (int)state->sgid);
299: if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
300: strlcpy(errbuf, _("unable to change to sudoers gid"), sizeof(errbuf));
301: goto bad;
302: }
1.1 misho 303:
304: state->ruid = ROOT_UID;
305: /*
306: * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
307: * we use a non-zero uid in order to avoid NFS lossage.
308: * Using uid 1 is a bit bogus but should work on all OS's.
309: */
1.1.1.3 ! misho 310: if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
1.1 misho 311: state->euid = 1;
312: else
313: state->euid = sudoers_uid;
314: state->suid = ROOT_UID;
1.1.1.2 misho 315: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
316: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
317: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
318: (int)state->ruid, (int)state->euid, (int)state->suid);
319: if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
320: snprintf(errbuf, sizeof(errbuf),
321: "PERM_SUDOERS: setresuid(%d, %d, %d)",
322: ID(ruid), ID(euid), ID(suid));
1.1 misho 323: goto bad;
324: }
325: break;
326:
327: case PERM_TIMESTAMP:
328: state->grlist = ostate->grlist;
1.1.1.3 ! misho 329: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 330: state->rgid = ostate->rgid;
331: state->egid = ostate->egid;
332: state->sgid = ostate->sgid;
1.1 misho 333: state->ruid = ROOT_UID;
334: state->euid = timestamp_uid;
335: state->suid = ROOT_UID;
1.1.1.2 misho 336: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
337: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
338: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
339: (int)state->ruid, (int)state->euid, (int)state->suid);
340: if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
341: snprintf(errbuf, sizeof(errbuf),
342: "PERM_TIMESTAMP: setresuid(%d, %d, %d)",
343: ID(ruid), ID(euid), ID(suid));
1.1 misho 344: goto bad;
345: }
346: break;
347: }
348:
349: perm_stack_depth++;
1.1.1.2 misho 350: debug_return_bool(1);
1.1 misho 351: bad:
1.1.1.2 misho 352: warningx("%s: %s", errbuf,
1.1 misho 353: errno == EAGAIN ? _("too many processes") : strerror(errno));
354: if (noexit)
1.1.1.2 misho 355: debug_return_bool(0);
1.1 misho 356: exit(1);
357: }
358:
359: void
360: restore_perms(void)
361: {
362: struct perm_state *state, *ostate;
1.1.1.2 misho 363: debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1.1 misho 364:
365: if (perm_stack_depth < 2)
1.1.1.2 misho 366: debug_return;
1.1 misho 367:
368: state = &perm_stack[perm_stack_depth - 1];
369: ostate = &perm_stack[perm_stack_depth - 2];
370: perm_stack_depth--;
371:
1.1.1.2 misho 372: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d, %d] -> [%d, %d, %d]",
373: __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
374: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid);
375: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d, %d] -> [%d, %d, %d]",
376: __func__, (int)state->rgid, (int)state->egid, (int)state->sgid,
377: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid);
378:
1.1 misho 379: /* XXX - more cases here where euid != ruid */
1.1.1.2 misho 380: if (OID(euid) == ROOT_UID) {
1.1 misho 381: if (setresuid(-1, ROOT_UID, -1)) {
382: warning("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
383: (int)state->ruid, (int)state->euid, (int)state->suid,
384: -1, ROOT_UID, -1);
385: goto bad;
386: }
387: }
388: if (setresuid(OID(ruid), OID(euid), OID(suid))) {
389: warning("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
390: (int)state->ruid, (int)state->euid, (int)state->suid,
391: (int)OID(ruid), (int)OID(euid), (int)OID(suid));
392: goto bad;
393: }
394: if (setresgid(OID(rgid), OID(egid), OID(sgid))) {
395: warning("setresgid() [%d, %d, %d] -> [%d, %d, %d]",
396: (int)state->rgid, (int)state->egid, (int)state->sgid,
397: (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
398: goto bad;
399: }
400: if (state->grlist != ostate->grlist) {
401: if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
402: warning("setgroups()");
403: goto bad;
404: }
405: }
1.1.1.3 ! misho 406: sudo_grlist_delref(state->grlist);
1.1.1.2 misho 407: debug_return;
1.1 misho 408:
409: bad:
410: exit(1);
411: }
412:
1.1.1.2 misho 413: #elif defined(_AIX) && defined(ID_SAVED)
414:
415: #define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid || state->suid != ostate->suid)
416: #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid || state->sgid != ostate->sgid)
1.1 misho 417:
418: /*
1.1.1.2 misho 419: * Set real and effective and saved uids and gids based on perm.
420: * We always retain a saved uid of 0 unless we are headed for an exec().
421: * We only flip the effective gid since it only changes for PERM_SUDOERS.
1.1 misho 422: * This version of set_perms() works fine with the "stay_setuid" option.
423: */
424: int
425: set_perms(int perm)
426: {
427: struct perm_state *state, *ostate = NULL;
1.1.1.2 misho 428: char errbuf[1024];
1.1 misho 429: int noexit;
1.1.1.2 misho 430: debug_decl(set_perms, SUDO_DEBUG_PERMS)
1.1 misho 431:
432: noexit = ISSET(perm, PERM_NOEXIT);
433: CLR(perm, PERM_MASK);
434:
435: if (perm_stack_depth == PERM_STACK_MAX) {
1.1.1.2 misho 436: strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
1.1 misho 437: errno = EINVAL;
438: goto bad;
439: }
440:
441: state = &perm_stack[perm_stack_depth];
442: if (perm != PERM_INITIAL) {
443: if (perm_stack_depth == 0) {
1.1.1.2 misho 444: strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
1.1 misho 445: errno = EINVAL;
446: goto bad;
447: }
448: ostate = &perm_stack[perm_stack_depth - 1];
449: }
450:
451: switch (perm) {
452: case PERM_INITIAL:
453: /* Stash initial state */
1.1.1.2 misho 454: state->ruid = getuidx(ID_REAL);
455: state->euid = getuidx(ID_EFFECTIVE);
456: state->suid = getuidx(ID_SAVED);
457: state->rgid = getgidx(ID_REAL);
458: state->egid = getgidx(ID_EFFECTIVE);
459: state->sgid = getgidx(ID_SAVED);
1.1 misho 460: state->grlist = user_group_list;
1.1.1.3 ! misho 461: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 462: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
463: "ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
464: __func__, (unsigned int)state->ruid, (unsigned int)state->euid,
465: (unsigned int)state->suid, (unsigned int)state->rgid,
466: (unsigned int)state->egid, (unsigned int)state->sgid);
1.1 misho 467: break;
468:
469: case PERM_ROOT:
1.1.1.2 misho 470: state->ruid = ROOT_UID;
471: state->euid = ROOT_UID;
472: state->suid = ROOT_UID;
473: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
474: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
475: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
476: (int)state->ruid, (int)state->euid, (int)state->suid);
477: if (UID_CHANGED && setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
478: snprintf(errbuf, sizeof(errbuf),
479: "PERM_ROOT: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
480: ROOT_UID);
481: goto bad;
482: }
483: state->rgid = ostate->rgid;
484: state->egid = ostate->egid;
485: state->sgid = ostate->sgid;
486: state->grlist = ostate->grlist;
1.1.1.3 ! misho 487: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 488: break;
489:
490: case PERM_USER:
491: state->rgid = ostate->rgid;
492: state->egid = user_gid;
493: state->sgid = ostate->sgid;
494: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
495: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
496: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
497: (int)state->rgid, (int)state->egid, (int)state->sgid);
498: if (GID_CHANGED && setgidx(ID_EFFECTIVE, user_gid)) {
499: snprintf(errbuf, sizeof(errbuf),
500: "PERM_USER: setgidx(ID_EFFECTIVE, %d)", user_gid);
501: goto bad;
502: }
503: state->grlist = user_group_list;
1.1.1.3 ! misho 504: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 505: if (state->grlist != ostate->grlist) {
506: if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
507: strlcpy(errbuf, "PERM_USER: setgroups", sizeof(errbuf));
508: goto bad;
509: }
510: }
511: state->ruid = user_uid;
512: state->euid = user_uid;
513: state->suid = ROOT_UID;
514: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
515: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
516: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
517: (int)state->ruid, (int)state->euid, (int)state->suid);
518: if (ostate->euid != ROOT_UID || ostate->suid != ROOT_UID) {
519: if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
520: snprintf(errbuf, sizeof(errbuf),
521: "PERM_USER: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
522: ROOT_UID);
523: goto bad;
524: }
525: }
526: if (setuidx(ID_EFFECTIVE|ID_REAL, user_uid)) {
527: snprintf(errbuf, sizeof(errbuf),
528: "PERM_USER: setuidx(ID_EFFECTIVE|ID_REAL, %d)", user_uid);
529: goto bad;
530: }
531: break;
532:
533: case PERM_FULL_USER:
534: /* headed for exec() */
535: state->rgid = user_gid;
536: state->egid = user_gid;
537: state->sgid = user_gid;
538: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
539: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
540: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
541: (int)state->rgid, (int)state->egid, (int)state->sgid);
542: if (GID_CHANGED && setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, user_gid)) {
543: snprintf(errbuf, sizeof(errbuf),
544: "PERM_FULL_USER: setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
545: user_gid);
546: goto bad;
547: }
548: state->grlist = user_group_list;
1.1.1.3 ! misho 549: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 550: if (state->grlist != ostate->grlist) {
551: if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
552: strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
553: goto bad;
554: }
555: }
556: state->ruid = user_uid;
557: state->euid = user_uid;
558: state->suid = user_uid;
559: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
560: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
561: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
562: (int)state->ruid, (int)state->euid, (int)state->suid);
563: if (UID_CHANGED && setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, user_uid)) {
564: snprintf(errbuf, sizeof(errbuf),
565: "PERM_FULL_USER: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
566: user_uid);
567: goto bad;
568: }
569: break;
570:
571: case PERM_RUNAS:
572: state->rgid = ostate->rgid;
573: state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
574: state->sgid = ostate->sgid;
575: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
576: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
577: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
578: (int)state->rgid, (int)state->egid, (int)state->sgid);
579: if (GID_CHANGED && setgidx(ID_EFFECTIVE, state->egid)) {
580: strlcpy(errbuf, _("unable to change to runas gid"), sizeof(errbuf));
581: goto bad;
582: }
583: state->grlist = runas_setgroups();
584: state->ruid = ostate->ruid;
585: state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
586: state->suid = ostate->suid;
587: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
588: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
589: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
590: (int)state->ruid, (int)state->euid, (int)state->suid);
591: if (UID_CHANGED && setuidx(ID_EFFECTIVE, state->euid)) {
592: strlcpy(errbuf, _("unable to change to runas uid"), sizeof(errbuf));
593: goto bad;
594: }
595: break;
596:
597: case PERM_SUDOERS:
598: state->grlist = ostate->grlist;
1.1.1.3 ! misho 599: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 600:
601: /* assume euid == ROOT_UID, ruid == user */
602: state->rgid = ostate->rgid;
603: state->egid = sudoers_gid;
604: state->sgid = ostate->sgid;
605: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
606: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
607: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
608: (int)state->rgid, (int)state->egid, (int)state->sgid);
609: if (GID_CHANGED && setgidx(ID_EFFECTIVE, sudoers_gid)) {
610: strlcpy(errbuf, _("unable to change to sudoers gid"), sizeof(errbuf));
611: goto bad;
612: }
613:
614: state->ruid = ROOT_UID;
1.1 misho 615: /*
1.1.1.2 misho 616: * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
617: * we use a non-zero uid in order to avoid NFS lossage.
618: * Using uid 1 is a bit bogus but should work on all OS's.
1.1 misho 619: */
1.1.1.3 ! misho 620: if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
1.1.1.2 misho 621: state->euid = 1;
622: else
623: state->euid = sudoers_uid;
624: state->suid = ROOT_UID;
625: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
626: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
627: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
628: (int)state->ruid, (int)state->euid, (int)state->suid);
629: if (UID_CHANGED) {
630: if (ostate->ruid != ROOT_UID || ostate->suid != ROOT_UID) {
631: if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
632: snprintf(errbuf, sizeof(errbuf),
633: "PERM_SUDOERS: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
634: ROOT_UID);
635: goto bad;
636: }
637: }
638: if (setuidx(ID_EFFECTIVE, state->euid)) {
639: snprintf(errbuf, sizeof(errbuf),
640: "PERM_SUDOERS: setuidx(ID_EFFECTIVE, %d)", sudoers_uid);
641: goto bad;
642: }
643: }
644: break;
645:
646: case PERM_TIMESTAMP:
647: state->grlist = ostate->grlist;
1.1.1.3 ! misho 648: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 649: state->rgid = ostate->rgid;
650: state->egid = ostate->egid;
651: state->sgid = ostate->sgid;
652: state->ruid = ROOT_UID;
653: state->euid = timestamp_uid;
654: state->suid = ROOT_UID;
655: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
656: "[%d, %d, %d] -> [%d, %d, %d]", __func__,
657: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
658: (int)state->ruid, (int)state->euid, (int)state->suid);
659: if (UID_CHANGED) {
660: if (ostate->ruid != ROOT_UID || ostate->suid != ROOT_UID) {
661: if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
662: snprintf(errbuf, sizeof(errbuf),
663: "PERM_TIMESTAMP: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
664: ROOT_UID);
665: goto bad;
666: }
667: }
668: if (setuidx(ID_EFFECTIVE, timestamp_uid)) {
669: snprintf(errbuf, sizeof(errbuf),
670: "PERM_TIMESTAMP: setuidx(ID_EFFECTIVE, %d)", timestamp_uid);
671: goto bad;
672: }
673: }
674: break;
675: }
676:
677: perm_stack_depth++;
678: debug_return_bool(1);
679: bad:
680: warningx("%s: %s", errbuf,
681: errno == EAGAIN ? _("too many processes") : strerror(errno));
682: if (noexit)
683: debug_return_bool(0);
684: exit(1);
685: }
686:
687: void
688: restore_perms(void)
689: {
690: struct perm_state *state, *ostate;
691: debug_decl(restore_perms, SUDO_DEBUG_PERMS)
692:
693: if (perm_stack_depth < 2)
694: debug_return;
695:
696: state = &perm_stack[perm_stack_depth - 1];
697: ostate = &perm_stack[perm_stack_depth - 2];
698: perm_stack_depth--;
699:
700: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d, %d] -> [%d, %d, %d]",
701: __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
702: (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid);
703: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d, %d] -> [%d, %d, %d]",
704: __func__, (int)state->rgid, (int)state->egid, (int)state->sgid,
705: (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid);
706:
707: if (OID(ruid) != -1 || OID(euid) != -1 || OID(suid) != -1) {
708: if (OID(euid) == ROOT_UID) {
709: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: setuidx(ID_EFFECTIVE, %d)",
710: __func__, ROOT_UID);
711: if (setuidx(ID_EFFECTIVE, ROOT_UID)) {
712: warning("setuidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
713: (int)state->ruid, (int)state->euid, (int)state->suid,
714: -1, ROOT_UID, -1);
715: goto bad;
716: }
717: }
718: if (OID(ruid) == OID(euid) && OID(euid) == OID(suid)) {
719: sudo_debug_printf(SUDO_DEBUG_INFO,
720: "%s: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
721: __func__, OID(ruid));
722: if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, OID(ruid))) {
723: warning("setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED) [%d, %d, %d] -> [%d, %d, %d]",
724: (int)state->ruid, (int)state->euid, (int)state->suid,
725: (int)OID(ruid), (int)OID(euid), (int)OID(suid));
726: goto bad;
727: }
728: } else if (OID(ruid) == -1 && OID(suid) == -1) {
729: /* May have already changed euid to ROOT_UID above. */
730: if (OID(euid) != ROOT_UID) {
731: sudo_debug_printf(SUDO_DEBUG_INFO,
732: "%s: setuidx(ID_EFFECTIVE, %d)", __func__, OID(euid));
733: if (setuidx(ID_EFFECTIVE, OID(euid))) {
734: warning("setuidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
735: (int)state->ruid, (int)state->euid, (int)state->suid,
736: (int)OID(ruid), (int)OID(euid), (int)OID(suid));
737: goto bad;
738: }
739: }
740: } else if (OID(suid) == -1) {
741: /* Cannot set the real uid alone. */
742: sudo_debug_printf(SUDO_DEBUG_INFO,
743: "%s: setuidx(ID_REAL|ID_EFFECTIVE, %d)", __func__, OID(ruid));
744: if (setuidx(ID_REAL|ID_EFFECTIVE, OID(ruid))) {
745: warning("setuidx(ID_REAL|ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
746: (int)state->ruid, (int)state->euid, (int)state->suid,
747: (int)OID(ruid), (int)OID(euid), (int)OID(suid));
748: goto bad;
749: }
750: /* Restore the effective euid if it doesn't match the ruid. */
751: if (OID(euid) != OID(ruid)) {
752: sudo_debug_printf(SUDO_DEBUG_INFO,
753: "%s: setuidx(ID_EFFECTIVE, %d)", __func__, ostate->euid);
754: if (setuidx(ID_EFFECTIVE, ostate->euid)) {
755: warning("setuidx(ID_EFFECTIVE, %d)", ostate->euid);
756: goto bad;
757: }
758: }
759: }
760: }
761: if (OID(rgid) != -1 || OID(egid) != -1 || OID(sgid) != -1) {
762: if (OID(rgid) == OID(egid) && OID(egid) == OID(sgid)) {
763: sudo_debug_printf(SUDO_DEBUG_INFO,
764: "%s: setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
765: __func__, OID(rgid));
766: if (setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, OID(rgid))) {
767: warning("setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED) [%d, %d, %d] -> [%d, %d, %d]",
768: (int)state->rgid, (int)state->egid, (int)state->sgid,
769: (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
770: goto bad;
771: }
772: } else if (OID(rgid) == -1 && OID(sgid) == -1) {
773: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: setgidx(ID_EFFECTIVE, %d)",
774: __func__, OID(egid));
775: if (setgidx(ID_EFFECTIVE, OID(egid))) {
776: warning("setgidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
777: (int)state->rgid, (int)state->egid, (int)state->sgid,
778: (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
779: goto bad;
780: }
781: } else if (OID(sgid) == -1) {
782: sudo_debug_printf(SUDO_DEBUG_INFO,
783: "%s: setgidx(ID_EFFECTIVE|ID_REAL, %d)", __func__, OID(rgid));
784: if (setgidx(ID_REAL|ID_EFFECTIVE, OID(rgid))) {
785: warning("setgidx(ID_REAL|ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
786: (int)state->rgid, (int)state->egid, (int)state->sgid,
787: (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
788: goto bad;
789: }
790: }
791: }
792: if (state->grlist != ostate->grlist) {
793: if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
794: warning("setgroups()");
1.1 misho 795: goto bad;
796: }
1.1.1.2 misho 797: }
1.1.1.3 ! misho 798: sudo_grlist_delref(state->grlist);
1.1.1.2 misho 799: debug_return;
800:
801: bad:
802: exit(1);
803: }
804:
805: #elif defined(HAVE_SETREUID)
806:
807: #define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid)
808: #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid)
809:
810: /*
811: * Set real and effective and saved uids and gids based on perm.
812: * We always retain a saved uid of 0 unless we are headed for an exec().
813: * We only flip the effective gid since it only changes for PERM_SUDOERS.
814: * This version of set_perms() works fine with the "stay_setuid" option.
815: */
816: int
817: set_perms(int perm)
818: {
819: struct perm_state *state, *ostate = NULL;
820: char errbuf[1024];
821: int noexit;
822: debug_decl(set_perms, SUDO_DEBUG_PERMS)
823:
824: noexit = ISSET(perm, PERM_NOEXIT);
825: CLR(perm, PERM_MASK);
826:
827: if (perm_stack_depth == PERM_STACK_MAX) {
828: strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
829: errno = EINVAL;
830: goto bad;
831: }
832:
833: state = &perm_stack[perm_stack_depth];
834: if (perm != PERM_INITIAL) {
835: if (perm_stack_depth == 0) {
836: strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
837: errno = EINVAL;
1.1 misho 838: goto bad;
839: }
1.1.1.2 misho 840: ostate = &perm_stack[perm_stack_depth - 1];
841: }
842:
843: switch (perm) {
844: case PERM_INITIAL:
845: /* Stash initial state */
846: state->ruid = getuid();
847: state->euid = geteuid();
848: state->rgid = getgid();
849: state->egid = getegid();
850: state->grlist = user_group_list;
1.1.1.3 ! misho 851: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 852: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
853: "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
854: (int)state->ruid, (int)state->euid,
855: (int)state->rgid, (int)state->egid);
856: break;
857:
858: case PERM_ROOT:
1.1 misho 859: state->ruid = ROOT_UID;
860: state->euid = ROOT_UID;
1.1.1.2 misho 861: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
862: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
863: (int)ostate->euid, (int)state->ruid, (int)state->euid);
864: /*
865: * setreuid(0, 0) may fail on some systems if euid is not already 0.
866: */
867: if (ostate->euid != ROOT_UID) {
868: if (setreuid(-1, ROOT_UID)) {
869: snprintf(errbuf, sizeof(errbuf),
870: "PERM_ROOT: setreuid(-1, %d)", PERM_ROOT);
871: goto bad;
872: }
873: }
874: if (ostate->ruid != ROOT_UID) {
875: if (setreuid(ROOT_UID, -1)) {
876: snprintf(errbuf, sizeof(errbuf),
877: "PERM_ROOT: setreuid(%d, -1)", ROOT_UID);
878: goto bad;
879: }
880: }
881: state->rgid = ostate->rgid;
882: state->egid = ostate->rgid;
1.1 misho 883: state->grlist = ostate->grlist;
1.1.1.3 ! misho 884: sudo_grlist_addref(state->grlist);
1.1 misho 885: break;
886:
887: case PERM_USER:
1.1.1.2 misho 888: state->rgid = ostate->rgid;
1.1 misho 889: state->egid = user_gid;
1.1.1.2 misho 890: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
891: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
892: (int)ostate->egid, (int)state->rgid, (int)state->egid);
893: if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
894: snprintf(errbuf, sizeof(errbuf),
895: "PERM_USER: setregid(%d, %d)", ID(rgid), ID(egid));
1.1 misho 896: goto bad;
897: }
898: state->grlist = user_group_list;
1.1.1.3 ! misho 899: sudo_grlist_addref(state->grlist);
1.1 misho 900: if (state->grlist != ostate->grlist) {
901: if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1.1.1.2 misho 902: strlcpy(errbuf, "PERM_USER: setgroups", sizeof(errbuf));
1.1 misho 903: goto bad;
904: }
905: }
906: state->ruid = ROOT_UID;
907: state->euid = user_uid;
1.1.1.2 misho 908: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
909: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
910: (int)ostate->euid, (int)state->ruid, (int)state->euid);
911: if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
912: snprintf(errbuf, sizeof(errbuf),
913: "PERM_USER: setreuid(%d, %d)", ID(ruid), ID(euid));
1.1 misho 914: goto bad;
915: }
916: break;
917:
918: case PERM_FULL_USER:
919: /* headed for exec() */
920: state->rgid = user_gid;
921: state->egid = user_gid;
1.1.1.2 misho 922: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
923: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
924: (int)ostate->egid, (int)state->rgid, (int)state->egid);
925: if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
926: snprintf(errbuf, sizeof(errbuf),
927: "PERM_FULL_USER: setregid(%d, %d)", ID(rgid), ID(egid));
1.1 misho 928: goto bad;
929: }
930: state->grlist = user_group_list;
1.1.1.3 ! misho 931: sudo_grlist_addref(state->grlist);
1.1 misho 932: if (state->grlist != ostate->grlist) {
933: if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1.1.1.2 misho 934: strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
1.1 misho 935: goto bad;
936: }
937: }
938: state->ruid = user_uid;
939: state->euid = user_uid;
1.1.1.2 misho 940: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
941: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
942: (int)ostate->euid, (int)state->ruid, (int)state->euid);
943: if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
944: snprintf(errbuf, sizeof(errbuf),
945: "PERM_FULL_USER: setreuid(%d, %d)", ID(ruid), ID(euid));
1.1 misho 946: goto bad;
947: }
948: break;
949:
950: case PERM_RUNAS:
1.1.1.2 misho 951: state->rgid = ostate->rgid;
1.1 misho 952: state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
1.1.1.2 misho 953: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
954: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
955: (int)ostate->egid, (int)state->rgid, (int)state->egid);
956: if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
957: strlcpy(errbuf, _("unable to change to runas gid"), sizeof(errbuf));
1.1 misho 958: goto bad;
959: }
960: state->grlist = runas_setgroups();
961: state->ruid = ROOT_UID;
962: state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
1.1.1.2 misho 963: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
964: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
965: (int)ostate->euid, (int)state->ruid, (int)state->euid);
966: if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
967: strlcpy(errbuf, _("unable to change to runas uid"), sizeof(errbuf));
1.1 misho 968: goto bad;
969: }
970: break;
971:
972: case PERM_SUDOERS:
973: state->grlist = ostate->grlist;
1.1.1.3 ! misho 974: sudo_grlist_addref(state->grlist);
1.1 misho 975:
976: /* assume euid == ROOT_UID, ruid == user */
1.1.1.2 misho 977: state->rgid = ostate->rgid;
1.1 misho 978: state->egid = sudoers_gid;
1.1.1.2 misho 979: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
980: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
981: (int)ostate->egid, (int)state->rgid, (int)state->egid);
982: if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
983: strlcpy(errbuf, _("unable to change to sudoers gid"), sizeof(errbuf));
984: goto bad;
985: }
1.1 misho 986:
987: state->ruid = ROOT_UID;
988: /*
989: * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
990: * we use a non-zero uid in order to avoid NFS lossage.
991: * Using uid 1 is a bit bogus but should work on all OS's.
992: */
1.1.1.3 ! misho 993: if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
1.1 misho 994: state->euid = 1;
995: else
996: state->euid = sudoers_uid;
1.1.1.2 misho 997: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
998: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
999: (int)ostate->euid, (int)state->ruid, (int)state->euid);
1000: if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
1001: snprintf(errbuf, sizeof(errbuf),
1002: "PERM_SUDOERS: setreuid(%d, %d)", ID(ruid), ID(euid));
1.1 misho 1003: goto bad;
1004: }
1005: break;
1006:
1007: case PERM_TIMESTAMP:
1008: state->grlist = ostate->grlist;
1.1.1.3 ! misho 1009: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 1010: state->rgid = ostate->rgid;
1011: state->egid = ostate->egid;
1.1 misho 1012: state->ruid = ROOT_UID;
1013: state->euid = timestamp_uid;
1.1.1.2 misho 1014: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
1015: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1016: (int)ostate->euid, (int)state->ruid, (int)state->euid);
1017: if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
1018: snprintf(errbuf, sizeof(errbuf),
1019: "PERM_TIMESTAMP: setreuid(%d, %d)", ID(ruid), ID(euid));
1.1 misho 1020: goto bad;
1021: }
1022: break;
1023: }
1024:
1025: perm_stack_depth++;
1.1.1.2 misho 1026: debug_return_bool(1);
1.1 misho 1027: bad:
1.1.1.2 misho 1028: warningx("%s: %s", errbuf,
1.1 misho 1029: errno == EAGAIN ? _("too many processes") : strerror(errno));
1030: if (noexit)
1.1.1.2 misho 1031: debug_return_bool(0);
1.1 misho 1032: exit(1);
1033: }
1034:
1035: void
1036: restore_perms(void)
1037: {
1038: struct perm_state *state, *ostate;
1.1.1.2 misho 1039: debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1.1 misho 1040:
1041: if (perm_stack_depth < 2)
1.1.1.2 misho 1042: debug_return;
1.1 misho 1043:
1044: state = &perm_stack[perm_stack_depth - 1];
1045: ostate = &perm_stack[perm_stack_depth - 2];
1046: perm_stack_depth--;
1047:
1.1.1.2 misho 1048: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d] -> [%d, %d]",
1049: __func__, (int)state->ruid, (int)state->euid,
1050: (int)ostate->ruid, (int)ostate->euid);
1051: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d] -> [%d, %d]",
1052: __func__, (int)state->rgid, (int)state->egid,
1053: (int)ostate->rgid, (int)ostate->egid);
1054:
1.1 misho 1055: /*
1056: * When changing euid to ROOT_UID, setreuid() may fail even if
1057: * the ruid is ROOT_UID so call setuid() first.
1058: */
1059: if (OID(euid) == ROOT_UID) {
1060: /* setuid() may not set the saved ID unless the euid is ROOT_UID */
1061: if (ID(euid) != ROOT_UID)
1062: (void)setreuid(-1, ROOT_UID);
1063: if (setuid(ROOT_UID)) {
1064: warning("setuid() [%d, %d] -> %d)", (int)state->ruid,
1065: (int)state->euid, ROOT_UID);
1066: goto bad;
1067: }
1068: }
1069: if (setreuid(OID(ruid), OID(euid))) {
1070: warning("setreuid() [%d, %d] -> [%d, %d]", (int)state->ruid,
1071: (int)state->euid, (int)OID(ruid), (int)OID(euid));
1072: goto bad;
1073: }
1074: if (setregid(OID(rgid), OID(egid))) {
1075: warning("setregid() [%d, %d] -> [%d, %d]", (int)state->rgid,
1076: (int)state->egid, (int)OID(rgid), (int)OID(egid));
1077: goto bad;
1078: }
1079: if (state->grlist != ostate->grlist) {
1080: if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
1081: warning("setgroups()");
1082: goto bad;
1083: }
1084: }
1.1.1.3 ! misho 1085: sudo_grlist_delref(state->grlist);
1.1.1.2 misho 1086: debug_return;
1.1 misho 1087:
1088: bad:
1089: exit(1);
1090: }
1091:
1.1.1.2 misho 1092: #elif defined(HAVE_SETEUID)
1093:
1094: #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid)
1.1 misho 1095:
1096: /*
1097: * Set real and effective uids and gids based on perm.
1098: * We always retain a real or effective uid of ROOT_UID unless
1099: * we are headed for an exec().
1100: * This version of set_perms() works fine with the "stay_setuid" option.
1101: */
1102: int
1103: set_perms(int perm)
1104: {
1105: struct perm_state *state, *ostate = NULL;
1.1.1.2 misho 1106: char errbuf[1024];
1.1 misho 1107: int noexit;
1.1.1.2 misho 1108: debug_decl(set_perms, SUDO_DEBUG_PERMS)
1.1 misho 1109:
1110: noexit = ISSET(perm, PERM_NOEXIT);
1111: CLR(perm, PERM_MASK);
1112:
1113: if (perm_stack_depth == PERM_STACK_MAX) {
1.1.1.2 misho 1114: strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
1.1 misho 1115: errno = EINVAL;
1116: goto bad;
1117: }
1118:
1119: state = &perm_stack[perm_stack_depth];
1120: if (perm != PERM_INITIAL) {
1121: if (perm_stack_depth == 0) {
1.1.1.2 misho 1122: strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
1.1 misho 1123: errno = EINVAL;
1124: goto bad;
1125: }
1126: ostate = &perm_stack[perm_stack_depth - 1];
1127: }
1128:
1129: /*
1130: * Since we only have setuid() and seteuid() and semantics
1131: * for these calls differ on various systems, we set
1132: * real and effective uids to ROOT_UID initially to be safe.
1133: */
1134: if (perm != PERM_INITIAL) {
1.1.1.2 misho 1135: if (ostate->euid != ROOT_UID && seteuid(ROOT_UID)) {
1136: snprintf(errbuf, sizeof(errbuf), "set_perms: seteuid(%d)", ROOT_UID);
1.1 misho 1137: goto bad;
1138: }
1.1.1.2 misho 1139: if (ostate->ruid != ROOT_UID && setuid(ROOT_UID)) {
1140: snprintf(errbuf, sizeof(errbuf), "set_perms: setuid(%d)", ROOT_UID);
1.1 misho 1141: goto bad;
1142: }
1143: }
1144:
1145: switch (perm) {
1146: case PERM_INITIAL:
1147: /* Stash initial state */
1148: state->ruid = getuid();
1149: state->euid = geteuid();
1150: state->rgid = getgid();
1151: state->egid = getegid();
1152: state->grlist = user_group_list;
1.1.1.3 ! misho 1153: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 1154: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
1155: "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
1156: (int)state->ruid, (int)state->euid,
1157: (int)state->rgid, (int)state->egid);
1.1 misho 1158: break;
1159:
1160: case PERM_ROOT:
1161: /* We already set ruid/euid above. */
1.1.1.2 misho 1162: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
1163: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1164: (int)ostate->euid, ROOT_UID, ROOT_UID);
1.1 misho 1165: state->ruid = ROOT_UID;
1166: state->euid = ROOT_UID;
1.1.1.2 misho 1167: state->rgid = ostate->rgid;
1168: state->egid = ostate->egid;
1.1 misho 1169: state->grlist = ostate->grlist;
1.1.1.3 ! misho 1170: sudo_grlist_addref(state->grlist);
1.1 misho 1171: break;
1172:
1173: case PERM_USER:
1174: state->egid = user_gid;
1.1.1.2 misho 1175: state->rgid = ostate->rgid;
1176: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
1177: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1178: (int)ostate->egid, (int)state->rgid, (int)state->egid);
1179: if (GID_CHANGED && setegid(user_gid)) {
1180: snprintf(errbuf, sizeof(errbuf),
1181: "PERM_USER: setegid(%d)", user_gid);
1.1 misho 1182: goto bad;
1183: }
1184: state->grlist = user_group_list;
1.1.1.3 ! misho 1185: sudo_grlist_addref(state->grlist);
1.1 misho 1186: if (state->grlist != ostate->grlist) {
1187: if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1.1.1.2 misho 1188: strlcpy(errbuf, "PERM_USER: setgroups", sizeof(errbuf));
1.1 misho 1189: goto bad;
1190: }
1191: }
1192: state->ruid = ROOT_UID;
1193: state->euid = user_uid;
1.1.1.2 misho 1194: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
1195: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1196: (int)ostate->euid, (int)state->ruid, (int)state->euid);
1197: if (seteuid(user_uid)) {
1198: snprintf(errbuf, sizeof(errbuf),
1199: "PERM_USER: seteuid(%d)", user_uid);
1.1 misho 1200: goto bad;
1201: }
1202: break;
1203:
1204: case PERM_FULL_USER:
1205: /* headed for exec() */
1206: state->rgid = user_gid;
1207: state->egid = user_gid;
1.1.1.2 misho 1208: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
1209: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1210: (int)ostate->egid, (int)state->rgid, (int)state->egid);
1211: if (GID_CHANGED && setgid(user_gid)) {
1212: snprintf(errbuf, sizeof(errbuf),
1213: "PERM_FULL_USER: setgid(%d)", user_gid);
1.1 misho 1214: goto bad;
1215: }
1216: state->grlist = user_group_list;
1.1.1.3 ! misho 1217: sudo_grlist_addref(state->grlist);
1.1 misho 1218: if (state->grlist != ostate->grlist) {
1219: if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1.1.1.2 misho 1220: strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
1.1 misho 1221: goto bad;
1222: }
1223: }
1224: state->ruid = user_uid;
1225: state->euid = user_uid;
1.1.1.2 misho 1226: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
1227: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1228: (int)ostate->euid, (int)state->ruid, (int)state->euid);
1.1 misho 1229: if (setuid(user_uid)) {
1.1.1.2 misho 1230: snprintf(errbuf, sizeof(errbuf),
1231: "PERM_FULL_USER: setuid(%d)", user_uid);
1.1 misho 1232: goto bad;
1233: }
1234: break;
1235:
1236: case PERM_RUNAS:
1.1.1.2 misho 1237: state->rgid = ostate->rgid;
1.1 misho 1238: state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
1.1.1.2 misho 1239: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
1240: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1241: (int)ostate->egid, (int)state->rgid, (int)state->egid);
1242: if (GID_CHANGED && setegid(state->egid)) {
1243: strlcpy(errbuf, _("unable to change to runas gid"), sizeof(errbuf));
1.1 misho 1244: goto bad;
1245: }
1246: state->grlist = runas_setgroups();
1.1.1.2 misho 1247: state->ruid = ostate->ruid;
1.1 misho 1248: state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
1.1.1.2 misho 1249: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
1250: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1251: (int)ostate->euid, (int)state->ruid, (int)state->euid);
1252: if (seteuid(state->euid)) {
1253: strlcpy(errbuf, _("unable to change to runas uid"), sizeof(errbuf));
1.1 misho 1254: goto bad;
1255: }
1256: break;
1257:
1258: case PERM_SUDOERS:
1259: state->grlist = ostate->grlist;
1.1.1.3 ! misho 1260: sudo_grlist_addref(state->grlist);
1.1 misho 1261:
1262: /* assume euid == ROOT_UID, ruid == user */
1.1.1.2 misho 1263: state->rgid = ostate->rgid;
1.1 misho 1264: state->egid = sudoers_gid;
1.1.1.2 misho 1265: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
1266: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1267: (int)ostate->egid, (int)state->rgid, (int)state->egid);
1268: if (GID_CHANGED && setegid(sudoers_gid)) {
1269: strlcpy(errbuf, _("unable to change to sudoers gid"), sizeof(errbuf));
1270: goto bad;
1271: }
1.1 misho 1272:
1273: state->ruid = ROOT_UID;
1274: /*
1275: * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
1276: * we use a non-zero uid in order to avoid NFS lossage.
1277: * Using uid 1 is a bit bogus but should work on all OS's.
1278: */
1.1.1.3 ! misho 1279: if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
1.1 misho 1280: state->euid = 1;
1281: else
1282: state->euid = sudoers_uid;
1.1.1.2 misho 1283: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
1284: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1285: (int)ostate->euid, (int)state->ruid, (int)state->euid);
1286: if (seteuid(state->euid)) {
1287: snprintf(errbuf, sizeof(errbuf),
1288: "PERM_SUDOERS: seteuid(%d)", state->euid);
1.1 misho 1289: goto bad;
1290: }
1291: break;
1292:
1293: case PERM_TIMESTAMP:
1294: state->grlist = ostate->grlist;
1.1.1.3 ! misho 1295: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 1296: state->rgid = ostate->rgid;
1297: state->egid = ostate->egid;
1.1 misho 1298: state->ruid = ROOT_UID;
1299: state->euid = timestamp_uid;
1.1.1.2 misho 1300: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
1301: "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1302: (int)ostate->euid, (int)state->ruid, (int)state->euid);
1303: if (seteuid(timestamp_uid)) {
1304: snprintf(errbuf, sizeof(errbuf),
1305: "PERM_TIMESTAMP: seteuid(%d)", timestamp_uid);
1.1 misho 1306: goto bad;
1307: }
1308: break;
1309: }
1310:
1311: perm_stack_depth++;
1.1.1.2 misho 1312: debug_return_bool(1);
1.1 misho 1313: bad:
1.1.1.2 misho 1314: warningx("%s: %s", errbuf,
1.1 misho 1315: errno == EAGAIN ? _("too many processes") : strerror(errno));
1316: if (noexit)
1.1.1.2 misho 1317: debug_return_bool(0);
1.1 misho 1318: exit(1);
1319: }
1320:
1321: void
1322: restore_perms(void)
1323: {
1324: struct perm_state *state, *ostate;
1.1.1.2 misho 1325: debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1.1 misho 1326:
1327: if (perm_stack_depth < 2)
1.1.1.2 misho 1328: debug_return;
1.1 misho 1329:
1330: state = &perm_stack[perm_stack_depth - 1];
1331: ostate = &perm_stack[perm_stack_depth - 2];
1332: perm_stack_depth--;
1333:
1.1.1.2 misho 1334: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d] -> [%d, %d]",
1335: __func__, (int)state->ruid, (int)state->euid,
1336: (int)ostate->ruid, (int)ostate->euid);
1337: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d] -> [%d, %d]",
1338: __func__, (int)state->rgid, (int)state->egid,
1339: (int)ostate->rgid, (int)ostate->egid);
1340:
1.1 misho 1341: /*
1342: * Since we only have setuid() and seteuid() and semantics
1343: * for these calls differ on various systems, we set
1344: * real and effective uids to ROOT_UID initially to be safe.
1345: */
1346: if (seteuid(ROOT_UID)) {
1.1.1.2 misho 1347: warningx("seteuid() [%d] -> [%d]", (int)state->euid, ROOT_UID);
1.1 misho 1348: goto bad;
1349: }
1350: if (setuid(ROOT_UID)) {
1.1.1.2 misho 1351: warningx("setuid() [%d, %d] -> [%d, %d]", (int)state->ruid, ROOT_UID,
1352: ROOT_UID, ROOT_UID);
1.1 misho 1353: goto bad;
1354: }
1355:
1.1.1.2 misho 1356: if (OID(egid) != -1 && setegid(ostate->egid)) {
1357: warning("setegid(%d)", (int)ostate->egid);
1.1 misho 1358: goto bad;
1359: }
1360: if (state->grlist != ostate->grlist) {
1361: if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
1362: warning("setgroups()");
1363: goto bad;
1364: }
1365: }
1.1.1.2 misho 1366: if (OID(euid) != -1 && seteuid(ostate->euid)) {
1367: warning("seteuid(%d)", ostate->euid);
1.1 misho 1368: goto bad;
1369: }
1.1.1.3 ! misho 1370: sudo_grlist_delref(state->grlist);
1.1.1.2 misho 1371: debug_return;
1.1 misho 1372:
1373: bad:
1374: exit(1);
1375: }
1376:
1.1.1.2 misho 1377: #else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
1.1 misho 1378:
1379: /*
1380: * Set uids and gids based on perm via setuid() and setgid().
1381: * NOTE: does not support the "stay_setuid" or timestampowner options.
1382: * Also, sudoers_uid and sudoers_gid are not used.
1383: */
1384: int
1385: set_perms(int perm)
1386: {
1387: struct perm_state *state, *ostate = NULL;
1.1.1.2 misho 1388: char errbuf[1024];
1.1 misho 1389: int noexit;
1.1.1.2 misho 1390: debug_decl(set_perms, SUDO_DEBUG_PERMS)
1.1 misho 1391:
1392: noexit = ISSET(perm, PERM_NOEXIT);
1393: CLR(perm, PERM_MASK);
1394:
1395: if (perm_stack_depth == PERM_STACK_MAX) {
1.1.1.2 misho 1396: strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
1.1 misho 1397: errno = EINVAL;
1398: goto bad;
1399: }
1400:
1401: state = &perm_stack[perm_stack_depth];
1402: if (perm != PERM_INITIAL) {
1403: if (perm_stack_depth == 0) {
1.1.1.2 misho 1404: strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
1.1 misho 1405: errno = EINVAL;
1406: goto bad;
1407: }
1408: ostate = &perm_stack[perm_stack_depth - 1];
1409: }
1410:
1411: switch (perm) {
1412: case PERM_INITIAL:
1413: /* Stash initial state */
1.1.1.2 misho 1414: state->ruid = geteuid() == ROOT_UID ? ROOT_UID : getuid();
1.1 misho 1415: state->rgid = getgid();
1416: state->grlist = user_group_list;
1.1.1.3 ! misho 1417: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 1418: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
1419: "ruid: %d, rgid: %d", __func__, (int)state->ruid, (int)state->rgid);
1.1 misho 1420: break;
1421:
1422: case PERM_ROOT:
1423: state->ruid = ROOT_UID;
1.1.1.2 misho 1424: state->rgid = ostate->rgid;
1.1 misho 1425: state->grlist = ostate->grlist;
1.1.1.3 ! misho 1426: sudo_grlist_addref(state->grlist);
1.1.1.2 misho 1427: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
1428: "[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
1.1 misho 1429: if (setuid(ROOT_UID)) {
1.1.1.2 misho 1430: snprintf(errbuf, sizeof(errbuf), "PERM_ROOT: setuid(%d)", ROOT_UID);
1.1 misho 1431: goto bad;
1432: }
1433: break;
1434:
1435: case PERM_FULL_USER:
1436: state->rgid = user_gid;
1.1.1.2 misho 1437: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
1438: "[%d] -> [%d]", __func__, (int)ostate->rgid, (int)state->rgid);
1.1 misho 1439: (void) setgid(user_gid);
1440: state->grlist = user_group_list;
1.1.1.3 ! misho 1441: sudo_grlist_addref(state->grlist);
1.1 misho 1442: if (state->grlist != ostate->grlist) {
1443: if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1.1.1.2 misho 1444: strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
1.1 misho 1445: goto bad;
1446: }
1447: }
1448: state->ruid = user_uid;
1.1.1.2 misho 1449: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
1450: "[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
1.1 misho 1451: if (setuid(user_uid)) {
1.1.1.2 misho 1452: snprintf(errbuf, sizeof(errbuf),
1453: "PERM_FULL_USER: setuid(%d)", user_uid);
1.1 misho 1454: goto bad;
1455: }
1456: break;
1457:
1458: case PERM_USER:
1459: case PERM_SUDOERS:
1460: case PERM_RUNAS:
1461: case PERM_TIMESTAMP:
1462: /* Unsupported since we can't set euid. */
1.1.1.2 misho 1463: state->ruid = ostate->ruid;
1464: state->rgid = ostate->rgid;
1465: state->grlist = ostate->grlist;
1.1.1.3 ! misho 1466: sudo_grlist_addref(state->grlist);
1.1 misho 1467: break;
1468: }
1469:
1470: perm_stack_depth++;
1.1.1.2 misho 1471: debug_return_bool(1);
1.1 misho 1472: bad:
1.1.1.2 misho 1473: warningx("%s: %s", errbuf,
1.1 misho 1474: errno == EAGAIN ? _("too many processes") : strerror(errno));
1475: if (noexit)
1.1.1.2 misho 1476: debug_return_bool(0);
1.1 misho 1477: exit(1);
1478: }
1479:
1480: void
1481: restore_perms(void)
1482: {
1483: struct perm_state *state, *ostate;
1.1.1.2 misho 1484: debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1.1 misho 1485:
1486: if (perm_stack_depth < 2)
1.1.1.2 misho 1487: debug_return;
1.1 misho 1488:
1489: state = &perm_stack[perm_stack_depth - 1];
1490: ostate = &perm_stack[perm_stack_depth - 2];
1491: perm_stack_depth--;
1492:
1.1.1.2 misho 1493: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d] -> [%d]",
1494: __func__, (int)state->ruid, (int)ostate->ruid);
1495: sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d] -> [%d]",
1496: __func__, (int)state->rgid, (int)ostate->rgid);
1497:
1.1 misho 1498: if (OID(rgid) != -1 && setgid(ostate->rgid)) {
1499: warning("setgid(%d)", (int)ostate->rgid);
1500: goto bad;
1501: }
1502: if (state->grlist != ostate->grlist) {
1503: if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
1504: warning("setgroups()");
1505: goto bad;
1506: }
1507: }
1.1.1.3 ! misho 1508: sudo_grlist_delref(state->grlist);
1.1 misho 1509: if (OID(ruid) != -1 && setuid(ostate->ruid)) {
1510: warning("setuid(%d)", (int)ostate->ruid);
1511: goto bad;
1512: }
1.1.1.2 misho 1513: debug_return;
1.1 misho 1514:
1515: bad:
1516: exit(1);
1517: }
1.1.1.2 misho 1518: #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
1.1 misho 1519:
1.1.1.2 misho 1520: #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
1.1 misho 1521: static struct group_list *
1522: runas_setgroups(void)
1523: {
1524: struct passwd *pw;
1525: struct group_list *grlist;
1.1.1.2 misho 1526: debug_decl(runas_setgroups, SUDO_DEBUG_PERMS)
1.1 misho 1527:
1528: if (def_preserve_groups) {
1.1.1.3 ! misho 1529: sudo_grlist_addref(user_group_list);
1.1.1.2 misho 1530: debug_return_ptr(user_group_list);
1.1 misho 1531: }
1532:
1533: pw = runas_pw ? runas_pw : sudo_user.pw;
1534: #ifdef HAVE_SETAUTHDB
1535: aix_setauthdb(pw->pw_name);
1536: #endif
1.1.1.3 ! misho 1537: grlist = sudo_get_grlist(pw);
1.1 misho 1538: #ifdef HAVE_SETAUTHDB
1539: aix_restoreauthdb();
1540: #endif
1541: if (sudo_setgroups(grlist->ngids, grlist->gids) < 0)
1.1.1.2 misho 1542: log_fatal(USE_ERRNO|MSG_ONLY, _("unable to set runas group vector"));
1543: debug_return_ptr(grlist);
1.1 misho 1544: }
1.1.1.2 misho 1545: #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>