1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 39 * $FreeBSD$ 40 */ 41 42 /* For 4.3 integer FS ID compatibility */ 43 #include "opt_compat.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/buf.h> 48 #include <sys/sysent.h> 49 #include <sys/malloc.h> 50 #include <sys/mount.h> 51 #include <sys/sysproto.h> 52 #include <sys/namei.h> 53 #include <sys/filedesc.h> 54 #include <sys/kernel.h> 55 #include <sys/fcntl.h> 56 #include <sys/file.h> 57 #include <sys/linker.h> 58 #include <sys/stat.h> 59 #include <sys/unistd.h> 60 #include <sys/vnode.h> 61 #include <sys/proc.h> 62 #include <sys/dirent.h> 63 64 #include <miscfs/union/union.h> 65 66 #include <vm/vm.h> 67 #include <vm/vm_object.h> 68 #include <vm/vm_zone.h> 69 #include <sys/sysctl.h> 70 71 static int change_dir __P((struct nameidata *ndp, struct proc *p)); 72 static void checkdirs __P((struct vnode *olddp)); 73 static int chroot_refuse_vdir_fds __P((struct filedesc *fdp)); 74 static int getutimes __P((const struct timeval *, struct timespec *)); 75 static int setfown __P((struct proc *, struct vnode *, uid_t, gid_t)); 76 static int setfmode __P((struct proc *, struct vnode *, int)); 77 static int setfflags __P((struct proc *, struct vnode *, int)); 78 static int setutimes __P((struct proc *, struct vnode *, 79 const struct timespec *, int)); 80 static int usermount = 0; /* if 1, non-root can mount fs. */ 81 82 int (*union_dircheckp) __P((struct proc *, struct vnode **, struct file *)); 83 84 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, ""); 85 86 /* 87 * Virtual File System System Calls 88 */ 89 90 /* 91 * Mount a file system. 92 */ 93 #ifndef _SYS_SYSPROTO_H_ 94 struct mount_args { 95 char *type; 96 char *path; 97 int flags; 98 caddr_t data; 99 }; 100 #endif 101 /* ARGSUSED */ 102 int 103 mount(p, uap) 104 struct proc *p; 105 register struct mount_args /* { 106 syscallarg(char *) type; 107 syscallarg(char *) path; 108 syscallarg(int) flags; 109 syscallarg(caddr_t) data; 110 } */ *uap; 111 { 112 struct vnode *vp; 113 struct mount *mp; 114 struct vfsconf *vfsp; 115 int error, flag = 0, flag2 = 0; 116 struct vattr va; 117 #ifdef COMPAT_43 118 u_long fstypenum; 119 #endif 120 struct nameidata nd; 121 char fstypename[MFSNAMELEN]; 122 123 if (usermount == 0 && (error = suser(p))) 124 return (error); 125 /* 126 * Do not allow NFS export by non-root users. 127 */ 128 if (SCARG(uap, flags) & MNT_EXPORTED) { 129 error = suser(p); 130 if (error) 131 return (error); 132 } 133 /* 134 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users 135 */ 136 if (suser_xxx(p->p_ucred, 0, 0)) 137 SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV; 138 /* 139 * Get vnode to be covered 140 */ 141 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 142 SCARG(uap, path), p); 143 if ((error = namei(&nd)) != 0) 144 return (error); 145 vp = nd.ni_vp; 146 if (SCARG(uap, flags) & MNT_UPDATE) { 147 if ((vp->v_flag & VROOT) == 0) { 148 vput(vp); 149 return (EINVAL); 150 } 151 mp = vp->v_mount; 152 flag = mp->mnt_flag; 153 flag2 = mp->mnt_kern_flag; 154 /* 155 * We only allow the filesystem to be reloaded if it 156 * is currently mounted read-only. 157 */ 158 if ((SCARG(uap, flags) & MNT_RELOAD) && 159 ((mp->mnt_flag & MNT_RDONLY) == 0)) { 160 vput(vp); 161 return (EOPNOTSUPP); /* Needs translation */ 162 } 163 mp->mnt_flag |= 164 SCARG(uap, flags) & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE); 165 /* 166 * Only root, or the user that did the original mount is 167 * permitted to update it. 168 */ 169 if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid && 170 (error = suser(p))) { 171 vput(vp); 172 return (error); 173 } 174 if (vfs_busy(mp, LK_NOWAIT, 0, p)) { 175 vput(vp); 176 return (EBUSY); 177 } 178 VOP_UNLOCK(vp, 0, p); 179 goto update; 180 } 181 /* 182 * If the user is not root, ensure that they own the directory 183 * onto which we are attempting to mount. 184 */ 185 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) || 186 (va.va_uid != p->p_ucred->cr_uid && 187 (error = suser(p)))) { 188 vput(vp); 189 return (error); 190 } 191 if ((error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) 192 return (error); 193 if (vp->v_type != VDIR) { 194 vput(vp); 195 return (ENOTDIR); 196 } 197 #ifdef COMPAT_43 198 /* 199 * Historically filesystem types were identified by number. If we 200 * get an integer for the filesystem type instead of a string, we 201 * check to see if it matches one of the historic filesystem types. 202 */ 203 fstypenum = (uintptr_t)SCARG(uap, type); 204 if (fstypenum < maxvfsconf) { 205 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 206 if (vfsp->vfc_typenum == fstypenum) 207 break; 208 if (vfsp == NULL) { 209 vput(vp); 210 return (ENODEV); 211 } 212 strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN); 213 } else 214 #endif /* COMPAT_43 */ 215 if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) { 216 vput(vp); 217 return (error); 218 } 219 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 220 if (!strcmp(vfsp->vfc_name, fstypename)) 221 break; 222 if (vfsp == NULL) { 223 linker_file_t lf; 224 225 /* Refuse to load modules if securelevel raised */ 226 if (securelevel > 0) { 227 vput(vp); 228 return EPERM; 229 } 230 /* Only load modules for root (very important!) */ 231 if ((error = suser(p)) != 0) { 232 vput(vp); 233 return error; 234 } 235 error = linker_load_file(fstypename, &lf); 236 if (error || lf == NULL) { 237 vput(vp); 238 if (lf == NULL) 239 error = ENODEV; 240 return error; 241 } 242 lf->userrefs++; 243 /* lookup again, see if the VFS was loaded */ 244 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 245 if (!strcmp(vfsp->vfc_name, fstypename)) 246 break; 247 if (vfsp == NULL) { 248 lf->userrefs--; 249 linker_file_unload(lf); 250 vput(vp); 251 return (ENODEV); 252 } 253 } 254 simple_lock(&vp->v_interlock); 255 if ((vp->v_flag & VMOUNT) != 0 || 256 vp->v_mountedhere != NULL) { 257 simple_unlock(&vp->v_interlock); 258 vput(vp); 259 return (EBUSY); 260 } 261 vp->v_flag |= VMOUNT; 262 simple_unlock(&vp->v_interlock); 263 264 /* 265 * Allocate and initialize the filesystem. 266 */ 267 mp = (struct mount *)malloc((u_long)sizeof(struct mount), 268 M_MOUNT, M_WAITOK); 269 bzero((char *)mp, (u_long)sizeof(struct mount)); 270 lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE); 271 (void)vfs_busy(mp, LK_NOWAIT, 0, p); 272 mp->mnt_op = vfsp->vfc_vfsops; 273 mp->mnt_vfc = vfsp; 274 vfsp->vfc_refcount++; 275 mp->mnt_stat.f_type = vfsp->vfc_typenum; 276 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK; 277 strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN); 278 mp->mnt_vnodecovered = vp; 279 mp->mnt_stat.f_owner = p->p_ucred->cr_uid; 280 mp->mnt_iosize_max = DFLTPHYS; 281 VOP_UNLOCK(vp, 0, p); 282 update: 283 /* 284 * Set the mount level flags. 285 */ 286 if (SCARG(uap, flags) & MNT_RDONLY) 287 mp->mnt_flag |= MNT_RDONLY; 288 else if (mp->mnt_flag & MNT_RDONLY) 289 mp->mnt_kern_flag |= MNTK_WANTRDWR; 290 mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV | 291 MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME | 292 MNT_NOSYMFOLLOW | 293 MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); 294 mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC | 295 MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE | 296 MNT_NOSYMFOLLOW | 297 MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); 298 /* 299 * Mount the filesystem. 300 */ 301 error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, p); 302 if (mp->mnt_flag & MNT_UPDATE) { 303 vrele(vp); 304 if (mp->mnt_kern_flag & MNTK_WANTRDWR) 305 mp->mnt_flag &= ~MNT_RDONLY; 306 mp->mnt_flag &=~ (MNT_UPDATE | MNT_RELOAD | MNT_FORCE); 307 mp->mnt_kern_flag &=~ MNTK_WANTRDWR; 308 if (error) { 309 mp->mnt_flag = flag; 310 mp->mnt_kern_flag = flag2; 311 } 312 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 313 if (mp->mnt_syncer == NULL) 314 error = vfs_allocate_syncvnode(mp); 315 } else { 316 if (mp->mnt_syncer != NULL) 317 vrele(mp->mnt_syncer); 318 mp->mnt_syncer = NULL; 319 } 320 vfs_unbusy(mp, p); 321 return (error); 322 } 323 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 324 /* 325 * Put the new filesystem on the mount list after root. 326 */ 327 cache_purge(vp); 328 if (!error) { 329 simple_lock(&vp->v_interlock); 330 vp->v_flag &= ~VMOUNT; 331 vp->v_mountedhere = mp; 332 simple_unlock(&vp->v_interlock); 333 simple_lock(&mountlist_slock); 334 CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); 335 simple_unlock(&mountlist_slock); 336 checkdirs(vp); 337 VOP_UNLOCK(vp, 0, p); 338 if ((mp->mnt_flag & MNT_RDONLY) == 0) 339 error = vfs_allocate_syncvnode(mp); 340 vfs_unbusy(mp, p); 341 if ((error = VFS_START(mp, 0, p)) != 0) 342 vrele(vp); 343 } else { 344 simple_lock(&vp->v_interlock); 345 vp->v_flag &= ~VMOUNT; 346 simple_unlock(&vp->v_interlock); 347 mp->mnt_vfc->vfc_refcount--; 348 vfs_unbusy(mp, p); 349 free((caddr_t)mp, M_MOUNT); 350 vput(vp); 351 } 352 return (error); 353 } 354 355 /* 356 * Scan all active processes to see if any of them have a current 357 * or root directory onto which the new filesystem has just been 358 * mounted. If so, replace them with the new mount point. 359 */ 360 static void 361 checkdirs(olddp) 362 struct vnode *olddp; 363 { 364 struct filedesc *fdp; 365 struct vnode *newdp; 366 struct proc *p; 367 368 if (olddp->v_usecount == 1) 369 return; 370 if (VFS_ROOT(olddp->v_mountedhere, &newdp)) 371 panic("mount: lost mount"); 372 for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { 373 fdp = p->p_fd; 374 if (fdp->fd_cdir == olddp) { 375 vrele(fdp->fd_cdir); 376 VREF(newdp); 377 fdp->fd_cdir = newdp; 378 } 379 if (fdp->fd_rdir == olddp) { 380 vrele(fdp->fd_rdir); 381 VREF(newdp); 382 fdp->fd_rdir = newdp; 383 } 384 } 385 if (rootvnode == olddp) { 386 vrele(rootvnode); 387 VREF(newdp); 388 rootvnode = newdp; 389 } 390 vput(newdp); 391 } 392 393 /* 394 * Unmount a file system. 395 * 396 * Note: unmount takes a path to the vnode mounted on as argument, 397 * not special file (as before). 398 */ 399 #ifndef _SYS_SYSPROTO_H_ 400 struct unmount_args { 401 char *path; 402 int flags; 403 }; 404 #endif 405 /* ARGSUSED */ 406 int 407 unmount(p, uap) 408 struct proc *p; 409 register struct unmount_args /* { 410 syscallarg(char *) path; 411 syscallarg(int) flags; 412 } */ *uap; 413 { 414 register struct vnode *vp; 415 struct mount *mp; 416 int error; 417 struct nameidata nd; 418 419 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 420 SCARG(uap, path), p); 421 if ((error = namei(&nd)) != 0) 422 return (error); 423 vp = nd.ni_vp; 424 mp = vp->v_mount; 425 426 /* 427 * Only root, or the user that did the original mount is 428 * permitted to unmount this filesystem. 429 */ 430 if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) && 431 (error = suser(p))) { 432 vput(vp); 433 return (error); 434 } 435 436 /* 437 * Don't allow unmounting the root file system. 438 */ 439 if (mp->mnt_flag & MNT_ROOTFS) { 440 vput(vp); 441 return (EINVAL); 442 } 443 444 /* 445 * Must be the root of the filesystem 446 */ 447 if ((vp->v_flag & VROOT) == 0) { 448 vput(vp); 449 return (EINVAL); 450 } 451 vput(vp); 452 return (dounmount(mp, SCARG(uap, flags), p)); 453 } 454 455 /* 456 * Do the actual file system unmount. 457 */ 458 int 459 dounmount(mp, flags, p) 460 register struct mount *mp; 461 int flags; 462 struct proc *p; 463 { 464 struct vnode *coveredvp; 465 int error; 466 int async_flag; 467 468 simple_lock(&mountlist_slock); 469 mp->mnt_kern_flag |= MNTK_UNMOUNT; 470 lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK, &mountlist_slock, p); 471 472 if (mp->mnt_flag & MNT_EXPUBLIC) 473 vfs_setpublicfs(NULL, NULL, NULL); 474 475 vfs_msync(mp, MNT_WAIT); 476 async_flag = mp->mnt_flag & MNT_ASYNC; 477 mp->mnt_flag &=~ MNT_ASYNC; 478 cache_purgevfs(mp); /* remove cache entries for this file sys */ 479 if (mp->mnt_syncer != NULL) 480 vrele(mp->mnt_syncer); 481 if (((mp->mnt_flag & MNT_RDONLY) || 482 (error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0) || 483 (flags & MNT_FORCE)) 484 error = VFS_UNMOUNT(mp, flags, p); 485 simple_lock(&mountlist_slock); 486 if (error) { 487 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL) 488 (void) vfs_allocate_syncvnode(mp); 489 mp->mnt_kern_flag &= ~MNTK_UNMOUNT; 490 mp->mnt_flag |= async_flag; 491 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE, 492 &mountlist_slock, p); 493 if (mp->mnt_kern_flag & MNTK_MWAIT) 494 wakeup((caddr_t)mp); 495 return (error); 496 } 497 CIRCLEQ_REMOVE(&mountlist, mp, mnt_list); 498 if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) { 499 coveredvp->v_mountedhere = (struct mount *)0; 500 vrele(coveredvp); 501 } 502 mp->mnt_vfc->vfc_refcount--; 503 if (mp->mnt_vnodelist.lh_first != NULL) 504 panic("unmount: dangling vnode"); 505 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock, p); 506 if (mp->mnt_kern_flag & MNTK_MWAIT) 507 wakeup((caddr_t)mp); 508 free((caddr_t)mp, M_MOUNT); 509 return (0); 510 } 511 512 /* 513 * Sync each mounted filesystem. 514 */ 515 #ifndef _SYS_SYSPROTO_H_ 516 struct sync_args { 517 int dummy; 518 }; 519 #endif 520 521 #ifdef DEBUG 522 static int syncprt = 0; 523 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, ""); 524 #endif 525 526 /* ARGSUSED */ 527 int 528 sync(p, uap) 529 struct proc *p; 530 struct sync_args *uap; 531 { 532 register struct mount *mp, *nmp; 533 int asyncflag; 534 535 simple_lock(&mountlist_slock); 536 for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) { 537 if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { 538 nmp = mp->mnt_list.cqe_next; 539 continue; 540 } 541 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 542 asyncflag = mp->mnt_flag & MNT_ASYNC; 543 mp->mnt_flag &= ~MNT_ASYNC; 544 vfs_msync(mp, MNT_NOWAIT); 545 VFS_SYNC(mp, MNT_NOWAIT, 546 ((p != NULL) ? p->p_ucred : NOCRED), p); 547 mp->mnt_flag |= asyncflag; 548 } 549 simple_lock(&mountlist_slock); 550 nmp = mp->mnt_list.cqe_next; 551 vfs_unbusy(mp, p); 552 } 553 simple_unlock(&mountlist_slock); 554 #if 0 555 /* 556 * XXX don't call vfs_bufstats() yet because that routine 557 * was not imported in the Lite2 merge. 558 */ 559 #ifdef DIAGNOSTIC 560 if (syncprt) 561 vfs_bufstats(); 562 #endif /* DIAGNOSTIC */ 563 #endif 564 return (0); 565 } 566 567 /* XXX PRISON: could be per prison flag */ 568 static int prison_quotas; 569 #if 0 570 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, ""); 571 #endif 572 573 /* 574 * Change filesystem quotas. 575 */ 576 #ifndef _SYS_SYSPROTO_H_ 577 struct quotactl_args { 578 char *path; 579 int cmd; 580 int uid; 581 caddr_t arg; 582 }; 583 #endif 584 /* ARGSUSED */ 585 int 586 quotactl(p, uap) 587 struct proc *p; 588 register struct quotactl_args /* { 589 syscallarg(char *) path; 590 syscallarg(int) cmd; 591 syscallarg(int) uid; 592 syscallarg(caddr_t) arg; 593 } */ *uap; 594 { 595 register struct mount *mp; 596 int error; 597 struct nameidata nd; 598 599 if (p->p_prison && !prison_quotas) 600 return (EPERM); 601 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 602 if ((error = namei(&nd)) != 0) 603 return (error); 604 mp = nd.ni_vp->v_mount; 605 vrele(nd.ni_vp); 606 return (VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid), 607 SCARG(uap, arg), p)); 608 } 609 610 /* 611 * Get filesystem statistics. 612 */ 613 #ifndef _SYS_SYSPROTO_H_ 614 struct statfs_args { 615 char *path; 616 struct statfs *buf; 617 }; 618 #endif 619 /* ARGSUSED */ 620 int 621 statfs(p, uap) 622 struct proc *p; 623 register struct statfs_args /* { 624 syscallarg(char *) path; 625 syscallarg(struct statfs *) buf; 626 } */ *uap; 627 { 628 register struct mount *mp; 629 register struct statfs *sp; 630 int error; 631 struct nameidata nd; 632 struct statfs sb; 633 634 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 635 if ((error = namei(&nd)) != 0) 636 return (error); 637 mp = nd.ni_vp->v_mount; 638 sp = &mp->mnt_stat; 639 vrele(nd.ni_vp); 640 error = VFS_STATFS(mp, sp, p); 641 if (error) 642 return (error); 643 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 644 if (suser_xxx(p->p_ucred, 0, 0)) { 645 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 646 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 647 sp = &sb; 648 } 649 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); 650 } 651 652 /* 653 * Get filesystem statistics. 654 */ 655 #ifndef _SYS_SYSPROTO_H_ 656 struct fstatfs_args { 657 int fd; 658 struct statfs *buf; 659 }; 660 #endif 661 /* ARGSUSED */ 662 int 663 fstatfs(p, uap) 664 struct proc *p; 665 register struct fstatfs_args /* { 666 syscallarg(int) fd; 667 syscallarg(struct statfs *) buf; 668 } */ *uap; 669 { 670 struct file *fp; 671 struct mount *mp; 672 register struct statfs *sp; 673 int error; 674 struct statfs sb; 675 676 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 677 return (error); 678 mp = ((struct vnode *)fp->f_data)->v_mount; 679 sp = &mp->mnt_stat; 680 error = VFS_STATFS(mp, sp, p); 681 if (error) 682 return (error); 683 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 684 if (suser_xxx(p->p_ucred, 0, 0)) { 685 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 686 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 687 sp = &sb; 688 } 689 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); 690 } 691 692 /* 693 * Get statistics on all filesystems. 694 */ 695 #ifndef _SYS_SYSPROTO_H_ 696 struct getfsstat_args { 697 struct statfs *buf; 698 long bufsize; 699 int flags; 700 }; 701 #endif 702 int 703 getfsstat(p, uap) 704 struct proc *p; 705 register struct getfsstat_args /* { 706 syscallarg(struct statfs *) buf; 707 syscallarg(long) bufsize; 708 syscallarg(int) flags; 709 } */ *uap; 710 { 711 register struct mount *mp, *nmp; 712 register struct statfs *sp; 713 caddr_t sfsp; 714 long count, maxcount, error; 715 716 maxcount = SCARG(uap, bufsize) / sizeof(struct statfs); 717 sfsp = (caddr_t)SCARG(uap, buf); 718 count = 0; 719 simple_lock(&mountlist_slock); 720 for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) { 721 if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { 722 nmp = mp->mnt_list.cqe_next; 723 continue; 724 } 725 if (sfsp && count < maxcount) { 726 sp = &mp->mnt_stat; 727 /* 728 * If MNT_NOWAIT or MNT_LAZY is specified, do not 729 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY 730 * overrides MNT_WAIT. 731 */ 732 if (((SCARG(uap, flags) & (MNT_LAZY|MNT_NOWAIT)) == 0 || 733 (SCARG(uap, flags) & MNT_WAIT)) && 734 (error = VFS_STATFS(mp, sp, p))) { 735 simple_lock(&mountlist_slock); 736 nmp = mp->mnt_list.cqe_next; 737 vfs_unbusy(mp, p); 738 continue; 739 } 740 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 741 error = copyout((caddr_t)sp, sfsp, sizeof(*sp)); 742 if (error) { 743 vfs_unbusy(mp, p); 744 return (error); 745 } 746 sfsp += sizeof(*sp); 747 } 748 count++; 749 simple_lock(&mountlist_slock); 750 nmp = mp->mnt_list.cqe_next; 751 vfs_unbusy(mp, p); 752 } 753 simple_unlock(&mountlist_slock); 754 if (sfsp && count > maxcount) 755 p->p_retval[0] = maxcount; 756 else 757 p->p_retval[0] = count; 758 return (0); 759 } 760 761 /* 762 * Change current working directory to a given file descriptor. 763 */ 764 #ifndef _SYS_SYSPROTO_H_ 765 struct fchdir_args { 766 int fd; 767 }; 768 #endif 769 /* ARGSUSED */ 770 int 771 fchdir(p, uap) 772 struct proc *p; 773 struct fchdir_args /* { 774 syscallarg(int) fd; 775 } */ *uap; 776 { 777 register struct filedesc *fdp = p->p_fd; 778 struct vnode *vp, *tdp; 779 struct mount *mp; 780 struct file *fp; 781 int error; 782 783 if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0) 784 return (error); 785 vp = (struct vnode *)fp->f_data; 786 VREF(vp); 787 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 788 if (vp->v_type != VDIR) 789 error = ENOTDIR; 790 else 791 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 792 while (!error && (mp = vp->v_mountedhere) != NULL) { 793 if (vfs_busy(mp, 0, 0, p)) 794 continue; 795 error = VFS_ROOT(mp, &tdp); 796 vfs_unbusy(mp, p); 797 if (error) 798 break; 799 vput(vp); 800 vp = tdp; 801 } 802 if (error) { 803 vput(vp); 804 return (error); 805 } 806 VOP_UNLOCK(vp, 0, p); 807 vrele(fdp->fd_cdir); 808 fdp->fd_cdir = vp; 809 return (0); 810 } 811 812 /* 813 * Change current working directory (``.''). 814 */ 815 #ifndef _SYS_SYSPROTO_H_ 816 struct chdir_args { 817 char *path; 818 }; 819 #endif 820 /* ARGSUSED */ 821 int 822 chdir(p, uap) 823 struct proc *p; 824 struct chdir_args /* { 825 syscallarg(char *) path; 826 } */ *uap; 827 { 828 register struct filedesc *fdp = p->p_fd; 829 int error; 830 struct nameidata nd; 831 832 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 833 SCARG(uap, path), p); 834 if ((error = change_dir(&nd, p)) != 0) 835 return (error); 836 vrele(fdp->fd_cdir); 837 fdp->fd_cdir = nd.ni_vp; 838 return (0); 839 } 840 841 /* 842 * Helper function for raised chroot(2) security function: Refuse if 843 * any filedescriptors are open directories. 844 */ 845 static int 846 chroot_refuse_vdir_fds(fdp) 847 struct filedesc *fdp; 848 { 849 struct vnode *vp; 850 struct file *fp; 851 int error; 852 int fd; 853 854 for (fd = 0; fd < fdp->fd_nfiles ; fd++) { 855 error = getvnode(fdp, fd, &fp); 856 if (error) 857 continue; 858 vp = (struct vnode *)fp->f_data; 859 if (vp->v_type != VDIR) 860 continue; 861 return(EPERM); 862 } 863 return (0); 864 } 865 866 /* 867 * This sysctl determines if we will allow a process to chroot(2) if it 868 * has a directory open: 869 * 0: disallowed for all processes. 870 * 1: allowed for processes that were not already chroot(2)'ed. 871 * 2: allowed for all processes. 872 */ 873 874 static int chroot_allow_open_directories = 1; 875 876 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW, 877 &chroot_allow_open_directories, 0, ""); 878 879 /* 880 * Change notion of root (``/'') directory. 881 */ 882 #ifndef _SYS_SYSPROTO_H_ 883 struct chroot_args { 884 char *path; 885 }; 886 #endif 887 /* ARGSUSED */ 888 int 889 chroot(p, uap) 890 struct proc *p; 891 struct chroot_args /* { 892 syscallarg(char *) path; 893 } */ *uap; 894 { 895 register struct filedesc *fdp = p->p_fd; 896 int error; 897 struct nameidata nd; 898 899 error = suser_xxx(0, p, PRISON_ROOT); 900 if (error) 901 return (error); 902 if (chroot_allow_open_directories == 0 || 903 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) 904 error = chroot_refuse_vdir_fds(fdp); 905 if (error) 906 return (error); 907 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 908 SCARG(uap, path), p); 909 if ((error = change_dir(&nd, p)) != 0) 910 return (error); 911 vrele(fdp->fd_rdir); 912 fdp->fd_rdir = nd.ni_vp; 913 if (!fdp->fd_jdir) { 914 fdp->fd_jdir = nd.ni_vp; 915 VREF(fdp->fd_jdir); 916 } 917 return (0); 918 } 919 920 /* 921 * Common routine for chroot and chdir. 922 */ 923 static int 924 change_dir(ndp, p) 925 register struct nameidata *ndp; 926 struct proc *p; 927 { 928 struct vnode *vp; 929 int error; 930 931 error = namei(ndp); 932 if (error) 933 return (error); 934 vp = ndp->ni_vp; 935 if (vp->v_type != VDIR) 936 error = ENOTDIR; 937 else 938 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 939 if (error) 940 vput(vp); 941 else 942 VOP_UNLOCK(vp, 0, p); 943 return (error); 944 } 945 946 /* 947 * Check permissions, allocate an open file structure, 948 * and call the device open routine if any. 949 */ 950 #ifndef _SYS_SYSPROTO_H_ 951 struct open_args { 952 char *path; 953 int flags; 954 int mode; 955 }; 956 #endif 957 int 958 open(p, uap) 959 struct proc *p; 960 register struct open_args /* { 961 syscallarg(char *) path; 962 syscallarg(int) flags; 963 syscallarg(int) mode; 964 } */ *uap; 965 { 966 register struct filedesc *fdp = p->p_fd; 967 register struct file *fp; 968 register struct vnode *vp; 969 int cmode, flags, oflags; 970 struct file *nfp; 971 int type, indx, error; 972 struct flock lf; 973 struct nameidata nd; 974 975 oflags = SCARG(uap, flags); 976 if ((oflags & O_ACCMODE) == O_ACCMODE) 977 return (EINVAL); 978 flags = FFLAGS(oflags); 979 error = falloc(p, &nfp, &indx); 980 if (error) 981 return (error); 982 fp = nfp; 983 cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; 984 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 985 p->p_dupfd = -indx - 1; /* XXX check for fdopen */ 986 error = vn_open(&nd, flags, cmode); 987 if (error) { 988 ffree(fp); 989 if ((error == ENODEV || error == ENXIO) && 990 p->p_dupfd >= 0 && /* XXX from fdopen */ 991 (error = 992 dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) { 993 p->p_retval[0] = indx; 994 return (0); 995 } 996 if (error == ERESTART) 997 error = EINTR; 998 fdp->fd_ofiles[indx] = NULL; 999 return (error); 1000 } 1001 p->p_dupfd = 0; 1002 vp = nd.ni_vp; 1003 1004 fp->f_data = (caddr_t)vp; 1005 fp->f_flag = flags & FMASK; 1006 fp->f_ops = &vnops; 1007 fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE); 1008 if (flags & (O_EXLOCK | O_SHLOCK)) { 1009 lf.l_whence = SEEK_SET; 1010 lf.l_start = 0; 1011 lf.l_len = 0; 1012 if (flags & O_EXLOCK) 1013 lf.l_type = F_WRLCK; 1014 else 1015 lf.l_type = F_RDLCK; 1016 type = F_FLOCK; 1017 if ((flags & FNONBLOCK) == 0) 1018 type |= F_WAIT; 1019 VOP_UNLOCK(vp, 0, p); 1020 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { 1021 (void) vn_close(vp, fp->f_flag, fp->f_cred, p); 1022 ffree(fp); 1023 fdp->fd_ofiles[indx] = NULL; 1024 return (error); 1025 } 1026 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1027 fp->f_flag |= FHASLOCK; 1028 } 1029 /* assert that vn_open created a backing object if one is needed */ 1030 KASSERT(!vn_canvmio(vp) || vp->v_object != NULL, 1031 ("open: vmio vnode has no backing object after vn_open")); 1032 VOP_UNLOCK(vp, 0, p); 1033 p->p_retval[0] = indx; 1034 return (0); 1035 } 1036 1037 #ifdef COMPAT_43 1038 /* 1039 * Create a file. 1040 */ 1041 #ifndef _SYS_SYSPROTO_H_ 1042 struct ocreat_args { 1043 char *path; 1044 int mode; 1045 }; 1046 #endif 1047 int 1048 ocreat(p, uap) 1049 struct proc *p; 1050 register struct ocreat_args /* { 1051 syscallarg(char *) path; 1052 syscallarg(int) mode; 1053 } */ *uap; 1054 { 1055 struct open_args /* { 1056 syscallarg(char *) path; 1057 syscallarg(int) flags; 1058 syscallarg(int) mode; 1059 } */ nuap; 1060 1061 SCARG(&nuap, path) = SCARG(uap, path); 1062 SCARG(&nuap, mode) = SCARG(uap, mode); 1063 SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC; 1064 return (open(p, &nuap)); 1065 } 1066 #endif /* COMPAT_43 */ 1067 1068 /* 1069 * Create a special file. 1070 */ 1071 #ifndef _SYS_SYSPROTO_H_ 1072 struct mknod_args { 1073 char *path; 1074 int mode; 1075 int dev; 1076 }; 1077 #endif 1078 /* ARGSUSED */ 1079 int 1080 mknod(p, uap) 1081 struct proc *p; 1082 register struct mknod_args /* { 1083 syscallarg(char *) path; 1084 syscallarg(int) mode; 1085 syscallarg(int) dev; 1086 } */ *uap; 1087 { 1088 register struct vnode *vp; 1089 struct vattr vattr; 1090 int error; 1091 int whiteout = 0; 1092 struct nameidata nd; 1093 1094 switch (SCARG(uap, mode) & S_IFMT) { 1095 case S_IFCHR: 1096 case S_IFBLK: 1097 error = suser(p); 1098 break; 1099 default: 1100 error = suser_xxx(0, p, PRISON_ROOT); 1101 break; 1102 } 1103 if (error) 1104 return (error); 1105 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 1106 if ((error = namei(&nd)) != 0) 1107 return (error); 1108 vp = nd.ni_vp; 1109 if (vp != NULL) 1110 error = EEXIST; 1111 else { 1112 VATTR_NULL(&vattr); 1113 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; 1114 vattr.va_rdev = SCARG(uap, dev); 1115 whiteout = 0; 1116 1117 switch (SCARG(uap, mode) & S_IFMT) { 1118 case S_IFMT: /* used by badsect to flag bad sectors */ 1119 vattr.va_type = VBAD; 1120 break; 1121 case S_IFCHR: 1122 vattr.va_type = VCHR; 1123 break; 1124 case S_IFBLK: 1125 vattr.va_type = VBLK; 1126 break; 1127 case S_IFWHT: 1128 whiteout = 1; 1129 break; 1130 default: 1131 error = EINVAL; 1132 break; 1133 } 1134 } 1135 if (!error) { 1136 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1137 if (whiteout) { 1138 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); 1139 if (error) 1140 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1141 vput(nd.ni_dvp); 1142 } else { 1143 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, 1144 &nd.ni_cnd, &vattr); 1145 vput(nd.ni_dvp); 1146 } 1147 } else { 1148 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1149 if (nd.ni_dvp == vp) 1150 vrele(nd.ni_dvp); 1151 else 1152 vput(nd.ni_dvp); 1153 if (vp) 1154 vrele(vp); 1155 } 1156 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod"); 1157 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod"); 1158 return (error); 1159 } 1160 1161 /* 1162 * Create a named pipe. 1163 */ 1164 #ifndef _SYS_SYSPROTO_H_ 1165 struct mkfifo_args { 1166 char *path; 1167 int mode; 1168 }; 1169 #endif 1170 /* ARGSUSED */ 1171 int 1172 mkfifo(p, uap) 1173 struct proc *p; 1174 register struct mkfifo_args /* { 1175 syscallarg(char *) path; 1176 syscallarg(int) mode; 1177 } */ *uap; 1178 { 1179 struct vattr vattr; 1180 int error; 1181 struct nameidata nd; 1182 1183 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 1184 if ((error = namei(&nd)) != 0) 1185 return (error); 1186 if (nd.ni_vp != NULL) { 1187 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1188 if (nd.ni_dvp == nd.ni_vp) 1189 vrele(nd.ni_dvp); 1190 else 1191 vput(nd.ni_dvp); 1192 vrele(nd.ni_vp); 1193 return (EEXIST); 1194 } 1195 VATTR_NULL(&vattr); 1196 vattr.va_type = VFIFO; 1197 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; 1198 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1199 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 1200 vput(nd.ni_dvp); 1201 return (error); 1202 } 1203 1204 /* 1205 * Make a hard file link. 1206 */ 1207 #ifndef _SYS_SYSPROTO_H_ 1208 struct link_args { 1209 char *path; 1210 char *link; 1211 }; 1212 #endif 1213 /* ARGSUSED */ 1214 int 1215 link(p, uap) 1216 struct proc *p; 1217 register struct link_args /* { 1218 syscallarg(char *) path; 1219 syscallarg(char *) link; 1220 } */ *uap; 1221 { 1222 register struct vnode *vp; 1223 struct nameidata nd; 1224 int error; 1225 1226 NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, UIO_USERSPACE, SCARG(uap, path), p); 1227 if ((error = namei(&nd)) != 0) 1228 return (error); 1229 vp = nd.ni_vp; 1230 if (vp->v_type == VDIR) 1231 error = EPERM; /* POSIX */ 1232 else { 1233 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), p); 1234 error = namei(&nd); 1235 if (!error) { 1236 if (nd.ni_vp != NULL) { 1237 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1238 if (nd.ni_vp) 1239 vrele(nd.ni_vp); 1240 error = EEXIST; 1241 } else { 1242 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, 1243 LEASE_WRITE); 1244 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1245 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 1246 } 1247 if (nd.ni_dvp == nd.ni_vp) 1248 vrele(nd.ni_dvp); 1249 else 1250 vput(nd.ni_dvp); 1251 } 1252 } 1253 vrele(vp); 1254 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link"); 1255 ASSERT_VOP_UNLOCKED(nd.ni_vp, "link"); 1256 return (error); 1257 } 1258 1259 /* 1260 * Make a symbolic link. 1261 */ 1262 #ifndef _SYS_SYSPROTO_H_ 1263 struct symlink_args { 1264 char *path; 1265 char *link; 1266 }; 1267 #endif 1268 /* ARGSUSED */ 1269 int 1270 symlink(p, uap) 1271 struct proc *p; 1272 register struct symlink_args /* { 1273 syscallarg(char *) path; 1274 syscallarg(char *) link; 1275 } */ *uap; 1276 { 1277 struct vattr vattr; 1278 char *path; 1279 int error; 1280 struct nameidata nd; 1281 1282 path = zalloc(namei_zone); 1283 if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0) 1284 goto out; 1285 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), p); 1286 if ((error = namei(&nd)) != 0) 1287 goto out; 1288 if (nd.ni_vp) { 1289 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1290 if (nd.ni_dvp == nd.ni_vp) 1291 vrele(nd.ni_dvp); 1292 else 1293 vput(nd.ni_dvp); 1294 vrele(nd.ni_vp); 1295 error = EEXIST; 1296 goto out; 1297 } 1298 VATTR_NULL(&vattr); 1299 vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask; 1300 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1301 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path); 1302 vput(nd.ni_dvp); 1303 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); 1304 ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); 1305 out: 1306 zfree(namei_zone, path); 1307 return (error); 1308 } 1309 1310 /* 1311 * Delete a whiteout from the filesystem. 1312 */ 1313 /* ARGSUSED */ 1314 int 1315 undelete(p, uap) 1316 struct proc *p; 1317 register struct undelete_args /* { 1318 syscallarg(char *) path; 1319 } */ *uap; 1320 { 1321 int error; 1322 struct nameidata nd; 1323 1324 NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE, 1325 SCARG(uap, path), p); 1326 error = namei(&nd); 1327 if (error) 1328 return (error); 1329 1330 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { 1331 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1332 if (nd.ni_dvp == nd.ni_vp) 1333 vrele(nd.ni_dvp); 1334 else 1335 vput(nd.ni_dvp); 1336 if (nd.ni_vp) 1337 vrele(nd.ni_vp); 1338 return (EEXIST); 1339 } 1340 1341 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1342 if ((error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE)) != 0) 1343 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1344 vput(nd.ni_dvp); 1345 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete"); 1346 ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete"); 1347 return (error); 1348 } 1349 1350 /* 1351 * Delete a name from the filesystem. 1352 */ 1353 #ifndef _SYS_SYSPROTO_H_ 1354 struct unlink_args { 1355 char *path; 1356 }; 1357 #endif 1358 /* ARGSUSED */ 1359 int 1360 unlink(p, uap) 1361 struct proc *p; 1362 struct unlink_args /* { 1363 syscallarg(char *) path; 1364 } */ *uap; 1365 { 1366 register struct vnode *vp; 1367 int error; 1368 struct nameidata nd; 1369 1370 NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 1371 if ((error = namei(&nd)) != 0) 1372 return (error); 1373 vp = nd.ni_vp; 1374 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1375 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1376 1377 if (vp->v_type == VDIR) 1378 error = EPERM; /* POSIX */ 1379 else { 1380 /* 1381 * The root of a mounted filesystem cannot be deleted. 1382 * 1383 * XXX: can this only be a VDIR case? 1384 */ 1385 if (vp->v_flag & VROOT) 1386 error = EBUSY; 1387 } 1388 1389 if (!error) { 1390 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1391 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); 1392 } else { 1393 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1394 } 1395 if (nd.ni_dvp == vp) 1396 vrele(nd.ni_dvp); 1397 else 1398 vput(nd.ni_dvp); 1399 if (vp != NULLVP) 1400 vput(vp); 1401 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink"); 1402 ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink"); 1403 return (error); 1404 } 1405 1406 /* 1407 * Reposition read/write file offset. 1408 */ 1409 #ifndef _SYS_SYSPROTO_H_ 1410 struct lseek_args { 1411 int fd; 1412 int pad; 1413 off_t offset; 1414 int whence; 1415 }; 1416 #endif 1417 int 1418 lseek(p, uap) 1419 struct proc *p; 1420 register struct lseek_args /* { 1421 syscallarg(int) fd; 1422 syscallarg(int) pad; 1423 syscallarg(off_t) offset; 1424 syscallarg(int) whence; 1425 } */ *uap; 1426 { 1427 struct ucred *cred = p->p_ucred; 1428 register struct filedesc *fdp = p->p_fd; 1429 register struct file *fp; 1430 struct vattr vattr; 1431 int error; 1432 1433 if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles || 1434 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL) 1435 return (EBADF); 1436 if (fp->f_type != DTYPE_VNODE) 1437 return (ESPIPE); 1438 switch (SCARG(uap, whence)) { 1439 case L_INCR: 1440 fp->f_offset += SCARG(uap, offset); 1441 break; 1442 case L_XTND: 1443 error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p); 1444 if (error) 1445 return (error); 1446 fp->f_offset = SCARG(uap, offset) + vattr.va_size; 1447 break; 1448 case L_SET: 1449 fp->f_offset = SCARG(uap, offset); 1450 break; 1451 default: 1452 return (EINVAL); 1453 } 1454 *(off_t *)(p->p_retval) = fp->f_offset; 1455 return (0); 1456 } 1457 1458 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1459 /* 1460 * Reposition read/write file offset. 1461 */ 1462 #ifndef _SYS_SYSPROTO_H_ 1463 struct olseek_args { 1464 int fd; 1465 long offset; 1466 int whence; 1467 }; 1468 #endif 1469 int 1470 olseek(p, uap) 1471 struct proc *p; 1472 register struct olseek_args /* { 1473 syscallarg(int) fd; 1474 syscallarg(long) offset; 1475 syscallarg(int) whence; 1476 } */ *uap; 1477 { 1478 struct lseek_args /* { 1479 syscallarg(int) fd; 1480 syscallarg(int) pad; 1481 syscallarg(off_t) offset; 1482 syscallarg(int) whence; 1483 } */ nuap; 1484 int error; 1485 1486 SCARG(&nuap, fd) = SCARG(uap, fd); 1487 SCARG(&nuap, offset) = SCARG(uap, offset); 1488 SCARG(&nuap, whence) = SCARG(uap, whence); 1489 error = lseek(p, &nuap); 1490 return (error); 1491 } 1492 #endif /* COMPAT_43 */ 1493 1494 /* 1495 * Check access permissions. 1496 */ 1497 #ifndef _SYS_SYSPROTO_H_ 1498 struct access_args { 1499 char *path; 1500 int flags; 1501 }; 1502 #endif 1503 int 1504 access(p, uap) 1505 struct proc *p; 1506 register struct access_args /* { 1507 syscallarg(char *) path; 1508 syscallarg(int) flags; 1509 } */ *uap; 1510 { 1511 register struct ucred *cred = p->p_ucred; 1512 register struct vnode *vp; 1513 int error, flags, t_gid, t_uid; 1514 struct nameidata nd; 1515 1516 t_uid = cred->cr_uid; 1517 t_gid = cred->cr_groups[0]; 1518 cred->cr_uid = p->p_cred->p_ruid; 1519 cred->cr_groups[0] = p->p_cred->p_rgid; 1520 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1521 SCARG(uap, path), p); 1522 if ((error = namei(&nd)) != 0) 1523 goto out1; 1524 vp = nd.ni_vp; 1525 1526 /* Flags == 0 means only check for existence. */ 1527 if (SCARG(uap, flags)) { 1528 flags = 0; 1529 if (SCARG(uap, flags) & R_OK) 1530 flags |= VREAD; 1531 if (SCARG(uap, flags) & W_OK) 1532 flags |= VWRITE; 1533 if (SCARG(uap, flags) & X_OK) 1534 flags |= VEXEC; 1535 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 1536 error = VOP_ACCESS(vp, flags, cred, p); 1537 } 1538 vput(vp); 1539 out1: 1540 cred->cr_uid = t_uid; 1541 cred->cr_groups[0] = t_gid; 1542 return (error); 1543 } 1544 1545 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1546 /* 1547 * Get file status; this version follows links. 1548 */ 1549 #ifndef _SYS_SYSPROTO_H_ 1550 struct ostat_args { 1551 char *path; 1552 struct ostat *ub; 1553 }; 1554 #endif 1555 /* ARGSUSED */ 1556 int 1557 ostat(p, uap) 1558 struct proc *p; 1559 register struct ostat_args /* { 1560 syscallarg(char *) path; 1561 syscallarg(struct ostat *) ub; 1562 } */ *uap; 1563 { 1564 struct stat sb; 1565 struct ostat osb; 1566 int error; 1567 struct nameidata nd; 1568 1569 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1570 SCARG(uap, path), p); 1571 if ((error = namei(&nd)) != 0) 1572 return (error); 1573 error = vn_stat(nd.ni_vp, &sb, p); 1574 vput(nd.ni_vp); 1575 if (error) 1576 return (error); 1577 cvtstat(&sb, &osb); 1578 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); 1579 return (error); 1580 } 1581 1582 /* 1583 * Get file status; this version does not follow links. 1584 */ 1585 #ifndef _SYS_SYSPROTO_H_ 1586 struct olstat_args { 1587 char *path; 1588 struct ostat *ub; 1589 }; 1590 #endif 1591 /* ARGSUSED */ 1592 int 1593 olstat(p, uap) 1594 struct proc *p; 1595 register struct olstat_args /* { 1596 syscallarg(char *) path; 1597 syscallarg(struct ostat *) ub; 1598 } */ *uap; 1599 { 1600 struct vnode *vp; 1601 struct stat sb; 1602 struct ostat osb; 1603 int error; 1604 struct nameidata nd; 1605 1606 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1607 SCARG(uap, path), p); 1608 if ((error = namei(&nd)) != 0) 1609 return (error); 1610 vp = nd.ni_vp; 1611 error = vn_stat(vp, &sb, p); 1612 vput(vp); 1613 if (error) 1614 return (error); 1615 cvtstat(&sb, &osb); 1616 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); 1617 return (error); 1618 } 1619 1620 /* 1621 * Convert from an old to a new stat structure. 1622 */ 1623 void 1624 cvtstat(st, ost) 1625 struct stat *st; 1626 struct ostat *ost; 1627 { 1628 1629 ost->st_dev = st->st_dev; 1630 ost->st_ino = st->st_ino; 1631 ost->st_mode = st->st_mode; 1632 ost->st_nlink = st->st_nlink; 1633 ost->st_uid = st->st_uid; 1634 ost->st_gid = st->st_gid; 1635 ost->st_rdev = st->st_rdev; 1636 if (st->st_size < (quad_t)1 << 32) 1637 ost->st_size = st->st_size; 1638 else 1639 ost->st_size = -2; 1640 ost->st_atime = st->st_atime; 1641 ost->st_mtime = st->st_mtime; 1642 ost->st_ctime = st->st_ctime; 1643 ost->st_blksize = st->st_blksize; 1644 ost->st_blocks = st->st_blocks; 1645 ost->st_flags = st->st_flags; 1646 ost->st_gen = st->st_gen; 1647 } 1648 #endif /* COMPAT_43 || COMPAT_SUNOS */ 1649 1650 /* 1651 * Get file status; this version follows links. 1652 */ 1653 #ifndef _SYS_SYSPROTO_H_ 1654 struct stat_args { 1655 char *path; 1656 struct stat *ub; 1657 }; 1658 #endif 1659 /* ARGSUSED */ 1660 int 1661 stat(p, uap) 1662 struct proc *p; 1663 register struct stat_args /* { 1664 syscallarg(char *) path; 1665 syscallarg(struct stat *) ub; 1666 } */ *uap; 1667 { 1668 struct stat sb; 1669 int error; 1670 struct nameidata nd; 1671 1672 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1673 SCARG(uap, path), p); 1674 if ((error = namei(&nd)) != 0) 1675 return (error); 1676 error = vn_stat(nd.ni_vp, &sb, p); 1677 vput(nd.ni_vp); 1678 if (error) 1679 return (error); 1680 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); 1681 return (error); 1682 } 1683 1684 /* 1685 * Get file status; this version does not follow links. 1686 */ 1687 #ifndef _SYS_SYSPROTO_H_ 1688 struct lstat_args { 1689 char *path; 1690 struct stat *ub; 1691 }; 1692 #endif 1693 /* ARGSUSED */ 1694 int 1695 lstat(p, uap) 1696 struct proc *p; 1697 register struct lstat_args /* { 1698 syscallarg(char *) path; 1699 syscallarg(struct stat *) ub; 1700 } */ *uap; 1701 { 1702 int error; 1703 struct vnode *vp; 1704 struct stat sb; 1705 struct nameidata nd; 1706 1707 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1708 SCARG(uap, path), p); 1709 if ((error = namei(&nd)) != 0) 1710 return (error); 1711 vp = nd.ni_vp; 1712 error = vn_stat(vp, &sb, p); 1713 vput(vp); 1714 if (error) 1715 return (error); 1716 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); 1717 return (error); 1718 } 1719 1720 void 1721 cvtnstat(sb, nsb) 1722 struct stat *sb; 1723 struct nstat *nsb; 1724 { 1725 nsb->st_dev = sb->st_dev; 1726 nsb->st_ino = sb->st_ino; 1727 nsb->st_mode = sb->st_mode; 1728 nsb->st_nlink = sb->st_nlink; 1729 nsb->st_uid = sb->st_uid; 1730 nsb->st_gid = sb->st_gid; 1731 nsb->st_rdev = sb->st_rdev; 1732 nsb->st_atimespec = sb->st_atimespec; 1733 nsb->st_mtimespec = sb->st_mtimespec; 1734 nsb->st_ctimespec = sb->st_ctimespec; 1735 nsb->st_size = sb->st_size; 1736 nsb->st_blocks = sb->st_blocks; 1737 nsb->st_blksize = sb->st_blksize; 1738 nsb->st_flags = sb->st_flags; 1739 nsb->st_gen = sb->st_gen; 1740 } 1741 1742 #ifndef _SYS_SYSPROTO_H_ 1743 struct nstat_args { 1744 char *path; 1745 struct nstat *ub; 1746 }; 1747 #endif 1748 /* ARGSUSED */ 1749 int 1750 nstat(p, uap) 1751 struct proc *p; 1752 register struct nstat_args /* { 1753 syscallarg(char *) path; 1754 syscallarg(struct nstat *) ub; 1755 } */ *uap; 1756 { 1757 struct stat sb; 1758 struct nstat nsb; 1759 int error; 1760 struct nameidata nd; 1761 1762 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1763 SCARG(uap, path), p); 1764 if ((error = namei(&nd)) != 0) 1765 return (error); 1766 error = vn_stat(nd.ni_vp, &sb, p); 1767 vput(nd.ni_vp); 1768 if (error) 1769 return (error); 1770 cvtnstat(&sb, &nsb); 1771 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb)); 1772 return (error); 1773 } 1774 1775 /* 1776 * Get file status; this version does not follow links. 1777 */ 1778 #ifndef _SYS_SYSPROTO_H_ 1779 struct lstat_args { 1780 char *path; 1781 struct stat *ub; 1782 }; 1783 #endif 1784 /* ARGSUSED */ 1785 int 1786 nlstat(p, uap) 1787 struct proc *p; 1788 register struct nlstat_args /* { 1789 syscallarg(char *) path; 1790 syscallarg(struct nstat *) ub; 1791 } */ *uap; 1792 { 1793 int error; 1794 struct vnode *vp; 1795 struct stat sb; 1796 struct nstat nsb; 1797 struct nameidata nd; 1798 1799 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1800 SCARG(uap, path), p); 1801 if ((error = namei(&nd)) != 0) 1802 return (error); 1803 vp = nd.ni_vp; 1804 error = vn_stat(vp, &sb, p); 1805 vput(vp); 1806 if (error) 1807 return (error); 1808 cvtnstat(&sb, &nsb); 1809 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb)); 1810 return (error); 1811 } 1812 1813 /* 1814 * Get configurable pathname variables. 1815 */ 1816 #ifndef _SYS_SYSPROTO_H_ 1817 struct pathconf_args { 1818 char *path; 1819 int name; 1820 }; 1821 #endif 1822 /* ARGSUSED */ 1823 int 1824 pathconf(p, uap) 1825 struct proc *p; 1826 register struct pathconf_args /* { 1827 syscallarg(char *) path; 1828 syscallarg(int) name; 1829 } */ *uap; 1830 { 1831 int error; 1832 struct nameidata nd; 1833 1834 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1835 SCARG(uap, path), p); 1836 if ((error = namei(&nd)) != 0) 1837 return (error); 1838 error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), p->p_retval); 1839 vput(nd.ni_vp); 1840 return (error); 1841 } 1842 1843 /* 1844 * Return target name of a symbolic link. 1845 */ 1846 #ifndef _SYS_SYSPROTO_H_ 1847 struct readlink_args { 1848 char *path; 1849 char *buf; 1850 int count; 1851 }; 1852 #endif 1853 /* ARGSUSED */ 1854 int 1855 readlink(p, uap) 1856 struct proc *p; 1857 register struct readlink_args /* { 1858 syscallarg(char *) path; 1859 syscallarg(char *) buf; 1860 syscallarg(int) count; 1861 } */ *uap; 1862 { 1863 register struct vnode *vp; 1864 struct iovec aiov; 1865 struct uio auio; 1866 int error; 1867 struct nameidata nd; 1868 1869 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1870 SCARG(uap, path), p); 1871 if ((error = namei(&nd)) != 0) 1872 return (error); 1873 vp = nd.ni_vp; 1874 if (vp->v_type != VLNK) 1875 error = EINVAL; 1876 else { 1877 aiov.iov_base = SCARG(uap, buf); 1878 aiov.iov_len = SCARG(uap, count); 1879 auio.uio_iov = &aiov; 1880 auio.uio_iovcnt = 1; 1881 auio.uio_offset = 0; 1882 auio.uio_rw = UIO_READ; 1883 auio.uio_segflg = UIO_USERSPACE; 1884 auio.uio_procp = p; 1885 auio.uio_resid = SCARG(uap, count); 1886 error = VOP_READLINK(vp, &auio, p->p_ucred); 1887 } 1888 vput(vp); 1889 p->p_retval[0] = SCARG(uap, count) - auio.uio_resid; 1890 return (error); 1891 } 1892 1893 static int 1894 setfflags(p, vp, flags) 1895 struct proc *p; 1896 struct vnode *vp; 1897 int flags; 1898 { 1899 int error; 1900 struct vattr vattr; 1901 1902 /* 1903 * Prevent non-root users from setting flags on devices. When 1904 * a device is reused, users can retain ownership of the device 1905 * if they are allowed to set flags and programs assume that 1906 * chown can't fail when done as root. 1907 */ 1908 if ((vp->v_type == VCHR || vp->v_type == VBLK) && 1909 ((error = suser_xxx(p->p_ucred, p, PRISON_ROOT)) != 0)) 1910 return (error); 1911 1912 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1913 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1914 VATTR_NULL(&vattr); 1915 vattr.va_flags = flags; 1916 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1917 VOP_UNLOCK(vp, 0, p); 1918 return (error); 1919 } 1920 1921 /* 1922 * Change flags of a file given a path name. 1923 */ 1924 #ifndef _SYS_SYSPROTO_H_ 1925 struct chflags_args { 1926 char *path; 1927 int flags; 1928 }; 1929 #endif 1930 /* ARGSUSED */ 1931 int 1932 chflags(p, uap) 1933 struct proc *p; 1934 register struct chflags_args /* { 1935 syscallarg(char *) path; 1936 syscallarg(int) flags; 1937 } */ *uap; 1938 { 1939 int error; 1940 struct nameidata nd; 1941 1942 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 1943 if ((error = namei(&nd)) != 0) 1944 return (error); 1945 error = setfflags(p, nd.ni_vp, SCARG(uap, flags)); 1946 vrele(nd.ni_vp); 1947 return error; 1948 } 1949 1950 /* 1951 * Change flags of a file given a file descriptor. 1952 */ 1953 #ifndef _SYS_SYSPROTO_H_ 1954 struct fchflags_args { 1955 int fd; 1956 int flags; 1957 }; 1958 #endif 1959 /* ARGSUSED */ 1960 int 1961 fchflags(p, uap) 1962 struct proc *p; 1963 register struct fchflags_args /* { 1964 syscallarg(int) fd; 1965 syscallarg(int) flags; 1966 } */ *uap; 1967 { 1968 struct file *fp; 1969 int error; 1970 1971 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 1972 return (error); 1973 return setfflags(p, (struct vnode *) fp->f_data, SCARG(uap, flags)); 1974 } 1975 1976 static int 1977 setfmode(p, vp, mode) 1978 struct proc *p; 1979 struct vnode *vp; 1980 int mode; 1981 { 1982 int error; 1983 struct vattr vattr; 1984 1985 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1986 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1987 VATTR_NULL(&vattr); 1988 vattr.va_mode = mode & ALLPERMS; 1989 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1990 VOP_UNLOCK(vp, 0, p); 1991 return error; 1992 } 1993 1994 /* 1995 * Change mode of a file given path name. 1996 */ 1997 #ifndef _SYS_SYSPROTO_H_ 1998 struct chmod_args { 1999 char *path; 2000 int mode; 2001 }; 2002 #endif 2003 /* ARGSUSED */ 2004 int 2005 chmod(p, uap) 2006 struct proc *p; 2007 register struct chmod_args /* { 2008 syscallarg(char *) path; 2009 syscallarg(int) mode; 2010 } */ *uap; 2011 { 2012 int error; 2013 struct nameidata nd; 2014 2015 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2016 if ((error = namei(&nd)) != 0) 2017 return (error); 2018 error = setfmode(p, nd.ni_vp, SCARG(uap, mode)); 2019 vrele(nd.ni_vp); 2020 return error; 2021 } 2022 2023 /* 2024 * Change mode of a file given path name (don't follow links.) 2025 */ 2026 #ifndef _SYS_SYSPROTO_H_ 2027 struct lchmod_args { 2028 char *path; 2029 int mode; 2030 }; 2031 #endif 2032 /* ARGSUSED */ 2033 int 2034 lchmod(p, uap) 2035 struct proc *p; 2036 register struct lchmod_args /* { 2037 syscallarg(char *) path; 2038 syscallarg(int) mode; 2039 } */ *uap; 2040 { 2041 int error; 2042 struct nameidata nd; 2043 2044 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2045 if ((error = namei(&nd)) != 0) 2046 return (error); 2047 error = setfmode(p, nd.ni_vp, SCARG(uap, mode)); 2048 vrele(nd.ni_vp); 2049 return error; 2050 } 2051 2052 /* 2053 * Change mode of a file given a file descriptor. 2054 */ 2055 #ifndef _SYS_SYSPROTO_H_ 2056 struct fchmod_args { 2057 int fd; 2058 int mode; 2059 }; 2060 #endif 2061 /* ARGSUSED */ 2062 int 2063 fchmod(p, uap) 2064 struct proc *p; 2065 register struct fchmod_args /* { 2066 syscallarg(int) fd; 2067 syscallarg(int) mode; 2068 } */ *uap; 2069 { 2070 struct file *fp; 2071 int error; 2072 2073 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2074 return (error); 2075 return setfmode(p, (struct vnode *)fp->f_data, SCARG(uap, mode)); 2076 } 2077 2078 static int 2079 setfown(p, vp, uid, gid) 2080 struct proc *p; 2081 struct vnode *vp; 2082 uid_t uid; 2083 gid_t gid; 2084 { 2085 int error; 2086 struct vattr vattr; 2087 2088 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2089 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2090 VATTR_NULL(&vattr); 2091 vattr.va_uid = uid; 2092 vattr.va_gid = gid; 2093 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 2094 VOP_UNLOCK(vp, 0, p); 2095 return error; 2096 } 2097 2098 /* 2099 * Set ownership given a path name. 2100 */ 2101 #ifndef _SYS_SYSPROTO_H_ 2102 struct chown_args { 2103 char *path; 2104 int uid; 2105 int gid; 2106 }; 2107 #endif 2108 /* ARGSUSED */ 2109 int 2110 chown(p, uap) 2111 struct proc *p; 2112 register struct chown_args /* { 2113 syscallarg(char *) path; 2114 syscallarg(int) uid; 2115 syscallarg(int) gid; 2116 } */ *uap; 2117 { 2118 int error; 2119 struct nameidata nd; 2120 2121 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2122 if ((error = namei(&nd)) != 0) 2123 return (error); 2124 error = setfown(p, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); 2125 vrele(nd.ni_vp); 2126 2127 return (error); 2128 } 2129 2130 /* 2131 * Set ownership given a path name, do not cross symlinks. 2132 */ 2133 #ifndef _SYS_SYSPROTO_H_ 2134 struct lchown_args { 2135 char *path; 2136 int uid; 2137 int gid; 2138 }; 2139 #endif 2140 /* ARGSUSED */ 2141 int 2142 lchown(p, uap) 2143 struct proc *p; 2144 register struct lchown_args /* { 2145 syscallarg(char *) path; 2146 syscallarg(int) uid; 2147 syscallarg(int) gid; 2148 } */ *uap; 2149 { 2150 int error; 2151 struct nameidata nd; 2152 2153 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2154 if ((error = namei(&nd)) != 0) 2155 return (error); 2156 error = setfown(p, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); 2157 vrele(nd.ni_vp); 2158 return (error); 2159 } 2160 2161 /* 2162 * Set ownership given a file descriptor. 2163 */ 2164 #ifndef _SYS_SYSPROTO_H_ 2165 struct fchown_args { 2166 int fd; 2167 int uid; 2168 int gid; 2169 }; 2170 #endif 2171 /* ARGSUSED */ 2172 int 2173 fchown(p, uap) 2174 struct proc *p; 2175 register struct fchown_args /* { 2176 syscallarg(int) fd; 2177 syscallarg(int) uid; 2178 syscallarg(int) gid; 2179 } */ *uap; 2180 { 2181 struct file *fp; 2182 int error; 2183 2184 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2185 return (error); 2186 return setfown(p, (struct vnode *)fp->f_data, 2187 SCARG(uap, uid), SCARG(uap, gid)); 2188 } 2189 2190 static int 2191 getutimes(usrtvp, tsp) 2192 const struct timeval *usrtvp; 2193 struct timespec *tsp; 2194 { 2195 struct timeval tv[2]; 2196 int error; 2197 2198 if (usrtvp == NULL) { 2199 microtime(&tv[0]); 2200 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 2201 tsp[1] = tsp[0]; 2202 } else { 2203 if ((error = copyin(usrtvp, tv, sizeof (tv))) != 0) 2204 return (error); 2205 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); 2206 TIMEVAL_TO_TIMESPEC(&tv[1], &tsp[1]); 2207 } 2208 return 0; 2209 } 2210 2211 static int 2212 setutimes(p, vp, ts, nullflag) 2213 struct proc *p; 2214 struct vnode *vp; 2215 const struct timespec *ts; 2216 int nullflag; 2217 { 2218 int error; 2219 struct vattr vattr; 2220 2221 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2222 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2223 VATTR_NULL(&vattr); 2224 vattr.va_atime = ts[0]; 2225 vattr.va_mtime = ts[1]; 2226 if (nullflag) 2227 vattr.va_vaflags |= VA_UTIMES_NULL; 2228 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 2229 VOP_UNLOCK(vp, 0, p); 2230 return error; 2231 } 2232 2233 /* 2234 * Set the access and modification times of a file. 2235 */ 2236 #ifndef _SYS_SYSPROTO_H_ 2237 struct utimes_args { 2238 char *path; 2239 struct timeval *tptr; 2240 }; 2241 #endif 2242 /* ARGSUSED */ 2243 int 2244 utimes(p, uap) 2245 struct proc *p; 2246 register struct utimes_args /* { 2247 syscallarg(char *) path; 2248 syscallarg(struct timeval *) tptr; 2249 } */ *uap; 2250 { 2251 struct timespec ts[2]; 2252 struct timeval *usrtvp; 2253 int error; 2254 struct nameidata nd; 2255 2256 usrtvp = SCARG(uap, tptr); 2257 if ((error = getutimes(usrtvp, ts)) != 0) 2258 return (error); 2259 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2260 if ((error = namei(&nd)) != 0) 2261 return (error); 2262 error = setutimes(p, nd.ni_vp, ts, usrtvp == NULL); 2263 vrele(nd.ni_vp); 2264 return (error); 2265 } 2266 2267 /* 2268 * Set the access and modification times of a file. 2269 */ 2270 #ifndef _SYS_SYSPROTO_H_ 2271 struct lutimes_args { 2272 char *path; 2273 struct timeval *tptr; 2274 }; 2275 #endif 2276 /* ARGSUSED */ 2277 int 2278 lutimes(p, uap) 2279 struct proc *p; 2280 register struct lutimes_args /* { 2281 syscallarg(char *) path; 2282 syscallarg(struct timeval *) tptr; 2283 } */ *uap; 2284 { 2285 struct timespec ts[2]; 2286 struct timeval *usrtvp; 2287 int error; 2288 struct nameidata nd; 2289 2290 usrtvp = SCARG(uap, tptr); 2291 if ((error = getutimes(usrtvp, ts)) != 0) 2292 return (error); 2293 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2294 if ((error = namei(&nd)) != 0) 2295 return (error); 2296 error = setutimes(p, nd.ni_vp, ts, usrtvp == NULL); 2297 vrele(nd.ni_vp); 2298 return (error); 2299 } 2300 2301 /* 2302 * Set the access and modification times of a file. 2303 */ 2304 #ifndef _SYS_SYSPROTO_H_ 2305 struct futimes_args { 2306 int fd; 2307 struct timeval *tptr; 2308 }; 2309 #endif 2310 /* ARGSUSED */ 2311 int 2312 futimes(p, uap) 2313 struct proc *p; 2314 register struct futimes_args /* { 2315 syscallarg(int ) fd; 2316 syscallarg(struct timeval *) tptr; 2317 } */ *uap; 2318 { 2319 struct timespec ts[2]; 2320 struct file *fp; 2321 struct timeval *usrtvp; 2322 int error; 2323 2324 usrtvp = SCARG(uap, tptr); 2325 if ((error = getutimes(usrtvp, ts)) != 0) 2326 return (error); 2327 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2328 return (error); 2329 return setutimes(p, (struct vnode *)fp->f_data, ts, usrtvp == NULL); 2330 } 2331 2332 /* 2333 * Truncate a file given its path name. 2334 */ 2335 #ifndef _SYS_SYSPROTO_H_ 2336 struct truncate_args { 2337 char *path; 2338 int pad; 2339 off_t length; 2340 }; 2341 #endif 2342 /* ARGSUSED */ 2343 int 2344 truncate(p, uap) 2345 struct proc *p; 2346 register struct truncate_args /* { 2347 syscallarg(char *) path; 2348 syscallarg(int) pad; 2349 syscallarg(off_t) length; 2350 } */ *uap; 2351 { 2352 register struct vnode *vp; 2353 struct vattr vattr; 2354 int error; 2355 struct nameidata nd; 2356 2357 if (uap->length < 0) 2358 return(EINVAL); 2359 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2360 if ((error = namei(&nd)) != 0) 2361 return (error); 2362 vp = nd.ni_vp; 2363 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2364 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2365 if (vp->v_type == VDIR) 2366 error = EISDIR; 2367 else if ((error = vn_writechk(vp)) == 0 && 2368 (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)) == 0) { 2369 VATTR_NULL(&vattr); 2370 vattr.va_size = SCARG(uap, length); 2371 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 2372 } 2373 vput(vp); 2374 return (error); 2375 } 2376 2377 /* 2378 * Truncate a file given a file descriptor. 2379 */ 2380 #ifndef _SYS_SYSPROTO_H_ 2381 struct ftruncate_args { 2382 int fd; 2383 int pad; 2384 off_t length; 2385 }; 2386 #endif 2387 /* ARGSUSED */ 2388 int 2389 ftruncate(p, uap) 2390 struct proc *p; 2391 register struct ftruncate_args /* { 2392 syscallarg(int) fd; 2393 syscallarg(int) pad; 2394 syscallarg(off_t) length; 2395 } */ *uap; 2396 { 2397 struct vattr vattr; 2398 struct vnode *vp; 2399 struct file *fp; 2400 int error; 2401 2402 if (uap->length < 0) 2403 return(EINVAL); 2404 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2405 return (error); 2406 if ((fp->f_flag & FWRITE) == 0) 2407 return (EINVAL); 2408 vp = (struct vnode *)fp->f_data; 2409 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2410 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2411 if (vp->v_type == VDIR) 2412 error = EISDIR; 2413 else if ((error = vn_writechk(vp)) == 0) { 2414 VATTR_NULL(&vattr); 2415 vattr.va_size = SCARG(uap, length); 2416 error = VOP_SETATTR(vp, &vattr, fp->f_cred, p); 2417 } 2418 VOP_UNLOCK(vp, 0, p); 2419 return (error); 2420 } 2421 2422 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 2423 /* 2424 * Truncate a file given its path name. 2425 */ 2426 #ifndef _SYS_SYSPROTO_H_ 2427 struct otruncate_args { 2428 char *path; 2429 long length; 2430 }; 2431 #endif 2432 /* ARGSUSED */ 2433 int 2434 otruncate(p, uap) 2435 struct proc *p; 2436 register struct otruncate_args /* { 2437 syscallarg(char *) path; 2438 syscallarg(long) length; 2439 } */ *uap; 2440 { 2441 struct truncate_args /* { 2442 syscallarg(char *) path; 2443 syscallarg(int) pad; 2444 syscallarg(off_t) length; 2445 } */ nuap; 2446 2447 SCARG(&nuap, path) = SCARG(uap, path); 2448 SCARG(&nuap, length) = SCARG(uap, length); 2449 return (truncate(p, &nuap)); 2450 } 2451 2452 /* 2453 * Truncate a file given a file descriptor. 2454 */ 2455 #ifndef _SYS_SYSPROTO_H_ 2456 struct oftruncate_args { 2457 int fd; 2458 long length; 2459 }; 2460 #endif 2461 /* ARGSUSED */ 2462 int 2463 oftruncate(p, uap) 2464 struct proc *p; 2465 register struct oftruncate_args /* { 2466 syscallarg(int) fd; 2467 syscallarg(long) length; 2468 } */ *uap; 2469 { 2470 struct ftruncate_args /* { 2471 syscallarg(int) fd; 2472 syscallarg(int) pad; 2473 syscallarg(off_t) length; 2474 } */ nuap; 2475 2476 SCARG(&nuap, fd) = SCARG(uap, fd); 2477 SCARG(&nuap, length) = SCARG(uap, length); 2478 return (ftruncate(p, &nuap)); 2479 } 2480 #endif /* COMPAT_43 || COMPAT_SUNOS */ 2481 2482 /* 2483 * Sync an open file. 2484 */ 2485 #ifndef _SYS_SYSPROTO_H_ 2486 struct fsync_args { 2487 int fd; 2488 }; 2489 #endif 2490 /* ARGSUSED */ 2491 int 2492 fsync(p, uap) 2493 struct proc *p; 2494 struct fsync_args /* { 2495 syscallarg(int) fd; 2496 } */ *uap; 2497 { 2498 register struct vnode *vp; 2499 struct file *fp; 2500 int error; 2501 2502 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2503 return (error); 2504 vp = (struct vnode *)fp->f_data; 2505 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2506 if (vp->v_object) 2507 vm_object_page_clean(vp->v_object, 0, 0, 0); 2508 if ((error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p)) == 0 && 2509 vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) && 2510 bioops.io_fsync) 2511 error = (*bioops.io_fsync)(vp); 2512 VOP_UNLOCK(vp, 0, p); 2513 return (error); 2514 } 2515 2516 /* 2517 * Rename files. Source and destination must either both be directories, 2518 * or both not be directories. If target is a directory, it must be empty. 2519 */ 2520 #ifndef _SYS_SYSPROTO_H_ 2521 struct rename_args { 2522 char *from; 2523 char *to; 2524 }; 2525 #endif 2526 /* ARGSUSED */ 2527 int 2528 rename(p, uap) 2529 struct proc *p; 2530 register struct rename_args /* { 2531 syscallarg(char *) from; 2532 syscallarg(char *) to; 2533 } */ *uap; 2534 { 2535 register struct vnode *tvp, *fvp, *tdvp; 2536 struct nameidata fromnd, tond; 2537 int error; 2538 2539 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE, 2540 SCARG(uap, from), p); 2541 if ((error = namei(&fromnd)) != 0) 2542 return (error); 2543 fvp = fromnd.ni_vp; 2544 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | NOOBJ, 2545 UIO_USERSPACE, SCARG(uap, to), p); 2546 if (fromnd.ni_vp->v_type == VDIR) 2547 tond.ni_cnd.cn_flags |= WILLBEDIR; 2548 if ((error = namei(&tond)) != 0) { 2549 /* Translate error code for rename("dir1", "dir2/."). */ 2550 if (error == EISDIR && fvp->v_type == VDIR) 2551 error = EINVAL; 2552 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 2553 vrele(fromnd.ni_dvp); 2554 vrele(fvp); 2555 goto out1; 2556 } 2557 tdvp = tond.ni_dvp; 2558 tvp = tond.ni_vp; 2559 if (tvp != NULL) { 2560 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 2561 error = ENOTDIR; 2562 goto out; 2563 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 2564 error = EISDIR; 2565 goto out; 2566 } 2567 } 2568 if (fvp == tdvp) 2569 error = EINVAL; 2570 /* 2571 * If source is the same as the destination (that is the 2572 * same inode number with the same name in the same directory), 2573 * then there is nothing to do. 2574 */ 2575 if (fvp == tvp && fromnd.ni_dvp == tdvp && 2576 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen && 2577 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr, 2578 fromnd.ni_cnd.cn_namelen)) 2579 error = -1; 2580 out: 2581 if (!error) { 2582 VOP_LEASE(tdvp, p, p->p_ucred, LEASE_WRITE); 2583 if (fromnd.ni_dvp != tdvp) { 2584 VOP_LEASE(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 2585 } 2586 if (tvp) { 2587 VOP_LEASE(tvp, p, p->p_ucred, LEASE_WRITE); 2588 } 2589 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 2590 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 2591 } else { 2592 VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd); 2593 if (tdvp == tvp) 2594 vrele(tdvp); 2595 else 2596 vput(tdvp); 2597 if (tvp) 2598 vput(tvp); 2599 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 2600 vrele(fromnd.ni_dvp); 2601 vrele(fvp); 2602 } 2603 vrele(tond.ni_startdir); 2604 ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename"); 2605 ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename"); 2606 ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename"); 2607 ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename"); 2608 zfree(namei_zone, tond.ni_cnd.cn_pnbuf); 2609 out1: 2610 if (fromnd.ni_startdir) 2611 vrele(fromnd.ni_startdir); 2612 zfree(namei_zone, fromnd.ni_cnd.cn_pnbuf); 2613 if (error == -1) 2614 return (0); 2615 return (error); 2616 } 2617 2618 /* 2619 * Make a directory file. 2620 */ 2621 #ifndef _SYS_SYSPROTO_H_ 2622 struct mkdir_args { 2623 char *path; 2624 int mode; 2625 }; 2626 #endif 2627 /* ARGSUSED */ 2628 int 2629 mkdir(p, uap) 2630 struct proc *p; 2631 register struct mkdir_args /* { 2632 syscallarg(char *) path; 2633 syscallarg(int) mode; 2634 } */ *uap; 2635 { 2636 register struct vnode *vp; 2637 struct vattr vattr; 2638 int error; 2639 struct nameidata nd; 2640 2641 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 2642 nd.ni_cnd.cn_flags |= WILLBEDIR; 2643 if ((error = namei(&nd)) != 0) 2644 return (error); 2645 vp = nd.ni_vp; 2646 if (vp != NULL) { 2647 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 2648 if (nd.ni_dvp == vp) 2649 vrele(nd.ni_dvp); 2650 else 2651 vput(nd.ni_dvp); 2652 vrele(vp); 2653 return (EEXIST); 2654 } 2655 VATTR_NULL(&vattr); 2656 vattr.va_type = VDIR; 2657 vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask; 2658 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 2659 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 2660 vput(nd.ni_dvp); 2661 if (!error) 2662 vput(nd.ni_vp); 2663 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir"); 2664 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir"); 2665 return (error); 2666 } 2667 2668 /* 2669 * Remove a directory file. 2670 */ 2671 #ifndef _SYS_SYSPROTO_H_ 2672 struct rmdir_args { 2673 char *path; 2674 }; 2675 #endif 2676 /* ARGSUSED */ 2677 int 2678 rmdir(p, uap) 2679 struct proc *p; 2680 struct rmdir_args /* { 2681 syscallarg(char *) path; 2682 } */ *uap; 2683 { 2684 register struct vnode *vp; 2685 int error; 2686 struct nameidata nd; 2687 2688 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, 2689 SCARG(uap, path), p); 2690 if ((error = namei(&nd)) != 0) 2691 return (error); 2692 vp = nd.ni_vp; 2693 if (vp->v_type != VDIR) { 2694 error = ENOTDIR; 2695 goto out; 2696 } 2697 /* 2698 * No rmdir "." please. 2699 */ 2700 if (nd.ni_dvp == vp) { 2701 error = EINVAL; 2702 goto out; 2703 } 2704 /* 2705 * The root of a mounted filesystem cannot be deleted. 2706 */ 2707 if (vp->v_flag & VROOT) 2708 error = EBUSY; 2709 out: 2710 if (!error) { 2711 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 2712 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2713 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 2714 } else { 2715 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 2716 } 2717 if (nd.ni_dvp == vp) 2718 vrele(nd.ni_dvp); 2719 else 2720 vput(nd.ni_dvp); 2721 if (vp != NULLVP) 2722 vput(vp); 2723 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir"); 2724 ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir"); 2725 return (error); 2726 } 2727 2728 #ifdef COMPAT_43 2729 /* 2730 * Read a block of directory entries in a file system independent format. 2731 */ 2732 #ifndef _SYS_SYSPROTO_H_ 2733 struct ogetdirentries_args { 2734 int fd; 2735 char *buf; 2736 u_int count; 2737 long *basep; 2738 }; 2739 #endif 2740 int 2741 ogetdirentries(p, uap) 2742 struct proc *p; 2743 register struct ogetdirentries_args /* { 2744 syscallarg(int) fd; 2745 syscallarg(char *) buf; 2746 syscallarg(u_int) count; 2747 syscallarg(long *) basep; 2748 } */ *uap; 2749 { 2750 struct vnode *vp; 2751 struct file *fp; 2752 struct uio auio, kuio; 2753 struct iovec aiov, kiov; 2754 struct dirent *dp, *edp; 2755 caddr_t dirbuf; 2756 int error, eofflag, readcnt; 2757 long loff; 2758 2759 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2760 return (error); 2761 if ((fp->f_flag & FREAD) == 0) 2762 return (EBADF); 2763 vp = (struct vnode *)fp->f_data; 2764 unionread: 2765 if (vp->v_type != VDIR) 2766 return (EINVAL); 2767 aiov.iov_base = SCARG(uap, buf); 2768 aiov.iov_len = SCARG(uap, count); 2769 auio.uio_iov = &aiov; 2770 auio.uio_iovcnt = 1; 2771 auio.uio_rw = UIO_READ; 2772 auio.uio_segflg = UIO_USERSPACE; 2773 auio.uio_procp = p; 2774 auio.uio_resid = SCARG(uap, count); 2775 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2776 loff = auio.uio_offset = fp->f_offset; 2777 # if (BYTE_ORDER != LITTLE_ENDIAN) 2778 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 2779 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 2780 NULL, NULL); 2781 fp->f_offset = auio.uio_offset; 2782 } else 2783 # endif 2784 { 2785 kuio = auio; 2786 kuio.uio_iov = &kiov; 2787 kuio.uio_segflg = UIO_SYSSPACE; 2788 kiov.iov_len = SCARG(uap, count); 2789 MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK); 2790 kiov.iov_base = dirbuf; 2791 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, 2792 NULL, NULL); 2793 fp->f_offset = kuio.uio_offset; 2794 if (error == 0) { 2795 readcnt = SCARG(uap, count) - kuio.uio_resid; 2796 edp = (struct dirent *)&dirbuf[readcnt]; 2797 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 2798 # if (BYTE_ORDER == LITTLE_ENDIAN) 2799 /* 2800 * The expected low byte of 2801 * dp->d_namlen is our dp->d_type. 2802 * The high MBZ byte of dp->d_namlen 2803 * is our dp->d_namlen. 2804 */ 2805 dp->d_type = dp->d_namlen; 2806 dp->d_namlen = 0; 2807 # else 2808 /* 2809 * The dp->d_type is the high byte 2810 * of the expected dp->d_namlen, 2811 * so must be zero'ed. 2812 */ 2813 dp->d_type = 0; 2814 # endif 2815 if (dp->d_reclen > 0) { 2816 dp = (struct dirent *) 2817 ((char *)dp + dp->d_reclen); 2818 } else { 2819 error = EIO; 2820 break; 2821 } 2822 } 2823 if (dp >= edp) 2824 error = uiomove(dirbuf, readcnt, &auio); 2825 } 2826 FREE(dirbuf, M_TEMP); 2827 } 2828 VOP_UNLOCK(vp, 0, p); 2829 if (error) 2830 return (error); 2831 if (SCARG(uap, count) == auio.uio_resid) { 2832 if (union_dircheckp) { 2833 error = union_dircheckp(p, &vp, fp); 2834 if (error == -1) 2835 goto unionread; 2836 if (error) 2837 return (error); 2838 } 2839 if ((vp->v_flag & VROOT) && 2840 (vp->v_mount->mnt_flag & MNT_UNION)) { 2841 struct vnode *tvp = vp; 2842 vp = vp->v_mount->mnt_vnodecovered; 2843 VREF(vp); 2844 fp->f_data = (caddr_t) vp; 2845 fp->f_offset = 0; 2846 vrele(tvp); 2847 goto unionread; 2848 } 2849 } 2850 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), 2851 sizeof(long)); 2852 p->p_retval[0] = SCARG(uap, count) - auio.uio_resid; 2853 return (error); 2854 } 2855 #endif /* COMPAT_43 */ 2856 2857 /* 2858 * Read a block of directory entries in a file system independent format. 2859 */ 2860 #ifndef _SYS_SYSPROTO_H_ 2861 struct getdirentries_args { 2862 int fd; 2863 char *buf; 2864 u_int count; 2865 long *basep; 2866 }; 2867 #endif 2868 int 2869 getdirentries(p, uap) 2870 struct proc *p; 2871 register struct getdirentries_args /* { 2872 syscallarg(int) fd; 2873 syscallarg(char *) buf; 2874 syscallarg(u_int) count; 2875 syscallarg(long *) basep; 2876 } */ *uap; 2877 { 2878 struct vnode *vp; 2879 struct file *fp; 2880 struct uio auio; 2881 struct iovec aiov; 2882 long loff; 2883 int error, eofflag; 2884 2885 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2886 return (error); 2887 if ((fp->f_flag & FREAD) == 0) 2888 return (EBADF); 2889 vp = (struct vnode *)fp->f_data; 2890 unionread: 2891 if (vp->v_type != VDIR) 2892 return (EINVAL); 2893 aiov.iov_base = SCARG(uap, buf); 2894 aiov.iov_len = SCARG(uap, count); 2895 auio.uio_iov = &aiov; 2896 auio.uio_iovcnt = 1; 2897 auio.uio_rw = UIO_READ; 2898 auio.uio_segflg = UIO_USERSPACE; 2899 auio.uio_procp = p; 2900 auio.uio_resid = SCARG(uap, count); 2901 /* vn_lock(vp, LK_SHARED | LK_RETRY, p); */ 2902 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2903 loff = auio.uio_offset = fp->f_offset; 2904 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); 2905 fp->f_offset = auio.uio_offset; 2906 VOP_UNLOCK(vp, 0, p); 2907 if (error) 2908 return (error); 2909 if (SCARG(uap, count) == auio.uio_resid) { 2910 if (union_dircheckp) { 2911 error = union_dircheckp(p, &vp, fp); 2912 if (error == -1) 2913 goto unionread; 2914 if (error) 2915 return (error); 2916 } 2917 if ((vp->v_flag & VROOT) && 2918 (vp->v_mount->mnt_flag & MNT_UNION)) { 2919 struct vnode *tvp = vp; 2920 vp = vp->v_mount->mnt_vnodecovered; 2921 VREF(vp); 2922 fp->f_data = (caddr_t) vp; 2923 fp->f_offset = 0; 2924 vrele(tvp); 2925 goto unionread; 2926 } 2927 } 2928 if (SCARG(uap, basep) != NULL) { 2929 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), 2930 sizeof(long)); 2931 } 2932 p->p_retval[0] = SCARG(uap, count) - auio.uio_resid; 2933 return (error); 2934 } 2935 #ifndef _SYS_SYSPROTO_H_ 2936 struct getdents_args { 2937 int fd; 2938 char *buf; 2939 size_t count; 2940 }; 2941 #endif 2942 int 2943 getdents(p, uap) 2944 struct proc *p; 2945 register struct getdents_args /* { 2946 syscallarg(int) fd; 2947 syscallarg(char *) buf; 2948 syscallarg(u_int) count; 2949 } */ *uap; 2950 { 2951 struct getdirentries_args ap; 2952 ap.fd = uap->fd; 2953 ap.buf = uap->buf; 2954 ap.count = uap->count; 2955 ap.basep = NULL; 2956 return getdirentries(p, &ap); 2957 } 2958 2959 /* 2960 * Set the mode mask for creation of filesystem nodes. 2961 */ 2962 #ifndef _SYS_SYSPROTO_H_ 2963 struct umask_args { 2964 int newmask; 2965 }; 2966 #endif 2967 int 2968 umask(p, uap) 2969 struct proc *p; 2970 struct umask_args /* { 2971 syscallarg(int) newmask; 2972 } */ *uap; 2973 { 2974 register struct filedesc *fdp; 2975 2976 fdp = p->p_fd; 2977 p->p_retval[0] = fdp->fd_cmask; 2978 fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS; 2979 return (0); 2980 } 2981 2982 /* 2983 * Void all references to file by ripping underlying filesystem 2984 * away from vnode. 2985 */ 2986 #ifndef _SYS_SYSPROTO_H_ 2987 struct revoke_args { 2988 char *path; 2989 }; 2990 #endif 2991 /* ARGSUSED */ 2992 int 2993 revoke(p, uap) 2994 struct proc *p; 2995 register struct revoke_args /* { 2996 syscallarg(char *) path; 2997 } */ *uap; 2998 { 2999 register struct vnode *vp; 3000 struct vattr vattr; 3001 int error; 3002 struct nameidata nd; 3003 3004 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 3005 if ((error = namei(&nd)) != 0) 3006 return (error); 3007 vp = nd.ni_vp; 3008 if (vp->v_type != VCHR && vp->v_type != VBLK) { 3009 error = EINVAL; 3010 goto out; 3011 } 3012 if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0) 3013 goto out; 3014 if (p->p_ucred->cr_uid != vattr.va_uid && 3015 (error = suser_xxx(0, p, PRISON_ROOT))) 3016 goto out; 3017 if (vcount(vp) > 1) 3018 VOP_REVOKE(vp, REVOKEALL); 3019 out: 3020 vrele(vp); 3021 return (error); 3022 } 3023 3024 /* 3025 * Convert a user file descriptor to a kernel file entry. 3026 */ 3027 int 3028 getvnode(fdp, fd, fpp) 3029 struct filedesc *fdp; 3030 int fd; 3031 struct file **fpp; 3032 { 3033 struct file *fp; 3034 3035 if ((u_int)fd >= fdp->fd_nfiles || 3036 (fp = fdp->fd_ofiles[fd]) == NULL) 3037 return (EBADF); 3038 if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) 3039 return (EINVAL); 3040 *fpp = fp; 3041 return (0); 3042 } 3043 /* 3044 * Get (NFS) file handle 3045 */ 3046 #ifndef _SYS_SYSPROTO_H_ 3047 struct getfh_args { 3048 char *fname; 3049 fhandle_t *fhp; 3050 }; 3051 #endif 3052 int 3053 getfh(p, uap) 3054 struct proc *p; 3055 register struct getfh_args *uap; 3056 { 3057 struct nameidata nd; 3058 fhandle_t fh; 3059 register struct vnode *vp; 3060 int error; 3061 3062 /* 3063 * Must be super user 3064 */ 3065 error = suser(p); 3066 if (error) 3067 return (error); 3068 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 3069 error = namei(&nd); 3070 if (error) 3071 return (error); 3072 vp = nd.ni_vp; 3073 bzero(&fh, sizeof(fh)); 3074 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; 3075 error = VFS_VPTOFH(vp, &fh.fh_fid); 3076 vput(vp); 3077 if (error) 3078 return (error); 3079 error = copyout(&fh, uap->fhp, sizeof (fh)); 3080 return (error); 3081 } 3082 3083 /* 3084 * syscall for the rpc.lockd to use to translate a NFS file handle into 3085 * an open descriptor. 3086 * 3087 * warning: do not remove the suser() call or this becomes one giant 3088 * security hole. 3089 */ 3090 #ifndef _SYS_SYSPROTO_H_ 3091 struct fhopen_args { 3092 const struct fhandle *u_fhp; 3093 int flags; 3094 }; 3095 #endif 3096 int 3097 fhopen(p, uap) 3098 struct proc *p; 3099 struct fhopen_args /* { 3100 syscallarg(const struct fhandle *) u_fhp; 3101 syscallarg(int) flags; 3102 } */ *uap; 3103 { 3104 struct mount *mp; 3105 struct vnode *vp; 3106 struct fhandle fhp; 3107 struct vattr vat; 3108 struct vattr *vap = &vat; 3109 struct flock lf; 3110 struct file *fp; 3111 register struct filedesc *fdp = p->p_fd; 3112 int fmode, mode, error, type; 3113 struct file *nfp; 3114 int indx; 3115 3116 /* 3117 * Must be super user 3118 */ 3119 error = suser(p); 3120 if (error) 3121 return (error); 3122 3123 fmode = FFLAGS(SCARG(uap, flags)); 3124 /* why not allow a non-read/write open for our lockd? */ 3125 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) 3126 return (EINVAL); 3127 error = copyin(SCARG(uap,u_fhp), &fhp, sizeof(fhp)); 3128 if (error) 3129 return(error); 3130 /* find the mount point */ 3131 mp = vfs_getvfs(&fhp.fh_fsid); 3132 if (mp == NULL) 3133 return (ESTALE); 3134 /* now give me my vnode, it gets returned to me locked */ 3135 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp); 3136 if (error) 3137 return (error); 3138 /* 3139 * from now on we have to make sure not 3140 * to forget about the vnode 3141 * any error that causes an abort must vput(vp) 3142 * just set error = err and 'goto bad;'. 3143 */ 3144 3145 /* 3146 * from vn_open 3147 */ 3148 if (vp->v_type == VLNK) { 3149 error = EMLINK; 3150 goto bad; 3151 } 3152 if (vp->v_type == VSOCK) { 3153 error = EOPNOTSUPP; 3154 goto bad; 3155 } 3156 mode = 0; 3157 if (fmode & (FWRITE | O_TRUNC)) { 3158 if (vp->v_type == VDIR) { 3159 error = EISDIR; 3160 goto bad; 3161 } 3162 error = vn_writechk(vp); 3163 if (error) 3164 goto bad; 3165 mode |= VWRITE; 3166 } 3167 if (fmode & FREAD) 3168 mode |= VREAD; 3169 if (mode) { 3170 error = VOP_ACCESS(vp, mode, p->p_ucred, p); 3171 if (error) 3172 goto bad; 3173 } 3174 if (fmode & O_TRUNC) { 3175 VOP_UNLOCK(vp, 0, p); /* XXX */ 3176 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 3177 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */ 3178 VATTR_NULL(vap); 3179 vap->va_size = 0; 3180 error = VOP_SETATTR(vp, vap, p->p_ucred, p); 3181 if (error) 3182 goto bad; 3183 } 3184 error = VOP_OPEN(vp, fmode, p->p_ucred, p); 3185 if (error) 3186 goto bad; 3187 /* 3188 * Make sure that a VM object is created for VMIO support. 3189 */ 3190 if (vn_canvmio(vp) == TRUE) { 3191 if ((error = vfs_object_create(vp, p, p->p_ucred)) != 0) 3192 goto bad; 3193 } 3194 if (fmode & FWRITE) 3195 vp->v_writecount++; 3196 3197 /* 3198 * end of vn_open code 3199 */ 3200 3201 if ((error = falloc(p, &nfp, &indx)) != 0) 3202 goto bad; 3203 fp = nfp; 3204 nfp->f_data = (caddr_t)vp; 3205 nfp->f_flag = fmode & FMASK; 3206 nfp->f_ops = &vnops; 3207 nfp->f_type = DTYPE_VNODE; 3208 if (fmode & (O_EXLOCK | O_SHLOCK)) { 3209 lf.l_whence = SEEK_SET; 3210 lf.l_start = 0; 3211 lf.l_len = 0; 3212 if (fmode & O_EXLOCK) 3213 lf.l_type = F_WRLCK; 3214 else 3215 lf.l_type = F_RDLCK; 3216 type = F_FLOCK; 3217 if ((fmode & FNONBLOCK) == 0) 3218 type |= F_WAIT; 3219 VOP_UNLOCK(vp, 0, p); 3220 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { 3221 (void) vn_close(vp, fp->f_flag, fp->f_cred, p); 3222 ffree(fp); 3223 fdp->fd_ofiles[indx] = NULL; 3224 return (error); 3225 } 3226 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 3227 fp->f_flag |= FHASLOCK; 3228 } 3229 if ((vp->v_type == VREG) && (vp->v_object == NULL)) 3230 vfs_object_create(vp, p, p->p_ucred); 3231 3232 VOP_UNLOCK(vp, 0, p); 3233 p->p_retval[0] = indx; 3234 return (0); 3235 3236 bad: 3237 vput(vp); 3238 return (error); 3239 } 3240 3241 #ifndef _SYS_SYSPROTO_H_ 3242 struct fhstat_args { 3243 struct fhandle *u_fhp; 3244 struct stat *sb; 3245 }; 3246 #endif 3247 int 3248 fhstat(p, uap) 3249 struct proc *p; 3250 register struct fhstat_args /* { 3251 syscallarg(struct fhandle *) u_fhp; 3252 syscallarg(struct stat *) sb; 3253 } */ *uap; 3254 { 3255 struct stat sb; 3256 fhandle_t fh; 3257 struct mount *mp; 3258 struct vnode *vp; 3259 int error; 3260 3261 /* 3262 * Must be super user 3263 */ 3264 error = suser(p); 3265 if (error) 3266 return (error); 3267 3268 error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t)); 3269 if (error) 3270 return (error); 3271 3272 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 3273 return (ESTALE); 3274 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) 3275 return (error); 3276 error = vn_stat(vp, &sb, p); 3277 vput(vp); 3278 if (error) 3279 return (error); 3280 error = copyout(&sb, SCARG(uap, sb), sizeof(sb)); 3281 return (error); 3282 } 3283 3284 #ifndef _SYS_SYSPROTO_H_ 3285 struct fhstatfs_args { 3286 struct fhandle *u_fhp; 3287 struct statfs *buf; 3288 }; 3289 #endif 3290 int 3291 fhstatfs(p, uap) 3292 struct proc *p; 3293 struct fhstatfs_args /* { 3294 syscallarg(struct fhandle) *u_fhp; 3295 syscallarg(struct statfs) *buf; 3296 } */ *uap; 3297 { 3298 struct statfs *sp; 3299 struct mount *mp; 3300 struct vnode *vp; 3301 struct statfs sb; 3302 fhandle_t fh; 3303 int error; 3304 3305 /* 3306 * Must be super user 3307 */ 3308 if ((error = suser(p))) 3309 return (error); 3310 3311 if ((error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t))) != 0) 3312 return (error); 3313 3314 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) 3315 return (ESTALE); 3316 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) 3317 return (error); 3318 mp = vp->v_mount; 3319 sp = &mp->mnt_stat; 3320 vput(vp); 3321 if ((error = VFS_STATFS(mp, sp, p)) != 0) 3322 return (error); 3323 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 3324 if (suser_xxx(p->p_ucred, 0, 0)) { 3325 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 3326 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 3327 sp = &sb; 3328 } 3329 return (copyout(sp, SCARG(uap, buf), sizeof(*sp))); 3330 } 3331