summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1997-01-26 05:18:30 +0000
committerJason Downs <downsj@cvs.openbsd.org>1997-01-26 05:18:30 +0000
commit263b5fe1fe5a828ec19e6df99b56bc284a888f15 (patch)
tree8eabd06a2e787d55d8d5a72538ba5c280028d48f /sys/kern
parent860369cea67319fa9df33453a90c6dbb2150d356 (diff)
Add lchown(2).
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/syscalls.master5
-rw-r--r--sys/kern/vfs_syscalls.c54
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 */