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