* Copyright (c) 1982, 1986, 1989, 1990 Regents of the University of California.
* %sccs.include.redist.c%
* @(#)kern_prot.c 7.15 (Berkeley) %G%
* System calls related to processes and protection
if (uap
->pid
!= 0 && (p
= pfind(uap
->pid
)) == 0)
*retval
= p
->p_pgrp
->pg_id
;
retval
[1] = u
.u_cred
->cr_uid
;
*retval
= u
.u_cred
->cr_uid
;
retval
[1] = u
.u_cred
->cr_groups
[0];
* Get effective group ID.
* The "egid" is groups[0], and thus could be obtained via getgroups;
* this is somewhat painful to do correctly in a library function,
* this the existence of this syscall.
*retval
= u
.u_cred
->cr_groups
[0];
getgroups(p
, uap
, retval
)
int *gidset
; /* XXX not yet POSIX */
if ((ngrp
= uap
->gidsetsize
) == 0) {
*retval
= u
.u_cred
->cr_ngroups
;
if (ngrp
< u
.u_cred
->cr_ngroups
)
ngrp
= u
.u_cred
->cr_ngroups
;
for (gp
= u
.u_cred
->cr_groups
, lp
= groups
; lp
< &groups
[ngrp
]; )
if (error
= copyout((caddr_t
)groups
, (caddr_t
)uap
->gidset
,
ngrp
* sizeof (groups
[0])))
if (p
->p_pgid
== p
->p_pid
|| pgfind(p
->p_pid
)) {
* set process group (setpgrp/setpgid)
* caller does setpgrp(pid, pgid)
* pid must be caller or child of caller (ESRCH)
* pid must be in same session (EPERM)
* pid can't have done an exec (EACCES)
* there must exist some pid in same session having pgid (EPERM)
* pid must not be session leader (EPERM)
register struct pgrp
*pgrp
;
if ((p
= pfind(uap
->pid
)) == 0 || !inferior(p
))
if (p
->p_session
!= cp
->p_session
)
else if ((uap
->pgid
!= p
->p_pid
) &&
(((pgrp
= pgfind(uap
->pgid
)) == 0) ||
pgrp
->pg_session
!= u
.u_procp
->p_session
))
* done checking, now do it
if (uid
!= p
->p_ruid
&& (error
= suser(u
.u_cred
, &u
.u_acflag
)))
* Everything's okay, do it.
* Copy credentials so other references do not
if (u
.u_cred
->cr_ref
> 1)
u
.u_cred
= crcopy(u
.u_cred
);
if (euid
!= p
->p_ruid
&& euid
!= p
->p_svuid
&&
(error
= suser(u
.u_cred
, &u
.u_acflag
)))
* Everything's okay, do it.
* Copy credentials so other references do not
if (u
.u_cred
->cr_ref
> 1)
u
.u_cred
= crcopy(u
.u_cred
);
if (gid
!= p
->p_rgid
&& (error
= suser(u
.u_cred
, &u
.u_acflag
)))
if (u
.u_cred
->cr_ref
> 1)
u
.u_cred
= crcopy(u
.u_cred
);
u
.u_cred
->cr_groups
[0] = gid
;
p
->p_svgid
= gid
; /* ??? */
if (egid
!= p
->p_rgid
&& egid
!= p
->p_svgid
&&
(error
= suser(u
.u_cred
, &u
.u_acflag
)))
if (u
.u_cred
->cr_ref
> 1)
u
.u_cred
= crcopy(u
.u_cred
);
u
.u_cred
->cr_groups
[0] = egid
;
osetreuid(p
, uap
, retval
)
register uid_t ruid
, euid
;
(error
= suser(u
.u_cred
, &u
.u_acflag
)))
euid
!= p
->p_svuid
&& (error
= suser(u
.u_cred
, &u
.u_acflag
)))
* Everything's okay, do it.
* Copy credentials so other references do not
if (u
.u_cred
->cr_ref
> 1)
u
.u_cred
= crcopy(u
.u_cred
);
osetregid(p
, uap
, retval
)
register gid_t rgid
, egid
;
(error
= suser(u
.u_cred
, &u
.u_acflag
)))
egid
!= p
->p_svgid
&& (error
= suser(u
.u_cred
, &u
.u_acflag
)))
if (u
.u_cred
->cr_ref
> 1)
u
.u_cred
= crcopy(u
.u_cred
);
u
.u_cred
->cr_groups
[0] = egid
;
setgroups(p
, uap
, retval
)
int error
, groups
[NGROUPS
];
if (error
= suser(u
.u_cred
, &u
.u_acflag
))
if ((ngrp
= uap
->gidsetsize
) > NGROUPS
)
if (error
= copyin((caddr_t
)uap
->gidset
, (caddr_t
)groups
,
ngrp
* sizeof (groups
[0])))
u
.u_cred
->cr_ngroups
= ngrp
;
/* convert from int's to gid_t's */
for (gp
= u
.u_cred
->cr_groups
, lp
= groups
; ngrp
--; )
* Check if gid is a member of the group set.
register struct ucred
*cred
;
egp
= &(cred
->cr_groups
[cred
->cr_ngroups
]);
for (gp
= cred
->cr_groups
; gp
< egp
; gp
++)
* Test if the current user is the super user.
* Allocate a zeroed cred structure.
register struct ucred
*cr
;
MALLOC(cr
, struct ucred
*, sizeof(*cr
), M_CRED
, M_WAITOK
);
bzero((caddr_t
)cr
, sizeof(*cr
));
* Throws away space when ref count gets to 0.
FREE((caddr_t
)cr
, M_CRED
);
* Copy cred structure to a new one and free the old one.
* Dup cred struct to a new held one.
* Get login name, if available.
if (uap
->namelen
> sizeof (p
->p_logname
))
uap
->namelen
= sizeof (p
->p_logname
);
return (copyout((caddr_t
)p
->p_logname
, (caddr_t
)uap
->namebuf
,
if (error
= suser(u
.u_cred
, &u
.u_acflag
))
error
= copyinstr((caddr_t
)uap
->namebuf
, (caddr_t
)p
->p_logname
,
sizeof (p
->p_logname
) - 1, (int *) 0);
if (error
== ENOENT
) /* name too long */