* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#)kern_prot.c 7.8 (Berkeley) %G%
* System calls related to processes and protection
#include "../ufs/quota.h"
u
.u_r
.r_val1
= u
.u_procp
->p_pid
;
u
.u_r
.r_val2
= u
.u_procp
->p_ppid
;
} *uap
= (struct a
*)u
.u_ap
;
else if ((p
= pfind(uap
->pid
)) == 0) {
u
.u_r
.r_val1
= p
->p_pgrp
->pg_id
;
u
.u_r
.r_val1
= u
.u_procp
->p_ruid
;
u
.u_r
.r_val2
= u
.u_cred
->cr_uid
;
u
.u_r
.r_val1
= u
.u_procp
->p_rgid
;
u
.u_r
.r_val2
= u
.u_cred
->cr_groups
[0];
} *uap
= (struct a
*)u
.u_ap
;
if (uap
->gidsetsize
== 0) {
u
.u_r
.r_val1
= u
.u_cred
->cr_ngroups
;
if (uap
->gidsetsize
< u
.u_cred
->cr_ngroups
) {
uap
->gidsetsize
= u
.u_cred
->cr_ngroups
;
gp
= u
.u_cred
->cr_groups
;
for (lp
= groups
; lp
< &groups
[uap
->gidsetsize
]; )
u
.u_error
= copyout((caddr_t
)groups
, (caddr_t
)uap
->gidset
,
uap
->gidsetsize
* sizeof (groups
[0]));
u
.u_r
.r_val1
= uap
->gidsetsize
;
register struct proc
*p
= u
.u_procp
;
if ((p
->p_pgid
== p
->p_pid
) || pgfind(p
->p_pid
))
* 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)
} *uap
= (struct a
*)u
.u_ap
;
register struct pgrp
*pgrp
;
else if ((p
= pfind(uap
->pid
)) == 0 || !inferior(p
)) {
else if (p
!= u
.u_procp
) {
if (p
->p_session
!= u
.u_procp
->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 doit
register struct proc
*p
= u
.u_procp
;
uap
= (struct a
*)u
.u_ap
;
* Everything's okay, do it.
* Copy credentials so other references do not
if (u
.u_quota
->q_uid
!= ruid
) {
qstart(getquota((uid_t
)ruid
, 0, 0));
if (u
.u_cred
->cr_ref
> 1)
u
.u_cred
= crcopy(u
.u_cred
);
register struct proc
*p
= u
.u_procp
;
uap
= (struct a
*)u
.u_ap
;
if (u
.u_cred
->cr_ref
> 1)
u
.u_cred
= crcopy(u
.u_cred
);
u
.u_cred
->cr_groups
[0] = egid
;
} *uap
= (struct a
*)u
.u_ap
;
int ngrp
, groups
[NGROUPS
];
if (u
.u_error
= suser(u
.u_cred
, &u
.u_acflag
))
u
.u_error
= copyin((caddr_t
)uap
->gidset
, (caddr_t
)groups
,
uap
->gidsetsize
* sizeof (groups
[0]));
gp
= u
.u_cred
->cr_groups
;
for (lp
= groups
; lp
< &groups
[uap
->gidsetsize
]; )
u
.u_cred
->cr_ngroups
= 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.
} *uap
= (struct a
*)u
.u_ap
;
if (uap
->namelen
> sizeof (u
.u_procp
->p_logname
))
uap
->namelen
= sizeof (u
.u_procp
->p_logname
);
u
.u_error
= copyout((caddr_t
)u
.u_procp
->p_logname
,
(caddr_t
)uap
->namebuf
, uap
->namelen
);
} *uap
= (struct a
*)u
.u_ap
;
if (u
.u_error
= suser(u
.u_cred
, &u
.u_acflag
))
error
= copyinstr((caddr_t
)uap
->namebuf
, (caddr_t
)u
.u_procp
->p_logname
,
sizeof (u
.u_procp
->p_logname
) - 1, (int *) 0);
if (error
== ENOENT
) /* name too long */