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