Add lchown(2).
authordownsj <downsj@openbsd.org>
Sun, 26 Jan 1997 05:18:27 +0000 (05:18 +0000)
committerdownsj <downsj@openbsd.org>
Sun, 26 Jan 1997 05:18:27 +0000 (05:18 +0000)
sys/kern/syscalls.master
sys/kern/vfs_syscalls.c

index 3e480c3..16f4245 100644 (file)
@@ -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 ...]
 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); }
index d2c14f3..4ebf43c 100644 (file)
@@ -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 $        */
 
 /*
@@ -1563,6 +1563,58 @@ out:
        return (error);
 }
 
+/*
+ * 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.
  */