2 * Copyright (c) 1994-1996,1998-2011 Todd C. Miller <Todd.Miller@courtesan.com>
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.
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.
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.
23 #include <sys/types.h>
24 #include <sys/param.h>
34 #endif /* STDC_HEADERS */
37 #endif /* HAVE_STRING_H */
40 #endif /* HAVE_STRINGS_H */
43 #endif /* HAVE_UNISTD_H */
56 #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
57 static struct group_list *runas_setgroups(void);
61 * We keep track of the current permisstions and use a stack to restore
62 * the old permissions. A depth of 16 is overkill.
67 #if defined(HAVE_SETRESUID) || defined(ID_SAVED)
72 #if defined(HAVE_SETRESUID) || defined(ID_SAVED)
75 struct group_list *grlist;
78 #define PERM_STACK_MAX 16
79 static struct perm_state perm_stack[PERM_STACK_MAX];
80 static int perm_stack_depth = 0;
83 #define ID(x) (state->x == ostate->x ? -1 : state->x)
85 #define OID(x) (ostate->x == state->x ? -1 : ostate->x)
90 debug_decl(rewind_perms, SUDO_DEBUG_PERMS)
92 while (perm_stack_depth > 1)
94 grlist_delref(perm_stack[0].grlist);
99 #if defined(HAVE_SETRESUID)
101 #define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid || state->suid != ostate->suid)
102 #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid || state->sgid != ostate->sgid)
105 * Set real and effective and saved uids and gids based on perm.
106 * We always retain a saved uid of 0 unless we are headed for an exec().
107 * We only flip the effective gid since it only changes for PERM_SUDOERS.
108 * This version of set_perms() works fine with the "stay_setuid" option.
113 struct perm_state *state, *ostate = NULL;
116 debug_decl(set_perms, SUDO_DEBUG_PERMS)
118 noexit = ISSET(perm, PERM_NOEXIT);
119 CLR(perm, PERM_MASK);
121 if (perm_stack_depth == PERM_STACK_MAX) {
122 strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
127 state = &perm_stack[perm_stack_depth];
128 if (perm != PERM_INITIAL) {
129 if (perm_stack_depth == 0) {
130 strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
134 ostate = &perm_stack[perm_stack_depth - 1];
139 /* Stash initial state */
140 #ifdef HAVE_GETRESUID
141 if (getresuid(&state->ruid, &state->euid, &state->suid)) {
142 strlcpy(errbuf, "PERM_INITIAL: getresuid", sizeof(errbuf));
146 if (getresgid(&state->rgid, &state->egid, &state->sgid)) {
147 strlcpy(errbuf, "PERM_INITIAL: getresgid", sizeof(errbuf));
151 state->ruid = getuid();
152 state->euid = geteuid();
153 state->suid = state->euid; /* in case we are setuid */
155 state->rgid = getgid();
156 state->egid = getegid();
157 state->sgid = state->egid; /* in case we are setgid */
159 state->grlist = user_group_list;
160 grlist_addref(state->grlist);
161 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
162 "ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
163 __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
164 (int)state->rgid, (int)state->egid, (int)state->sgid);
168 state->ruid = ROOT_UID;
169 state->euid = ROOT_UID;
170 state->suid = ROOT_UID;
171 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
172 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
173 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
174 (int)state->ruid, (int)state->euid, (int)state->suid);
175 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
176 snprintf(errbuf, sizeof(errbuf),
177 "PERM_ROOT: setresuid(%d, %d, %d)",
178 ID(ruid), ID(euid), ID(suid));
181 state->rgid = ostate->rgid;
182 state->egid = ostate->egid;
183 state->sgid = ostate->sgid;
184 state->grlist = ostate->grlist;
185 grlist_addref(state->grlist);
189 state->rgid = ostate->rgid;
190 state->egid = user_gid;
191 state->sgid = ostate->sgid;
192 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
193 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
194 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
195 (int)state->rgid, (int)state->egid, (int)state->sgid);
196 if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
197 snprintf(errbuf, sizeof(errbuf), "PERM_USER: setresgid(%d, %d, %d)",
198 ID(rgid), ID(egid), ID(sgid));
201 state->grlist = user_group_list;
202 grlist_addref(state->grlist);
203 if (state->grlist != ostate->grlist) {
204 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
205 strlcpy(errbuf, "PERM_USER: setgroups", sizeof(errbuf));
209 state->ruid = user_uid;
210 state->euid = user_uid;
211 state->suid = ROOT_UID;
212 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
213 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
214 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
215 (int)state->ruid, (int)state->euid, (int)state->suid);
216 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
217 snprintf(errbuf, sizeof(errbuf), "PERM_USER: setresuid(%d, %d, %d)",
218 ID(ruid), ID(euid), ID(suid));
224 /* headed for exec() */
225 state->rgid = user_gid;
226 state->egid = user_gid;
227 state->sgid = user_gid;
228 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
229 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
230 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
231 (int)state->rgid, (int)state->egid, (int)state->sgid);
232 if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
233 snprintf(errbuf, sizeof(errbuf),
234 "PERM_FULL_USER: setresgid(%d, %d, %d)",
235 ID(rgid), ID(egid), ID(sgid));
238 state->grlist = user_group_list;
239 grlist_addref(state->grlist);
240 if (state->grlist != ostate->grlist) {
241 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
242 strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
246 state->ruid = user_uid;
247 state->euid = user_uid;
248 state->suid = user_uid;
249 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
250 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
251 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
252 (int)state->ruid, (int)state->euid, (int)state->suid);
253 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
254 snprintf(errbuf, sizeof(errbuf),
255 "PERM_FULL_USER: setresuid(%d, %d, %d)",
256 ID(ruid), ID(euid), ID(suid));
262 state->rgid = ostate->rgid;
263 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
264 state->sgid = ostate->sgid;
265 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
266 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
267 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
268 (int)state->rgid, (int)state->egid, (int)state->sgid);
269 if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
270 strlcpy(errbuf, _("unable to change to runas gid"), sizeof(errbuf));
273 state->grlist = runas_setgroups();
274 state->ruid = ostate->ruid;
275 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
276 state->suid = ostate->suid;
277 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
278 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
279 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
280 (int)state->ruid, (int)state->euid, (int)state->suid);
281 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
282 strlcpy(errbuf, _("unable to change to runas uid"), sizeof(errbuf));
288 state->grlist = ostate->grlist;
289 grlist_addref(state->grlist);
291 /* assumes euid == ROOT_UID, ruid == user */
292 state->rgid = ostate->rgid;
293 state->egid = sudoers_gid;
294 state->sgid = ostate->sgid;
295 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
296 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
297 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
298 (int)state->rgid, (int)state->egid, (int)state->sgid);
299 if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
300 strlcpy(errbuf, _("unable to change to sudoers gid"), sizeof(errbuf));
304 state->ruid = ROOT_UID;
306 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
307 * we use a non-zero uid in order to avoid NFS lossage.
308 * Using uid 1 is a bit bogus but should work on all OS's.
310 if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
313 state->euid = sudoers_uid;
314 state->suid = ROOT_UID;
315 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
316 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
317 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
318 (int)state->ruid, (int)state->euid, (int)state->suid);
319 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
320 snprintf(errbuf, sizeof(errbuf),
321 "PERM_SUDOERS: setresuid(%d, %d, %d)",
322 ID(ruid), ID(euid), ID(suid));
328 state->grlist = ostate->grlist;
329 grlist_addref(state->grlist);
330 state->rgid = ostate->rgid;
331 state->egid = ostate->egid;
332 state->sgid = ostate->sgid;
333 state->ruid = ROOT_UID;
334 state->euid = timestamp_uid;
335 state->suid = ROOT_UID;
336 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
337 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
338 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
339 (int)state->ruid, (int)state->euid, (int)state->suid);
340 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
341 snprintf(errbuf, sizeof(errbuf),
342 "PERM_TIMESTAMP: setresuid(%d, %d, %d)",
343 ID(ruid), ID(euid), ID(suid));
350 debug_return_bool(1);
352 warningx("%s: %s", errbuf,
353 errno == EAGAIN ? _("too many processes") : strerror(errno));
355 debug_return_bool(0);
362 struct perm_state *state, *ostate;
363 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
365 if (perm_stack_depth < 2)
368 state = &perm_stack[perm_stack_depth - 1];
369 ostate = &perm_stack[perm_stack_depth - 2];
372 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d, %d] -> [%d, %d, %d]",
373 __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
374 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid);
375 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d, %d] -> [%d, %d, %d]",
376 __func__, (int)state->rgid, (int)state->egid, (int)state->sgid,
377 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid);
379 /* XXX - more cases here where euid != ruid */
380 if (OID(euid) == ROOT_UID) {
381 if (setresuid(-1, ROOT_UID, -1)) {
382 warning("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
383 (int)state->ruid, (int)state->euid, (int)state->suid,
388 if (setresuid(OID(ruid), OID(euid), OID(suid))) {
389 warning("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
390 (int)state->ruid, (int)state->euid, (int)state->suid,
391 (int)OID(ruid), (int)OID(euid), (int)OID(suid));
394 if (setresgid(OID(rgid), OID(egid), OID(sgid))) {
395 warning("setresgid() [%d, %d, %d] -> [%d, %d, %d]",
396 (int)state->rgid, (int)state->egid, (int)state->sgid,
397 (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
400 if (state->grlist != ostate->grlist) {
401 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
402 warning("setgroups()");
406 grlist_delref(state->grlist);
413 #elif defined(_AIX) && defined(ID_SAVED)
415 #define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid || state->suid != ostate->suid)
416 #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid || state->sgid != ostate->sgid)
419 * Set real and effective and saved uids and gids based on perm.
420 * We always retain a saved uid of 0 unless we are headed for an exec().
421 * We only flip the effective gid since it only changes for PERM_SUDOERS.
422 * This version of set_perms() works fine with the "stay_setuid" option.
427 struct perm_state *state, *ostate = NULL;
430 debug_decl(set_perms, SUDO_DEBUG_PERMS)
432 noexit = ISSET(perm, PERM_NOEXIT);
433 CLR(perm, PERM_MASK);
435 if (perm_stack_depth == PERM_STACK_MAX) {
436 strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
441 state = &perm_stack[perm_stack_depth];
442 if (perm != PERM_INITIAL) {
443 if (perm_stack_depth == 0) {
444 strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
448 ostate = &perm_stack[perm_stack_depth - 1];
453 /* Stash initial state */
454 state->ruid = getuidx(ID_REAL);
455 state->euid = getuidx(ID_EFFECTIVE);
456 state->suid = getuidx(ID_SAVED);
457 state->rgid = getgidx(ID_REAL);
458 state->egid = getgidx(ID_EFFECTIVE);
459 state->sgid = getgidx(ID_SAVED);
460 state->grlist = user_group_list;
461 grlist_addref(state->grlist);
462 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
463 "ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
464 __func__, (unsigned int)state->ruid, (unsigned int)state->euid,
465 (unsigned int)state->suid, (unsigned int)state->rgid,
466 (unsigned int)state->egid, (unsigned int)state->sgid);
470 state->ruid = ROOT_UID;
471 state->euid = ROOT_UID;
472 state->suid = ROOT_UID;
473 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
474 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
475 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
476 (int)state->ruid, (int)state->euid, (int)state->suid);
477 if (UID_CHANGED && setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
478 snprintf(errbuf, sizeof(errbuf),
479 "PERM_ROOT: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
483 state->rgid = ostate->rgid;
484 state->egid = ostate->egid;
485 state->sgid = ostate->sgid;
486 state->grlist = ostate->grlist;
487 grlist_addref(state->grlist);
491 state->rgid = ostate->rgid;
492 state->egid = user_gid;
493 state->sgid = ostate->sgid;
494 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
495 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
496 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
497 (int)state->rgid, (int)state->egid, (int)state->sgid);
498 if (GID_CHANGED && setgidx(ID_EFFECTIVE, user_gid)) {
499 snprintf(errbuf, sizeof(errbuf),
500 "PERM_USER: setgidx(ID_EFFECTIVE, %d)", user_gid);
503 state->grlist = user_group_list;
504 grlist_addref(state->grlist);
505 if (state->grlist != ostate->grlist) {
506 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
507 strlcpy(errbuf, "PERM_USER: setgroups", sizeof(errbuf));
511 state->ruid = user_uid;
512 state->euid = user_uid;
513 state->suid = ROOT_UID;
514 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
515 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
516 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
517 (int)state->ruid, (int)state->euid, (int)state->suid);
518 if (ostate->euid != ROOT_UID || ostate->suid != ROOT_UID) {
519 if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
520 snprintf(errbuf, sizeof(errbuf),
521 "PERM_USER: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
526 if (setuidx(ID_EFFECTIVE|ID_REAL, user_uid)) {
527 snprintf(errbuf, sizeof(errbuf),
528 "PERM_USER: setuidx(ID_EFFECTIVE|ID_REAL, %d)", user_uid);
534 /* headed for exec() */
535 state->rgid = user_gid;
536 state->egid = user_gid;
537 state->sgid = user_gid;
538 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
539 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
540 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
541 (int)state->rgid, (int)state->egid, (int)state->sgid);
542 if (GID_CHANGED && setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, user_gid)) {
543 snprintf(errbuf, sizeof(errbuf),
544 "PERM_FULL_USER: setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
548 state->grlist = user_group_list;
549 grlist_addref(state->grlist);
550 if (state->grlist != ostate->grlist) {
551 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
552 strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
556 state->ruid = user_uid;
557 state->euid = user_uid;
558 state->suid = user_uid;
559 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
560 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
561 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
562 (int)state->ruid, (int)state->euid, (int)state->suid);
563 if (UID_CHANGED && setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, user_uid)) {
564 snprintf(errbuf, sizeof(errbuf),
565 "PERM_FULL_USER: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
572 state->rgid = ostate->rgid;
573 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
574 state->sgid = ostate->sgid;
575 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
576 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
577 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
578 (int)state->rgid, (int)state->egid, (int)state->sgid);
579 if (GID_CHANGED && setgidx(ID_EFFECTIVE, state->egid)) {
580 strlcpy(errbuf, _("unable to change to runas gid"), sizeof(errbuf));
583 state->grlist = runas_setgroups();
584 state->ruid = ostate->ruid;
585 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
586 state->suid = ostate->suid;
587 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
588 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
589 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
590 (int)state->ruid, (int)state->euid, (int)state->suid);
591 if (UID_CHANGED && setuidx(ID_EFFECTIVE, state->euid)) {
592 strlcpy(errbuf, _("unable to change to runas uid"), sizeof(errbuf));
598 state->grlist = ostate->grlist;
599 grlist_addref(state->grlist);
601 /* assume euid == ROOT_UID, ruid == user */
602 state->rgid = ostate->rgid;
603 state->egid = sudoers_gid;
604 state->sgid = ostate->sgid;
605 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
606 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
607 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
608 (int)state->rgid, (int)state->egid, (int)state->sgid);
609 if (GID_CHANGED && setgidx(ID_EFFECTIVE, sudoers_gid)) {
610 strlcpy(errbuf, _("unable to change to sudoers gid"), sizeof(errbuf));
614 state->ruid = ROOT_UID;
616 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
617 * we use a non-zero uid in order to avoid NFS lossage.
618 * Using uid 1 is a bit bogus but should work on all OS's.
620 if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
623 state->euid = sudoers_uid;
624 state->suid = ROOT_UID;
625 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
626 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
627 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
628 (int)state->ruid, (int)state->euid, (int)state->suid);
630 if (ostate->ruid != ROOT_UID || ostate->suid != ROOT_UID) {
631 if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
632 snprintf(errbuf, sizeof(errbuf),
633 "PERM_SUDOERS: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
638 if (setuidx(ID_EFFECTIVE, state->euid)) {
639 snprintf(errbuf, sizeof(errbuf),
640 "PERM_SUDOERS: setuidx(ID_EFFECTIVE, %d)", sudoers_uid);
647 state->grlist = ostate->grlist;
648 grlist_addref(state->grlist);
649 state->rgid = ostate->rgid;
650 state->egid = ostate->egid;
651 state->sgid = ostate->sgid;
652 state->ruid = ROOT_UID;
653 state->euid = timestamp_uid;
654 state->suid = ROOT_UID;
655 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
656 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
657 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
658 (int)state->ruid, (int)state->euid, (int)state->suid);
660 if (ostate->ruid != ROOT_UID || ostate->suid != ROOT_UID) {
661 if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
662 snprintf(errbuf, sizeof(errbuf),
663 "PERM_TIMESTAMP: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
668 if (setuidx(ID_EFFECTIVE, timestamp_uid)) {
669 snprintf(errbuf, sizeof(errbuf),
670 "PERM_TIMESTAMP: setuidx(ID_EFFECTIVE, %d)", timestamp_uid);
678 debug_return_bool(1);
680 warningx("%s: %s", errbuf,
681 errno == EAGAIN ? _("too many processes") : strerror(errno));
683 debug_return_bool(0);
690 struct perm_state *state, *ostate;
691 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
693 if (perm_stack_depth < 2)
696 state = &perm_stack[perm_stack_depth - 1];
697 ostate = &perm_stack[perm_stack_depth - 2];
700 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d, %d] -> [%d, %d, %d]",
701 __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
702 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid);
703 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d, %d] -> [%d, %d, %d]",
704 __func__, (int)state->rgid, (int)state->egid, (int)state->sgid,
705 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid);
707 if (OID(ruid) != -1 || OID(euid) != -1 || OID(suid) != -1) {
708 if (OID(euid) == ROOT_UID) {
709 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: setuidx(ID_EFFECTIVE, %d)",
711 if (setuidx(ID_EFFECTIVE, ROOT_UID)) {
712 warning("setuidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
713 (int)state->ruid, (int)state->euid, (int)state->suid,
718 if (OID(ruid) == OID(euid) && OID(euid) == OID(suid)) {
719 sudo_debug_printf(SUDO_DEBUG_INFO,
720 "%s: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
721 __func__, OID(ruid));
722 if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, OID(ruid))) {
723 warning("setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED) [%d, %d, %d] -> [%d, %d, %d]",
724 (int)state->ruid, (int)state->euid, (int)state->suid,
725 (int)OID(ruid), (int)OID(euid), (int)OID(suid));
728 } else if (OID(ruid) == -1 && OID(suid) == -1) {
729 /* May have already changed euid to ROOT_UID above. */
730 if (OID(euid) != ROOT_UID) {
731 sudo_debug_printf(SUDO_DEBUG_INFO,
732 "%s: setuidx(ID_EFFECTIVE, %d)", __func__, OID(euid));
733 if (setuidx(ID_EFFECTIVE, OID(euid))) {
734 warning("setuidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
735 (int)state->ruid, (int)state->euid, (int)state->suid,
736 (int)OID(ruid), (int)OID(euid), (int)OID(suid));
740 } else if (OID(suid) == -1) {
741 /* Cannot set the real uid alone. */
742 sudo_debug_printf(SUDO_DEBUG_INFO,
743 "%s: setuidx(ID_REAL|ID_EFFECTIVE, %d)", __func__, OID(ruid));
744 if (setuidx(ID_REAL|ID_EFFECTIVE, OID(ruid))) {
745 warning("setuidx(ID_REAL|ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
746 (int)state->ruid, (int)state->euid, (int)state->suid,
747 (int)OID(ruid), (int)OID(euid), (int)OID(suid));
750 /* Restore the effective euid if it doesn't match the ruid. */
751 if (OID(euid) != OID(ruid)) {
752 sudo_debug_printf(SUDO_DEBUG_INFO,
753 "%s: setuidx(ID_EFFECTIVE, %d)", __func__, ostate->euid);
754 if (setuidx(ID_EFFECTIVE, ostate->euid)) {
755 warning("setuidx(ID_EFFECTIVE, %d)", ostate->euid);
761 if (OID(rgid) != -1 || OID(egid) != -1 || OID(sgid) != -1) {
762 if (OID(rgid) == OID(egid) && OID(egid) == OID(sgid)) {
763 sudo_debug_printf(SUDO_DEBUG_INFO,
764 "%s: setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
765 __func__, OID(rgid));
766 if (setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, OID(rgid))) {
767 warning("setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED) [%d, %d, %d] -> [%d, %d, %d]",
768 (int)state->rgid, (int)state->egid, (int)state->sgid,
769 (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
772 } else if (OID(rgid) == -1 && OID(sgid) == -1) {
773 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: setgidx(ID_EFFECTIVE, %d)",
774 __func__, OID(egid));
775 if (setgidx(ID_EFFECTIVE, OID(egid))) {
776 warning("setgidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
777 (int)state->rgid, (int)state->egid, (int)state->sgid,
778 (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
781 } else if (OID(sgid) == -1) {
782 sudo_debug_printf(SUDO_DEBUG_INFO,
783 "%s: setgidx(ID_EFFECTIVE|ID_REAL, %d)", __func__, OID(rgid));
784 if (setgidx(ID_REAL|ID_EFFECTIVE, OID(rgid))) {
785 warning("setgidx(ID_REAL|ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
786 (int)state->rgid, (int)state->egid, (int)state->sgid,
787 (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
792 if (state->grlist != ostate->grlist) {
793 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
794 warning("setgroups()");
798 grlist_delref(state->grlist);
805 #elif defined(HAVE_SETREUID)
807 #define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid)
808 #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid)
811 * Set real and effective and saved uids and gids based on perm.
812 * We always retain a saved uid of 0 unless we are headed for an exec().
813 * We only flip the effective gid since it only changes for PERM_SUDOERS.
814 * This version of set_perms() works fine with the "stay_setuid" option.
819 struct perm_state *state, *ostate = NULL;
822 debug_decl(set_perms, SUDO_DEBUG_PERMS)
824 noexit = ISSET(perm, PERM_NOEXIT);
825 CLR(perm, PERM_MASK);
827 if (perm_stack_depth == PERM_STACK_MAX) {
828 strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
833 state = &perm_stack[perm_stack_depth];
834 if (perm != PERM_INITIAL) {
835 if (perm_stack_depth == 0) {
836 strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
840 ostate = &perm_stack[perm_stack_depth - 1];
845 /* Stash initial state */
846 state->ruid = getuid();
847 state->euid = geteuid();
848 state->rgid = getgid();
849 state->egid = getegid();
850 state->grlist = user_group_list;
851 grlist_addref(state->grlist);
852 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
853 "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
854 (int)state->ruid, (int)state->euid,
855 (int)state->rgid, (int)state->egid);
859 state->ruid = ROOT_UID;
860 state->euid = ROOT_UID;
861 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
862 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
863 (int)ostate->euid, (int)state->ruid, (int)state->euid);
865 * setreuid(0, 0) may fail on some systems if euid is not already 0.
867 if (ostate->euid != ROOT_UID) {
868 if (setreuid(-1, ROOT_UID)) {
869 snprintf(errbuf, sizeof(errbuf),
870 "PERM_ROOT: setreuid(-1, %d)", PERM_ROOT);
874 if (ostate->ruid != ROOT_UID) {
875 if (setreuid(ROOT_UID, -1)) {
876 snprintf(errbuf, sizeof(errbuf),
877 "PERM_ROOT: setreuid(%d, -1)", ROOT_UID);
881 state->rgid = ostate->rgid;
882 state->egid = ostate->rgid;
883 state->grlist = ostate->grlist;
884 grlist_addref(state->grlist);
888 state->rgid = ostate->rgid;
889 state->egid = user_gid;
890 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
891 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
892 (int)ostate->egid, (int)state->rgid, (int)state->egid);
893 if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
894 snprintf(errbuf, sizeof(errbuf),
895 "PERM_USER: setregid(%d, %d)", ID(rgid), ID(egid));
898 state->grlist = user_group_list;
899 grlist_addref(state->grlist);
900 if (state->grlist != ostate->grlist) {
901 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
902 strlcpy(errbuf, "PERM_USER: setgroups", sizeof(errbuf));
906 state->ruid = ROOT_UID;
907 state->euid = user_uid;
908 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
909 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
910 (int)ostate->euid, (int)state->ruid, (int)state->euid);
911 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
912 snprintf(errbuf, sizeof(errbuf),
913 "PERM_USER: setreuid(%d, %d)", ID(ruid), ID(euid));
919 /* headed for exec() */
920 state->rgid = user_gid;
921 state->egid = user_gid;
922 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
923 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
924 (int)ostate->egid, (int)state->rgid, (int)state->egid);
925 if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
926 snprintf(errbuf, sizeof(errbuf),
927 "PERM_FULL_USER: setregid(%d, %d)", ID(rgid), ID(egid));
930 state->grlist = user_group_list;
931 grlist_addref(state->grlist);
932 if (state->grlist != ostate->grlist) {
933 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
934 strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
938 state->ruid = user_uid;
939 state->euid = user_uid;
940 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
941 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
942 (int)ostate->euid, (int)state->ruid, (int)state->euid);
943 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
944 snprintf(errbuf, sizeof(errbuf),
945 "PERM_FULL_USER: setreuid(%d, %d)", ID(ruid), ID(euid));
951 state->rgid = ostate->rgid;
952 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
953 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
954 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
955 (int)ostate->egid, (int)state->rgid, (int)state->egid);
956 if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
957 strlcpy(errbuf, _("unable to change to runas gid"), sizeof(errbuf));
960 state->grlist = runas_setgroups();
961 state->ruid = ROOT_UID;
962 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
963 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
964 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
965 (int)ostate->euid, (int)state->ruid, (int)state->euid);
966 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
967 strlcpy(errbuf, _("unable to change to runas uid"), sizeof(errbuf));
973 state->grlist = ostate->grlist;
974 grlist_addref(state->grlist);
976 /* assume euid == ROOT_UID, ruid == user */
977 state->rgid = ostate->rgid;
978 state->egid = sudoers_gid;
979 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
980 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
981 (int)ostate->egid, (int)state->rgid, (int)state->egid);
982 if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
983 strlcpy(errbuf, _("unable to change to sudoers gid"), sizeof(errbuf));
987 state->ruid = ROOT_UID;
989 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
990 * we use a non-zero uid in order to avoid NFS lossage.
991 * Using uid 1 is a bit bogus but should work on all OS's.
993 if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
996 state->euid = sudoers_uid;
997 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
998 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
999 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1000 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
1001 snprintf(errbuf, sizeof(errbuf),
1002 "PERM_SUDOERS: setreuid(%d, %d)", ID(ruid), ID(euid));
1007 case PERM_TIMESTAMP:
1008 state->grlist = ostate->grlist;
1009 grlist_addref(state->grlist);
1010 state->rgid = ostate->rgid;
1011 state->egid = ostate->egid;
1012 state->ruid = ROOT_UID;
1013 state->euid = timestamp_uid;
1014 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
1015 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1016 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1017 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
1018 snprintf(errbuf, sizeof(errbuf),
1019 "PERM_TIMESTAMP: setreuid(%d, %d)", ID(ruid), ID(euid));
1026 debug_return_bool(1);
1028 warningx("%s: %s", errbuf,
1029 errno == EAGAIN ? _("too many processes") : strerror(errno));
1031 debug_return_bool(0);
1038 struct perm_state *state, *ostate;
1039 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1041 if (perm_stack_depth < 2)
1044 state = &perm_stack[perm_stack_depth - 1];
1045 ostate = &perm_stack[perm_stack_depth - 2];
1048 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d] -> [%d, %d]",
1049 __func__, (int)state->ruid, (int)state->euid,
1050 (int)ostate->ruid, (int)ostate->euid);
1051 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d] -> [%d, %d]",
1052 __func__, (int)state->rgid, (int)state->egid,
1053 (int)ostate->rgid, (int)ostate->egid);
1056 * When changing euid to ROOT_UID, setreuid() may fail even if
1057 * the ruid is ROOT_UID so call setuid() first.
1059 if (OID(euid) == ROOT_UID) {
1060 /* setuid() may not set the saved ID unless the euid is ROOT_UID */
1061 if (ID(euid) != ROOT_UID)
1062 (void)setreuid(-1, ROOT_UID);
1063 if (setuid(ROOT_UID)) {
1064 warning("setuid() [%d, %d] -> %d)", (int)state->ruid,
1065 (int)state->euid, ROOT_UID);
1069 if (setreuid(OID(ruid), OID(euid))) {
1070 warning("setreuid() [%d, %d] -> [%d, %d]", (int)state->ruid,
1071 (int)state->euid, (int)OID(ruid), (int)OID(euid));
1074 if (setregid(OID(rgid), OID(egid))) {
1075 warning("setregid() [%d, %d] -> [%d, %d]", (int)state->rgid,
1076 (int)state->egid, (int)OID(rgid), (int)OID(egid));
1079 if (state->grlist != ostate->grlist) {
1080 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
1081 warning("setgroups()");
1085 grlist_delref(state->grlist);
1092 #elif defined(HAVE_SETEUID)
1094 #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid)
1097 * Set real and effective uids and gids based on perm.
1098 * We always retain a real or effective uid of ROOT_UID unless
1099 * we are headed for an exec().
1100 * This version of set_perms() works fine with the "stay_setuid" option.
1105 struct perm_state *state, *ostate = NULL;
1108 debug_decl(set_perms, SUDO_DEBUG_PERMS)
1110 noexit = ISSET(perm, PERM_NOEXIT);
1111 CLR(perm, PERM_MASK);
1113 if (perm_stack_depth == PERM_STACK_MAX) {
1114 strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
1119 state = &perm_stack[perm_stack_depth];
1120 if (perm != PERM_INITIAL) {
1121 if (perm_stack_depth == 0) {
1122 strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
1126 ostate = &perm_stack[perm_stack_depth - 1];
1130 * Since we only have setuid() and seteuid() and semantics
1131 * for these calls differ on various systems, we set
1132 * real and effective uids to ROOT_UID initially to be safe.
1134 if (perm != PERM_INITIAL) {
1135 if (ostate->euid != ROOT_UID && seteuid(ROOT_UID)) {
1136 snprintf(errbuf, sizeof(errbuf), "set_perms: seteuid(%d)", ROOT_UID);
1139 if (ostate->ruid != ROOT_UID && setuid(ROOT_UID)) {
1140 snprintf(errbuf, sizeof(errbuf), "set_perms: setuid(%d)", ROOT_UID);
1147 /* Stash initial state */
1148 state->ruid = getuid();
1149 state->euid = geteuid();
1150 state->rgid = getgid();
1151 state->egid = getegid();
1152 state->grlist = user_group_list;
1153 grlist_addref(state->grlist);
1154 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
1155 "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
1156 (int)state->ruid, (int)state->euid,
1157 (int)state->rgid, (int)state->egid);
1161 /* We already set ruid/euid above. */
1162 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
1163 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1164 (int)ostate->euid, ROOT_UID, ROOT_UID);
1165 state->ruid = ROOT_UID;
1166 state->euid = ROOT_UID;
1167 state->rgid = ostate->rgid;
1168 state->egid = ostate->egid;
1169 state->grlist = ostate->grlist;
1170 grlist_addref(state->grlist);
1174 state->egid = user_gid;
1175 state->rgid = ostate->rgid;
1176 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
1177 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1178 (int)ostate->egid, (int)state->rgid, (int)state->egid);
1179 if (GID_CHANGED && setegid(user_gid)) {
1180 snprintf(errbuf, sizeof(errbuf),
1181 "PERM_USER: setegid(%d)", user_gid);
1184 state->grlist = user_group_list;
1185 grlist_addref(state->grlist);
1186 if (state->grlist != ostate->grlist) {
1187 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1188 strlcpy(errbuf, "PERM_USER: setgroups", sizeof(errbuf));
1192 state->ruid = ROOT_UID;
1193 state->euid = user_uid;
1194 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
1195 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1196 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1197 if (seteuid(user_uid)) {
1198 snprintf(errbuf, sizeof(errbuf),
1199 "PERM_USER: seteuid(%d)", user_uid);
1204 case PERM_FULL_USER:
1205 /* headed for exec() */
1206 state->rgid = user_gid;
1207 state->egid = user_gid;
1208 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
1209 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1210 (int)ostate->egid, (int)state->rgid, (int)state->egid);
1211 if (GID_CHANGED && setgid(user_gid)) {
1212 snprintf(errbuf, sizeof(errbuf),
1213 "PERM_FULL_USER: setgid(%d)", user_gid);
1216 state->grlist = user_group_list;
1217 grlist_addref(state->grlist);
1218 if (state->grlist != ostate->grlist) {
1219 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1220 strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
1224 state->ruid = user_uid;
1225 state->euid = user_uid;
1226 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
1227 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1228 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1229 if (setuid(user_uid)) {
1230 snprintf(errbuf, sizeof(errbuf),
1231 "PERM_FULL_USER: setuid(%d)", user_uid);
1237 state->rgid = ostate->rgid;
1238 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
1239 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
1240 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1241 (int)ostate->egid, (int)state->rgid, (int)state->egid);
1242 if (GID_CHANGED && setegid(state->egid)) {
1243 strlcpy(errbuf, _("unable to change to runas gid"), sizeof(errbuf));
1246 state->grlist = runas_setgroups();
1247 state->ruid = ostate->ruid;
1248 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
1249 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
1250 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1251 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1252 if (seteuid(state->euid)) {
1253 strlcpy(errbuf, _("unable to change to runas uid"), sizeof(errbuf));
1259 state->grlist = ostate->grlist;
1260 grlist_addref(state->grlist);
1262 /* assume euid == ROOT_UID, ruid == user */
1263 state->rgid = ostate->rgid;
1264 state->egid = sudoers_gid;
1265 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
1266 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1267 (int)ostate->egid, (int)state->rgid, (int)state->egid);
1268 if (GID_CHANGED && setegid(sudoers_gid)) {
1269 strlcpy(errbuf, _("unable to change to sudoers gid"), sizeof(errbuf));
1273 state->ruid = ROOT_UID;
1275 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
1276 * we use a non-zero uid in order to avoid NFS lossage.
1277 * Using uid 1 is a bit bogus but should work on all OS's.
1279 if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
1282 state->euid = sudoers_uid;
1283 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
1284 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1285 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1286 if (seteuid(state->euid)) {
1287 snprintf(errbuf, sizeof(errbuf),
1288 "PERM_SUDOERS: seteuid(%d)", state->euid);
1293 case PERM_TIMESTAMP:
1294 state->grlist = ostate->grlist;
1295 grlist_addref(state->grlist);
1296 state->rgid = ostate->rgid;
1297 state->egid = ostate->egid;
1298 state->ruid = ROOT_UID;
1299 state->euid = timestamp_uid;
1300 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
1301 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1302 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1303 if (seteuid(timestamp_uid)) {
1304 snprintf(errbuf, sizeof(errbuf),
1305 "PERM_TIMESTAMP: seteuid(%d)", timestamp_uid);
1312 debug_return_bool(1);
1314 warningx("%s: %s", errbuf,
1315 errno == EAGAIN ? _("too many processes") : strerror(errno));
1317 debug_return_bool(0);
1324 struct perm_state *state, *ostate;
1325 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1327 if (perm_stack_depth < 2)
1330 state = &perm_stack[perm_stack_depth - 1];
1331 ostate = &perm_stack[perm_stack_depth - 2];
1334 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d] -> [%d, %d]",
1335 __func__, (int)state->ruid, (int)state->euid,
1336 (int)ostate->ruid, (int)ostate->euid);
1337 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d] -> [%d, %d]",
1338 __func__, (int)state->rgid, (int)state->egid,
1339 (int)ostate->rgid, (int)ostate->egid);
1342 * Since we only have setuid() and seteuid() and semantics
1343 * for these calls differ on various systems, we set
1344 * real and effective uids to ROOT_UID initially to be safe.
1346 if (seteuid(ROOT_UID)) {
1347 warningx("seteuid() [%d] -> [%d]", (int)state->euid, ROOT_UID);
1350 if (setuid(ROOT_UID)) {
1351 warningx("setuid() [%d, %d] -> [%d, %d]", (int)state->ruid, ROOT_UID,
1352 ROOT_UID, ROOT_UID);
1356 if (OID(egid) != -1 && setegid(ostate->egid)) {
1357 warning("setegid(%d)", (int)ostate->egid);
1360 if (state->grlist != ostate->grlist) {
1361 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
1362 warning("setgroups()");
1366 if (OID(euid) != -1 && seteuid(ostate->euid)) {
1367 warning("seteuid(%d)", ostate->euid);
1370 grlist_delref(state->grlist);
1377 #else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
1380 * Set uids and gids based on perm via setuid() and setgid().
1381 * NOTE: does not support the "stay_setuid" or timestampowner options.
1382 * Also, sudoers_uid and sudoers_gid are not used.
1387 struct perm_state *state, *ostate = NULL;
1390 debug_decl(set_perms, SUDO_DEBUG_PERMS)
1392 noexit = ISSET(perm, PERM_NOEXIT);
1393 CLR(perm, PERM_MASK);
1395 if (perm_stack_depth == PERM_STACK_MAX) {
1396 strlcpy(errbuf, _("perm stack overflow"), sizeof(errbuf));
1401 state = &perm_stack[perm_stack_depth];
1402 if (perm != PERM_INITIAL) {
1403 if (perm_stack_depth == 0) {
1404 strlcpy(errbuf, _("perm stack underflow"), sizeof(errbuf));
1408 ostate = &perm_stack[perm_stack_depth - 1];
1413 /* Stash initial state */
1414 state->ruid = geteuid() == ROOT_UID ? ROOT_UID : getuid();
1415 state->rgid = getgid();
1416 state->grlist = user_group_list;
1417 grlist_addref(state->grlist);
1418 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
1419 "ruid: %d, rgid: %d", __func__, (int)state->ruid, (int)state->rgid);
1423 state->ruid = ROOT_UID;
1424 state->rgid = ostate->rgid;
1425 state->grlist = ostate->grlist;
1426 grlist_addref(state->grlist);
1427 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
1428 "[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
1429 if (setuid(ROOT_UID)) {
1430 snprintf(errbuf, sizeof(errbuf), "PERM_ROOT: setuid(%d)", ROOT_UID);
1435 case PERM_FULL_USER:
1436 state->rgid = user_gid;
1437 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
1438 "[%d] -> [%d]", __func__, (int)ostate->rgid, (int)state->rgid);
1439 (void) setgid(user_gid);
1440 state->grlist = user_group_list;
1441 grlist_addref(state->grlist);
1442 if (state->grlist != ostate->grlist) {
1443 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1444 strlcpy(errbuf, "PERM_FULL_USER: setgroups", sizeof(errbuf));
1448 state->ruid = user_uid;
1449 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
1450 "[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
1451 if (setuid(user_uid)) {
1452 snprintf(errbuf, sizeof(errbuf),
1453 "PERM_FULL_USER: setuid(%d)", user_uid);
1461 case PERM_TIMESTAMP:
1462 /* Unsupported since we can't set euid. */
1463 state->ruid = ostate->ruid;
1464 state->rgid = ostate->rgid;
1465 state->grlist = ostate->grlist;
1466 grlist_addref(state->grlist);
1471 debug_return_bool(1);
1473 warningx("%s: %s", errbuf,
1474 errno == EAGAIN ? _("too many processes") : strerror(errno));
1476 debug_return_bool(0);
1483 struct perm_state *state, *ostate;
1484 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1486 if (perm_stack_depth < 2)
1489 state = &perm_stack[perm_stack_depth - 1];
1490 ostate = &perm_stack[perm_stack_depth - 2];
1493 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d] -> [%d]",
1494 __func__, (int)state->ruid, (int)ostate->ruid);
1495 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d] -> [%d]",
1496 __func__, (int)state->rgid, (int)ostate->rgid);
1498 if (OID(rgid) != -1 && setgid(ostate->rgid)) {
1499 warning("setgid(%d)", (int)ostate->rgid);
1502 if (state->grlist != ostate->grlist) {
1503 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
1504 warning("setgroups()");
1508 grlist_delref(state->grlist);
1509 if (OID(ruid) != -1 && setuid(ostate->ruid)) {
1510 warning("setuid(%d)", (int)ostate->ruid);
1518 #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
1520 #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
1521 static struct group_list *
1522 runas_setgroups(void)
1525 struct group_list *grlist;
1526 debug_decl(runas_setgroups, SUDO_DEBUG_PERMS)
1528 if (def_preserve_groups) {
1529 grlist_addref(user_group_list);
1530 debug_return_ptr(user_group_list);
1533 pw = runas_pw ? runas_pw : sudo_user.pw;
1534 #ifdef HAVE_SETAUTHDB
1535 aix_setauthdb(pw->pw_name);
1537 grlist = get_group_list(pw);
1538 #ifdef HAVE_SETAUTHDB
1539 aix_restoreauthdb();
1541 if (sudo_setgroups(grlist->ngids, grlist->gids) < 0)
1542 log_fatal(USE_ERRNO|MSG_ONLY, _("unable to set runas group vector"));
1543 debug_return_ptr(grlist);
1545 #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */