Deleted Added
full compact
kern_prot.c (46116) kern_prot.c (46155)
1/*
2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
1/*
2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
39 * $Id: kern_prot.c,v 1.45 1999/04/27 11:16:01 phk Exp $
39 * $Id: kern_prot.c,v 1.46 1999/04/27 12:21:06 phk Exp $
40 */
41
42/*
43 * System calls related to processes and protection
44 */
45
46#include "opt_compat.h"
47

--- 342 unchanged lines hidden (view full) ---

390 uid = uap->uid;
391 if (uid != pc->p_ruid && /* allow setuid(getuid()) */
392#ifdef _POSIX_SAVED_IDS
393 uid != pc->p_svuid && /* allow setuid(saved gid) */
394#endif
395#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
396 uid != pc->pc_ucred->cr_uid && /* allow setuid(geteuid()) */
397#endif
40 */
41
42/*
43 * System calls related to processes and protection
44 */
45
46#include "opt_compat.h"
47

--- 342 unchanged lines hidden (view full) ---

390 uid = uap->uid;
391 if (uid != pc->p_ruid && /* allow setuid(getuid()) */
392#ifdef _POSIX_SAVED_IDS
393 uid != pc->p_svuid && /* allow setuid(saved gid) */
394#endif
395#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
396 uid != pc->pc_ucred->cr_uid && /* allow setuid(geteuid()) */
397#endif
398 (error = suser(p)))
398 (error = suser_xxx(0, p, PRISON_ROOT)))
399 return (error);
400
401#ifdef _POSIX_SAVED_IDS
402 /*
403 * Do we have "appropriate privileges" (are we root or uid == euid)
404 * If so, we are changing the real uid and/or saved uid.
405 */
406 if (
407#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */
408 uid == pc->pc_ucred->cr_uid ||
409#endif
399 return (error);
400
401#ifdef _POSIX_SAVED_IDS
402 /*
403 * Do we have "appropriate privileges" (are we root or uid == euid)
404 * If so, we are changing the real uid and/or saved uid.
405 */
406 if (
407#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */
408 uid == pc->pc_ucred->cr_uid ||
409#endif
410 suser(p) == 0) /* we are using privs */
410 suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
411#endif
412 {
413 /*
414 * Transfer proc count to new user.
415 */
416 if (uid != pc->p_ruid) {
417 (void)chgproccnt(pc->p_ruid, -1);
418 (void)chgproccnt(uid, 1);

--- 43 unchanged lines hidden (view full) ---

462{
463 register struct pcred *pc = p->p_cred;
464 register uid_t euid;
465 int error;
466
467 euid = uap->euid;
468 if (euid != pc->p_ruid && /* allow seteuid(getuid()) */
469 euid != pc->p_svuid && /* allow seteuid(saved uid) */
411#endif
412 {
413 /*
414 * Transfer proc count to new user.
415 */
416 if (uid != pc->p_ruid) {
417 (void)chgproccnt(pc->p_ruid, -1);
418 (void)chgproccnt(uid, 1);

--- 43 unchanged lines hidden (view full) ---

462{
463 register struct pcred *pc = p->p_cred;
464 register uid_t euid;
465 int error;
466
467 euid = uap->euid;
468 if (euid != pc->p_ruid && /* allow seteuid(getuid()) */
469 euid != pc->p_svuid && /* allow seteuid(saved uid) */
470 (error = suser(p)))
470 (error = suser_xxx(0, p, PRISON_ROOT)))
471 return (error);
472 /*
473 * Everything's okay, do it. Copy credentials so other references do
474 * not see our changes.
475 */
476 if (pc->pc_ucred->cr_uid != euid) {
477 pc->pc_ucred = crcopy(pc->pc_ucred);
478 pc->pc_ucred->cr_uid = euid;

--- 31 unchanged lines hidden (view full) ---

510 gid = uap->gid;
511 if (gid != pc->p_rgid && /* allow setgid(getgid()) */
512#ifdef _POSIX_SAVED_IDS
513 gid != pc->p_svgid && /* allow setgid(saved gid) */
514#endif
515#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
516 gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */
517#endif
471 return (error);
472 /*
473 * Everything's okay, do it. Copy credentials so other references do
474 * not see our changes.
475 */
476 if (pc->pc_ucred->cr_uid != euid) {
477 pc->pc_ucred = crcopy(pc->pc_ucred);
478 pc->pc_ucred->cr_uid = euid;

--- 31 unchanged lines hidden (view full) ---

510 gid = uap->gid;
511 if (gid != pc->p_rgid && /* allow setgid(getgid()) */
512#ifdef _POSIX_SAVED_IDS
513 gid != pc->p_svgid && /* allow setgid(saved gid) */
514#endif
515#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
516 gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */
517#endif
518 (error = suser(p)))
518 (error = suser_xxx(0, p, PRISON_ROOT)))
519 return (error);
520
521#ifdef _POSIX_SAVED_IDS
522 /*
523 * Do we have "appropriate privileges" (are we root or gid == egid)
524 * If so, we are changing the real uid and saved gid.
525 */
526 if (
527#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */
528 gid == pc->pc_ucred->cr_groups[0] ||
529#endif
519 return (error);
520
521#ifdef _POSIX_SAVED_IDS
522 /*
523 * Do we have "appropriate privileges" (are we root or gid == egid)
524 * If so, we are changing the real uid and saved gid.
525 */
526 if (
527#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */
528 gid == pc->pc_ucred->cr_groups[0] ||
529#endif
530 suser(p) == 0) /* we are using privs */
530 suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
531#endif
532 {
533 /*
534 * Set real gid
535 */
536 if (pc->p_rgid != gid) {
537 pc->p_rgid = gid;
538 setsugid(p);

--- 35 unchanged lines hidden (view full) ---

574{
575 register struct pcred *pc = p->p_cred;
576 register gid_t egid;
577 int error;
578
579 egid = uap->egid;
580 if (egid != pc->p_rgid && /* allow setegid(getgid()) */
581 egid != pc->p_svgid && /* allow setegid(saved gid) */
531#endif
532 {
533 /*
534 * Set real gid
535 */
536 if (pc->p_rgid != gid) {
537 pc->p_rgid = gid;
538 setsugid(p);

--- 35 unchanged lines hidden (view full) ---

574{
575 register struct pcred *pc = p->p_cred;
576 register gid_t egid;
577 int error;
578
579 egid = uap->egid;
580 if (egid != pc->p_rgid && /* allow setegid(getgid()) */
581 egid != pc->p_svgid && /* allow setegid(saved gid) */
582 (error = suser(p)))
582 (error = suser_xxx(0, p, PRISON_ROOT)))
583 return (error);
584 if (pc->pc_ucred->cr_groups[0] != egid) {
585 pc->pc_ucred = crcopy(pc->pc_ucred);
586 pc->pc_ucred->cr_groups[0] = egid;
587 setsugid(p);
588 }
589 return (0);
590}

--- 9 unchanged lines hidden (view full) ---

600setgroups(p, uap)
601 struct proc *p;
602 struct setgroups_args *uap;
603{
604 register struct pcred *pc = p->p_cred;
605 register u_int ngrp;
606 int error;
607
583 return (error);
584 if (pc->pc_ucred->cr_groups[0] != egid) {
585 pc->pc_ucred = crcopy(pc->pc_ucred);
586 pc->pc_ucred->cr_groups[0] = egid;
587 setsugid(p);
588 }
589 return (0);
590}

--- 9 unchanged lines hidden (view full) ---

600setgroups(p, uap)
601 struct proc *p;
602 struct setgroups_args *uap;
603{
604 register struct pcred *pc = p->p_cred;
605 register u_int ngrp;
606 int error;
607
608 if ((error = suser(p)))
608 if ((error = suser_xxx(0, p, PRISON_ROOT)))
609 return (error);
610 ngrp = uap->gidsetsize;
611 if (ngrp > NGROUPS)
612 return (EINVAL);
613 /*
614 * XXX A little bit lazy here. We could test if anything has
615 * changed before crcopy() and setting P_SUGID.
616 */

--- 32 unchanged lines hidden (view full) ---

649 register uid_t ruid, euid;
650 int error;
651
652 ruid = uap->ruid;
653 euid = uap->euid;
654 if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) ||
655 (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid &&
656 euid != pc->p_ruid && euid != pc->p_svuid)) &&
609 return (error);
610 ngrp = uap->gidsetsize;
611 if (ngrp > NGROUPS)
612 return (EINVAL);
613 /*
614 * XXX A little bit lazy here. We could test if anything has
615 * changed before crcopy() and setting P_SUGID.
616 */

--- 32 unchanged lines hidden (view full) ---

649 register uid_t ruid, euid;
650 int error;
651
652 ruid = uap->ruid;
653 euid = uap->euid;
654 if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) ||
655 (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid &&
656 euid != pc->p_ruid && euid != pc->p_svuid)) &&
657 (error = suser(p)) != 0)
657 (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
658 return (error);
659
660 if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
661 pc->pc_ucred = crcopy(pc->pc_ucred);
662 pc->pc_ucred->cr_uid = euid;
663 setsugid(p);
664 }
665 if (ruid != (uid_t)-1 && pc->p_ruid != ruid) {

--- 26 unchanged lines hidden (view full) ---

692 register gid_t rgid, egid;
693 int error;
694
695 rgid = uap->rgid;
696 egid = uap->egid;
697 if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) ||
698 (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] &&
699 egid != pc->p_rgid && egid != pc->p_svgid)) &&
658 return (error);
659
660 if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
661 pc->pc_ucred = crcopy(pc->pc_ucred);
662 pc->pc_ucred->cr_uid = euid;
663 setsugid(p);
664 }
665 if (ruid != (uid_t)-1 && pc->p_ruid != ruid) {

--- 26 unchanged lines hidden (view full) ---

692 register gid_t rgid, egid;
693 int error;
694
695 rgid = uap->rgid;
696 egid = uap->egid;
697 if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) ||
698 (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] &&
699 egid != pc->p_rgid && egid != pc->p_svgid)) &&
700 (error = suser(p)) != 0)
700 (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
701 return (error);
702
703 if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
704 pc->pc_ucred = crcopy(pc->pc_ucred);
705 pc->pc_ucred->cr_groups[0] = egid;
706 setsugid(p);
707 }
708 if (rgid != (gid_t)-1 && pc->p_rgid != rgid) {

--- 55 unchanged lines hidden (view full) ---

764 * privilege; if so, and we have accounting info, set the flag
765 * indicating use of super-powers.
766 * Returns 0 or error.
767 */
768int
769suser(p)
770 struct proc *p;
771{
701 return (error);
702
703 if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
704 pc->pc_ucred = crcopy(pc->pc_ucred);
705 pc->pc_ucred->cr_groups[0] = egid;
706 setsugid(p);
707 }
708 if (rgid != (gid_t)-1 && pc->p_rgid != rgid) {

--- 55 unchanged lines hidden (view full) ---

764 * privilege; if so, and we have accounting info, set the flag
765 * indicating use of super-powers.
766 * Returns 0 or error.
767 */
768int
769suser(p)
770 struct proc *p;
771{
772 return suser_xxx(p->p_ucred, &p->p_acflag);
772 return suser_xxx(0, p, 0);
773}
774
775int
773}
774
775int
776suser_xxx(cred, acflag)
776suser_xxx(cred, proc, flag)
777 struct ucred *cred;
777 struct ucred *cred;
778 u_short *acflag;
778 struct proc *proc;
779 int flag;
779{
780{
780 if (cred->cr_uid == 0) {
781 if (acflag)
782 *acflag |= ASU;
783 return (0);
781 if (!cred && !proc) {
782 printf("suser_xxx(): THINK!\n");
783 return (EPERM);
784 }
784 }
785 return (EPERM);
785 if (!cred)
786 cred = proc->p_ucred;
787 if (cred->cr_uid != 0)
788 return (EPERM);
789 if (proc && proc->p_prison && !(flag & PRISON_ROOT))
790 return (EPERM);
791 if (proc)
792 proc->p_acflag |= ASU;
793 return (0);
786}
787
788/*
789 * Allocate a zeroed cred structure.
790 */
791struct ucred *
792crget()
793{

--- 84 unchanged lines hidden (view full) ---

878int
879setlogin(p, uap)
880 struct proc *p;
881 struct setlogin_args *uap;
882{
883 int error;
884 char logintmp[MAXLOGNAME];
885
794}
795
796/*
797 * Allocate a zeroed cred structure.
798 */
799struct ucred *
800crget()
801{

--- 84 unchanged lines hidden (view full) ---

886int
887setlogin(p, uap)
888 struct proc *p;
889 struct setlogin_args *uap;
890{
891 int error;
892 char logintmp[MAXLOGNAME];
893
886 if ((error = suser(p)))
894 if ((error = suser_xxx(0, p, PRISON_ROOT)))
887 return (error);
888 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
889 sizeof(logintmp), (size_t *)0);
890 if (error == ENAMETOOLONG)
891 error = EINVAL;
892 else if (!error)
893 (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp,
894 sizeof(logintmp));
895 return (error);
896}
897
898void
899setsugid(p)
900 struct proc *p;
901{
902 p->p_flag |= P_SUGID;
903 if (!(p->p_pfsflags & PF_ISUGID))
904 p->p_stops = 0;
905}
895 return (error);
896 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
897 sizeof(logintmp), (size_t *)0);
898 if (error == ENAMETOOLONG)
899 error = EINVAL;
900 else if (!error)
901 (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp,
902 sizeof(logintmp));
903 return (error);
904}
905
906void
907setsugid(p)
908 struct proc *p;
909{
910 p->p_flag |= P_SUGID;
911 if (!(p->p_pfsflags & PF_ISUGID))
912 p->p_stops = 0;
913}