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.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
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
38 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
39 * $FreeBSD: src/sys/kern/kern_prot.c,v 1.53.2.9 2002/03/09 05:20:26 dd Exp $
40 * $DragonFly: src/sys/kern/kern_prot.c,v 1.14 2003/12/20 05:58:30 dillon Exp $
44 * System calls related to processes and protection
47 #include "opt_compat.h"
49 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/sysproto.h>
53 #include <sys/kernel.h>
55 #include <sys/malloc.h>
56 #include <sys/pioctl.h>
57 #include <sys/resourcevar.h>
58 #include <sys/thread2.h>
61 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
64 * NOT MP SAFE due to p_pptr access
68 getpid(struct getpid_args *uap)
70 struct proc *p = curproc;
72 uap->sysmsg_fds[0] = p->p_pid;
73 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
74 uap->sysmsg_fds[1] = p->p_pptr->p_pid;
81 getppid(struct getppid_args *uap)
83 struct proc *p = curproc;
85 uap->sysmsg_result = p->p_pptr->p_pid;
90 * Get process group ID; note that POSIX getpgrp takes no parameter
95 getpgrp(struct getpgrp_args *uap)
97 struct proc *p = curproc;
99 uap->sysmsg_result = p->p_pgrp->pg_id;
104 * Get an arbitary pid's process group id
107 getpgid(struct getpgid_args *uap)
109 struct proc *p = curproc;
116 if ((pt = pfind(uap->pid)) == 0)
119 uap->sysmsg_result = pt->p_pgrp->pg_id;
124 * Get an arbitary pid's session id.
127 getsid(struct getsid_args *uap)
129 struct proc *p = curproc;
136 if ((pt = pfind(uap->pid)) == 0)
139 uap->sysmsg_result = pt->p_session->s_sid;
149 getuid(struct getuid_args *uap)
151 struct proc *p = curproc;
153 uap->sysmsg_fds[0] = p->p_ucred->cr_ruid;
154 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
155 uap->sysmsg_fds[1] = p->p_ucred->cr_uid;
161 * geteuid() - MP SAFE
165 geteuid(struct geteuid_args *uap)
167 struct proc *p = curproc;
169 uap->sysmsg_result = p->p_ucred->cr_uid;
178 getgid(struct getgid_args *uap)
180 struct proc *p = curproc;
182 uap->sysmsg_fds[0] = p->p_ucred->cr_rgid;
183 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
184 uap->sysmsg_fds[1] = p->p_ucred->cr_groups[0];
190 * Get effective group ID. The "egid" is groups[0], and could be obtained
191 * via getgroups. This syscall exists because it is somewhat painful to do
192 * correctly in a library function.
196 getegid(struct getegid_args *uap)
198 struct proc *p = curproc;
200 uap->sysmsg_result = p->p_ucred->cr_groups[0];
205 getgroups(struct getgroups_args *uap)
207 struct proc *p = curproc;
212 if (p == NULL) /* API enforcement */
216 if ((ngrp = uap->gidsetsize) == 0) {
217 uap->sysmsg_result = cr->cr_ngroups;
220 if (ngrp < cr->cr_ngroups)
222 ngrp = cr->cr_ngroups;
223 if ((error = copyout((caddr_t)cr->cr_groups,
224 (caddr_t)uap->gidset, ngrp * sizeof(gid_t))))
226 uap->sysmsg_result = ngrp;
232 setsid(struct setsid_args *uap)
234 struct proc *p = curproc;
236 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
239 (void)enterpgrp(p, p->p_pid, 1);
240 uap->sysmsg_result = p->p_pid;
246 * set process group (setpgid/old setpgrp)
248 * caller does setpgid(targpid, targpgid)
250 * pid must be caller or child of caller (ESRCH)
252 * pid must be in same session (EPERM)
253 * pid can't have done an exec (EACCES)
255 * there must exist some pid in same session having pgid (EPERM)
256 * pid must not be session leader (EPERM)
260 setpgid(struct setpgid_args *uap)
262 struct proc *curp = curproc;
263 struct proc *targp; /* target process */
264 struct pgrp *pgrp; /* target pgrp */
268 if (uap->pid != 0 && uap->pid != curp->p_pid) {
269 if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
271 if (targp->p_pgrp == NULL || targp->p_session != curp->p_session)
273 if (targp->p_flag & P_EXEC)
277 if (SESS_LEADER(targp))
280 uap->pgid = targp->p_pid;
281 else if (uap->pgid != targp->p_pid)
282 if ((pgrp = pgfind(uap->pgid)) == 0 ||
283 pgrp->pg_session != curp->p_session)
285 return (enterpgrp(targp, uap->pgid, 0));
289 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
290 * compatible. It says that setting the uid/gid to euid/egid is a special
291 * case of "appropriate privilege". Once the rules are expanded out, this
292 * basically means that setuid(nnn) sets all three id's, in all permitted
293 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid())
294 * does not set the saved id - this is dangerous for traditional BSD
295 * programs. For this reason, we *really* do not want to set
296 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
298 #define POSIX_APPENDIX_B_4_2_2
302 setuid(struct setuid_args *uap)
304 struct proc *p = curproc;
309 if (p == NULL) /* API enforcement */
314 * See if we have "permission" by POSIX 1003.1 rules.
316 * Note that setuid(geteuid()) is a special case of
317 * "appropriate privileges" in appendix B.4.2.2. We need
318 * to use this clause to be compatible with traditional BSD
319 * semantics. Basically, it means that "setuid(xx)" sets all
320 * three id's (assuming you have privs).
322 * Notes on the logic. We do things in three steps.
323 * 1: We determine if the euid is going to change, and do EPERM
324 * right away. We unconditionally change the euid later if this
325 * test is satisfied, simplifying that part of the logic.
326 * 2: We determine if the real and/or saved uid's are going to
327 * change. Determined by compile options.
328 * 3: Change euid last. (after tests in #2 for "appropriate privs")
331 if (uid != cr->cr_ruid && /* allow setuid(getuid()) */
332 #ifdef _POSIX_SAVED_IDS
333 uid != crc->cr_svuid && /* allow setuid(saved gid) */
335 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
336 uid != cr->cr_uid && /* allow setuid(geteuid()) */
338 (error = suser_cred(cr, PRISON_ROOT)))
341 #ifdef _POSIX_SAVED_IDS
343 * Do we have "appropriate privileges" (are we root or uid == euid)
344 * If so, we are changing the real uid and/or saved uid.
347 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */
350 suser_cred(cr, PRISON_ROOT) == 0) /* we are using privs */
354 * Set the real uid and transfer proc count to new user.
356 if (uid != cr->cr_ruid) {
363 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as
364 * the security of seteuid() depends on it. B.4.2.2 says it
365 * is important that we should do this.
367 if (cr->cr_svuid != uid) {
368 cr = cratom(&p->p_ucred);
375 * In all permitted cases, we are changing the euid.
376 * Copy credentials so other references do not see our changes.
378 if (cr->cr_uid != uid) {
387 seteuid(struct seteuid_args *uap)
389 struct proc *p = curproc;
394 if (p == NULL) /* API enforcement */
399 if (euid != cr->cr_ruid && /* allow seteuid(getuid()) */
400 euid != cr->cr_svuid && /* allow seteuid(saved uid) */
401 (error = suser_cred(cr, PRISON_ROOT)))
404 * Everything's okay, do it. Copy credentials so other references do
405 * not see our changes.
407 if (cr->cr_uid != euid) {
416 setgid(struct setgid_args *uap)
418 struct proc *p = curproc;
423 if (p == NULL) /* API enforcement */
428 * See if we have "permission" by POSIX 1003.1 rules.
430 * Note that setgid(getegid()) is a special case of
431 * "appropriate privileges" in appendix B.4.2.2. We need
432 * to use this clause to be compatible with traditional BSD
433 * semantics. Basically, it means that "setgid(xx)" sets all
434 * three id's (assuming you have privs).
436 * For notes on the logic here, see setuid() above.
439 if (gid != cr->cr_rgid && /* allow setgid(getgid()) */
440 #ifdef _POSIX_SAVED_IDS
441 gid != cr->cr_svgid && /* allow setgid(saved gid) */
443 #ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */
444 gid != cr->cr_groups[0] && /* allow setgid(getegid()) */
446 (error = suser_cred(cr, PRISON_ROOT)))
449 #ifdef _POSIX_SAVED_IDS
451 * Do we have "appropriate privileges" (are we root or gid == egid)
452 * If so, we are changing the real uid and saved gid.
455 #ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */
456 gid == cr->cr_groups[0] ||
458 suser_cred(cr, PRISON_ROOT) == 0) /* we are using privs */
464 if (cr->cr_rgid != gid) {
465 cr = cratom(&p->p_ucred);
472 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as
473 * the security of setegid() depends on it. B.4.2.2 says it
474 * is important that we should do this.
476 if (cr->cr_svgid != gid) {
477 cr = cratom(&p->p_ucred);
483 * In all cases permitted cases, we are changing the egid.
484 * Copy credentials so other references do not see our changes.
486 if (cr->cr_groups[0] != gid) {
487 cr = cratom(&p->p_ucred);
488 cr->cr_groups[0] = gid;
496 setegid(struct setegid_args *uap)
498 struct proc *p = curproc;
503 if (p == NULL) /* API enforcement */
508 if (egid != cr->cr_rgid && /* allow setegid(getgid()) */
509 egid != cr->cr_svgid && /* allow setegid(saved gid) */
510 (error = suser_cred(cr, PRISON_ROOT)))
512 if (cr->cr_groups[0] != egid) {
513 cr = cratom(&p->p_ucred);
514 cr->cr_groups[0] = egid;
522 setgroups(struct setgroups_args *uap)
524 struct proc *p = curproc;
529 if (p == NULL) /* API enforcement */
533 if ((error = suser_cred(cr, PRISON_ROOT)))
535 ngrp = uap->gidsetsize;
539 * XXX A little bit lazy here. We could test if anything has
540 * changed before cratom() and setting P_SUGID.
542 cr = cratom(&p->p_ucred);
545 * setgroups(0, NULL) is a legitimate way of clearing the
546 * groups vector on non-BSD systems (which generally do not
547 * have the egid in the groups[0]). We risk security holes
548 * when running non-BSD software if we do not do the same.
552 if ((error = copyin((caddr_t)uap->gidset,
553 (caddr_t)cr->cr_groups, ngrp * sizeof(gid_t))))
555 cr->cr_ngroups = ngrp;
563 setreuid(struct setreuid_args *uap)
565 struct proc *p = curproc;
570 if (p == NULL) /* API enforcement */
576 if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid) ||
577 (euid != (uid_t)-1 && euid != cr->cr_uid &&
578 euid != cr->cr_ruid && euid != cr->cr_svuid)) &&
579 (error = suser_cred(cr, PRISON_ROOT)) != 0)
582 if (euid != (uid_t)-1 && cr->cr_uid != euid) {
586 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
590 if ((ruid != (uid_t)-1 || cr->cr_uid != cr->cr_ruid) &&
591 cr->cr_svuid != cr->cr_uid) {
592 cr = cratom(&p->p_ucred);
593 cr->cr_svuid = cr->cr_uid;
601 setregid(struct setregid_args *uap)
603 struct proc *p = curproc;
608 if (p == NULL) /* API enforcement */
614 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid) ||
615 (egid != (gid_t)-1 && egid != cr->cr_groups[0] &&
616 egid != cr->cr_rgid && egid != cr->cr_svgid)) &&
617 (error = suser_cred(cr, PRISON_ROOT)) != 0)
620 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
621 cr = cratom(&p->p_ucred);
622 cr->cr_groups[0] = egid;
625 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
626 cr = cratom(&p->p_ucred);
630 if ((rgid != (gid_t)-1 || cr->cr_groups[0] != cr->cr_rgid) &&
631 cr->cr_svgid != cr->cr_groups[0]) {
632 cr = cratom(&p->p_ucred);
633 cr->cr_svgid = cr->cr_groups[0];
640 * setresuid(ruid, euid, suid) is like setreuid except control over the
641 * saved uid is explicit.
646 setresuid(struct setresuid_args *uap)
648 struct proc *p = curproc;
650 uid_t ruid, euid, suid;
657 if (((ruid != (uid_t)-1 && ruid != cr->cr_ruid && ruid != cr->cr_svuid &&
658 ruid != cr->cr_uid) ||
659 (euid != (uid_t)-1 && euid != cr->cr_ruid && euid != cr->cr_svuid &&
660 euid != cr->cr_uid) ||
661 (suid != (uid_t)-1 && suid != cr->cr_ruid && suid != cr->cr_svuid &&
662 suid != cr->cr_uid)) &&
663 (error = suser_cred(cr, PRISON_ROOT)) != 0)
665 if (euid != (uid_t)-1 && cr->cr_uid != euid) {
669 if (ruid != (uid_t)-1 && cr->cr_ruid != ruid) {
673 if (suid != (uid_t)-1 && cr->cr_svuid != suid) {
674 cr = cratom(&p->p_ucred);
682 * setresgid(rgid, egid, sgid) is like setregid except control over the
683 * saved gid is explicit.
688 setresgid(struct setresgid_args *uap)
690 struct proc *p = curproc;
692 gid_t rgid, egid, sgid;
699 if (((rgid != (gid_t)-1 && rgid != cr->cr_rgid && rgid != cr->cr_svgid &&
700 rgid != cr->cr_groups[0]) ||
701 (egid != (gid_t)-1 && egid != cr->cr_rgid && egid != cr->cr_svgid &&
702 egid != cr->cr_groups[0]) ||
703 (sgid != (gid_t)-1 && sgid != cr->cr_rgid && sgid != cr->cr_svgid &&
704 sgid != cr->cr_groups[0])) &&
705 (error = suser_cred(cr, PRISON_ROOT)) != 0)
708 if (egid != (gid_t)-1 && cr->cr_groups[0] != egid) {
709 cr = cratom(&p->p_ucred);
710 cr->cr_groups[0] = egid;
713 if (rgid != (gid_t)-1 && cr->cr_rgid != rgid) {
714 cr = cratom(&p->p_ucred);
718 if (sgid != (gid_t)-1 && cr->cr_svgid != sgid) {
719 cr = cratom(&p->p_ucred);
728 getresuid(struct getresuid_args *uap)
730 struct proc *p = curproc;
731 struct ucred *cr = p->p_ucred;
732 int error1 = 0, error2 = 0, error3 = 0;
735 error1 = copyout((caddr_t)&cr->cr_ruid,
736 (caddr_t)uap->ruid, sizeof(cr->cr_ruid));
738 error2 = copyout((caddr_t)&cr->cr_uid,
739 (caddr_t)uap->euid, sizeof(cr->cr_uid));
741 error3 = copyout((caddr_t)&cr->cr_svuid,
742 (caddr_t)uap->suid, sizeof(cr->cr_svuid));
743 return error1 ? error1 : (error2 ? error2 : error3);
748 getresgid(struct getresgid_args *uap)
750 struct proc *p = curproc;
751 struct ucred *cr = p->p_ucred;
752 int error1 = 0, error2 = 0, error3 = 0;
755 error1 = copyout((caddr_t)&cr->cr_rgid,
756 (caddr_t)uap->rgid, sizeof(cr->cr_rgid));
758 error2 = copyout((caddr_t)&cr->cr_groups[0],
759 (caddr_t)uap->egid, sizeof(cr->cr_groups[0]));
761 error3 = copyout((caddr_t)&cr->cr_svgid,
762 (caddr_t)uap->sgid, sizeof(cr->cr_svgid));
763 return error1 ? error1 : (error2 ? error2 : error3);
769 issetugid(struct issetugid_args *uap)
771 struct proc *p = curproc;
773 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
774 * we use P_SUGID because we consider changing the owners as
775 * "tainting" as well.
776 * This is significant for procs that start as root and "become"
777 * a user without an exec - programs cannot know *everything*
778 * that libc *might* have put in their data segment.
780 uap->sysmsg_result = (p->p_flag & P_SUGID) ? 1 : 0;
785 * Check if gid is a member of the group set.
788 groupmember(gid_t gid, struct ucred *cred)
793 egp = &(cred->cr_groups[cred->cr_ngroups]);
794 for (gp = cred->cr_groups; gp < egp; gp++) {
802 * Test whether the specified credentials imply "super-user"
803 * privilege; if so, and we have accounting info, set the flag
804 * indicating use of super-powers. A kernel thread without a process
805 * context is assumed to have super user capabilities. In situations
806 * where the caller always expect a cred to exist, the cred should be
807 * passed separately and suser_cred()should be used instead of suser().
809 * Returns 0 or error.
812 suser(struct thread *td)
814 struct proc *p = td->td_proc;
817 return suser_cred(p->p_ucred, 0);
824 suser_cred(struct ucred *cred, int flag)
826 KASSERT(cred != NULL, ("suser_cred: NULL cred!"));
828 if (cred->cr_uid != 0)
830 if (cred->cr_prison && !(flag & PRISON_ROOT))
832 /* NOTE: accounting for suser access (p_acflag/ASU) removed */
837 * Return zero if p1 can fondle p2, return errno (EPERM/ESRCH) otherwise.
840 p_trespass(struct ucred *cr1, struct ucred *cr2)
844 if (!PRISON_CHECK(cr1, cr2))
846 if (cr1->cr_ruid == cr2->cr_ruid)
848 if (cr1->cr_uid == cr2->cr_ruid)
850 if (cr1->cr_ruid == cr2->cr_uid)
852 if (cr1->cr_uid == cr2->cr_uid)
854 if (suser_cred(cr1, PRISON_ROOT) == 0)
860 * Allocate a zeroed cred structure.
867 MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
868 bzero((caddr_t)cr, sizeof(*cr));
874 * Claim another reference to a ucred structure. Can be used with special
878 crhold(struct ucred *cr)
880 if (cr != NOCRED && cr != FSCRED)
886 * Free a cred structure.
887 * Throws away space when ref count gets to 0.
891 crfree(struct ucred *cr)
893 /* Protect crfree() as a critical section as there
894 * appears to be a crfree race which can occur on
899 panic("Freeing already free credential! %p", cr);
901 if (--cr->cr_ref == 0) {
903 * Some callers of crget(), such as nfs_statfs(),
904 * allocate a temporary credential, but don't
905 * allocate a uidinfo structure.
907 if (cr->cr_uidinfo != NULL) {
908 uidrop(cr->cr_uidinfo);
909 cr->cr_uidinfo = NULL;
911 if (cr->cr_ruidinfo != NULL) {
912 uidrop(cr->cr_ruidinfo);
913 cr->cr_ruidinfo = NULL;
917 * Destroy empty prisons
919 if (cr->cr_prison && !--cr->cr_prison->pr_ref) {
920 if (cr->cr_prison->pr_linux != NULL)
921 FREE(cr->cr_prison->pr_linux, M_PRISON);
922 FREE(cr->cr_prison, M_PRISON);
924 cr->cr_prison = NULL; /* safety */
926 FREE((caddr_t)cr, M_CRED);
932 * Atomize a cred structure so it can be modified without polluting
933 * other references to it.
936 cratom(struct ucred **pcr)
942 if (oldcr->cr_ref == 1)
946 if (newcr->cr_uidinfo)
947 uihold(newcr->cr_uidinfo);
948 if (newcr->cr_ruidinfo)
949 uihold(newcr->cr_ruidinfo);
950 if (newcr->cr_prison)
951 ++newcr->cr_prison->pr_ref;
958 #if 0 /* no longer used but keep around for a little while */
960 * Copy cred structure to a new one and free the old one.
963 crcopy(struct ucred *cr)
971 if (newcr->cr_uidinfo)
972 uihold(newcr->cr_uidinfo);
973 if (newcr->cr_ruidinfo)
974 uihold(newcr->cr_ruidinfo);
975 if (newcr->cr_prison)
976 ++newcr->cr_prison->pr_ref;
984 * Dup cred struct to a new held one.
994 if (newcr->cr_uidinfo)
995 uihold(newcr->cr_uidinfo);
996 if (newcr->cr_ruidinfo)
997 uihold(newcr->cr_ruidinfo);
998 if (newcr->cr_prison)
999 ++newcr->cr_prison->pr_ref;
1005 * Fill in a struct xucred based on a struct ucred.
1013 bzero(xcr, sizeof(*xcr));
1014 xcr->cr_version = XUCRED_VERSION;
1015 xcr->cr_uid = cr->cr_uid;
1016 xcr->cr_ngroups = cr->cr_ngroups;
1017 bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
1021 * Get login name, if available.
1025 getlogin(struct getlogin_args *uap)
1027 struct proc *p = curproc;
1029 if (uap->namelen > MAXLOGNAME)
1030 uap->namelen = MAXLOGNAME;
1031 return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
1032 (caddr_t) uap->namebuf, uap->namelen));
1040 setlogin(struct setlogin_args *uap)
1042 struct proc *p = curproc;
1044 char logintmp[MAXLOGNAME];
1046 KKASSERT(p != NULL);
1047 if ((error = suser_cred(p->p_ucred, PRISON_ROOT)))
1049 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
1050 sizeof(logintmp), (size_t *)0);
1051 if (error == ENAMETOOLONG)
1054 (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp,
1062 struct proc *p = curproc;
1064 KKASSERT(p != NULL);
1065 p->p_flag |= P_SUGID;
1066 if (!(p->p_pfsflags & PF_ISUGID))
1071 * Helper function to change the effective uid of a process
1074 change_euid(uid_t euid)
1076 struct proc *p = curproc;
1079 KKASSERT(p != NULL);
1080 cr = cratom(&p->p_ucred);
1082 uireplace(&cr->cr_uidinfo, uifind(euid));
1086 * Helper function to change the real uid of a process
1088 * The per-uid process count for this process is transfered from
1089 * the old uid to the new uid.
1092 change_ruid(uid_t ruid)
1094 struct proc *p = curproc;
1097 KKASSERT(p != NULL);
1099 cr = cratom(&p->p_ucred);
1100 (void)chgproccnt(cr->cr_ruidinfo, -1, 0);
1101 /* It is assumed that pcred is not shared between processes */
1103 uireplace(&cr->cr_ruidinfo, uifind(ruid));
1104 (void)chgproccnt(cr->cr_ruidinfo, 1, 0);