Annotation of embedaddon/sudo/plugins/sudoers/set_perms.c, revision 1.1.1.2
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();
94: 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;
160: 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;
185: grlist_addref(state->grlist);
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;
202: grlist_addref(state->grlist);
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;
239: grlist_addref(state->grlist);
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;
289: grlist_addref(state->grlist);
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: */
310: if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
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;
329: 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: }
406: 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;
461: 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;
! 487: grlist_addref(state->grlist);
! 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;
! 504: grlist_addref(state->grlist);
! 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;
! 549: grlist_addref(state->grlist);
! 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;
! 599: grlist_addref(state->grlist);
! 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.2 ! misho 620: if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
! 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;
! 648: grlist_addref(state->grlist);
! 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: }
! 798: grlist_delref(state->grlist);
! 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;
! 851: grlist_addref(state->grlist);
! 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;
884: grlist_addref(state->grlist);
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;
899: grlist_addref(state->grlist);
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;
931: grlist_addref(state->grlist);
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;
974: grlist_addref(state->grlist);
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: */
993: if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
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;
1009: 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: }
1085: 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;
1153: 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;
1170: grlist_addref(state->grlist);
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;
1185: grlist_addref(state->grlist);
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;
1217: grlist_addref(state->grlist);
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;
1260: grlist_addref(state->grlist);
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: */
1279: if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
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;
1295: 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: }
1370: 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;
1417: 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;
1426: 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;
1441: grlist_addref(state->grlist);
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;
! 1466: 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: }
1508: grlist_delref(state->grlist);
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) {
1529: 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
1537: grlist = get_group_list(pw);
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>