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 */
53 static struct group_list *runas_setgroups(void);
56 * We keep track of the current permisstions and use a stack to restore
57 * the old permissions. A depth of 16 is overkill.
70 struct group_list *grlist;
73 #define PERM_STACK_MAX 16
74 static struct perm_state perm_stack[PERM_STACK_MAX];
75 static int perm_stack_depth = 0;
78 #define ID(x) (state->x == ostate->x ? -1 : state->x)
80 #define OID(x) (ostate->x == state->x ? -1 : ostate->x)
85 while (perm_stack_depth > 1)
87 grlist_delref(perm_stack[0].grlist);
93 * Set real and effective and saved uids and gids based on perm.
94 * We always retain a saved uid of 0 unless we are headed for an exec().
95 * We only flip the effective gid since it only changes for PERM_SUDOERS.
96 * This version of set_perms() works fine with the "stay_setuid" option.
101 struct perm_state *state, *ostate = NULL;
105 noexit = ISSET(perm, PERM_NOEXIT);
106 CLR(perm, PERM_MASK);
108 if (perm_stack_depth == PERM_STACK_MAX) {
109 errstr = _("perm stack overflow");
114 state = &perm_stack[perm_stack_depth];
115 if (perm != PERM_INITIAL) {
116 if (perm_stack_depth == 0) {
117 errstr = _("perm stack underflow");
121 ostate = &perm_stack[perm_stack_depth - 1];
122 if (memcmp(state, ostate, sizeof(*state)) == 0)
128 /* Stash initial state */
129 #ifdef HAVE_GETRESUID
130 if (getresuid(&state->ruid, &state->euid, &state->suid)) {
131 errstr = "getresuid";
135 if (getresgid(&state->rgid, &state->egid, &state->sgid)) {
136 errstr = "getresgid";
140 state->ruid = getuid();
141 state->euid = geteuid();
142 state->suid = state->euid; /* in case we are setuid */
144 state->rgid = getgid();
145 state->egid = getegid();
146 state->sgid = state->egid; /* in case we are setgid */
148 state->grlist = user_group_list;
149 grlist_addref(state->grlist);
153 state->ruid = ROOT_UID;
154 state->euid = ROOT_UID;
155 state->suid = ROOT_UID;
156 if (setresuid(ID(ruid), ID(euid), ID(suid))) {
157 errstr = "setresuid(ROOT_UID, ROOT_UID, ROOT_UID)";
163 state->grlist = ostate->grlist;
164 grlist_addref(state->grlist);
169 state->egid = user_gid;
171 if (setresgid(-1, ID(egid), -1)) {
172 errstr = "setresgid(-1, user_gid, -1)";
175 state->grlist = user_group_list;
176 grlist_addref(state->grlist);
177 if (state->grlist != ostate->grlist) {
178 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
179 errstr = "setgroups()";
183 state->ruid = user_uid;
184 state->euid = user_uid;
185 state->suid = ROOT_UID;
186 if (setresuid(ID(ruid), ID(euid), ID(suid))) {
187 errstr = "setresuid(user_uid, user_uid, ROOT_UID)";
193 /* headed for exec() */
194 state->rgid = user_gid;
195 state->egid = user_gid;
196 state->sgid = user_gid;
197 if (setresgid(ID(rgid), ID(egid), ID(sgid))) {
198 errstr = "setresgid(user_gid, user_gid, user_gid)";
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 errstr = "setgroups()";
209 state->ruid = user_uid;
210 state->euid = user_uid;
211 state->suid = user_uid;
212 if (setresuid(ID(ruid), ID(euid), ID(suid))) {
213 errstr = "setresuid(user_uid, user_uid, user_uid)";
220 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
222 if (setresgid(-1, ID(egid), -1)) {
223 errstr = _("unable to change to runas gid");
226 state->grlist = runas_setgroups();
228 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
230 if (setresuid(-1, ID(euid), -1)) {
231 errstr = _("unable to change to runas uid");
237 state->grlist = ostate->grlist;
238 grlist_addref(state->grlist);
240 /* assumes euid == ROOT_UID, ruid == user */
242 state->egid = sudoers_gid;
244 if (setresgid(-1, ID(egid), -1))
245 error(1, _("unable to change to sudoers gid"));
247 state->ruid = ROOT_UID;
249 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
250 * we use a non-zero uid in order to avoid NFS lossage.
251 * Using uid 1 is a bit bogus but should work on all OS's.
253 if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
256 state->euid = sudoers_uid;
257 state->suid = ROOT_UID;
258 if (setresuid(ID(ruid), ID(euid), ID(suid))) {
259 errstr = "setresuid(ROOT_UID, SUDOERS_UID, ROOT_UID)";
265 state->grlist = ostate->grlist;
266 grlist_addref(state->grlist);
270 state->ruid = ROOT_UID;
271 state->euid = timestamp_uid;
272 state->suid = ROOT_UID;
273 if (setresuid(ID(ruid), ID(euid), ID(suid))) {
274 errstr = "setresuid(ROOT_UID, timestamp_uid, ROOT_UID)";
284 /* XXX - better warnings inline */
285 warningx("%s: %s", errstr,
286 errno == EAGAIN ? _("too many processes") : strerror(errno));
295 struct perm_state *state, *ostate;
297 if (perm_stack_depth < 2)
300 state = &perm_stack[perm_stack_depth - 1];
301 ostate = &perm_stack[perm_stack_depth - 2];
304 /* XXX - more cases here where euid != ruid */
305 if (OID(euid) == ROOT_UID && state->euid != ROOT_UID) {
306 if (setresuid(-1, ROOT_UID, -1)) {
307 warning("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
308 (int)state->ruid, (int)state->euid, (int)state->suid,
313 if (setresuid(OID(ruid), OID(euid), OID(suid))) {
314 warning("setresuid() [%d, %d, %d] -> [%d, %d, %d]",
315 (int)state->ruid, (int)state->euid, (int)state->suid,
316 (int)OID(ruid), (int)OID(euid), (int)OID(suid));
319 if (setresgid(OID(rgid), OID(egid), OID(sgid))) {
320 warning("setresgid() [%d, %d, %d] -> [%d, %d, %d]",
321 (int)state->rgid, (int)state->egid, (int)state->sgid,
322 (int)OID(rgid), (int)OID(egid), (int)OID(sgid));
325 if (state->grlist != ostate->grlist) {
326 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
327 warning("setgroups()");
331 grlist_delref(state->grlist);
339 # ifdef HAVE_SETREUID
342 * Set real and effective uids and gids based on perm.
343 * We always retain a real or effective uid of ROOT_UID unless
344 * we are headed for an exec().
345 * This version of set_perms() works fine with the "stay_setuid" option.
350 struct perm_state *state, *ostate = NULL;
354 noexit = ISSET(perm, PERM_NOEXIT);
355 CLR(perm, PERM_MASK);
357 if (perm_stack_depth == PERM_STACK_MAX) {
358 errstr = _("perm stack overflow");
363 state = &perm_stack[perm_stack_depth];
364 if (perm != PERM_INITIAL) {
365 if (perm_stack_depth == 0) {
366 errstr = _("perm stack underflow");
370 ostate = &perm_stack[perm_stack_depth - 1];
371 if (memcmp(state, ostate, sizeof(*state)) == 0)
377 /* Stash initial state */
378 state->ruid = getuid();
379 state->euid = geteuid();
380 state->rgid = getgid();
381 state->egid = getegid();
382 state->grlist = user_group_list;
383 grlist_addref(state->grlist);
388 * setreuid(0, 0) may fail on some systems
389 * when the euid is not already 0.
391 if (setreuid(-1, ROOT_UID)) {
392 errstr = "setreuid(-1, ROOT_UID)";
395 if (setuid(ROOT_UID)) {
396 errstr = "setuid(ROOT_UID)";
399 state->ruid = ROOT_UID;
400 state->euid = ROOT_UID;
403 state->grlist = ostate->grlist;
404 grlist_addref(state->grlist);
409 state->egid = user_gid;
410 if (setregid(-1, ID(egid))) {
411 errstr = "setregid(-1, user_gid)";
414 state->grlist = user_group_list;
415 grlist_addref(state->grlist);
416 if (state->grlist != ostate->grlist) {
417 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
418 errstr = "setgroups()";
422 state->ruid = ROOT_UID;
423 state->euid = user_uid;
424 if (setreuid(ID(ruid), ID(euid))) {
425 errstr = "setreuid(ROOT_UID, user_uid)";
431 /* headed for exec() */
432 state->rgid = user_gid;
433 state->egid = user_gid;
434 if (setregid(ID(rgid), ID(egid))) {
435 errstr = "setregid(user_gid, user_gid)";
438 state->grlist = user_group_list;
439 grlist_addref(state->grlist);
440 if (state->grlist != ostate->grlist) {
441 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
442 errstr = "setgroups()";
446 state->ruid = user_uid;
447 state->euid = user_uid;
448 if (setreuid(ID(ruid), ID(euid))) {
449 errstr = "setreuid(user_uid, user_uid)";
456 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
457 if (setregid(ID(rgid), ID(egid))) {
458 errstr = _("unable to change to runas gid");
461 state->grlist = runas_setgroups();
462 state->ruid = ROOT_UID;
463 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
464 if (setreuid(ID(ruid), ID(euid))) {
465 errstr = _("unable to change to runas uid");
471 state->grlist = ostate->grlist;
472 grlist_addref(state->grlist);
474 /* assume euid == ROOT_UID, ruid == user */
476 state->egid = sudoers_gid;
477 if (setregid(-1, ID(egid)))
478 error(1, _("unable to change to sudoers gid"));
480 state->ruid = ROOT_UID;
482 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
483 * we use a non-zero uid in order to avoid NFS lossage.
484 * Using uid 1 is a bit bogus but should work on all OS's.
486 if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
489 state->euid = sudoers_uid;
490 if (setreuid(ID(ruid), ID(euid))) {
491 errstr = "setreuid(ROOT_UID, SUDOERS_UID)";
497 state->grlist = ostate->grlist;
498 grlist_addref(state->grlist);
501 state->ruid = ROOT_UID;
502 state->euid = timestamp_uid;
503 if (setreuid(ID(ruid), ID(euid))) {
504 errstr = "setreuid(ROOT_UID, timestamp_uid)";
514 /* XXX - better warnings inline */
515 warningx("%s: %s", errstr,
516 errno == EAGAIN ? _("too many processes") : strerror(errno));
525 struct perm_state *state, *ostate;
527 if (perm_stack_depth < 2)
530 state = &perm_stack[perm_stack_depth - 1];
531 ostate = &perm_stack[perm_stack_depth - 2];
535 * When changing euid to ROOT_UID, setreuid() may fail even if
536 * the ruid is ROOT_UID so call setuid() first.
538 if (OID(euid) == ROOT_UID) {
539 /* setuid() may not set the saved ID unless the euid is ROOT_UID */
540 if (ID(euid) != ROOT_UID)
541 (void)setreuid(-1, ROOT_UID);
542 if (setuid(ROOT_UID)) {
543 warning("setuid() [%d, %d] -> %d)", (int)state->ruid,
544 (int)state->euid, ROOT_UID);
548 if (setreuid(OID(ruid), OID(euid))) {
549 warning("setreuid() [%d, %d] -> [%d, %d]", (int)state->ruid,
550 (int)state->euid, (int)OID(ruid), (int)OID(euid));
553 if (setregid(OID(rgid), OID(egid))) {
554 warning("setregid() [%d, %d] -> [%d, %d]", (int)state->rgid,
555 (int)state->egid, (int)OID(rgid), (int)OID(egid));
558 if (state->grlist != ostate->grlist) {
559 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
560 warning("setgroups()");
564 grlist_delref(state->grlist);
571 # else /* !HAVE_SETRESUID && !HAVE_SETREUID */
575 * Set real and effective uids and gids based on perm.
576 * We always retain a real or effective uid of ROOT_UID unless
577 * we are headed for an exec().
578 * This version of set_perms() works fine with the "stay_setuid" option.
583 struct perm_state *state, *ostate = NULL;
587 noexit = ISSET(perm, PERM_NOEXIT);
588 CLR(perm, PERM_MASK);
590 if (perm_stack_depth == PERM_STACK_MAX) {
591 errstr = _("perm stack overflow");
596 state = &perm_stack[perm_stack_depth];
597 if (perm != PERM_INITIAL) {
598 if (perm_stack_depth == 0) {
599 errstr = _("perm stack underflow");
603 ostate = &perm_stack[perm_stack_depth - 1];
604 if (memcmp(state, ostate, sizeof(*state)) == 0)
609 * Since we only have setuid() and seteuid() and semantics
610 * for these calls differ on various systems, we set
611 * real and effective uids to ROOT_UID initially to be safe.
613 if (perm != PERM_INITIAL) {
614 if (seteuid(ROOT_UID)) {
615 errstr = "seteuid(ROOT_UID)";
618 if (setuid(ROOT_UID)) {
619 errstr = "setuid(ROOT_UID)";
626 /* Stash initial state */
627 state->ruid = getuid();
628 state->euid = geteuid();
629 state->rgid = getgid();
630 state->egid = getegid();
631 state->grlist = user_group_list;
632 grlist_addref(state->grlist);
636 /* We already set ruid/euid above. */
637 state->ruid = ROOT_UID;
638 state->euid = ROOT_UID;
641 state->grlist = ostate->grlist;
642 grlist_addref(state->grlist);
646 state->egid = user_gid;
647 if (setegid(ID(egid))) {
648 errstr = "setegid(user_gid)";
651 state->grlist = user_group_list;
652 grlist_addref(state->grlist);
653 if (state->grlist != ostate->grlist) {
654 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
655 errstr = "setgroups()";
660 state->ruid = ROOT_UID;
661 state->euid = user_uid;
662 if (seteuid(ID(euid))) {
663 errstr = "seteuid(user_uid)";
669 /* headed for exec() */
670 state->rgid = user_gid;
671 state->egid = user_gid;
672 if (setgid(user_gid)) {
673 errstr = "setgid(user_gid)";
676 state->grlist = user_group_list;
677 grlist_addref(state->grlist);
678 if (state->grlist != ostate->grlist) {
679 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
680 errstr = "setgroups()";
684 state->ruid = user_uid;
685 state->euid = user_uid;
686 if (setuid(user_uid)) {
687 errstr = "setuid(user_uid)";
694 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
695 if (setegid(ID(egid))) {
696 errstr = _("unable to change to runas gid");
699 state->grlist = runas_setgroups();
701 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
702 if (seteuid(ID(euid))) {
703 errstr = _("unable to change to runas uid");
709 state->grlist = ostate->grlist;
710 grlist_addref(state->grlist);
712 /* assume euid == ROOT_UID, ruid == user */
714 state->egid = sudoers_gid;
715 if (setegid(ID(egid)))
716 error(1, _("unable to change to sudoers gid"));
718 state->ruid = ROOT_UID;
720 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
721 * we use a non-zero uid in order to avoid NFS lossage.
722 * Using uid 1 is a bit bogus but should work on all OS's.
724 if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
727 state->euid = sudoers_uid;
728 if (seteuid(ID(euid))) {
729 errstr = "seteuid(SUDOERS_UID)";
735 state->grlist = ostate->grlist;
736 grlist_addref(state->grlist);
739 state->ruid = ROOT_UID;
740 state->euid = timestamp_uid;
741 if (seteuid(ID(euid))) {
742 errstr = "seteuid(timestamp_uid)";
752 /* XXX - better warnings inline */
753 warningx("%s: %s", errstr,
754 errno == EAGAIN ? _("too many processes") : strerror(errno));
763 struct perm_state *state, *ostate;
765 if (perm_stack_depth < 2)
768 state = &perm_stack[perm_stack_depth - 1];
769 ostate = &perm_stack[perm_stack_depth - 2];
773 * Since we only have setuid() and seteuid() and semantics
774 * for these calls differ on various systems, we set
775 * real and effective uids to ROOT_UID initially to be safe.
777 if (seteuid(ROOT_UID)) {
778 errstr = "seteuid(ROOT_UID)";
781 if (setuid(ROOT_UID)) {
782 errstr = "setuid(ROOT_UID)";
786 if (setegid(OID(egid))) {
787 warning("setegid(%d)", (int)OID(egid));
790 if (state->grlist != ostate->grlist) {
791 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
792 warning("setgroups()");
796 if (seteuid(OID(euid))) {
797 warning("seteuid(%d)", (int)OID(euid));
800 grlist_delref(state->grlist);
807 # else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
810 * Set uids and gids based on perm via setuid() and setgid().
811 * NOTE: does not support the "stay_setuid" or timestampowner options.
812 * Also, sudoers_uid and sudoers_gid are not used.
817 struct perm_state *state, *ostate = NULL;
821 noexit = ISSET(perm, PERM_NOEXIT);
822 CLR(perm, PERM_MASK);
824 if (perm_stack_depth == PERM_STACK_MAX) {
825 errstr = _("perm stack overflow");
830 state = &perm_stack[perm_stack_depth];
831 if (perm != PERM_INITIAL) {
832 if (perm_stack_depth == 0) {
833 errstr = _("perm stack underflow");
837 ostate = &perm_stack[perm_stack_depth - 1];
838 if (memcmp(state, ostate, sizeof(*state)) == 0)
844 /* Stash initial state */
845 state->ruid = getuid();
846 state->rgid = getgid();
847 state->grlist = user_group_list;
848 grlist_addref(state->grlist);
852 state->ruid = ROOT_UID;
854 state->grlist = ostate->grlist;
855 grlist_addref(state->grlist);
856 if (setuid(ROOT_UID)) {
857 errstr = "setuid(ROOT_UID)";
863 state->rgid = user_gid;
864 (void) setgid(user_gid);
865 state->grlist = user_group_list;
866 grlist_addref(state->grlist);
867 if (state->grlist != ostate->grlist) {
868 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
869 errstr = "setgroups()";
873 state->ruid = user_uid;
874 if (setuid(user_uid)) {
875 errstr = "setuid(user_uid)";
884 /* Unsupported since we can't set euid. */
892 /* XXX - better warnings inline */
893 warningx("%s: %s", errstr,
894 errno == EAGAIN ? _("too many processes") : strerror(errno));
903 struct perm_state *state, *ostate;
905 if (perm_stack_depth < 2)
908 state = &perm_stack[perm_stack_depth - 1];
909 ostate = &perm_stack[perm_stack_depth - 2];
912 if (OID(rgid) != -1 && setgid(ostate->rgid)) {
913 warning("setgid(%d)", (int)ostate->rgid);
916 if (state->grlist != ostate->grlist) {
917 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
918 warning("setgroups()");
922 grlist_delref(state->grlist);
923 if (OID(ruid) != -1 && setuid(ostate->ruid)) {
924 warning("setuid(%d)", (int)ostate->ruid);
932 # endif /* HAVE_SETEUID */
933 # endif /* HAVE_SETREUID */
934 #endif /* HAVE_SETRESUID */
936 static struct group_list *
937 runas_setgroups(void)
940 struct group_list *grlist;
942 if (def_preserve_groups) {
943 grlist_addref(user_group_list);
944 return user_group_list;
947 pw = runas_pw ? runas_pw : sudo_user.pw;
948 #ifdef HAVE_SETAUTHDB
949 aix_setauthdb(pw->pw_name);
951 grlist = get_group_list(pw);
952 #ifdef HAVE_SETAUTHDB
955 if (sudo_setgroups(grlist->ngids, grlist->gids) < 0)
956 log_error(USE_ERRNO|MSG_ONLY, _("unable to set runas group vector"));