diff options
author | Jason Downs <downsj@cvs.openbsd.org> | 1997-01-26 05:18:30 +0000 |
---|---|---|
committer | Jason Downs <downsj@cvs.openbsd.org> | 1997-01-26 05:18:30 +0000 |
commit | 263b5fe1fe5a828ec19e6df99b56bc284a888f15 (patch) | |
tree | 8eabd06a2e787d55d8d5a72538ba5c280028d48f /sys/kern | |
parent | 860369cea67319fa9df33453a90c6dbb2150d356 (diff) |
Add lchown(2).
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/syscalls.master | 5 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 54 |
2 files changed, 56 insertions, 3 deletions
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 3e480c3a0cf..16f4245b2d0 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,9 +1,9 @@ - $OpenBSD: syscalls.master,v 1.12 1996/10/29 03:46:28 deraadt Exp $ + $OpenBSD: syscalls.master,v 1.13 1997/01/26 05:18:27 downsj Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 -; NetBSD system call name/number "master" file. +; OpenBSD system call name/number "master" file. ; (See syscalls.conf to see what it is processed into.) ; ; Fields: number type [type-dependent ...] @@ -458,3 +458,4 @@ 252 STD { int sys_poll(struct pollfd *fds, \ unsigned long nfds, int timeout); } 253 STD { int sys_issetugid(void); } +254 STD { int sys_lchown(char *path, int uid, int gid); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index d2c14f3dc0f..4ebf43cc0d0 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_syscalls.c,v 1.19 1997/01/25 00:27:31 dm Exp $ */ +/* $OpenBSD: vfs_syscalls.c,v 1.20 1997/01/26 05:18:29 downsj Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */ /* @@ -1564,6 +1564,58 @@ out: } /* + * Set ownership given a path name, without following links. + */ +/* ARGSUSED */ +int +sys_lchown(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct sys_lchown_args /* { + syscallarg(char *) path; + syscallarg(int) uid; + syscallarg(int) gid; + } */ *uap = v; + register struct vnode *vp; + struct vattr vattr; + int error; + struct nameidata nd; + u_short mode; + + NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); + if ((error = namei(&nd)) != 0) + return (error); + vp = nd.ni_vp; + VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); + VOP_LOCK(vp); + if (vp->v_mount->mnt_flag & MNT_RDONLY) + error = EROFS; + else { + if (suser(p->p_ucred, &p->p_acflag) || + suid_clear) { + error = VOP_GETATTR(vp, &vattr, p->p_ucred, p); + if (error) + goto out; + mode = vattr.va_mode & ~(VSUID | VSGID); + if (mode == vattr.va_mode) + mode = VNOVAL; + } + else + mode = VNOVAL; + VATTR_NULL(&vattr); + vattr.va_uid = SCARG(uap, uid); + vattr.va_gid = SCARG(uap, gid); + vattr.va_mode = mode; + error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); + } +out: + vput(vp); + return (error); +} + +/* * Set ownership given a file descriptor. */ /* ARGSUSED */ |