diff options
| author | thorpej <thorpej@NetBSD.org> | 1999-05-14 18:45:31 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 1999-05-14 18:45:31 +0000 |
| commit | 0f74e48ca5b6cf92aa5c0dda9b1e6eb8bf83bc5d (patch) | |
| tree | 582f261bdec3f7ce894664956614dc643fb516fd /sys/compat/linux | |
| parent | 8a61761cc555f41b29714cb6a157ea3d98b2ab00 (diff) | |
Emulate the Linux {get,set}resgid(2) system calls.
Diffstat (limited to 'sys/compat/linux')
| -rw-r--r-- | sys/compat/linux/common/linux_misc_notalpha.c | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/sys/compat/linux/common/linux_misc_notalpha.c b/sys/compat/linux/common/linux_misc_notalpha.c index c040c05632d..bbd56236267 100644 --- a/sys/compat/linux/common/linux_misc_notalpha.c +++ b/sys/compat/linux/common/linux_misc_notalpha.c @@ -1,11 +1,12 @@ -/* $NetBSD: linux_misc_notalpha.c,v 1.50 1999/02/09 20:37:19 christos Exp $ */ +/* $NetBSD: linux_misc_notalpha.c,v 1.51 1999/05/14 18:45:31 thorpej Exp $ */ /*- * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation - * by Frank van der Linden and Eric Haszlakiewicz. + * by Frank van der Linden and Eric Haszlakiewicz; by Jason R. Thorpe + * of the Numerical Aerospace Simulation Facility, NASA Ames Research Center. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -291,3 +292,102 @@ linux_sys_waitpid(p, v, retval) return 0; } + +int +linux_sys_setresgid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct linux_sys_setresgid_args /* { + syscallarg(gid_t) rgid; + syscallarg(gid_t) egid; + syscallarg(gid_t) sgid; + } */ *uap = v; + struct pcred *pc = p->p_cred; + gid_t rgid, egid, sgid; + int error; + + rgid = SCARG(uap, rgid); + egid = SCARG(uap, egid); + sgid = SCARG(uap, sgid); + + /* + * Note: These checks are a little different than the NetBSD + * setregid(2) call performs. This precisely follows the + * behavior of the Linux kernel. + */ + if (rgid != (gid_t)-1 && + rgid != pc->p_rgid && + rgid != pc->pc_ucred->cr_gid && + rgid != pc->p_svgid && + (error = suser(pc->pc_ucred, &p->p_acflag))) + return (error); + + if (egid != (gid_t)-1 && + egid != pc->p_rgid && + egid != pc->pc_ucred->cr_gid && + egid != pc->p_svgid && + (error = suser(pc->pc_ucred, &p->p_acflag))) + return (error); + + if (sgid != (gid_t)-1 && + sgid != pc->p_rgid && + sgid != pc->pc_ucred->cr_gid && + sgid != pc->p_svgid && + (error = suser(pc->pc_ucred, &p->p_acflag))) + return (error); + + /* + * Now assign the real, effective, and saved GIDs. + * Note that Linux, unlike NetBSD in setregid(2), does not + * set the saved UID in this call unless the user specifies + * it. + */ + if (rgid != (gid_t)-1) + pc->p_rgid = rgid; + + if (egid != (gid_t)-1) { + pc->pc_ucred = crcopy(pc->pc_ucred); + pc->pc_ucred->cr_gid = egid; + } + + if (sgid != (gid_t)-1) + pc->p_svgid = sgid; + + if (rgid != (gid_t)-1 && egid != (gid_t)-1 && sgid != (gid_t)-1) + p->p_flag |= P_SUGID; + return (0); +} + +int +linux_sys_getresgid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct linux_sys_getresgid_args /* { + syscallarg(gid_t *) rgid; + syscallarg(gid_t *) egid; + syscallarg(gid_t *) sgid; + } */ *uap = v; + struct pcred *pc = p->p_cred; + int error; + + /* + * Linux copies these values out to userspace like so: + * + * 1. Copy out rgid. + * 2. If that succeeds, copy out egid. + * 3. If both of those succeed, copy out sgid. + */ + if ((error = copyout(&pc->p_rgid, SCARG(uap, rgid), + sizeof(gid_t))) != 0) + return (error); + + if ((error = copyout(&pc->pc_ucred->cr_uid, SCARG(uap, egid), + sizeof(gid_t))) != 0) + return (error); + + return (copyout(&pc->p_svgid, SCARG(uap, sgid), sizeof(gid_t))); +} |
