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