2 * Copyright (c) 1994-1996,1998-2013 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>
33 #endif /* STDC_HEADERS */
36 #endif /* HAVE_STRING_H */
39 #endif /* HAVE_STRINGS_H */
42 #endif /* HAVE_UNISTD_H */
55 #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
56 static struct group_list *runas_setgroups(void);
60 * We keep track of the current permisstions and use a stack to restore
61 * the old permissions. A depth of 16 is overkill.
66 #if defined(HAVE_SETRESUID) || defined(ID_SAVED)
71 #if defined(HAVE_SETRESUID) || defined(ID_SAVED)
74 struct group_list *grlist;
77 #define PERM_STACK_MAX 16
78 static struct perm_state perm_stack[PERM_STACK_MAX];
79 static int perm_stack_depth = 0;
82 #define ID(x) (state->x == ostate->x ? -1 : state->x)
84 #define OID(x) (ostate->x == state->x ? -1 : ostate->x)
89 debug_decl(rewind_perms, SUDO_DEBUG_PERMS)
91 while (perm_stack_depth > 1)
93 sudo_grlist_delref(perm_stack[0].grlist);
98 #if defined(HAVE_SETRESUID)
100 #define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid || state->suid != ostate->suid)
101 #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid || state->sgid != ostate->sgid)
104 * Set real and effective and saved uids and gids based on perm.
105 * We always retain a saved uid of 0 unless we are headed for an exec().
106 * We only flip the effective gid since it only changes for PERM_SUDOERS.
107 * This version of set_perms() works fine with the "stay_setuid" option.
112 struct perm_state *state, *ostate = NULL;
114 const char *errstr = errbuf;
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 errstr = N_("perm stack overflow");
127 state = &perm_stack[perm_stack_depth];
128 if (perm != PERM_INITIAL) {
129 if (perm_stack_depth == 0) {
130 errstr = N_("perm stack underflow");
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 errstr = "PERM_INITIAL: getresuid";
146 if (getresgid(&state->rgid, &state->egid, &state->sgid)) {
147 errstr = "PERM_INITIAL: getresgid";
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 sudo_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 = ROOT_GID;
183 state->sgid = ostate->sgid;
184 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
185 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
186 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
187 (int)state->rgid, (int)state->egid, (int)state->sgid);
188 if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
189 errstr = N_("unable to change to root gid");
192 state->grlist = ostate->grlist;
193 sudo_grlist_addref(state->grlist);
197 state->rgid = ostate->rgid;
198 state->egid = user_gid;
199 state->sgid = ostate->sgid;
200 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
201 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
202 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
203 (int)state->rgid, (int)state->egid, (int)state->sgid);
204 if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
205 snprintf(errbuf, sizeof(errbuf), "PERM_USER: setresgid(%d, %d, %d)",
206 ID(rgid), ID(egid), ID(sgid));
209 state->grlist = user_group_list;
210 sudo_grlist_addref(state->grlist);
211 if (state->grlist != ostate->grlist) {
212 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
213 errstr = "PERM_USER: setgroups";
217 state->ruid = user_uid;
218 state->euid = user_uid;
219 state->suid = ROOT_UID;
220 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
221 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
222 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
223 (int)state->ruid, (int)state->euid, (int)state->suid);
224 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
225 snprintf(errbuf, sizeof(errbuf), "PERM_USER: setresuid(%d, %d, %d)",
226 ID(ruid), ID(euid), ID(suid));
232 /* headed for exec() */
233 state->rgid = user_gid;
234 state->egid = user_gid;
235 state->sgid = user_gid;
236 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
237 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
238 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
239 (int)state->rgid, (int)state->egid, (int)state->sgid);
240 if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
241 snprintf(errbuf, sizeof(errbuf),
242 "PERM_FULL_USER: setresgid(%d, %d, %d)",
243 ID(rgid), ID(egid), ID(sgid));
246 state->grlist = user_group_list;
247 sudo_grlist_addref(state->grlist);
248 if (state->grlist != ostate->grlist) {
249 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
250 errstr = "PERM_FULL_USER: setgroups";
254 state->ruid = user_uid;
255 state->euid = user_uid;
256 state->suid = user_uid;
257 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
258 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
259 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
260 (int)state->ruid, (int)state->euid, (int)state->suid);
261 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
262 snprintf(errbuf, sizeof(errbuf),
263 "PERM_FULL_USER: setresuid(%d, %d, %d)",
264 ID(ruid), ID(euid), ID(suid));
270 state->rgid = ostate->rgid;
271 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
272 state->sgid = ostate->sgid;
273 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
274 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
275 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
276 (int)state->rgid, (int)state->egid, (int)state->sgid);
277 if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
278 errstr = N_("unable to change to runas gid");
281 state->grlist = runas_setgroups();
282 state->ruid = ostate->ruid;
283 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
284 state->suid = ostate->suid;
285 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
286 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
287 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
288 (int)state->ruid, (int)state->euid, (int)state->suid);
289 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
290 errstr = N_("unable to change to runas uid");
296 state->grlist = ostate->grlist;
297 sudo_grlist_addref(state->grlist);
299 /* assumes euid == ROOT_UID, ruid == user */
300 state->rgid = ostate->rgid;
301 state->egid = sudoers_gid;
302 state->sgid = ostate->sgid;
303 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
304 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
305 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
306 (int)state->rgid, (int)state->egid, (int)state->sgid);
307 if (GID_CHANGED && setresgid(ID(rgid), ID(egid), ID(sgid))) {
308 errstr = N_("unable to change to sudoers gid");
312 state->ruid = ROOT_UID;
314 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
315 * we use a non-zero uid in order to avoid NFS lossage.
316 * Using uid 1 is a bit bogus but should work on all OS's.
318 if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
321 state->euid = sudoers_uid;
322 state->suid = ROOT_UID;
323 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
324 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
325 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
326 (int)state->ruid, (int)state->euid, (int)state->suid);
327 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
328 snprintf(errbuf, sizeof(errbuf),
329 "PERM_SUDOERS: setresuid(%d, %d, %d)",
330 ID(ruid), ID(euid), ID(suid));
336 state->grlist = ostate->grlist;
337 sudo_grlist_addref(state->grlist);
338 state->rgid = ostate->rgid;
339 state->egid = ostate->egid;
340 state->sgid = ostate->sgid;
341 state->ruid = ROOT_UID;
342 state->euid = timestamp_uid;
343 state->suid = ROOT_UID;
344 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
345 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
346 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
347 (int)state->ruid, (int)state->euid, (int)state->suid);
348 if (UID_CHANGED && setresuid(ID(ruid), ID(euid), ID(suid))) {
349 snprintf(errbuf, sizeof(errbuf),
350 "PERM_TIMESTAMP: setresuid(%d, %d, %d)",
351 ID(ruid), ID(euid), ID(suid));
358 debug_return_bool(1);
360 warningx("%s: %s", _(errstr),
361 errno == EAGAIN ? _("too many processes") : strerror(errno));
363 debug_return_bool(0);
370 struct perm_state *state, *ostate;
371 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
373 if (perm_stack_depth < 2)
376 state = &perm_stack[perm_stack_depth - 1];
377 ostate = &perm_stack[perm_stack_depth - 2];
380 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d, %d] -> [%d, %d, %d]",
381 __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
382 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid);
383 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d, %d] -> [%d, %d, %d]",
384 __func__, (int)state->rgid, (int)state->egid, (int)state->sgid,
385 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid);
387 /* XXX - more cases here where euid != ruid */
388 if (OID(euid) == ROOT_UID) {
389 if (setresuid(-1, ROOT_UID, -1)) {
390 warning("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
391 (int)state->ruid, (int)state->euid, (int)state->suid,
396 if (setresuid(OID(ruid), OID(euid), OID(suid))) {
397 warning("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
398 (int)state->ruid, (int)state->euid, (int)state->suid,
399 (int)OID(ruid), (int)OID(euid), (int)OID(suid));
402 if (setresgid(OID(rgid), OID(egid), OID(sgid))) {
403 warning("setresgid() [%d, %d, %d] -> [%d, %d, %d]",
404 (int)state->rgid, (int)state->egid, (int)state->sgid,
405 (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
408 if (state->grlist != ostate->grlist) {
409 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
410 warning("setgroups()");
414 sudo_grlist_delref(state->grlist);
421 #elif defined(_AIX) && defined(ID_SAVED)
423 #define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid || state->suid != ostate->suid)
424 #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid || state->sgid != ostate->sgid)
427 * Set real and effective and saved uids and gids based on perm.
428 * We always retain a saved uid of 0 unless we are headed for an exec().
429 * We only flip the effective gid since it only changes for PERM_SUDOERS.
430 * This version of set_perms() works fine with the "stay_setuid" option.
435 struct perm_state *state, *ostate = NULL;
437 const char *errstr = errbuf;
439 debug_decl(set_perms, SUDO_DEBUG_PERMS)
441 noexit = ISSET(perm, PERM_NOEXIT);
442 CLR(perm, PERM_MASK);
444 if (perm_stack_depth == PERM_STACK_MAX) {
445 errstr = N_("perm stack overflow");
450 state = &perm_stack[perm_stack_depth];
451 if (perm != PERM_INITIAL) {
452 if (perm_stack_depth == 0) {
453 errstr = N_("perm stack underflow");
457 ostate = &perm_stack[perm_stack_depth - 1];
462 /* Stash initial state */
463 state->ruid = getuidx(ID_REAL);
464 state->euid = getuidx(ID_EFFECTIVE);
465 state->suid = getuidx(ID_SAVED);
466 state->rgid = getgidx(ID_REAL);
467 state->egid = getgidx(ID_EFFECTIVE);
468 state->sgid = getgidx(ID_SAVED);
469 state->grlist = user_group_list;
470 sudo_grlist_addref(state->grlist);
471 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
472 "ruid: %d, euid: %d, suid: %d, rgid: %d, egid: %d, sgid: %d",
473 __func__, (unsigned int)state->ruid, (unsigned int)state->euid,
474 (unsigned int)state->suid, (unsigned int)state->rgid,
475 (unsigned int)state->egid, (unsigned int)state->sgid);
479 state->ruid = ROOT_UID;
480 state->euid = ROOT_UID;
481 state->suid = ROOT_UID;
482 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
483 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
484 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
485 (int)state->ruid, (int)state->euid, (int)state->suid);
486 if (UID_CHANGED && setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
487 snprintf(errbuf, sizeof(errbuf),
488 "PERM_ROOT: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
492 state->rgid = ostate->rgid;
493 state->egid = ROOT_GID;
494 state->sgid = ostate->sgid;
495 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
496 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
497 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
498 (int)state->rgid, (int)state->egid, (int)state->sgid);
499 if (GID_CHANGED && setgidx(ID_EFFECTIVE, ROOT_GID)) {
500 errstr = N_("unable to change to root gid");
503 state->grlist = ostate->grlist;
504 sudo_grlist_addref(state->grlist);
508 state->rgid = ostate->rgid;
509 state->egid = user_gid;
510 state->sgid = ostate->sgid;
511 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
512 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
513 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
514 (int)state->rgid, (int)state->egid, (int)state->sgid);
515 if (GID_CHANGED && setgidx(ID_EFFECTIVE, user_gid)) {
516 snprintf(errbuf, sizeof(errbuf),
517 "PERM_USER: setgidx(ID_EFFECTIVE, %d)", user_gid);
520 state->grlist = user_group_list;
521 sudo_grlist_addref(state->grlist);
522 if (state->grlist != ostate->grlist) {
523 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
524 errstr = "PERM_USER: setgroups";
528 state->ruid = user_uid;
529 state->euid = user_uid;
530 state->suid = ROOT_UID;
531 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
532 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
533 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
534 (int)state->ruid, (int)state->euid, (int)state->suid);
535 if (ostate->euid != ROOT_UID || ostate->suid != ROOT_UID) {
536 if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
537 snprintf(errbuf, sizeof(errbuf),
538 "PERM_USER: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
543 if (setuidx(ID_EFFECTIVE|ID_REAL, user_uid)) {
544 snprintf(errbuf, sizeof(errbuf),
545 "PERM_USER: setuidx(ID_EFFECTIVE|ID_REAL, %d)", user_uid);
551 /* headed for exec() */
552 state->rgid = user_gid;
553 state->egid = user_gid;
554 state->sgid = user_gid;
555 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
556 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
557 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
558 (int)state->rgid, (int)state->egid, (int)state->sgid);
559 if (GID_CHANGED && setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, user_gid)) {
560 snprintf(errbuf, sizeof(errbuf),
561 "PERM_FULL_USER: setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
565 state->grlist = user_group_list;
566 sudo_grlist_addref(state->grlist);
567 if (state->grlist != ostate->grlist) {
568 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
569 errstr = "PERM_FULL_USER: setgroups";
573 state->ruid = user_uid;
574 state->euid = user_uid;
575 state->suid = user_uid;
576 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
577 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
578 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
579 (int)state->ruid, (int)state->euid, (int)state->suid);
580 if (UID_CHANGED && setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, user_uid)) {
581 snprintf(errbuf, sizeof(errbuf),
582 "PERM_FULL_USER: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
589 state->rgid = ostate->rgid;
590 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
591 state->sgid = ostate->sgid;
592 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
593 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
594 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
595 (int)state->rgid, (int)state->egid, (int)state->sgid);
596 if (GID_CHANGED && setgidx(ID_EFFECTIVE, state->egid)) {
597 errstr = N_("unable to change to runas gid");
600 state->grlist = runas_setgroups();
601 state->ruid = ostate->ruid;
602 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
603 state->suid = ostate->suid;
604 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
605 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
606 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
607 (int)state->ruid, (int)state->euid, (int)state->suid);
608 if (UID_CHANGED && setuidx(ID_EFFECTIVE, state->euid)) {
609 errstr = N_("unable to change to runas uid");
615 state->grlist = ostate->grlist;
616 sudo_grlist_addref(state->grlist);
618 /* assume euid == ROOT_UID, ruid == user */
619 state->rgid = ostate->rgid;
620 state->egid = sudoers_gid;
621 state->sgid = ostate->sgid;
622 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
623 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
624 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid,
625 (int)state->rgid, (int)state->egid, (int)state->sgid);
626 if (GID_CHANGED && setgidx(ID_EFFECTIVE, sudoers_gid)) {
627 errstr = N_("unable to change to sudoers gid");
631 state->ruid = ROOT_UID;
633 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
634 * we use a non-zero uid in order to avoid NFS lossage.
635 * Using uid 1 is a bit bogus but should work on all OS's.
637 if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
640 state->euid = sudoers_uid;
641 state->suid = ROOT_UID;
642 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
643 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
644 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
645 (int)state->ruid, (int)state->euid, (int)state->suid);
647 if (ostate->ruid != ROOT_UID || ostate->suid != ROOT_UID) {
648 if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
649 snprintf(errbuf, sizeof(errbuf),
650 "PERM_SUDOERS: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
655 if (setuidx(ID_EFFECTIVE, state->euid)) {
656 snprintf(errbuf, sizeof(errbuf),
657 "PERM_SUDOERS: setuidx(ID_EFFECTIVE, %d)", sudoers_uid);
664 state->grlist = ostate->grlist;
665 sudo_grlist_addref(state->grlist);
666 state->rgid = ostate->rgid;
667 state->egid = ostate->egid;
668 state->sgid = ostate->sgid;
669 state->ruid = ROOT_UID;
670 state->euid = timestamp_uid;
671 state->suid = ROOT_UID;
672 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
673 "[%d, %d, %d] -> [%d, %d, %d]", __func__,
674 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid,
675 (int)state->ruid, (int)state->euid, (int)state->suid);
677 if (ostate->ruid != ROOT_UID || ostate->suid != ROOT_UID) {
678 if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID)) {
679 snprintf(errbuf, sizeof(errbuf),
680 "PERM_TIMESTAMP: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
685 if (setuidx(ID_EFFECTIVE, timestamp_uid)) {
686 snprintf(errbuf, sizeof(errbuf),
687 "PERM_TIMESTAMP: setuidx(ID_EFFECTIVE, %d)", timestamp_uid);
695 debug_return_bool(1);
697 warningx("%s: %s", _(errstr),
698 errno == EAGAIN ? _("too many processes") : strerror(errno));
700 debug_return_bool(0);
707 struct perm_state *state, *ostate;
708 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
710 if (perm_stack_depth < 2)
713 state = &perm_stack[perm_stack_depth - 1];
714 ostate = &perm_stack[perm_stack_depth - 2];
717 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d, %d] -> [%d, %d, %d]",
718 __func__, (int)state->ruid, (int)state->euid, (int)state->suid,
719 (int)ostate->ruid, (int)ostate->euid, (int)ostate->suid);
720 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d, %d] -> [%d, %d, %d]",
721 __func__, (int)state->rgid, (int)state->egid, (int)state->sgid,
722 (int)ostate->rgid, (int)ostate->egid, (int)ostate->sgid);
724 if (OID(ruid) != -1 || OID(euid) != -1 || OID(suid) != -1) {
725 if (OID(euid) == ROOT_UID) {
726 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: setuidx(ID_EFFECTIVE, %d)",
728 if (setuidx(ID_EFFECTIVE, ROOT_UID)) {
729 warning("setuidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
730 (int)state->ruid, (int)state->euid, (int)state->suid,
735 if (OID(ruid) == OID(euid) && OID(euid) == OID(suid)) {
736 sudo_debug_printf(SUDO_DEBUG_INFO,
737 "%s: setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
738 __func__, OID(ruid));
739 if (setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, OID(ruid))) {
740 warning("setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED) [%d, %d, %d] -> [%d, %d, %d]",
741 (int)state->ruid, (int)state->euid, (int)state->suid,
742 (int)OID(ruid), (int)OID(euid), (int)OID(suid));
745 } else if (OID(ruid) == -1 && OID(suid) == -1) {
746 /* May have already changed euid to ROOT_UID above. */
747 if (OID(euid) != ROOT_UID) {
748 sudo_debug_printf(SUDO_DEBUG_INFO,
749 "%s: setuidx(ID_EFFECTIVE, %d)", __func__, OID(euid));
750 if (setuidx(ID_EFFECTIVE, OID(euid))) {
751 warning("setuidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
752 (int)state->ruid, (int)state->euid, (int)state->suid,
753 (int)OID(ruid), (int)OID(euid), (int)OID(suid));
757 } else if (OID(suid) == -1) {
758 /* Cannot set the real uid alone. */
759 sudo_debug_printf(SUDO_DEBUG_INFO,
760 "%s: setuidx(ID_REAL|ID_EFFECTIVE, %d)", __func__, OID(ruid));
761 if (setuidx(ID_REAL|ID_EFFECTIVE, OID(ruid))) {
762 warning("setuidx(ID_REAL|ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
763 (int)state->ruid, (int)state->euid, (int)state->suid,
764 (int)OID(ruid), (int)OID(euid), (int)OID(suid));
767 /* Restore the effective euid if it doesn't match the ruid. */
768 if (OID(euid) != OID(ruid)) {
769 sudo_debug_printf(SUDO_DEBUG_INFO,
770 "%s: setuidx(ID_EFFECTIVE, %d)", __func__, ostate->euid);
771 if (setuidx(ID_EFFECTIVE, ostate->euid)) {
772 warning("setuidx(ID_EFFECTIVE, %d)", ostate->euid);
778 if (OID(rgid) != -1 || OID(egid) != -1 || OID(sgid) != -1) {
779 if (OID(rgid) == OID(egid) && OID(egid) == OID(sgid)) {
780 sudo_debug_printf(SUDO_DEBUG_INFO,
781 "%s: setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, %d)",
782 __func__, OID(rgid));
783 if (setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, OID(rgid))) {
784 warning("setgidx(ID_EFFECTIVE|ID_REAL|ID_SAVED) [%d, %d, %d] -> [%d, %d, %d]",
785 (int)state->rgid, (int)state->egid, (int)state->sgid,
786 (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
789 } else if (OID(rgid) == -1 && OID(sgid) == -1) {
790 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: setgidx(ID_EFFECTIVE, %d)",
791 __func__, OID(egid));
792 if (setgidx(ID_EFFECTIVE, OID(egid))) {
793 warning("setgidx(ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
794 (int)state->rgid, (int)state->egid, (int)state->sgid,
795 (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
798 } else if (OID(sgid) == -1) {
799 sudo_debug_printf(SUDO_DEBUG_INFO,
800 "%s: setgidx(ID_EFFECTIVE|ID_REAL, %d)", __func__, OID(rgid));
801 if (setgidx(ID_REAL|ID_EFFECTIVE, OID(rgid))) {
802 warning("setgidx(ID_REAL|ID_EFFECTIVE) [%d, %d, %d] -> [%d, %d, %d]",
803 (int)state->rgid, (int)state->egid, (int)state->sgid,
804 (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
809 if (state->grlist != ostate->grlist) {
810 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
811 warning("setgroups()");
815 sudo_grlist_delref(state->grlist);
822 #elif defined(HAVE_SETREUID)
824 #define UID_CHANGED (state->ruid != ostate->ruid || state->euid != ostate->euid)
825 #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid)
828 * Set real and effective and saved uids and gids based on perm.
829 * We always retain a saved uid of 0 unless we are headed for an exec().
830 * We only flip the effective gid since it only changes for PERM_SUDOERS.
831 * This version of set_perms() works fine with the "stay_setuid" option.
836 struct perm_state *state, *ostate = NULL;
838 const char *errstr = errbuf;
840 debug_decl(set_perms, SUDO_DEBUG_PERMS)
842 noexit = ISSET(perm, PERM_NOEXIT);
843 CLR(perm, PERM_MASK);
845 if (perm_stack_depth == PERM_STACK_MAX) {
846 errstr = N_("perm stack overflow");
851 state = &perm_stack[perm_stack_depth];
852 if (perm != PERM_INITIAL) {
853 if (perm_stack_depth == 0) {
854 errstr = N_("perm stack underflow");
858 ostate = &perm_stack[perm_stack_depth - 1];
863 /* Stash initial state */
864 state->ruid = getuid();
865 state->euid = geteuid();
866 state->rgid = getgid();
867 state->egid = getegid();
868 state->grlist = user_group_list;
869 sudo_grlist_addref(state->grlist);
870 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
871 "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
872 (int)state->ruid, (int)state->euid,
873 (int)state->rgid, (int)state->egid);
877 state->ruid = ROOT_UID;
878 state->euid = ROOT_UID;
879 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
880 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
881 (int)ostate->euid, (int)state->ruid, (int)state->euid);
883 * setreuid(0, 0) may fail on some systems if euid is not already 0.
885 if (ostate->euid != ROOT_UID) {
886 if (setreuid(-1, ROOT_UID)) {
887 snprintf(errbuf, sizeof(errbuf),
888 "PERM_ROOT: setreuid(-1, %d)", PERM_ROOT);
892 if (ostate->ruid != ROOT_UID) {
893 if (setreuid(ROOT_UID, -1)) {
894 snprintf(errbuf, sizeof(errbuf),
895 "PERM_ROOT: setreuid(%d, -1)", ROOT_UID);
899 state->rgid = ostate->rgid;
900 state->egid = ROOT_GID;
901 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
902 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
903 (int)ostate->egid, (int)state->rgid, (int)state->egid);
904 if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
905 snprintf(errbuf, sizeof(errbuf),
906 "PERM_ROOT: setregid(%d, %d)", ID(rgid), ID(egid));
909 state->grlist = ostate->grlist;
910 sudo_grlist_addref(state->grlist);
914 state->rgid = ostate->rgid;
915 state->egid = user_gid;
916 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
917 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
918 (int)ostate->egid, (int)state->rgid, (int)state->egid);
919 if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
920 snprintf(errbuf, sizeof(errbuf),
921 "PERM_USER: setregid(%d, %d)", ID(rgid), ID(egid));
924 state->grlist = user_group_list;
925 sudo_grlist_addref(state->grlist);
926 if (state->grlist != ostate->grlist) {
927 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
928 errstr = "PERM_USER: setgroups";
932 state->ruid = ROOT_UID;
933 state->euid = user_uid;
934 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
935 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
936 (int)ostate->euid, (int)state->ruid, (int)state->euid);
937 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
938 snprintf(errbuf, sizeof(errbuf),
939 "PERM_USER: setreuid(%d, %d)", ID(ruid), ID(euid));
945 /* headed for exec() */
946 state->rgid = user_gid;
947 state->egid = user_gid;
948 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
949 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
950 (int)ostate->egid, (int)state->rgid, (int)state->egid);
951 if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
952 snprintf(errbuf, sizeof(errbuf),
953 "PERM_FULL_USER: setregid(%d, %d)", ID(rgid), ID(egid));
956 state->grlist = user_group_list;
957 sudo_grlist_addref(state->grlist);
958 if (state->grlist != ostate->grlist) {
959 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
960 errstr = "PERM_FULL_USER: setgroups";
964 state->ruid = user_uid;
965 state->euid = user_uid;
966 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
967 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
968 (int)ostate->euid, (int)state->ruid, (int)state->euid);
969 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
970 snprintf(errbuf, sizeof(errbuf),
971 "PERM_FULL_USER: setreuid(%d, %d)", ID(ruid), ID(euid));
977 state->rgid = ostate->rgid;
978 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
979 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
980 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
981 (int)ostate->egid, (int)state->rgid, (int)state->egid);
982 if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
983 errstr = N_("unable to change to runas gid");
986 state->grlist = runas_setgroups();
987 state->ruid = ROOT_UID;
988 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
989 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
990 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
991 (int)ostate->euid, (int)state->ruid, (int)state->euid);
992 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
993 errstr = N_("unable to change to runas uid");
999 state->grlist = ostate->grlist;
1000 sudo_grlist_addref(state->grlist);
1002 /* assume euid == ROOT_UID, ruid == user */
1003 state->rgid = ostate->rgid;
1004 state->egid = sudoers_gid;
1005 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
1006 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1007 (int)ostate->egid, (int)state->rgid, (int)state->egid);
1008 if (GID_CHANGED && setregid(ID(rgid), ID(egid))) {
1009 errstr = N_("unable to change to sudoers gid");
1013 state->ruid = ROOT_UID;
1015 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
1016 * we use a non-zero uid in order to avoid NFS lossage.
1017 * Using uid 1 is a bit bogus but should work on all OS's.
1019 if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
1022 state->euid = sudoers_uid;
1023 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
1024 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1025 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1026 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
1027 snprintf(errbuf, sizeof(errbuf),
1028 "PERM_SUDOERS: setreuid(%d, %d)", ID(ruid), ID(euid));
1033 case PERM_TIMESTAMP:
1034 state->grlist = ostate->grlist;
1035 sudo_grlist_addref(state->grlist);
1036 state->rgid = ostate->rgid;
1037 state->egid = ostate->egid;
1038 state->ruid = ROOT_UID;
1039 state->euid = timestamp_uid;
1040 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
1041 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1042 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1043 if (UID_CHANGED && setreuid(ID(ruid), ID(euid))) {
1044 snprintf(errbuf, sizeof(errbuf),
1045 "PERM_TIMESTAMP: setreuid(%d, %d)", ID(ruid), ID(euid));
1052 debug_return_bool(1);
1054 warningx("%s: %s", _(errstr),
1055 errno == EAGAIN ? _("too many processes") : strerror(errno));
1057 debug_return_bool(0);
1064 struct perm_state *state, *ostate;
1065 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1067 if (perm_stack_depth < 2)
1070 state = &perm_stack[perm_stack_depth - 1];
1071 ostate = &perm_stack[perm_stack_depth - 2];
1074 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d] -> [%d, %d]",
1075 __func__, (int)state->ruid, (int)state->euid,
1076 (int)ostate->ruid, (int)ostate->euid);
1077 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d] -> [%d, %d]",
1078 __func__, (int)state->rgid, (int)state->egid,
1079 (int)ostate->rgid, (int)ostate->egid);
1082 * When changing euid to ROOT_UID, setreuid() may fail even if
1083 * the ruid is ROOT_UID so call setuid() first.
1085 if (OID(euid) == ROOT_UID) {
1086 /* setuid() may not set the saved ID unless the euid is ROOT_UID */
1087 if (ID(euid) != ROOT_UID)
1088 ignore_result(setreuid(-1, ROOT_UID));
1089 if (setuid(ROOT_UID)) {
1090 warning("setuid() [%d, %d] -> %d)", (int)state->ruid,
1091 (int)state->euid, ROOT_UID);
1095 if (setreuid(OID(ruid), OID(euid))) {
1096 warning("setreuid() [%d, %d] -> [%d, %d]", (int)state->ruid,
1097 (int)state->euid, (int)OID(ruid), (int)OID(euid));
1100 if (setregid(OID(rgid), OID(egid))) {
1101 warning("setregid() [%d, %d] -> [%d, %d]", (int)state->rgid,
1102 (int)state->egid, (int)OID(rgid), (int)OID(egid));
1105 if (state->grlist != ostate->grlist) {
1106 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
1107 warning("setgroups()");
1111 sudo_grlist_delref(state->grlist);
1118 #elif defined(HAVE_SETEUID)
1120 #define GID_CHANGED (state->rgid != ostate->rgid || state->egid != ostate->egid)
1123 * Set real and effective uids and gids based on perm.
1124 * We always retain a real or effective uid of ROOT_UID unless
1125 * we are headed for an exec().
1126 * This version of set_perms() works fine with the "stay_setuid" option.
1131 struct perm_state *state, *ostate = NULL;
1133 const char *errstr = errbuf;
1135 debug_decl(set_perms, SUDO_DEBUG_PERMS)
1137 noexit = ISSET(perm, PERM_NOEXIT);
1138 CLR(perm, PERM_MASK);
1140 if (perm_stack_depth == PERM_STACK_MAX) {
1141 errstr = N_("perm stack overflow");
1146 state = &perm_stack[perm_stack_depth];
1147 if (perm != PERM_INITIAL) {
1148 if (perm_stack_depth == 0) {
1149 errstr = N_("perm stack underflow");
1153 ostate = &perm_stack[perm_stack_depth - 1];
1157 * Since we only have setuid() and seteuid() and semantics
1158 * for these calls differ on various systems, we set
1159 * real and effective uids to ROOT_UID initially to be safe.
1161 if (perm != PERM_INITIAL) {
1162 if (ostate->euid != ROOT_UID && seteuid(ROOT_UID)) {
1163 snprintf(errbuf, sizeof(errbuf), "set_perms: seteuid(%d)", ROOT_UID);
1166 if (ostate->ruid != ROOT_UID && setuid(ROOT_UID)) {
1167 snprintf(errbuf, sizeof(errbuf), "set_perms: setuid(%d)", ROOT_UID);
1174 /* Stash initial state */
1175 state->ruid = getuid();
1176 state->euid = geteuid();
1177 state->rgid = getgid();
1178 state->egid = getegid();
1179 state->grlist = user_group_list;
1180 sudo_grlist_addref(state->grlist);
1181 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
1182 "ruid: %d, euid: %d, rgid: %d, egid: %d", __func__,
1183 (int)state->ruid, (int)state->euid,
1184 (int)state->rgid, (int)state->egid);
1188 /* We already set ruid/euid above. */
1189 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
1190 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1191 (int)ostate->euid, ROOT_UID, ROOT_UID);
1192 state->ruid = ROOT_UID;
1193 state->euid = ROOT_UID;
1194 state->rgid = ostate->rgid;
1195 state->egid = ROOT_GID;
1196 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
1197 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1198 (int)ostate->egid, ROOT_GID, ROOT_GID);
1199 if (GID_CHANGED && setegid(ROOT_GID)) {
1200 errstr = N_("unable to change to root gid");
1203 state->grlist = ostate->grlist;
1204 sudo_grlist_addref(state->grlist);
1208 state->egid = user_gid;
1209 state->rgid = ostate->rgid;
1210 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: gid: "
1211 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1212 (int)ostate->egid, (int)state->rgid, (int)state->egid);
1213 if (GID_CHANGED && setegid(user_gid)) {
1214 snprintf(errbuf, sizeof(errbuf),
1215 "PERM_USER: setegid(%d)", user_gid);
1218 state->grlist = user_group_list;
1219 sudo_grlist_addref(state->grlist);
1220 if (state->grlist != ostate->grlist) {
1221 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1222 errstr = "PERM_USER: setgroups";
1226 state->ruid = ROOT_UID;
1227 state->euid = user_uid;
1228 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_USER: uid: "
1229 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1230 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1231 if (seteuid(user_uid)) {
1232 snprintf(errbuf, sizeof(errbuf),
1233 "PERM_USER: seteuid(%d)", user_uid);
1238 case PERM_FULL_USER:
1239 /* headed for exec() */
1240 state->rgid = user_gid;
1241 state->egid = user_gid;
1242 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
1243 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1244 (int)ostate->egid, (int)state->rgid, (int)state->egid);
1245 if (GID_CHANGED && setgid(user_gid)) {
1246 snprintf(errbuf, sizeof(errbuf),
1247 "PERM_FULL_USER: setgid(%d)", user_gid);
1250 state->grlist = user_group_list;
1251 sudo_grlist_addref(state->grlist);
1252 if (state->grlist != ostate->grlist) {
1253 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1254 errstr = "PERM_FULL_USER: setgroups";
1258 state->ruid = user_uid;
1259 state->euid = user_uid;
1260 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
1261 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1262 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1263 if (setuid(user_uid)) {
1264 snprintf(errbuf, sizeof(errbuf),
1265 "PERM_FULL_USER: setuid(%d)", user_uid);
1271 state->rgid = ostate->rgid;
1272 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
1273 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: gid: "
1274 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1275 (int)ostate->egid, (int)state->rgid, (int)state->egid);
1276 if (GID_CHANGED && setegid(state->egid)) {
1277 errstr = N_("unable to change to runas gid");
1280 state->grlist = runas_setgroups();
1281 state->ruid = ostate->ruid;
1282 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
1283 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_RUNAS: uid: "
1284 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1285 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1286 if (seteuid(state->euid)) {
1287 errstr = N_("unable to change to runas uid");
1293 state->grlist = ostate->grlist;
1294 sudo_grlist_addref(state->grlist);
1296 /* assume euid == ROOT_UID, ruid == user */
1297 state->rgid = ostate->rgid;
1298 state->egid = sudoers_gid;
1299 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: gid: "
1300 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->rgid,
1301 (int)ostate->egid, (int)state->rgid, (int)state->egid);
1302 if (GID_CHANGED && setegid(sudoers_gid)) {
1303 errstr = N_("unable to change to sudoers gid");
1307 state->ruid = ROOT_UID;
1309 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
1310 * we use a non-zero uid in order to avoid NFS lossage.
1311 * Using uid 1 is a bit bogus but should work on all OS's.
1313 if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP))
1316 state->euid = sudoers_uid;
1317 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_SUDOERS: uid: "
1318 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1319 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1320 if (seteuid(state->euid)) {
1321 snprintf(errbuf, sizeof(errbuf),
1322 "PERM_SUDOERS: seteuid(%d)", state->euid);
1327 case PERM_TIMESTAMP:
1328 state->grlist = ostate->grlist;
1329 sudo_grlist_addref(state->grlist);
1330 state->rgid = ostate->rgid;
1331 state->egid = ostate->egid;
1332 state->ruid = ROOT_UID;
1333 state->euid = timestamp_uid;
1334 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_TIMESTAMP: uid: "
1335 "[%d, %d] -> [%d, %d]", __func__, (int)ostate->ruid,
1336 (int)ostate->euid, (int)state->ruid, (int)state->euid);
1337 if (seteuid(timestamp_uid)) {
1338 snprintf(errbuf, sizeof(errbuf),
1339 "PERM_TIMESTAMP: seteuid(%d)", timestamp_uid);
1346 debug_return_bool(1);
1348 warningx("%s: %s", _(errstr),
1349 errno == EAGAIN ? _("too many processes") : strerror(errno));
1351 debug_return_bool(0);
1358 struct perm_state *state, *ostate;
1359 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1361 if (perm_stack_depth < 2)
1364 state = &perm_stack[perm_stack_depth - 1];
1365 ostate = &perm_stack[perm_stack_depth - 2];
1368 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d, %d] -> [%d, %d]",
1369 __func__, (int)state->ruid, (int)state->euid,
1370 (int)ostate->ruid, (int)ostate->euid);
1371 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d, %d] -> [%d, %d]",
1372 __func__, (int)state->rgid, (int)state->egid,
1373 (int)ostate->rgid, (int)ostate->egid);
1376 * Since we only have setuid() and seteuid() and semantics
1377 * for these calls differ on various systems, we set
1378 * real and effective uids to ROOT_UID initially to be safe.
1380 if (seteuid(ROOT_UID)) {
1381 warningx("seteuid() [%d] -> [%d]", (int)state->euid, ROOT_UID);
1384 if (setuid(ROOT_UID)) {
1385 warningx("setuid() [%d, %d] -> [%d, %d]", (int)state->ruid, ROOT_UID,
1386 ROOT_UID, ROOT_UID);
1390 if (OID(egid) != -1 && setegid(ostate->egid)) {
1391 warning("setegid(%d)", (int)ostate->egid);
1394 if (state->grlist != ostate->grlist) {
1395 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
1396 warning("setgroups()");
1400 if (OID(euid) != -1 && seteuid(ostate->euid)) {
1401 warning("seteuid(%d)", ostate->euid);
1404 sudo_grlist_delref(state->grlist);
1411 #else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
1414 * Set uids and gids based on perm via setuid() and setgid().
1415 * NOTE: does not support the "stay_setuid" or timestampowner options.
1416 * Also, sudoers_uid and sudoers_gid are not used.
1421 struct perm_state *state, *ostate = NULL;
1423 const char *errstr = errbuf;
1425 debug_decl(set_perms, SUDO_DEBUG_PERMS)
1427 noexit = ISSET(perm, PERM_NOEXIT);
1428 CLR(perm, PERM_MASK);
1430 if (perm_stack_depth == PERM_STACK_MAX) {
1431 errstr = N_("perm stack overflow");
1436 state = &perm_stack[perm_stack_depth];
1437 if (perm != PERM_INITIAL) {
1438 if (perm_stack_depth == 0) {
1439 errstr = N_("perm stack underflow");
1443 ostate = &perm_stack[perm_stack_depth - 1];
1448 /* Stash initial state */
1449 state->ruid = geteuid() == ROOT_UID ? ROOT_UID : getuid();
1450 state->rgid = getgid();
1451 state->grlist = user_group_list;
1452 sudo_grlist_addref(state->grlist);
1453 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_INITIAL: "
1454 "ruid: %d, rgid: %d", __func__, (int)state->ruid, (int)state->rgid);
1458 state->ruid = ROOT_UID;
1459 state->rgid = ROOT_GID;
1460 state->grlist = ostate->grlist;
1461 sudo_grlist_addref(state->grlist);
1462 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: uid: "
1463 "[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
1464 if (setuid(ROOT_UID)) {
1465 snprintf(errbuf, sizeof(errbuf), "PERM_ROOT: setuid(%d)", ROOT_UID);
1468 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_ROOT: gid: "
1469 "[%d] -> [%d]", __func__, (int)ostate->rgid, (int)state->rgid);
1470 if (setgid(ROOT_GID)) {
1471 errstr = N_("unable to change to root gid");
1476 case PERM_FULL_USER:
1477 state->rgid = user_gid;
1478 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: gid: "
1479 "[%d] -> [%d]", __func__, (int)ostate->rgid, (int)state->rgid);
1480 (void) setgid(user_gid);
1481 state->grlist = user_group_list;
1482 sudo_grlist_addref(state->grlist);
1483 if (state->grlist != ostate->grlist) {
1484 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
1485 errstr = "PERM_FULL_USER: setgroups";
1489 state->ruid = user_uid;
1490 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: PERM_FULL_USER: uid: "
1491 "[%d] -> [%d]", __func__, (int)ostate->ruid, (int)state->ruid);
1492 if (setuid(user_uid)) {
1493 snprintf(errbuf, sizeof(errbuf),
1494 "PERM_FULL_USER: setuid(%d)", user_uid);
1502 case PERM_TIMESTAMP:
1503 /* Unsupported since we can't set euid. */
1504 state->ruid = ostate->ruid;
1505 state->rgid = ostate->rgid;
1506 state->grlist = ostate->grlist;
1507 sudo_grlist_addref(state->grlist);
1512 debug_return_bool(1);
1514 warningx("%s: %s", _(errstr),
1515 errno == EAGAIN ? _("too many processes") : strerror(errno));
1517 debug_return_bool(0);
1524 struct perm_state *state, *ostate;
1525 debug_decl(restore_perms, SUDO_DEBUG_PERMS)
1527 if (perm_stack_depth < 2)
1530 state = &perm_stack[perm_stack_depth - 1];
1531 ostate = &perm_stack[perm_stack_depth - 2];
1534 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: uid: [%d] -> [%d]",
1535 __func__, (int)state->ruid, (int)ostate->ruid);
1536 sudo_debug_printf(SUDO_DEBUG_INFO, "%s: gid: [%d] -> [%d]",
1537 __func__, (int)state->rgid, (int)ostate->rgid);
1539 if (OID(rgid) != -1 && setgid(ostate->rgid)) {
1540 warning("setgid(%d)", (int)ostate->rgid);
1543 if (state->grlist != ostate->grlist) {
1544 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
1545 warning("setgroups()");
1549 sudo_grlist_delref(state->grlist);
1550 if (OID(ruid) != -1 && setuid(ostate->ruid)) {
1551 warning("setuid(%d)", (int)ostate->ruid);
1559 #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
1561 #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
1562 static struct group_list *
1563 runas_setgroups(void)
1566 struct group_list *grlist;
1567 debug_decl(runas_setgroups, SUDO_DEBUG_PERMS)
1569 if (def_preserve_groups) {
1570 sudo_grlist_addref(user_group_list);
1571 debug_return_ptr(user_group_list);
1574 pw = runas_pw ? runas_pw : sudo_user.pw;
1575 #ifdef HAVE_SETAUTHDB
1576 aix_setauthdb(pw->pw_name);
1578 grlist = sudo_get_grlist(pw);
1579 #ifdef HAVE_SETAUTHDB
1580 aix_restoreauthdb();
1582 if (sudo_setgroups(grlist->ngids, grlist->gids) < 0)
1583 log_fatal(USE_ERRNO|MSG_ONLY, N_("unable to set runas group vector"));
1584 debug_return_ptr(grlist);
1586 #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */