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;
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]", state->ruid,
308 state->euid, state->suid, -1, ROOT_UID, -1);
312 if (setresuid(OID(ruid), OID(euid), OID(suid))) {
313 warning("setresuid() [%d, %d, %d] -> [%d, %d, %d]", state->ruid,
314 state->euid, state->suid, OID(ruid), OID(euid), OID(suid));
317 if (setresgid(OID(rgid), OID(egid), OID(sgid))) {
318 warning("setresgid() [%d, %d, %d] -> [%d, %d, %d]", state->rgid,
319 state->egid, state->sgid, OID(rgid), OID(egid), OID(sgid));
322 if (state->grlist != ostate->grlist) {
323 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
324 warning("setgroups()");
328 grlist_delref(state->grlist);
336 # ifdef HAVE_SETREUID
339 * Set real and effective uids and gids based on perm.
340 * We always retain a real or effective uid of ROOT_UID unless
341 * we are headed for an exec().
342 * This version of set_perms() works fine with the "stay_setuid" option.
347 struct perm_state *state, *ostate;
351 noexit = ISSET(perm, PERM_NOEXIT);
352 CLR(perm, PERM_MASK);
354 if (perm_stack_depth == PERM_STACK_MAX) {
355 errstr = _("perm stack overflow");
360 state = &perm_stack[perm_stack_depth];
361 if (perm != PERM_INITIAL) {
362 if (perm_stack_depth == 0) {
363 errstr = _("perm stack underflow");
367 ostate = &perm_stack[perm_stack_depth - 1];
368 if (memcmp(state, ostate, sizeof(*state)) == 0)
374 /* Stash initial state */
375 state->ruid = getuid();
376 state->euid = geteuid();
377 state->rgid = getgid();
378 state->egid = getegid();
379 state->grlist = user_group_list;
380 grlist_addref(state->grlist);
385 * setreuid(0, 0) may fail on some systems
386 * when the euid is not already 0.
388 if (setreuid(-1, ROOT_UID)) {
389 errstr = "setreuid(-1, ROOT_UID)";
392 if (setuid(ROOT_UID)) {
393 errstr = "setuid(ROOT_UID)";
396 state->ruid = ROOT_UID;
397 state->euid = ROOT_UID;
400 state->grlist = ostate->grlist;
401 grlist_addref(state->grlist);
406 state->egid = user_gid;
407 if (setregid(-1, ID(egid))) {
408 errstr = "setregid(-1, user_gid)";
411 state->grlist = user_group_list;
412 grlist_addref(state->grlist);
413 if (state->grlist != ostate->grlist) {
414 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
415 errstr = "setgroups()";
419 state->ruid = ROOT_UID;
420 state->euid = user_uid;
421 if (setreuid(ID(ruid), ID(euid))) {
422 errstr = "setreuid(ROOT_UID, user_uid)";
428 /* headed for exec() */
429 state->rgid = user_gid;
430 state->egid = user_gid;
431 if (setregid(ID(rgid), ID(egid))) {
432 errstr = "setregid(user_gid, user_gid)";
435 state->grlist = user_group_list;
436 grlist_addref(state->grlist);
437 if (state->grlist != ostate->grlist) {
438 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
439 errstr = "setgroups()";
443 state->ruid = user_uid;
444 state->euid = user_uid;
445 if (setreuid(ID(ruid), ID(euid))) {
446 errstr = "setreuid(user_uid, user_uid)";
453 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
454 if (setregid(ID(rgid), ID(egid))) {
455 errstr = _("unable to change to runas gid");
458 state->grlist = runas_setgroups();
459 state->ruid = ROOT_UID;
460 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
461 if (setreuid(ID(ruid), ID(euid))) {
462 errstr = _("unable to change to runas uid");
468 state->grlist = ostate->grlist;
469 grlist_addref(state->grlist);
471 /* assume euid == ROOT_UID, ruid == user */
473 state->egid = sudoers_gid;
474 if (setregid(-1, ID(egid)))
475 error(1, _("unable to change to sudoers gid"));
477 state->ruid = ROOT_UID;
479 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
480 * we use a non-zero uid in order to avoid NFS lossage.
481 * Using uid 1 is a bit bogus but should work on all OS's.
483 if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
486 state->euid = sudoers_uid;
487 if (setreuid(ID(ruid), ID(euid))) {
488 errstr = "setreuid(ROOT_UID, SUDOERS_UID)";
494 state->grlist = ostate->grlist;
495 grlist_addref(state->grlist);
498 state->ruid = ROOT_UID;
499 state->euid = timestamp_uid;
500 if (setreuid(ID(ruid), ID(euid))) {
501 errstr = "setreuid(ROOT_UID, timestamp_uid)";
511 /* XXX - better warnings inline */
512 warningx("%s: %s", errstr,
513 errno == EAGAIN ? _("too many processes") : strerror(errno));
522 struct perm_state *state, *ostate;
524 if (perm_stack_depth < 2)
527 state = &perm_stack[perm_stack_depth - 1];
528 ostate = &perm_stack[perm_stack_depth - 2];
532 * When changing euid to ROOT_UID, setreuid() may fail even if
533 * the ruid is ROOT_UID so call setuid() first.
535 if (OID(euid) == ROOT_UID) {
536 /* setuid() may not set the saved ID unless the euid is ROOT_UID */
537 if (ID(euid) != ROOT_UID)
538 (void)setreuid(-1, ROOT_UID);
539 if (setuid(ROOT_UID)) {
540 warning("setuid(%d)", ROOT_UID);
544 if (setreuid(OID(ruid), OID(euid))) {
545 warning("setreuid() [%d, %d] -> [%d, %d]", state->ruid,
546 state->euid, OID(ruid), OID(euid));
549 if (setregid(OID(rgid), OID(egid))) {
550 warning("setregid() [%d, %d] -> [%d, %d]", state->rgid,
551 state->egid, OID(rgid), OID(egid));
554 if (state->grlist != ostate->grlist) {
555 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
556 warning("setgroups()");
560 grlist_delref(state->grlist);
567 # else /* !HAVE_SETRESUID && !HAVE_SETREUID */
571 * Set real and effective uids and gids based on perm.
572 * We always retain a real or effective uid of ROOT_UID unless
573 * we are headed for an exec().
574 * This version of set_perms() works fine with the "stay_setuid" option.
579 struct perm_state *state, *ostate;
583 noexit = ISSET(perm, PERM_NOEXIT);
584 CLR(perm, PERM_MASK);
586 if (perm_stack_depth == PERM_STACK_MAX) {
587 errstr = _("perm stack overflow");
592 state = &perm_stack[perm_stack_depth];
593 if (perm != PERM_INITIAL) {
594 if (perm_stack_depth == 0) {
595 errstr = _("perm stack underflow");
599 ostate = &perm_stack[perm_stack_depth - 1];
600 if (memcmp(state, ostate, sizeof(*state)) == 0)
605 * Since we only have setuid() and seteuid() and semantics
606 * for these calls differ on various systems, we set
607 * real and effective uids to ROOT_UID initially to be safe.
609 if (perm != PERM_INITIAL) {
610 if (seteuid(ROOT_UID)) {
611 errstr = "seteuid(ROOT_UID)";
614 if (setuid(ROOT_UID)) {
615 errstr = "setuid(ROOT_UID)";
622 /* Stash initial state */
623 state->ruid = getuid();
624 state->euid = geteuid();
625 state->rgid = getgid();
626 state->egid = getegid();
627 state->grlist = user_group_list;
628 grlist_addref(state->grlist);
632 /* We already set ruid/euid above. */
633 state->ruid = ROOT_UID;
634 state->euid = ROOT_UID;
637 state->grlist = ostate->grlist;
638 grlist_addref(state->grlist);
642 state->egid = user_gid;
643 if (setegid(ID(egid))) {
644 errstr = "setegid(user_gid)";
647 state->grlist = user_group_list;
648 grlist_addref(state->grlist);
649 if (state->grlist != ostate->grlist) {
650 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
651 errstr = "setgroups()";
656 state->ruid = ROOT_UID;
657 state->euid = user_uid;
658 if (seteuid(ID(euid))) {
659 errstr = "seteuid(user_uid)";
665 /* headed for exec() */
666 state->rgid = user_gid;
667 state->egid = user_gid;
668 if (setgid(user_gid)) {
669 errstr = "setgid(user_gid)";
672 state->grlist = user_group_list;
673 grlist_addref(state->grlist);
674 if (state->grlist != ostate->grlist) {
675 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
676 errstr = "setgroups()";
680 state->ruid = user_uid;
681 state->euid = user_uid;
682 if (setuid(user_uid)) {
683 errstr = "setuid(user_uid)";
690 state->egid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
691 if (setegid(ID(egid))) {
692 errstr = _("unable to change to runas gid");
695 state->grlist = runas_setgroups();
697 state->euid = runas_pw ? runas_pw->pw_uid : user_uid;
698 if (seteuid(ID(euid))) {
699 errstr = _("unable to change to runas uid");
705 state->grlist = ostate->grlist;
706 grlist_addref(state->grlist);
708 /* assume euid == ROOT_UID, ruid == user */
710 state->egid = sudoers_gid;
711 if (setegid(ID(egid)))
712 error(1, _("unable to change to sudoers gid"));
714 state->ruid = ROOT_UID;
716 * If sudoers_uid == ROOT_UID and sudoers_mode is group readable
717 * we use a non-zero uid in order to avoid NFS lossage.
718 * Using uid 1 is a bit bogus but should work on all OS's.
720 if (sudoers_uid == ROOT_UID && (sudoers_mode & 040))
723 state->euid = sudoers_uid;
724 if (seteuid(ID(euid))) {
725 errstr = "seteuid(SUDOERS_UID)";
731 state->grlist = ostate->grlist;
732 grlist_addref(state->grlist);
735 state->ruid = ROOT_UID;
736 state->euid = timestamp_uid;
737 if (seteuid(ID(euid))) {
738 errstr = "seteuid(timestamp_uid)";
748 /* XXX - better warnings inline */
749 warningx("%s: %s", errstr,
750 errno == EAGAIN ? _("too many processes") : strerror(errno));
759 struct perm_state *state, *ostate;
761 if (perm_stack_depth < 2)
764 state = &perm_stack[perm_stack_depth - 1];
765 ostate = &perm_stack[perm_stack_depth - 2];
769 * Since we only have setuid() and seteuid() and semantics
770 * for these calls differ on various systems, we set
771 * real and effective uids to ROOT_UID initially to be safe.
773 if (seteuid(ROOT_UID)) {
774 errstr = "seteuid(ROOT_UID)";
777 if (setuid(ROOT_UID)) {
778 errstr = "setuid(ROOT_UID)";
782 if (setegid(OID(egid))) {
783 warning("setegid(%d)", OID(egid));
786 if (state->grlist != ostate->grlist) {
787 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
788 warning("setgroups()");
792 if (seteuid(OID(euid))) {
793 warning("seteuid(%d)", OID(euid));
796 grlist_delref(state->grlist);
803 # else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
806 * Set uids and gids based on perm via setuid() and setgid().
807 * NOTE: does not support the "stay_setuid" or timestampowner options.
808 * Also, sudoers_uid and sudoers_gid are not used.
813 struct perm_state *state, *ostate;
817 noexit = ISSET(perm, PERM_NOEXIT);
818 CLR(perm, PERM_MASK);
820 if (perm_stack_depth == PERM_STACK_MAX) {
821 errstr = _("perm stack overflow");
826 state = &perm_stack[perm_stack_depth];
827 if (perm != PERM_INITIAL) {
828 if (perm_stack_depth == 0) {
829 errstr = _("perm stack underflow");
833 ostate = &perm_stack[perm_stack_depth - 1];
834 if (memcmp(state, ostate, sizeof(*state)) == 0)
840 /* Stash initial state */
841 state->ruid = getuid();
842 state->rgid = getgid();
843 state->grlist = user_group_list;
844 grlist_addref(state->grlist);
848 state->ruid = ROOT_UID;
850 state->grlist = ostate->grlist;
851 grlist_addref(state->grlist);
852 if (setuid(ROOT_UID)) {
853 errstr = "setuid(ROOT_UID)";
859 state->rgid = user_gid;
860 (void) setgid(user_gid);
861 state->grlist = user_group_list;
862 grlist_addref(state->grlist);
863 if (state->grlist != ostate->grlist) {
864 if (sudo_setgroups(state->grlist->ngids, state->grlist->gids)) {
865 errstr = "setgroups()";
869 state->ruid = user_uid;
870 if (setuid(user_uid)) {
871 errstr = "setuid(user_uid)";
880 /* Unsupported since we can't set euid. */
888 /* XXX - better warnings inline */
889 warningx("%s: %s", errstr,
890 errno == EAGAIN ? _("too many processes") : strerror(errno));
899 struct perm_state *state, *ostate;
901 if (perm_stack_depth < 2)
904 state = &perm_stack[perm_stack_depth - 1];
905 ostate = &perm_stack[perm_stack_depth - 2];
908 if (OID(rgid) != -1 && setgid(ostate->rgid)) {
909 warning("setgid(%d)", ostate->rgid);
912 if (state->grlist != ostate->grlist) {
913 if (sudo_setgroups(ostate->grlist->ngids, ostate->grlist->gids)) {
914 warning("setgroups()");
918 grlist_delref(state->grlist);
919 if (OID(ruid) != -1 && setuid(ostate->ruid)) {
920 warning("setuid(%d)", ostate->ruid);
928 # endif /* HAVE_SETEUID */
929 # endif /* HAVE_SETREUID */
930 #endif /* HAVE_SETRESUID */
932 static struct group_list *
933 runas_setgroups(void)
936 struct group_list *grlist;
938 if (def_preserve_groups) {
939 grlist_addref(user_group_list);
940 return user_group_list;
943 pw = runas_pw ? runas_pw : sudo_user.pw;
944 #ifdef HAVE_SETAUTHDB
945 aix_setauthdb(pw->pw_name);
947 grlist = get_group_list(pw);
948 #ifdef HAVE_SETAUTHDB
951 if (sudo_setgroups(grlist->ngids, grlist->gids) < 0)
952 log_error(USE_ERRNO|MSG_ONLY, _("unable to set runas group vector"));