]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/vfs_syscalls.c
add -n option to suppress clearing the build tree and add -DNO_CLEAN
[FreeBSD/FreeBSD.git] / sys / kern / vfs_syscalls.c
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  * 4. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *      @(#)vfs_syscalls.c      8.13 (Berkeley) 4/15/94
35  */
36
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
39
40 #include "opt_compat.h"
41 #include "opt_ktrace.h"
42 #include "opt_mac.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/bio.h>
47 #include <sys/buf.h>
48 #include <sys/sysent.h>
49 #include <sys/malloc.h>
50 #include <sys/mount.h>
51 #include <sys/mutex.h>
52 #include <sys/sysproto.h>
53 #include <sys/namei.h>
54 #include <sys/filedesc.h>
55 #include <sys/kernel.h>
56 #include <sys/fcntl.h>
57 #include <sys/file.h>
58 #include <sys/filio.h>
59 #include <sys/limits.h>
60 #include <sys/linker.h>
61 #include <sys/stat.h>
62 #include <sys/sx.h>
63 #include <sys/unistd.h>
64 #include <sys/vnode.h>
65 #include <sys/priv.h>
66 #include <sys/proc.h>
67 #include <sys/dirent.h>
68 #include <sys/jail.h>
69 #include <sys/syscallsubr.h>
70 #include <sys/sysctl.h>
71 #ifdef KTRACE
72 #include <sys/ktrace.h>
73 #endif
74
75 #include <machine/stdarg.h>
76
77 #include <security/audit/audit.h>
78 #include <security/mac/mac_framework.h>
79
80 #include <vm/vm.h>
81 #include <vm/vm_object.h>
82 #include <vm/vm_page.h>
83 #include <vm/uma.h>
84
85 static int chroot_refuse_vdir_fds(struct filedesc *fdp);
86 static int getutimes(const struct timeval *, enum uio_seg, struct timespec *);
87 static int setfown(struct thread *td, struct vnode *, uid_t, gid_t);
88 static int setfmode(struct thread *td, struct vnode *, int);
89 static int setfflags(struct thread *td, struct vnode *, int);
90 static int setutimes(struct thread *td, struct vnode *,
91     const struct timespec *, int, int);
92 static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred,
93     struct thread *td);
94
95 /*
96  * The module initialization routine for POSIX asynchronous I/O will
97  * set this to the version of AIO that it implements.  (Zero means
98  * that it is not implemented.)  This value is used here by pathconf()
99  * and in kern_descrip.c by fpathconf().
100  */
101 int async_io_version;
102
103 #ifdef DEBUG
104 static int syncprt = 0;
105 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, "");
106 #endif
107
108 /*
109  * Sync each mounted filesystem.
110  */
111 #ifndef _SYS_SYSPROTO_H_
112 struct sync_args {
113         int     dummy;
114 };
115 #endif
116 /* ARGSUSED */
117 int
118 sync(td, uap)
119         struct thread *td;
120         struct sync_args *uap;
121 {
122         struct mount *mp, *nmp;
123         int vfslocked;
124
125         mtx_lock(&mountlist_mtx);
126         for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
127                 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx)) {
128                         nmp = TAILQ_NEXT(mp, mnt_list);
129                         continue;
130                 }
131                 vfslocked = VFS_LOCK_GIANT(mp);
132                 if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
133                     vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
134                         MNT_ILOCK(mp);
135                         mp->mnt_noasync++;
136                         mp->mnt_kern_flag &= ~MNTK_ASYNC;
137                         MNT_IUNLOCK(mp);
138                         vfs_msync(mp, MNT_NOWAIT);
139                         VFS_SYNC(mp, MNT_NOWAIT, td);
140                         MNT_ILOCK(mp);
141                         mp->mnt_noasync--;
142                         if ((mp->mnt_flag & MNT_ASYNC) != 0 &&
143                             mp->mnt_noasync == 0)
144                                 mp->mnt_kern_flag |= MNTK_ASYNC;
145                         MNT_IUNLOCK(mp);
146                         vn_finished_write(mp);
147                 }
148                 VFS_UNLOCK_GIANT(vfslocked);
149                 mtx_lock(&mountlist_mtx);
150                 nmp = TAILQ_NEXT(mp, mnt_list);
151                 vfs_unbusy(mp);
152         }
153         mtx_unlock(&mountlist_mtx);
154         return (0);
155 }
156
157 /* XXX PRISON: could be per prison flag */
158 static int prison_quotas;
159 #if 0
160 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
161 #endif
162
163 /*
164  * Change filesystem quotas.
165  */
166 #ifndef _SYS_SYSPROTO_H_
167 struct quotactl_args {
168         char *path;
169         int cmd;
170         int uid;
171         caddr_t arg;
172 };
173 #endif
174 int
175 quotactl(td, uap)
176         struct thread *td;
177         register struct quotactl_args /* {
178                 char *path;
179                 int cmd;
180                 int uid;
181                 caddr_t arg;
182         } */ *uap;
183 {
184         struct mount *mp;
185         int vfslocked;
186         int error;
187         struct nameidata nd;
188
189         AUDIT_ARG(cmd, uap->cmd);
190         AUDIT_ARG(uid, uap->uid);
191         if (jailed(td->td_ucred) && !prison_quotas)
192                 return (EPERM);
193         NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1,
194            UIO_USERSPACE, uap->path, td);
195         if ((error = namei(&nd)) != 0)
196                 return (error);
197         vfslocked = NDHASGIANT(&nd);
198         NDFREE(&nd, NDF_ONLY_PNBUF);
199         mp = nd.ni_vp->v_mount;
200         if ((error = vfs_busy(mp, 0, NULL))) {
201                 vrele(nd.ni_vp);
202                 VFS_UNLOCK_GIANT(vfslocked);
203                 return (error);
204         }
205         vrele(nd.ni_vp);
206         error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, td);
207         vfs_unbusy(mp);
208         VFS_UNLOCK_GIANT(vfslocked);
209         return (error);
210 }
211
212 /*
213  * Used by statfs conversion routines to scale the block size up if
214  * necessary so that all of the block counts are <= 'max_size'.  Note
215  * that 'max_size' should be a bitmask, i.e. 2^n - 1 for some non-zero
216  * value of 'n'.
217  */
218 void
219 statfs_scale_blocks(struct statfs *sf, long max_size)
220 {
221         uint64_t count;
222         int shift;
223
224         KASSERT(powerof2(max_size + 1), ("%s: invalid max_size", __func__));
225
226         /*
227          * Attempt to scale the block counts to give a more accurate
228          * overview to userland of the ratio of free space to used
229          * space.  To do this, find the largest block count and compute
230          * a divisor that lets it fit into a signed integer <= max_size.
231          */
232         if (sf->f_bavail < 0)
233                 count = -sf->f_bavail;
234         else
235                 count = sf->f_bavail;
236         count = MAX(sf->f_blocks, MAX(sf->f_bfree, count));
237         if (count <= max_size)
238                 return;
239
240         count >>= flsl(max_size);
241         shift = 0;
242         while (count > 0) {
243                 shift++;
244                 count >>=1;
245         }
246
247         sf->f_bsize <<= shift;
248         sf->f_blocks >>= shift;
249         sf->f_bfree >>= shift;
250         sf->f_bavail >>= shift;
251 }
252
253 /*
254  * Get filesystem statistics.
255  */
256 #ifndef _SYS_SYSPROTO_H_
257 struct statfs_args {
258         char *path;
259         struct statfs *buf;
260 };
261 #endif
262 int
263 statfs(td, uap)
264         struct thread *td;
265         register struct statfs_args /* {
266                 char *path;
267                 struct statfs *buf;
268         } */ *uap;
269 {
270         struct statfs sf;
271         int error;
272
273         error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
274         if (error == 0)
275                 error = copyout(&sf, uap->buf, sizeof(sf));
276         return (error);
277 }
278
279 int
280 kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
281     struct statfs *buf)
282 {
283         struct mount *mp;
284         struct statfs *sp, sb;
285         int vfslocked;
286         int error;
287         struct nameidata nd;
288
289         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
290             pathseg, path, td);
291         error = namei(&nd);
292         if (error)
293                 return (error);
294         vfslocked = NDHASGIANT(&nd);
295         mp = nd.ni_vp->v_mount;
296         vfs_ref(mp);
297         NDFREE(&nd, NDF_ONLY_PNBUF);
298         vput(nd.ni_vp);
299 #ifdef MAC
300         error = mac_mount_check_stat(td->td_ucred, mp);
301         if (error)
302                 goto out;
303 #endif
304         /*
305          * Set these in case the underlying filesystem fails to do so.
306          */
307         sp = &mp->mnt_stat;
308         sp->f_version = STATFS_VERSION;
309         sp->f_namemax = NAME_MAX;
310         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
311         error = VFS_STATFS(mp, sp, td);
312         if (error)
313                 goto out;
314         if (priv_check(td, PRIV_VFS_GENERATION)) {
315                 bcopy(sp, &sb, sizeof(sb));
316                 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
317                 prison_enforce_statfs(td->td_ucred, mp, &sb);
318                 sp = &sb;
319         }
320         *buf = *sp;
321 out:
322         vfs_rel(mp);
323         VFS_UNLOCK_GIANT(vfslocked);
324         if (mtx_owned(&Giant))
325                 printf("statfs(%d): %s: %d\n", vfslocked, path, error);
326         return (error);
327 }
328
329 /*
330  * Get filesystem statistics.
331  */
332 #ifndef _SYS_SYSPROTO_H_
333 struct fstatfs_args {
334         int fd;
335         struct statfs *buf;
336 };
337 #endif
338 int
339 fstatfs(td, uap)
340         struct thread *td;
341         register struct fstatfs_args /* {
342                 int fd;
343                 struct statfs *buf;
344         } */ *uap;
345 {
346         struct statfs sf;
347         int error;
348
349         error = kern_fstatfs(td, uap->fd, &sf);
350         if (error == 0)
351                 error = copyout(&sf, uap->buf, sizeof(sf));
352         return (error);
353 }
354
355 int
356 kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
357 {
358         struct file *fp;
359         struct mount *mp;
360         struct statfs *sp, sb;
361         int vfslocked;
362         struct vnode *vp;
363         int error;
364
365         AUDIT_ARG(fd, fd);
366         error = getvnode(td->td_proc->p_fd, fd, &fp);
367         if (error)
368                 return (error);
369         vp = fp->f_vnode;
370         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
371         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
372 #ifdef AUDIT
373         AUDIT_ARG(vnode, vp, ARG_VNODE1);
374 #endif
375         mp = vp->v_mount;
376         if (mp)
377                 vfs_ref(mp);
378         VOP_UNLOCK(vp, 0);
379         fdrop(fp, td);
380         if (vp->v_iflag & VI_DOOMED) {
381                 error = EBADF;
382                 goto out;
383         }
384 #ifdef MAC
385         error = mac_mount_check_stat(td->td_ucred, mp);
386         if (error)
387                 goto out;
388 #endif
389         /*
390          * Set these in case the underlying filesystem fails to do so.
391          */
392         sp = &mp->mnt_stat;
393         sp->f_version = STATFS_VERSION;
394         sp->f_namemax = NAME_MAX;
395         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
396         error = VFS_STATFS(mp, sp, td);
397         if (error)
398                 goto out;
399         if (priv_check(td, PRIV_VFS_GENERATION)) {
400                 bcopy(sp, &sb, sizeof(sb));
401                 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
402                 prison_enforce_statfs(td->td_ucred, mp, &sb);
403                 sp = &sb;
404         }
405         *buf = *sp;
406 out:
407         if (mp)
408                 vfs_rel(mp);
409         VFS_UNLOCK_GIANT(vfslocked);
410         return (error);
411 }
412
413 /*
414  * Get statistics on all filesystems.
415  */
416 #ifndef _SYS_SYSPROTO_H_
417 struct getfsstat_args {
418         struct statfs *buf;
419         long bufsize;
420         int flags;
421 };
422 #endif
423 int
424 getfsstat(td, uap)
425         struct thread *td;
426         register struct getfsstat_args /* {
427                 struct statfs *buf;
428                 long bufsize;
429                 int flags;
430         } */ *uap;
431 {
432
433         return (kern_getfsstat(td, &uap->buf, uap->bufsize, UIO_USERSPACE,
434             uap->flags));
435 }
436
437 /*
438  * If (bufsize > 0 && bufseg == UIO_SYSSPACE)
439  *      The caller is responsible for freeing memory which will be allocated
440  *      in '*buf'.
441  */
442 int
443 kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
444     enum uio_seg bufseg, int flags)
445 {
446         struct mount *mp, *nmp;
447         struct statfs *sfsp, *sp, sb;
448         size_t count, maxcount;
449         int vfslocked;
450         int error;
451
452         maxcount = bufsize / sizeof(struct statfs);
453         if (bufsize == 0)
454                 sfsp = NULL;
455         else if (bufseg == UIO_USERSPACE)
456                 sfsp = *buf;
457         else /* if (bufseg == UIO_SYSSPACE) */ {
458                 count = 0;
459                 mtx_lock(&mountlist_mtx);
460                 TAILQ_FOREACH(mp, &mountlist, mnt_list) {
461                         count++;
462                 }
463                 mtx_unlock(&mountlist_mtx);
464                 if (maxcount > count)
465                         maxcount = count;
466                 sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_TEMP,
467                     M_WAITOK);
468         }
469         count = 0;
470         mtx_lock(&mountlist_mtx);
471         for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
472                 if (prison_canseemount(td->td_ucred, mp) != 0) {
473                         nmp = TAILQ_NEXT(mp, mnt_list);
474                         continue;
475                 }
476 #ifdef MAC
477                 if (mac_mount_check_stat(td->td_ucred, mp) != 0) {
478                         nmp = TAILQ_NEXT(mp, mnt_list);
479                         continue;
480                 }
481 #endif
482                 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx)) {
483                         nmp = TAILQ_NEXT(mp, mnt_list);
484                         continue;
485                 }
486                 vfslocked = VFS_LOCK_GIANT(mp);
487                 if (sfsp && count < maxcount) {
488                         sp = &mp->mnt_stat;
489                         /*
490                          * Set these in case the underlying filesystem
491                          * fails to do so.
492                          */
493                         sp->f_version = STATFS_VERSION;
494                         sp->f_namemax = NAME_MAX;
495                         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
496                         /*
497                          * If MNT_NOWAIT or MNT_LAZY is specified, do not
498                          * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
499                          * overrides MNT_WAIT.
500                          */
501                         if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
502                             (flags & MNT_WAIT)) &&
503                             (error = VFS_STATFS(mp, sp, td))) {
504                                 VFS_UNLOCK_GIANT(vfslocked);
505                                 mtx_lock(&mountlist_mtx);
506                                 nmp = TAILQ_NEXT(mp, mnt_list);
507                                 vfs_unbusy(mp);
508                                 continue;
509                         }
510                         if (priv_check(td, PRIV_VFS_GENERATION)) {
511                                 bcopy(sp, &sb, sizeof(sb));
512                                 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
513                                 prison_enforce_statfs(td->td_ucred, mp, &sb);
514                                 sp = &sb;
515                         }
516                         if (bufseg == UIO_SYSSPACE)
517                                 bcopy(sp, sfsp, sizeof(*sp));
518                         else /* if (bufseg == UIO_USERSPACE) */ {
519                                 error = copyout(sp, sfsp, sizeof(*sp));
520                                 if (error) {
521                                         vfs_unbusy(mp);
522                                         VFS_UNLOCK_GIANT(vfslocked);
523                                         return (error);
524                                 }
525                         }
526                         sfsp++;
527                 }
528                 VFS_UNLOCK_GIANT(vfslocked);
529                 count++;
530                 mtx_lock(&mountlist_mtx);
531                 nmp = TAILQ_NEXT(mp, mnt_list);
532                 vfs_unbusy(mp);
533         }
534         mtx_unlock(&mountlist_mtx);
535         if (sfsp && count > maxcount)
536                 td->td_retval[0] = maxcount;
537         else
538                 td->td_retval[0] = count;
539         return (0);
540 }
541
542 #ifdef COMPAT_FREEBSD4
543 /*
544  * Get old format filesystem statistics.
545  */
546 static void cvtstatfs(struct statfs *, struct ostatfs *);
547
548 #ifndef _SYS_SYSPROTO_H_
549 struct freebsd4_statfs_args {
550         char *path;
551         struct ostatfs *buf;
552 };
553 #endif
554 int
555 freebsd4_statfs(td, uap)
556         struct thread *td;
557         struct freebsd4_statfs_args /* {
558                 char *path;
559                 struct ostatfs *buf;
560         } */ *uap;
561 {
562         struct ostatfs osb;
563         struct statfs sf;
564         int error;
565
566         error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
567         if (error)
568                 return (error);
569         cvtstatfs(&sf, &osb);
570         return (copyout(&osb, uap->buf, sizeof(osb)));
571 }
572
573 /*
574  * Get filesystem statistics.
575  */
576 #ifndef _SYS_SYSPROTO_H_
577 struct freebsd4_fstatfs_args {
578         int fd;
579         struct ostatfs *buf;
580 };
581 #endif
582 int
583 freebsd4_fstatfs(td, uap)
584         struct thread *td;
585         struct freebsd4_fstatfs_args /* {
586                 int fd;
587                 struct ostatfs *buf;
588         } */ *uap;
589 {
590         struct ostatfs osb;
591         struct statfs sf;
592         int error;
593
594         error = kern_fstatfs(td, uap->fd, &sf);
595         if (error)
596                 return (error);
597         cvtstatfs(&sf, &osb);
598         return (copyout(&osb, uap->buf, sizeof(osb)));
599 }
600
601 /*
602  * Get statistics on all filesystems.
603  */
604 #ifndef _SYS_SYSPROTO_H_
605 struct freebsd4_getfsstat_args {
606         struct ostatfs *buf;
607         long bufsize;
608         int flags;
609 };
610 #endif
611 int
612 freebsd4_getfsstat(td, uap)
613         struct thread *td;
614         register struct freebsd4_getfsstat_args /* {
615                 struct ostatfs *buf;
616                 long bufsize;
617                 int flags;
618         } */ *uap;
619 {
620         struct statfs *buf, *sp;
621         struct ostatfs osb;
622         size_t count, size;
623         int error;
624
625         count = uap->bufsize / sizeof(struct ostatfs);
626         size = count * sizeof(struct statfs);
627         error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
628         if (size > 0) {
629                 count = td->td_retval[0];
630                 sp = buf;
631                 while (count > 0 && error == 0) {
632                         cvtstatfs(sp, &osb);
633                         error = copyout(&osb, uap->buf, sizeof(osb));
634                         sp++;
635                         uap->buf++;
636                         count--;
637                 }
638                 free(buf, M_TEMP);
639         }
640         return (error);
641 }
642
643 /*
644  * Implement fstatfs() for (NFS) file handles.
645  */
646 #ifndef _SYS_SYSPROTO_H_
647 struct freebsd4_fhstatfs_args {
648         struct fhandle *u_fhp;
649         struct ostatfs *buf;
650 };
651 #endif
652 int
653 freebsd4_fhstatfs(td, uap)
654         struct thread *td;
655         struct freebsd4_fhstatfs_args /* {
656                 struct fhandle *u_fhp;
657                 struct ostatfs *buf;
658         } */ *uap;
659 {
660         struct ostatfs osb;
661         struct statfs sf;
662         fhandle_t fh;
663         int error;
664
665         error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
666         if (error)
667                 return (error);
668         error = kern_fhstatfs(td, fh, &sf);
669         if (error)
670                 return (error);
671         cvtstatfs(&sf, &osb);
672         return (copyout(&osb, uap->buf, sizeof(osb)));
673 }
674
675 /*
676  * Convert a new format statfs structure to an old format statfs structure.
677  */
678 static void
679 cvtstatfs(nsp, osp)
680         struct statfs *nsp;
681         struct ostatfs *osp;
682 {
683
684         statfs_scale_blocks(nsp, LONG_MAX);
685         bzero(osp, sizeof(*osp));
686         osp->f_bsize = nsp->f_bsize;
687         osp->f_iosize = MIN(nsp->f_iosize, LONG_MAX);
688         osp->f_blocks = nsp->f_blocks;
689         osp->f_bfree = nsp->f_bfree;
690         osp->f_bavail = nsp->f_bavail;
691         osp->f_files = MIN(nsp->f_files, LONG_MAX);
692         osp->f_ffree = MIN(nsp->f_ffree, LONG_MAX);
693         osp->f_owner = nsp->f_owner;
694         osp->f_type = nsp->f_type;
695         osp->f_flags = nsp->f_flags;
696         osp->f_syncwrites = MIN(nsp->f_syncwrites, LONG_MAX);
697         osp->f_asyncwrites = MIN(nsp->f_asyncwrites, LONG_MAX);
698         osp->f_syncreads = MIN(nsp->f_syncreads, LONG_MAX);
699         osp->f_asyncreads = MIN(nsp->f_asyncreads, LONG_MAX);
700         strlcpy(osp->f_fstypename, nsp->f_fstypename,
701             MIN(MFSNAMELEN, OMFSNAMELEN));
702         strlcpy(osp->f_mntonname, nsp->f_mntonname,
703             MIN(MNAMELEN, OMNAMELEN));
704         strlcpy(osp->f_mntfromname, nsp->f_mntfromname,
705             MIN(MNAMELEN, OMNAMELEN));
706         osp->f_fsid = nsp->f_fsid;
707 }
708 #endif /* COMPAT_FREEBSD4 */
709
710 /*
711  * Change current working directory to a given file descriptor.
712  */
713 #ifndef _SYS_SYSPROTO_H_
714 struct fchdir_args {
715         int     fd;
716 };
717 #endif
718 int
719 fchdir(td, uap)
720         struct thread *td;
721         struct fchdir_args /* {
722                 int fd;
723         } */ *uap;
724 {
725         register struct filedesc *fdp = td->td_proc->p_fd;
726         struct vnode *vp, *tdp, *vpold;
727         struct mount *mp;
728         struct file *fp;
729         int vfslocked;
730         int error;
731
732         AUDIT_ARG(fd, uap->fd);
733         if ((error = getvnode(fdp, uap->fd, &fp)) != 0)
734                 return (error);
735         vp = fp->f_vnode;
736         VREF(vp);
737         fdrop(fp, td);
738         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
739         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
740         AUDIT_ARG(vnode, vp, ARG_VNODE1);
741         error = change_dir(vp, td);
742         while (!error && (mp = vp->v_mountedhere) != NULL) {
743                 int tvfslocked;
744                 if (vfs_busy(mp, 0, 0))
745                         continue;
746                 tvfslocked = VFS_LOCK_GIANT(mp);
747                 error = VFS_ROOT(mp, LK_EXCLUSIVE, &tdp, td);
748                 vfs_unbusy(mp);
749                 if (error) {
750                         VFS_UNLOCK_GIANT(tvfslocked);
751                         break;
752                 }
753                 vput(vp);
754                 VFS_UNLOCK_GIANT(vfslocked);
755                 vp = tdp;
756                 vfslocked = tvfslocked;
757         }
758         if (error) {
759                 vput(vp);
760                 VFS_UNLOCK_GIANT(vfslocked);
761                 return (error);
762         }
763         VOP_UNLOCK(vp, 0);
764         VFS_UNLOCK_GIANT(vfslocked);
765         FILEDESC_XLOCK(fdp);
766         vpold = fdp->fd_cdir;
767         fdp->fd_cdir = vp;
768         FILEDESC_XUNLOCK(fdp);
769         vfslocked = VFS_LOCK_GIANT(vpold->v_mount);
770         vrele(vpold);
771         VFS_UNLOCK_GIANT(vfslocked);
772         return (0);
773 }
774
775 /*
776  * Change current working directory (``.'').
777  */
778 #ifndef _SYS_SYSPROTO_H_
779 struct chdir_args {
780         char    *path;
781 };
782 #endif
783 int
784 chdir(td, uap)
785         struct thread *td;
786         struct chdir_args /* {
787                 char *path;
788         } */ *uap;
789 {
790
791         return (kern_chdir(td, uap->path, UIO_USERSPACE));
792 }
793
794 int
795 kern_chdir(struct thread *td, char *path, enum uio_seg pathseg)
796 {
797         register struct filedesc *fdp = td->td_proc->p_fd;
798         int error;
799         struct nameidata nd;
800         struct vnode *vp;
801         int vfslocked;
802
803         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1 | MPSAFE,
804             pathseg, path, td);
805         if ((error = namei(&nd)) != 0)
806                 return (error);
807         vfslocked = NDHASGIANT(&nd);
808         if ((error = change_dir(nd.ni_vp, td)) != 0) {
809                 vput(nd.ni_vp);
810                 VFS_UNLOCK_GIANT(vfslocked);
811                 NDFREE(&nd, NDF_ONLY_PNBUF);
812                 return (error);
813         }
814         VOP_UNLOCK(nd.ni_vp, 0);
815         VFS_UNLOCK_GIANT(vfslocked);
816         NDFREE(&nd, NDF_ONLY_PNBUF);
817         FILEDESC_XLOCK(fdp);
818         vp = fdp->fd_cdir;
819         fdp->fd_cdir = nd.ni_vp;
820         FILEDESC_XUNLOCK(fdp);
821         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
822         vrele(vp);
823         VFS_UNLOCK_GIANT(vfslocked);
824         return (0);
825 }
826
827 /*
828  * Helper function for raised chroot(2) security function:  Refuse if
829  * any filedescriptors are open directories.
830  */
831 static int
832 chroot_refuse_vdir_fds(fdp)
833         struct filedesc *fdp;
834 {
835         struct vnode *vp;
836         struct file *fp;
837         int fd;
838
839         FILEDESC_LOCK_ASSERT(fdp);
840
841         for (fd = 0; fd < fdp->fd_nfiles ; fd++) {
842                 fp = fget_locked(fdp, fd);
843                 if (fp == NULL)
844                         continue;
845                 if (fp->f_type == DTYPE_VNODE) {
846                         vp = fp->f_vnode;
847                         if (vp->v_type == VDIR)
848                                 return (EPERM);
849                 }
850         }
851         return (0);
852 }
853
854 /*
855  * This sysctl determines if we will allow a process to chroot(2) if it
856  * has a directory open:
857  *      0: disallowed for all processes.
858  *      1: allowed for processes that were not already chroot(2)'ed.
859  *      2: allowed for all processes.
860  */
861
862 static int chroot_allow_open_directories = 1;
863
864 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW,
865      &chroot_allow_open_directories, 0, "");
866
867 /*
868  * Change notion of root (``/'') directory.
869  */
870 #ifndef _SYS_SYSPROTO_H_
871 struct chroot_args {
872         char    *path;
873 };
874 #endif
875 int
876 chroot(td, uap)
877         struct thread *td;
878         struct chroot_args /* {
879                 char *path;
880         } */ *uap;
881 {
882         int error;
883         struct nameidata nd;
884         int vfslocked;
885
886         error = priv_check(td, PRIV_VFS_CHROOT);
887         if (error)
888                 return (error);
889         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
890             UIO_USERSPACE, uap->path, td);
891         error = namei(&nd);
892         if (error)
893                 goto error;
894         vfslocked = NDHASGIANT(&nd);
895         if ((error = change_dir(nd.ni_vp, td)) != 0)
896                 goto e_vunlock;
897 #ifdef MAC
898         if ((error = mac_vnode_check_chroot(td->td_ucred, nd.ni_vp)))
899                 goto e_vunlock;
900 #endif
901         VOP_UNLOCK(nd.ni_vp, 0);
902         error = change_root(nd.ni_vp, td);
903         vrele(nd.ni_vp);
904         VFS_UNLOCK_GIANT(vfslocked);
905         NDFREE(&nd, NDF_ONLY_PNBUF);
906         return (error);
907 e_vunlock:
908         vput(nd.ni_vp);
909         VFS_UNLOCK_GIANT(vfslocked);
910 error:
911         NDFREE(&nd, NDF_ONLY_PNBUF);
912         return (error);
913 }
914
915 /*
916  * Common routine for chroot and chdir.  Callers must provide a locked vnode
917  * instance.
918  */
919 int
920 change_dir(vp, td)
921         struct vnode *vp;
922         struct thread *td;
923 {
924         int error;
925
926         ASSERT_VOP_LOCKED(vp, "change_dir(): vp not locked");
927         if (vp->v_type != VDIR)
928                 return (ENOTDIR);
929 #ifdef MAC
930         error = mac_vnode_check_chdir(td->td_ucred, vp);
931         if (error)
932                 return (error);
933 #endif
934         error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
935         return (error);
936 }
937
938 /*
939  * Common routine for kern_chroot() and jail_attach().  The caller is
940  * responsible for invoking priv_check() and mac_vnode_check_chroot() to
941  * authorize this operation.
942  */
943 int
944 change_root(vp, td)
945         struct vnode *vp;
946         struct thread *td;
947 {
948         struct filedesc *fdp;
949         struct vnode *oldvp;
950         int vfslocked;
951         int error;
952
953         VFS_ASSERT_GIANT(vp->v_mount);
954         fdp = td->td_proc->p_fd;
955         FILEDESC_XLOCK(fdp);
956         if (chroot_allow_open_directories == 0 ||
957             (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) {
958                 error = chroot_refuse_vdir_fds(fdp);
959                 if (error) {
960                         FILEDESC_XUNLOCK(fdp);
961                         return (error);
962                 }
963         }
964         oldvp = fdp->fd_rdir;
965         fdp->fd_rdir = vp;
966         VREF(fdp->fd_rdir);
967         if (!fdp->fd_jdir) {
968                 fdp->fd_jdir = vp;
969                 VREF(fdp->fd_jdir);
970         }
971         FILEDESC_XUNLOCK(fdp);
972         vfslocked = VFS_LOCK_GIANT(oldvp->v_mount);
973         vrele(oldvp);
974         VFS_UNLOCK_GIANT(vfslocked);
975         return (0);
976 }
977
978 /*
979  * Check permissions, allocate an open file structure, and call the device
980  * open routine if any.
981  */
982 #ifndef _SYS_SYSPROTO_H_
983 struct open_args {
984         char    *path;
985         int     flags;
986         int     mode;
987 };
988 #endif
989 int
990 open(td, uap)
991         struct thread *td;
992         register struct open_args /* {
993                 char *path;
994                 int flags;
995                 int mode;
996         } */ *uap;
997 {
998
999         return (kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode));
1000 }
1001
1002 #ifndef _SYS_SYSPROTO_H_
1003 struct openat_args {
1004         int     fd;
1005         char    *path;
1006         int     flag;
1007         int     mode;
1008 };
1009 #endif
1010 int
1011 openat(struct thread *td, struct openat_args *uap)
1012 {
1013
1014         return (kern_openat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag,
1015             uap->mode));
1016 }
1017
1018 int
1019 kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags,
1020     int mode)
1021 {
1022
1023         return (kern_openat(td, AT_FDCWD, path, pathseg, flags, mode));
1024 }
1025
1026 int
1027 kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
1028     int flags, int mode)
1029 {
1030         struct proc *p = td->td_proc;
1031         struct filedesc *fdp = p->p_fd;
1032         struct file *fp;
1033         struct vnode *vp;
1034         struct vattr vat;
1035         struct mount *mp;
1036         int cmode;
1037         struct file *nfp;
1038         int type, indx, error;
1039         struct flock lf;
1040         struct nameidata nd;
1041         int vfslocked;
1042
1043         AUDIT_ARG(fflags, flags);
1044         AUDIT_ARG(mode, mode);
1045         /* XXX: audit dirfd */
1046         /*
1047          * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR may
1048          * be specified.
1049          */
1050         if (flags & O_EXEC) {
1051                 if (flags & O_ACCMODE)
1052                         return (EINVAL);
1053         } else if ((flags & O_ACCMODE) == O_ACCMODE)
1054                 return (EINVAL);
1055         else
1056                 flags = FFLAGS(flags);
1057
1058         error = falloc(td, &nfp, &indx);
1059         if (error)
1060                 return (error);
1061         /* An extra reference on `nfp' has been held for us by falloc(). */
1062         fp = nfp;
1063         /* Set the flags early so the finit in devfs can pick them up. */
1064         fp->f_flag = flags & FMASK;
1065         cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
1066         NDINIT_AT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, fd,
1067             td);
1068         td->td_dupfd = -1;              /* XXX check for fdopen */
1069         error = vn_open(&nd, &flags, cmode, fp);
1070         if (error) {
1071                 /*
1072                  * If the vn_open replaced the method vector, something
1073                  * wonderous happened deep below and we just pass it up
1074                  * pretending we know what we do.
1075                  */
1076                 if (error == ENXIO && fp->f_ops != &badfileops) {
1077                         fdrop(fp, td);
1078                         td->td_retval[0] = indx;
1079                         return (0);
1080                 }
1081
1082                 /*
1083                  * handle special fdopen() case.  bleh.  dupfdopen() is
1084                  * responsible for dropping the old contents of ofiles[indx]
1085                  * if it succeeds.
1086                  */
1087                 if ((error == ENODEV || error == ENXIO) &&
1088                     td->td_dupfd >= 0 &&                /* XXX from fdopen */
1089                     (error =
1090                         dupfdopen(td, fdp, indx, td->td_dupfd, flags, error)) == 0) {
1091                         td->td_retval[0] = indx;
1092                         fdrop(fp, td);
1093                         return (0);
1094                 }
1095                 /*
1096                  * Clean up the descriptor, but only if another thread hadn't
1097                  * replaced or closed it.
1098                  */
1099                 fdclose(fdp, fp, indx, td);
1100                 fdrop(fp, td);
1101
1102                 if (error == ERESTART)
1103                         error = EINTR;
1104                 return (error);
1105         }
1106         td->td_dupfd = 0;
1107         vfslocked = NDHASGIANT(&nd);
1108         NDFREE(&nd, NDF_ONLY_PNBUF);
1109         vp = nd.ni_vp;
1110
1111         fp->f_vnode = vp;       /* XXX Does devfs need this? */
1112         /*
1113          * If the file wasn't claimed by devfs bind it to the normal
1114          * vnode operations here.
1115          */
1116         if (fp->f_ops == &badfileops) {
1117                 KASSERT(vp->v_type != VFIFO, ("Unexpected fifo."));
1118                 fp->f_seqcount = 1;
1119                 finit(fp, flags & FMASK, DTYPE_VNODE, vp, &vnops);
1120         }
1121
1122         VOP_UNLOCK(vp, 0);
1123         if (flags & (O_EXLOCK | O_SHLOCK)) {
1124                 lf.l_whence = SEEK_SET;
1125                 lf.l_start = 0;
1126                 lf.l_len = 0;
1127                 if (flags & O_EXLOCK)
1128                         lf.l_type = F_WRLCK;
1129                 else
1130                         lf.l_type = F_RDLCK;
1131                 type = F_FLOCK;
1132                 if ((flags & FNONBLOCK) == 0)
1133                         type |= F_WAIT;
1134                 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
1135                             type)) != 0)
1136                         goto bad;
1137                 atomic_set_int(&fp->f_flag, FHASLOCK);
1138         }
1139         if (flags & O_TRUNC) {
1140                 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
1141                         goto bad;
1142                 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1143                 VATTR_NULL(&vat);
1144                 vat.va_size = 0;
1145                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1146 #ifdef MAC
1147                 error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp);
1148                 if (error == 0)
1149 #endif
1150                         error = VOP_SETATTR(vp, &vat, td->td_ucred);
1151                 VOP_UNLOCK(vp, 0);
1152                 vn_finished_write(mp);
1153                 if (error)
1154                         goto bad;
1155         }
1156         VFS_UNLOCK_GIANT(vfslocked);
1157         /*
1158          * Release our private reference, leaving the one associated with
1159          * the descriptor table intact.
1160          */
1161         fdrop(fp, td);
1162         td->td_retval[0] = indx;
1163         return (0);
1164 bad:
1165         VFS_UNLOCK_GIANT(vfslocked);
1166         fdclose(fdp, fp, indx, td);
1167         fdrop(fp, td);
1168         return (error);
1169 }
1170
1171 #ifdef COMPAT_43
1172 /*
1173  * Create a file.
1174  */
1175 #ifndef _SYS_SYSPROTO_H_
1176 struct ocreat_args {
1177         char    *path;
1178         int     mode;
1179 };
1180 #endif
1181 int
1182 ocreat(td, uap)
1183         struct thread *td;
1184         register struct ocreat_args /* {
1185                 char *path;
1186                 int mode;
1187         } */ *uap;
1188 {
1189
1190         return (kern_open(td, uap->path, UIO_USERSPACE,
1191             O_WRONLY | O_CREAT | O_TRUNC, uap->mode));
1192 }
1193 #endif /* COMPAT_43 */
1194
1195 /*
1196  * Create a special file.
1197  */
1198 #ifndef _SYS_SYSPROTO_H_
1199 struct mknod_args {
1200         char    *path;
1201         int     mode;
1202         int     dev;
1203 };
1204 #endif
1205 int
1206 mknod(td, uap)
1207         struct thread *td;
1208         register struct mknod_args /* {
1209                 char *path;
1210                 int mode;
1211                 int dev;
1212         } */ *uap;
1213 {
1214
1215         return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev));
1216 }
1217
1218 #ifndef _SYS_SYSPROTO_H_
1219 struct mknodat_args {
1220         int     fd;
1221         char    *path;
1222         mode_t  mode;
1223         dev_t   dev;
1224 };
1225 #endif
1226 int
1227 mknodat(struct thread *td, struct mknodat_args *uap)
1228 {
1229
1230         return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode,
1231             uap->dev));
1232 }
1233
1234 int
1235 kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode,
1236     int dev)
1237 {
1238
1239         return (kern_mknodat(td, AT_FDCWD, path, pathseg, mode, dev));
1240 }
1241
1242 int
1243 kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
1244     int mode, int dev)
1245 {
1246         struct vnode *vp;
1247         struct mount *mp;
1248         struct vattr vattr;
1249         int error;
1250         int whiteout = 0;
1251         struct nameidata nd;
1252         int vfslocked;
1253
1254         AUDIT_ARG(mode, mode);
1255         AUDIT_ARG(dev, dev);
1256         switch (mode & S_IFMT) {
1257         case S_IFCHR:
1258         case S_IFBLK:
1259                 error = priv_check(td, PRIV_VFS_MKNOD_DEV);
1260                 break;
1261         case S_IFMT:
1262                 error = priv_check(td, PRIV_VFS_MKNOD_BAD);
1263                 break;
1264         case S_IFWHT:
1265                 error = priv_check(td, PRIV_VFS_MKNOD_WHT);
1266                 break;
1267         case S_IFIFO:
1268                 if (dev == 0)
1269                         return (kern_mkfifoat(td, fd, path, pathseg, mode));
1270                 /* FALLTHROUGH */
1271         default:
1272                 error = EINVAL;
1273                 break;
1274         }
1275         if (error)
1276                 return (error);
1277 restart:
1278         bwillwrite();
1279         NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
1280             pathseg, path, fd, td);
1281         if ((error = namei(&nd)) != 0)
1282                 return (error);
1283         vfslocked = NDHASGIANT(&nd);
1284         vp = nd.ni_vp;
1285         if (vp != NULL) {
1286                 NDFREE(&nd, NDF_ONLY_PNBUF);
1287                 if (vp == nd.ni_dvp)
1288                         vrele(nd.ni_dvp);
1289                 else
1290                         vput(nd.ni_dvp);
1291                 vrele(vp);
1292                 VFS_UNLOCK_GIANT(vfslocked);
1293                 return (EEXIST);
1294         } else {
1295                 VATTR_NULL(&vattr);
1296                 FILEDESC_SLOCK(td->td_proc->p_fd);
1297                 vattr.va_mode = (mode & ALLPERMS) &
1298                     ~td->td_proc->p_fd->fd_cmask;
1299                 FILEDESC_SUNLOCK(td->td_proc->p_fd);
1300                 vattr.va_rdev = dev;
1301                 whiteout = 0;
1302
1303                 switch (mode & S_IFMT) {
1304                 case S_IFMT:    /* used by badsect to flag bad sectors */
1305                         vattr.va_type = VBAD;
1306                         break;
1307                 case S_IFCHR:
1308                         vattr.va_type = VCHR;
1309                         break;
1310                 case S_IFBLK:
1311                         vattr.va_type = VBLK;
1312                         break;
1313                 case S_IFWHT:
1314                         whiteout = 1;
1315                         break;
1316                 default:
1317                         panic("kern_mknod: invalid mode");
1318                 }
1319         }
1320         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1321                 NDFREE(&nd, NDF_ONLY_PNBUF);
1322                 vput(nd.ni_dvp);
1323                 VFS_UNLOCK_GIANT(vfslocked);
1324                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1325                         return (error);
1326                 goto restart;
1327         }
1328 #ifdef MAC
1329         if (error == 0 && !whiteout)
1330                 error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp,
1331                     &nd.ni_cnd, &vattr);
1332 #endif
1333         if (!error) {
1334                 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1335                 if (whiteout)
1336                         error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
1337                 else {
1338                         error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
1339                                                 &nd.ni_cnd, &vattr);
1340                         if (error == 0)
1341                                 vput(nd.ni_vp);
1342                 }
1343         }
1344         NDFREE(&nd, NDF_ONLY_PNBUF);
1345         vput(nd.ni_dvp);
1346         vn_finished_write(mp);
1347         VFS_UNLOCK_GIANT(vfslocked);
1348         return (error);
1349 }
1350
1351 /*
1352  * Create a named pipe.
1353  */
1354 #ifndef _SYS_SYSPROTO_H_
1355 struct mkfifo_args {
1356         char    *path;
1357         int     mode;
1358 };
1359 #endif
1360 int
1361 mkfifo(td, uap)
1362         struct thread *td;
1363         register struct mkfifo_args /* {
1364                 char *path;
1365                 int mode;
1366         } */ *uap;
1367 {
1368
1369         return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode));
1370 }
1371
1372 #ifndef _SYS_SYSPROTO_H_
1373 struct mkfifoat_args {
1374         int     fd;
1375         char    *path;
1376         mode_t  mode;
1377 };
1378 #endif
1379 int
1380 mkfifoat(struct thread *td, struct mkfifoat_args *uap)
1381 {
1382
1383         return (kern_mkfifoat(td, uap->fd, uap->path, UIO_USERSPACE,
1384             uap->mode));
1385 }
1386
1387 int
1388 kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode)
1389 {
1390
1391         return (kern_mkfifoat(td, AT_FDCWD, path, pathseg, mode));
1392 }
1393
1394 int
1395 kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
1396     int mode)
1397 {
1398         struct mount *mp;
1399         struct vattr vattr;
1400         int error;
1401         struct nameidata nd;
1402         int vfslocked;
1403
1404         AUDIT_ARG(mode, mode);
1405 restart:
1406         bwillwrite();
1407         NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
1408             pathseg, path, fd, td);
1409         if ((error = namei(&nd)) != 0)
1410                 return (error);
1411         vfslocked = NDHASGIANT(&nd);
1412         if (nd.ni_vp != NULL) {
1413                 NDFREE(&nd, NDF_ONLY_PNBUF);
1414                 if (nd.ni_vp == nd.ni_dvp)
1415                         vrele(nd.ni_dvp);
1416                 else
1417                         vput(nd.ni_dvp);
1418                 vrele(nd.ni_vp);
1419                 VFS_UNLOCK_GIANT(vfslocked);
1420                 return (EEXIST);
1421         }
1422         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1423                 NDFREE(&nd, NDF_ONLY_PNBUF);
1424                 vput(nd.ni_dvp);
1425                 VFS_UNLOCK_GIANT(vfslocked);
1426                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1427                         return (error);
1428                 goto restart;
1429         }
1430         VATTR_NULL(&vattr);
1431         vattr.va_type = VFIFO;
1432         FILEDESC_SLOCK(td->td_proc->p_fd);
1433         vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask;
1434         FILEDESC_SUNLOCK(td->td_proc->p_fd);
1435 #ifdef MAC
1436         error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1437             &vattr);
1438         if (error)
1439                 goto out;
1440 #endif
1441         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1442         error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1443         if (error == 0)
1444                 vput(nd.ni_vp);
1445 #ifdef MAC
1446 out:
1447 #endif
1448         vput(nd.ni_dvp);
1449         vn_finished_write(mp);
1450         VFS_UNLOCK_GIANT(vfslocked);
1451         NDFREE(&nd, NDF_ONLY_PNBUF);
1452         return (error);
1453 }
1454
1455 /*
1456  * Make a hard file link.
1457  */
1458 #ifndef _SYS_SYSPROTO_H_
1459 struct link_args {
1460         char    *path;
1461         char    *link;
1462 };
1463 #endif
1464 int
1465 link(td, uap)
1466         struct thread *td;
1467         register struct link_args /* {
1468                 char *path;
1469                 char *link;
1470         } */ *uap;
1471 {
1472
1473         return (kern_link(td, uap->path, uap->link, UIO_USERSPACE));
1474 }
1475
1476 #ifndef _SYS_SYSPROTO_H_
1477 struct linkat_args {
1478         int     fd1;
1479         char    *path1;
1480         int     fd2;
1481         char    *path2;
1482         int     flag;
1483 };
1484 #endif
1485 int
1486 linkat(struct thread *td, struct linkat_args *uap)
1487 {
1488         int flag;
1489
1490         flag = uap->flag;
1491         if (flag & ~AT_SYMLINK_FOLLOW)
1492                 return (EINVAL);
1493
1494         return (kern_linkat(td, uap->fd1, uap->fd2, uap->path1, uap->path2,
1495             UIO_USERSPACE, (flag & AT_SYMLINK_FOLLOW) ? FOLLOW : NOFOLLOW));
1496 }
1497
1498 static int hardlink_check_uid = 0;
1499 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW,
1500     &hardlink_check_uid, 0,
1501     "Unprivileged processes cannot create hard links to files owned by other "
1502     "users");
1503 static int hardlink_check_gid = 0;
1504 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW,
1505     &hardlink_check_gid, 0,
1506     "Unprivileged processes cannot create hard links to files owned by other "
1507     "groups");
1508
1509 static int
1510 can_hardlink(struct vnode *vp, struct ucred *cred)
1511 {
1512         struct vattr va;
1513         int error;
1514
1515         if (!hardlink_check_uid && !hardlink_check_gid)
1516                 return (0);
1517
1518         error = VOP_GETATTR(vp, &va, cred);
1519         if (error != 0)
1520                 return (error);
1521
1522         if (hardlink_check_uid && cred->cr_uid != va.va_uid) {
1523                 error = priv_check_cred(cred, PRIV_VFS_LINK, 0);
1524                 if (error)
1525                         return (error);
1526         }
1527
1528         if (hardlink_check_gid && !groupmember(va.va_gid, cred)) {
1529                 error = priv_check_cred(cred, PRIV_VFS_LINK, 0);
1530                 if (error)
1531                         return (error);
1532         }
1533
1534         return (0);
1535 }
1536
1537 int
1538 kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg)
1539 {
1540
1541         return (kern_linkat(td, AT_FDCWD, AT_FDCWD, path,link, segflg, FOLLOW));
1542 }
1543
1544 int
1545 kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2,
1546     enum uio_seg segflg, int follow)
1547 {
1548         struct vnode *vp;
1549         struct mount *mp;
1550         struct nameidata nd;
1551         int vfslocked;
1552         int lvfslocked;
1553         int error;
1554
1555         bwillwrite();
1556         NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, segflg, path1,
1557             fd1, td);
1558
1559         if ((error = namei(&nd)) != 0)
1560                 return (error);
1561         vfslocked = NDHASGIANT(&nd);
1562         NDFREE(&nd, NDF_ONLY_PNBUF);
1563         vp = nd.ni_vp;
1564         if (vp->v_type == VDIR) {
1565                 vrele(vp);
1566                 VFS_UNLOCK_GIANT(vfslocked);
1567                 return (EPERM);         /* POSIX */
1568         }
1569         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
1570                 vrele(vp);
1571                 VFS_UNLOCK_GIANT(vfslocked);
1572                 return (error);
1573         }
1574         NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
1575             segflg, path2, fd2, td);
1576         if ((error = namei(&nd)) == 0) {
1577                 lvfslocked = NDHASGIANT(&nd);
1578                 if (nd.ni_vp != NULL) {
1579                         if (nd.ni_dvp == nd.ni_vp)
1580                                 vrele(nd.ni_dvp);
1581                         else
1582                                 vput(nd.ni_dvp);
1583                         vrele(nd.ni_vp);
1584                         error = EEXIST;
1585                 } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY))
1586                     == 0) {
1587                         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1588                         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1589                         error = can_hardlink(vp, td->td_ucred);
1590                         if (error == 0)
1591 #ifdef MAC
1592                                 error = mac_vnode_check_link(td->td_ucred,
1593                                     nd.ni_dvp, vp, &nd.ni_cnd);
1594                         if (error == 0)
1595 #endif
1596                                 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1597                         VOP_UNLOCK(vp, 0);
1598                         vput(nd.ni_dvp);
1599                 }
1600                 NDFREE(&nd, NDF_ONLY_PNBUF);
1601                 VFS_UNLOCK_GIANT(lvfslocked);
1602         }
1603         vrele(vp);
1604         vn_finished_write(mp);
1605         VFS_UNLOCK_GIANT(vfslocked);
1606         return (error);
1607 }
1608
1609 /*
1610  * Make a symbolic link.
1611  */
1612 #ifndef _SYS_SYSPROTO_H_
1613 struct symlink_args {
1614         char    *path;
1615         char    *link;
1616 };
1617 #endif
1618 int
1619 symlink(td, uap)
1620         struct thread *td;
1621         register struct symlink_args /* {
1622                 char *path;
1623                 char *link;
1624         } */ *uap;
1625 {
1626
1627         return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE));
1628 }
1629
1630 #ifndef _SYS_SYSPROTO_H_
1631 struct symlinkat_args {
1632         char    *path;
1633         int     fd;
1634         char    *path2;
1635 };
1636 #endif
1637 int
1638 symlinkat(struct thread *td, struct symlinkat_args *uap)
1639 {
1640
1641         return (kern_symlinkat(td, uap->path1, uap->fd, uap->path2,
1642             UIO_USERSPACE));
1643 }
1644
1645 int
1646 kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg)
1647 {
1648
1649         return (kern_symlinkat(td, path, AT_FDCWD, link, segflg));
1650 }
1651
1652 int
1653 kern_symlinkat(struct thread *td, char *path1, int fd, char *path2,
1654     enum uio_seg segflg)
1655 {
1656         struct mount *mp;
1657         struct vattr vattr;
1658         char *syspath;
1659         int error;
1660         struct nameidata nd;
1661         int vfslocked;
1662
1663         if (segflg == UIO_SYSSPACE) {
1664                 syspath = path1;
1665         } else {
1666                 syspath = uma_zalloc(namei_zone, M_WAITOK);
1667                 if ((error = copyinstr(path1, syspath, MAXPATHLEN, NULL)) != 0)
1668                         goto out;
1669         }
1670         AUDIT_ARG(text, syspath);
1671 restart:
1672         bwillwrite();
1673         NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
1674             segflg, path2, fd, td);
1675         if ((error = namei(&nd)) != 0)
1676                 goto out;
1677         vfslocked = NDHASGIANT(&nd);
1678         if (nd.ni_vp) {
1679                 NDFREE(&nd, NDF_ONLY_PNBUF);
1680                 if (nd.ni_vp == nd.ni_dvp)
1681                         vrele(nd.ni_dvp);
1682                 else
1683                         vput(nd.ni_dvp);
1684                 vrele(nd.ni_vp);
1685                 VFS_UNLOCK_GIANT(vfslocked);
1686                 error = EEXIST;
1687                 goto out;
1688         }
1689         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1690                 NDFREE(&nd, NDF_ONLY_PNBUF);
1691                 vput(nd.ni_dvp);
1692                 VFS_UNLOCK_GIANT(vfslocked);
1693                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1694                         goto out;
1695                 goto restart;
1696         }
1697         VATTR_NULL(&vattr);
1698         FILEDESC_SLOCK(td->td_proc->p_fd);
1699         vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask;
1700         FILEDESC_SUNLOCK(td->td_proc->p_fd);
1701 #ifdef MAC
1702         vattr.va_type = VLNK;
1703         error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1704             &vattr);
1705         if (error)
1706                 goto out2;
1707 #endif
1708         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1709         error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath);
1710         if (error == 0)
1711                 vput(nd.ni_vp);
1712 #ifdef MAC
1713 out2:
1714 #endif
1715         NDFREE(&nd, NDF_ONLY_PNBUF);
1716         vput(nd.ni_dvp);
1717         vn_finished_write(mp);
1718         VFS_UNLOCK_GIANT(vfslocked);
1719 out:
1720         if (segflg != UIO_SYSSPACE)
1721                 uma_zfree(namei_zone, syspath);
1722         return (error);
1723 }
1724
1725 /*
1726  * Delete a whiteout from the filesystem.
1727  */
1728 int
1729 undelete(td, uap)
1730         struct thread *td;
1731         register struct undelete_args /* {
1732                 char *path;
1733         } */ *uap;
1734 {
1735         int error;
1736         struct mount *mp;
1737         struct nameidata nd;
1738         int vfslocked;
1739
1740 restart:
1741         bwillwrite();
1742         NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | MPSAFE | AUDITVNODE1,
1743             UIO_USERSPACE, uap->path, td);
1744         error = namei(&nd);
1745         if (error)
1746                 return (error);
1747         vfslocked = NDHASGIANT(&nd);
1748
1749         if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
1750                 NDFREE(&nd, NDF_ONLY_PNBUF);
1751                 if (nd.ni_vp == nd.ni_dvp)
1752                         vrele(nd.ni_dvp);
1753                 else
1754                         vput(nd.ni_dvp);
1755                 if (nd.ni_vp)
1756                         vrele(nd.ni_vp);
1757                 VFS_UNLOCK_GIANT(vfslocked);
1758                 return (EEXIST);
1759         }
1760         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1761                 NDFREE(&nd, NDF_ONLY_PNBUF);
1762                 vput(nd.ni_dvp);
1763                 VFS_UNLOCK_GIANT(vfslocked);
1764                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1765                         return (error);
1766                 goto restart;
1767         }
1768         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1769         error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE);
1770         NDFREE(&nd, NDF_ONLY_PNBUF);
1771         vput(nd.ni_dvp);
1772         vn_finished_write(mp);
1773         VFS_UNLOCK_GIANT(vfslocked);
1774         return (error);
1775 }
1776
1777 /*
1778  * Delete a name from the filesystem.
1779  */
1780 #ifndef _SYS_SYSPROTO_H_
1781 struct unlink_args {
1782         char    *path;
1783 };
1784 #endif
1785 int
1786 unlink(td, uap)
1787         struct thread *td;
1788         struct unlink_args /* {
1789                 char *path;
1790         } */ *uap;
1791 {
1792
1793         return (kern_unlink(td, uap->path, UIO_USERSPACE));
1794 }
1795
1796 #ifndef _SYS_SYSPROTO_H_
1797 struct unlinkat_args {
1798         int     fd;
1799         char    *path;
1800         int     flag;
1801 };
1802 #endif
1803 int
1804 unlinkat(struct thread *td, struct unlinkat_args *uap)
1805 {
1806         int flag = uap->flag;
1807         int fd = uap->fd;
1808         char *path = uap->path;
1809
1810         if (flag & ~AT_REMOVEDIR)
1811                 return (EINVAL);
1812
1813         if (flag & AT_REMOVEDIR)
1814                 return (kern_rmdirat(td, fd, path, UIO_USERSPACE));
1815         else
1816                 return (kern_unlinkat(td, fd, path, UIO_USERSPACE));
1817 }
1818
1819 int
1820 kern_unlink(struct thread *td, char *path, enum uio_seg pathseg)
1821 {
1822
1823         return (kern_unlinkat(td, AT_FDCWD, path, pathseg));
1824 }
1825
1826 int
1827 kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg)
1828 {
1829         struct mount *mp;
1830         struct vnode *vp;
1831         int error;
1832         struct nameidata nd;
1833         int vfslocked;
1834
1835 restart:
1836         bwillwrite();
1837         NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1,
1838             pathseg, path, fd, td);
1839         if ((error = namei(&nd)) != 0)
1840                 return (error == EINVAL ? EPERM : error);
1841         vfslocked = NDHASGIANT(&nd);
1842         vp = nd.ni_vp;
1843         if (vp->v_type == VDIR)
1844                 error = EPERM;          /* POSIX */
1845         else {
1846                 /*
1847                  * The root of a mounted filesystem cannot be deleted.
1848                  *
1849                  * XXX: can this only be a VDIR case?
1850                  */
1851                 if (vp->v_vflag & VV_ROOT)
1852                         error = EBUSY;
1853         }
1854         if (error == 0) {
1855                 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1856                         NDFREE(&nd, NDF_ONLY_PNBUF);
1857                         vput(nd.ni_dvp);
1858                         if (vp == nd.ni_dvp)
1859                                 vrele(vp);
1860                         else
1861                                 vput(vp);
1862                         VFS_UNLOCK_GIANT(vfslocked);
1863                         if ((error = vn_start_write(NULL, &mp,
1864                             V_XSLEEP | PCATCH)) != 0)
1865                                 return (error);
1866                         goto restart;
1867                 }
1868 #ifdef MAC
1869                 error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp,
1870                     &nd.ni_cnd);
1871                 if (error)
1872                         goto out;
1873 #endif
1874                 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1875                 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
1876 #ifdef MAC
1877 out:
1878 #endif
1879                 vn_finished_write(mp);
1880         }
1881         NDFREE(&nd, NDF_ONLY_PNBUF);
1882         vput(nd.ni_dvp);
1883         if (vp == nd.ni_dvp)
1884                 vrele(vp);
1885         else
1886                 vput(vp);
1887         VFS_UNLOCK_GIANT(vfslocked);
1888         return (error);
1889 }
1890
1891 /*
1892  * Reposition read/write file offset.
1893  */
1894 #ifndef _SYS_SYSPROTO_H_
1895 struct lseek_args {
1896         int     fd;
1897         int     pad;
1898         off_t   offset;
1899         int     whence;
1900 };
1901 #endif
1902 int
1903 lseek(td, uap)
1904         struct thread *td;
1905         register struct lseek_args /* {
1906                 int fd;
1907                 int pad;
1908                 off_t offset;
1909                 int whence;
1910         } */ *uap;
1911 {
1912         struct ucred *cred = td->td_ucred;
1913         struct file *fp;
1914         struct vnode *vp;
1915         struct vattr vattr;
1916         off_t offset;
1917         int error, noneg;
1918         int vfslocked;
1919
1920         if ((error = fget(td, uap->fd, &fp)) != 0)
1921                 return (error);
1922         if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) {
1923                 fdrop(fp, td);
1924                 return (ESPIPE);
1925         }
1926         vp = fp->f_vnode;
1927         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1928         noneg = (vp->v_type != VCHR);
1929         offset = uap->offset;
1930         switch (uap->whence) {
1931         case L_INCR:
1932                 if (noneg &&
1933                     (fp->f_offset < 0 ||
1934                     (offset > 0 && fp->f_offset > OFF_MAX - offset))) {
1935                         error = EOVERFLOW;
1936                         break;
1937                 }
1938                 offset += fp->f_offset;
1939                 break;
1940         case L_XTND:
1941                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1942                 error = VOP_GETATTR(vp, &vattr, cred);
1943                 VOP_UNLOCK(vp, 0);
1944                 if (error)
1945                         break;
1946                 if (noneg &&
1947                     (vattr.va_size > OFF_MAX ||
1948                     (offset > 0 && vattr.va_size > OFF_MAX - offset))) {
1949                         error = EOVERFLOW;
1950                         break;
1951                 }
1952                 offset += vattr.va_size;
1953                 break;
1954         case L_SET:
1955                 break;
1956         case SEEK_DATA:
1957                 error = fo_ioctl(fp, FIOSEEKDATA, &offset, cred, td);
1958                 break;
1959         case SEEK_HOLE:
1960                 error = fo_ioctl(fp, FIOSEEKHOLE, &offset, cred, td);
1961                 break;
1962         default:
1963                 error = EINVAL;
1964         }
1965         if (error == 0 && noneg && offset < 0)
1966                 error = EINVAL;
1967         if (error != 0)
1968                 goto drop;
1969         fp->f_offset = offset;
1970         *(off_t *)(td->td_retval) = fp->f_offset;
1971 drop:
1972         fdrop(fp, td);
1973         VFS_UNLOCK_GIANT(vfslocked);
1974         return (error);
1975 }
1976
1977 #if defined(COMPAT_43)
1978 /*
1979  * Reposition read/write file offset.
1980  */
1981 #ifndef _SYS_SYSPROTO_H_
1982 struct olseek_args {
1983         int     fd;
1984         long    offset;
1985         int     whence;
1986 };
1987 #endif
1988 int
1989 olseek(td, uap)
1990         struct thread *td;
1991         register struct olseek_args /* {
1992                 int fd;
1993                 long offset;
1994                 int whence;
1995         } */ *uap;
1996 {
1997         struct lseek_args /* {
1998                 int fd;
1999                 int pad;
2000                 off_t offset;
2001                 int whence;
2002         } */ nuap;
2003
2004         nuap.fd = uap->fd;
2005         nuap.offset = uap->offset;
2006         nuap.whence = uap->whence;
2007         return (lseek(td, &nuap));
2008 }
2009 #endif /* COMPAT_43 */
2010
2011 /* Version with the 'pad' argument */
2012 int
2013 freebsd6_lseek(td, uap)
2014         struct thread *td;
2015         register struct freebsd6_lseek_args *uap;
2016 {
2017         struct lseek_args ouap;
2018
2019         ouap.fd = uap->fd;
2020         ouap.offset = uap->offset;
2021         ouap.whence = uap->whence;
2022         return (lseek(td, &ouap));
2023 }
2024
2025 /*
2026  * Check access permissions using passed credentials.
2027  */
2028 static int
2029 vn_access(vp, user_flags, cred, td)
2030         struct vnode    *vp;
2031         int             user_flags;
2032         struct ucred    *cred;
2033         struct thread   *td;
2034 {
2035         int error, flags;
2036
2037         /* Flags == 0 means only check for existence. */
2038         error = 0;
2039         if (user_flags) {
2040                 flags = 0;
2041                 if (user_flags & R_OK)
2042                         flags |= VREAD;
2043                 if (user_flags & W_OK)
2044                         flags |= VWRITE;
2045                 if (user_flags & X_OK)
2046                         flags |= VEXEC;
2047 #ifdef MAC
2048                 error = mac_vnode_check_access(cred, vp, flags);
2049                 if (error)
2050                         return (error);
2051 #endif
2052                 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
2053                         error = VOP_ACCESS(vp, flags, cred, td);
2054         }
2055         return (error);
2056 }
2057
2058 /*
2059  * Check access permissions using "real" credentials.
2060  */
2061 #ifndef _SYS_SYSPROTO_H_
2062 struct access_args {
2063         char    *path;
2064         int     flags;
2065 };
2066 #endif
2067 int
2068 access(td, uap)
2069         struct thread *td;
2070         register struct access_args /* {
2071                 char *path;
2072                 int flags;
2073         } */ *uap;
2074 {
2075
2076         return (kern_access(td, uap->path, UIO_USERSPACE, uap->flags));
2077 }
2078
2079 #ifndef _SYS_SYSPROTO_H_
2080 struct faccessat_args {
2081         int     dirfd;
2082         char    *path;
2083         int     mode;
2084         int     flag;
2085 }
2086 #endif
2087 int faccessat(struct thread *td, struct faccessat_args *uap)
2088 {
2089
2090         if (uap->flag & ~AT_EACCESS)
2091                 return (EINVAL);
2092         return (kern_accessat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag,
2093             uap->mode));
2094 }
2095
2096 int
2097 kern_access(struct thread *td, char *path, enum uio_seg pathseg, int mode)
2098 {
2099
2100         return (kern_accessat(td, AT_FDCWD, path, pathseg, 0, mode));
2101 }
2102
2103 int
2104 kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
2105     int flags, int mode)
2106 {
2107         struct ucred *cred, *tmpcred;
2108         struct vnode *vp;
2109         struct nameidata nd;
2110         int vfslocked;
2111         int error;
2112
2113         /*
2114          * Create and modify a temporary credential instead of one that
2115          * is potentially shared.  This could also mess up socket
2116          * buffer accounting which can run in an interrupt context.
2117          */
2118         if (!(flags & AT_EACCESS)) {
2119                 cred = td->td_ucred;
2120                 tmpcred = crdup(cred);
2121                 tmpcred->cr_uid = cred->cr_ruid;
2122                 tmpcred->cr_groups[0] = cred->cr_rgid;
2123                 td->td_ucred = tmpcred;
2124         } else
2125                 cred = tmpcred = td->td_ucred;
2126         NDINIT_AT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
2127             pathseg, path, fd, td);
2128         if ((error = namei(&nd)) != 0)
2129                 goto out1;
2130         vfslocked = NDHASGIANT(&nd);
2131         vp = nd.ni_vp;
2132
2133         error = vn_access(vp, mode, tmpcred, td);
2134         NDFREE(&nd, NDF_ONLY_PNBUF);
2135         vput(vp);
2136         VFS_UNLOCK_GIANT(vfslocked);
2137 out1:
2138         if (!(flags & AT_EACCESS)) {
2139                 td->td_ucred = cred;
2140                 crfree(tmpcred);
2141         }
2142         return (error);
2143 }
2144
2145 /*
2146  * Check access permissions using "effective" credentials.
2147  */
2148 #ifndef _SYS_SYSPROTO_H_
2149 struct eaccess_args {
2150         char    *path;
2151         int     flags;
2152 };
2153 #endif
2154 int
2155 eaccess(td, uap)
2156         struct thread *td;
2157         register struct eaccess_args /* {
2158                 char *path;
2159                 int flags;
2160         } */ *uap;
2161 {
2162
2163         return (kern_eaccess(td, uap->path, UIO_USERSPACE, uap->flags));
2164 }
2165
2166 int
2167 kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, int flags)
2168 {
2169
2170         return (kern_accessat(td, AT_FDCWD, path, pathseg, AT_EACCESS, flags));
2171 }
2172
2173 #if defined(COMPAT_43)
2174 /*
2175  * Get file status; this version follows links.
2176  */
2177 #ifndef _SYS_SYSPROTO_H_
2178 struct ostat_args {
2179         char    *path;
2180         struct ostat *ub;
2181 };
2182 #endif
2183 int
2184 ostat(td, uap)
2185         struct thread *td;
2186         register struct ostat_args /* {
2187                 char *path;
2188                 struct ostat *ub;
2189         } */ *uap;
2190 {
2191         struct stat sb;
2192         struct ostat osb;
2193         int error;
2194
2195         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2196         if (error)
2197                 return (error);
2198         cvtstat(&sb, &osb);
2199         error = copyout(&osb, uap->ub, sizeof (osb));
2200         return (error);
2201 }
2202
2203 /*
2204  * Get file status; this version does not follow links.
2205  */
2206 #ifndef _SYS_SYSPROTO_H_
2207 struct olstat_args {
2208         char    *path;
2209         struct ostat *ub;
2210 };
2211 #endif
2212 int
2213 olstat(td, uap)
2214         struct thread *td;
2215         register struct olstat_args /* {
2216                 char *path;
2217                 struct ostat *ub;
2218         } */ *uap;
2219 {
2220         struct stat sb;
2221         struct ostat osb;
2222         int error;
2223
2224         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2225         if (error)
2226                 return (error);
2227         cvtstat(&sb, &osb);
2228         error = copyout(&osb, uap->ub, sizeof (osb));
2229         return (error);
2230 }
2231
2232 /*
2233  * Convert from an old to a new stat structure.
2234  */
2235 void
2236 cvtstat(st, ost)
2237         struct stat *st;
2238         struct ostat *ost;
2239 {
2240
2241         ost->st_dev = st->st_dev;
2242         ost->st_ino = st->st_ino;
2243         ost->st_mode = st->st_mode;
2244         ost->st_nlink = st->st_nlink;
2245         ost->st_uid = st->st_uid;
2246         ost->st_gid = st->st_gid;
2247         ost->st_rdev = st->st_rdev;
2248         if (st->st_size < (quad_t)1 << 32)
2249                 ost->st_size = st->st_size;
2250         else
2251                 ost->st_size = -2;
2252         ost->st_atime = st->st_atime;
2253         ost->st_mtime = st->st_mtime;
2254         ost->st_ctime = st->st_ctime;
2255         ost->st_blksize = st->st_blksize;
2256         ost->st_blocks = st->st_blocks;
2257         ost->st_flags = st->st_flags;
2258         ost->st_gen = st->st_gen;
2259 }
2260 #endif /* COMPAT_43 */
2261
2262 /*
2263  * Get file status; this version follows links.
2264  */
2265 #ifndef _SYS_SYSPROTO_H_
2266 struct stat_args {
2267         char    *path;
2268         struct stat *ub;
2269 };
2270 #endif
2271 int
2272 stat(td, uap)
2273         struct thread *td;
2274         register struct stat_args /* {
2275                 char *path;
2276                 struct stat *ub;
2277         } */ *uap;
2278 {
2279         struct stat sb;
2280         int error;
2281
2282         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2283         if (error == 0)
2284                 error = copyout(&sb, uap->ub, sizeof (sb));
2285         return (error);
2286 }
2287
2288 #ifndef _SYS_SYSPROTO_H_
2289 struct fstatat_args {
2290         int     fd;
2291         char    *path;
2292         struct stat     *buf;
2293         int     flag;
2294 }
2295 #endif
2296 int
2297 fstatat(struct thread *td, struct fstatat_args *uap)
2298 {
2299         struct stat sb;
2300         int error;
2301
2302         error = kern_statat(td, uap->flag, uap->fd, uap->path,
2303             UIO_USERSPACE, &sb);
2304         if (error == 0)
2305                 error = copyout(&sb, uap->buf, sizeof (sb));
2306         return (error);
2307 }
2308
2309 int
2310 kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
2311 {
2312
2313         return (kern_statat(td, 0, AT_FDCWD, path, pathseg, sbp));
2314 }
2315
2316 int
2317 kern_statat(struct thread *td, int flag, int fd, char *path,
2318     enum uio_seg pathseg, struct stat *sbp)
2319 {
2320         struct nameidata nd;
2321         struct stat sb;
2322         int error, vfslocked;
2323
2324         if (flag & ~AT_SYMLINK_NOFOLLOW)
2325                 return (EINVAL);
2326
2327         NDINIT_AT(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW :
2328             FOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg,
2329             path, fd, td);
2330
2331         if ((error = namei(&nd)) != 0)
2332                 return (error);
2333         vfslocked = NDHASGIANT(&nd);
2334         error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
2335         NDFREE(&nd, NDF_ONLY_PNBUF);
2336         vput(nd.ni_vp);
2337         VFS_UNLOCK_GIANT(vfslocked);
2338         if (mtx_owned(&Giant))
2339                 printf("stat(%d): %s\n", vfslocked, path);
2340         if (error)
2341                 return (error);
2342         *sbp = sb;
2343 #ifdef KTRACE
2344         if (KTRPOINT(td, KTR_STRUCT))
2345                 ktrstat(&sb);
2346 #endif
2347         return (0);
2348 }
2349
2350 /*
2351  * Get file status; this version does not follow links.
2352  */
2353 #ifndef _SYS_SYSPROTO_H_
2354 struct lstat_args {
2355         char    *path;
2356         struct stat *ub;
2357 };
2358 #endif
2359 int
2360 lstat(td, uap)
2361         struct thread *td;
2362         register struct lstat_args /* {
2363                 char *path;
2364                 struct stat *ub;
2365         } */ *uap;
2366 {
2367         struct stat sb;
2368         int error;
2369
2370         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2371         if (error == 0)
2372                 error = copyout(&sb, uap->ub, sizeof (sb));
2373         return (error);
2374 }
2375
2376 int
2377 kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
2378 {
2379
2380         return (kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, pathseg,
2381             sbp));
2382 }
2383
2384 /*
2385  * Implementation of the NetBSD [l]stat() functions.
2386  */
2387 void
2388 cvtnstat(sb, nsb)
2389         struct stat *sb;
2390         struct nstat *nsb;
2391 {
2392         bzero(nsb, sizeof *nsb);
2393         nsb->st_dev = sb->st_dev;
2394         nsb->st_ino = sb->st_ino;
2395         nsb->st_mode = sb->st_mode;
2396         nsb->st_nlink = sb->st_nlink;
2397         nsb->st_uid = sb->st_uid;
2398         nsb->st_gid = sb->st_gid;
2399         nsb->st_rdev = sb->st_rdev;
2400         nsb->st_atimespec = sb->st_atimespec;
2401         nsb->st_mtimespec = sb->st_mtimespec;
2402         nsb->st_ctimespec = sb->st_ctimespec;
2403         nsb->st_size = sb->st_size;
2404         nsb->st_blocks = sb->st_blocks;
2405         nsb->st_blksize = sb->st_blksize;
2406         nsb->st_flags = sb->st_flags;
2407         nsb->st_gen = sb->st_gen;
2408         nsb->st_birthtimespec = sb->st_birthtimespec;
2409 }
2410
2411 #ifndef _SYS_SYSPROTO_H_
2412 struct nstat_args {
2413         char    *path;
2414         struct nstat *ub;
2415 };
2416 #endif
2417 int
2418 nstat(td, uap)
2419         struct thread *td;
2420         register struct nstat_args /* {
2421                 char *path;
2422                 struct nstat *ub;
2423         } */ *uap;
2424 {
2425         struct stat sb;
2426         struct nstat nsb;
2427         int error;
2428
2429         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2430         if (error)
2431                 return (error);
2432         cvtnstat(&sb, &nsb);
2433         error = copyout(&nsb, uap->ub, sizeof (nsb));
2434         return (error);
2435 }
2436
2437 /*
2438  * NetBSD lstat.  Get file status; this version does not follow links.
2439  */
2440 #ifndef _SYS_SYSPROTO_H_
2441 struct lstat_args {
2442         char    *path;
2443         struct stat *ub;
2444 };
2445 #endif
2446 int
2447 nlstat(td, uap)
2448         struct thread *td;
2449         register struct nlstat_args /* {
2450                 char *path;
2451                 struct nstat *ub;
2452         } */ *uap;
2453 {
2454         struct stat sb;
2455         struct nstat nsb;
2456         int error;
2457
2458         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2459         if (error)
2460                 return (error);
2461         cvtnstat(&sb, &nsb);
2462         error = copyout(&nsb, uap->ub, sizeof (nsb));
2463         return (error);
2464 }
2465
2466 /*
2467  * Get configurable pathname variables.
2468  */
2469 #ifndef _SYS_SYSPROTO_H_
2470 struct pathconf_args {
2471         char    *path;
2472         int     name;
2473 };
2474 #endif
2475 int
2476 pathconf(td, uap)
2477         struct thread *td;
2478         register struct pathconf_args /* {
2479                 char *path;
2480                 int name;
2481         } */ *uap;
2482 {
2483
2484         return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name));
2485 }
2486
2487 int
2488 kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name)
2489 {
2490         struct nameidata nd;
2491         int error, vfslocked;
2492
2493         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
2494             pathseg, path, td);
2495         if ((error = namei(&nd)) != 0)
2496                 return (error);
2497         vfslocked = NDHASGIANT(&nd);
2498         NDFREE(&nd, NDF_ONLY_PNBUF);
2499
2500         /* If asynchronous I/O is available, it works for all files. */
2501         if (name == _PC_ASYNC_IO)
2502                 td->td_retval[0] = async_io_version;
2503         else
2504                 error = VOP_PATHCONF(nd.ni_vp, name, td->td_retval);
2505         vput(nd.ni_vp);
2506         VFS_UNLOCK_GIANT(vfslocked);
2507         return (error);
2508 }
2509
2510 /*
2511  * Return target name of a symbolic link.
2512  */
2513 #ifndef _SYS_SYSPROTO_H_
2514 struct readlink_args {
2515         char    *path;
2516         char    *buf;
2517         size_t  count;
2518 };
2519 #endif
2520 int
2521 readlink(td, uap)
2522         struct thread *td;
2523         register struct readlink_args /* {
2524                 char *path;
2525                 char *buf;
2526                 size_t count;
2527         } */ *uap;
2528 {
2529
2530         return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf,
2531             UIO_USERSPACE, uap->count));
2532 }
2533 #ifndef _SYS_SYSPROTO_H_
2534 struct readlinkat_args {
2535         int     fd;
2536         char    *path;
2537         char    *buf;
2538         size_t  bufsize;
2539 };
2540 #endif
2541 int
2542 readlinkat(struct thread *td, struct readlinkat_args *uap)
2543 {
2544
2545         return (kern_readlinkat(td, uap->fd, uap->path, UIO_USERSPACE,
2546             uap->buf, UIO_USERSPACE, uap->bufsize));
2547 }
2548
2549 int
2550 kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf,
2551     enum uio_seg bufseg, size_t count)
2552 {
2553
2554         return (kern_readlinkat(td, AT_FDCWD, path, pathseg, buf, bufseg,
2555             count));
2556 }
2557
2558 int
2559 kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
2560     char *buf, enum uio_seg bufseg, size_t count)
2561 {
2562         struct vnode *vp;
2563         struct iovec aiov;
2564         struct uio auio;
2565         int error;
2566         struct nameidata nd;
2567         int vfslocked;
2568
2569         NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
2570             pathseg, path, fd, td);
2571
2572         if ((error = namei(&nd)) != 0)
2573                 return (error);
2574         NDFREE(&nd, NDF_ONLY_PNBUF);
2575         vfslocked = NDHASGIANT(&nd);
2576         vp = nd.ni_vp;
2577 #ifdef MAC
2578         error = mac_vnode_check_readlink(td->td_ucred, vp);
2579         if (error) {
2580                 vput(vp);
2581                 VFS_UNLOCK_GIANT(vfslocked);
2582                 return (error);
2583         }
2584 #endif
2585         if (vp->v_type != VLNK)
2586                 error = EINVAL;
2587         else {
2588                 aiov.iov_base = buf;
2589                 aiov.iov_len = count;
2590                 auio.uio_iov = &aiov;
2591                 auio.uio_iovcnt = 1;
2592                 auio.uio_offset = 0;
2593                 auio.uio_rw = UIO_READ;
2594                 auio.uio_segflg = bufseg;
2595                 auio.uio_td = td;
2596                 auio.uio_resid = count;
2597                 error = VOP_READLINK(vp, &auio, td->td_ucred);
2598         }
2599         vput(vp);
2600         VFS_UNLOCK_GIANT(vfslocked);
2601         td->td_retval[0] = count - auio.uio_resid;
2602         return (error);
2603 }
2604
2605 /*
2606  * Common implementation code for chflags() and fchflags().
2607  */
2608 static int
2609 setfflags(td, vp, flags)
2610         struct thread *td;
2611         struct vnode *vp;
2612         int flags;
2613 {
2614         int error;
2615         struct mount *mp;
2616         struct vattr vattr;
2617
2618         /*
2619          * Prevent non-root users from setting flags on devices.  When
2620          * a device is reused, users can retain ownership of the device
2621          * if they are allowed to set flags and programs assume that
2622          * chown can't fail when done as root.
2623          */
2624         if (vp->v_type == VCHR || vp->v_type == VBLK) {
2625                 error = priv_check(td, PRIV_VFS_CHFLAGS_DEV);
2626                 if (error)
2627                         return (error);
2628         }
2629
2630         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2631                 return (error);
2632         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2633         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2634         VATTR_NULL(&vattr);
2635         vattr.va_flags = flags;
2636 #ifdef MAC
2637         error = mac_vnode_check_setflags(td->td_ucred, vp, vattr.va_flags);
2638         if (error == 0)
2639 #endif
2640                 error = VOP_SETATTR(vp, &vattr, td->td_ucred);
2641         VOP_UNLOCK(vp, 0);
2642         vn_finished_write(mp);
2643         return (error);
2644 }
2645
2646 /*
2647  * Change flags of a file given a path name.
2648  */
2649 #ifndef _SYS_SYSPROTO_H_
2650 struct chflags_args {
2651         char    *path;
2652         int     flags;
2653 };
2654 #endif
2655 int
2656 chflags(td, uap)
2657         struct thread *td;
2658         register struct chflags_args /* {
2659                 char *path;
2660                 int flags;
2661         } */ *uap;
2662 {
2663         int error;
2664         struct nameidata nd;
2665         int vfslocked;
2666
2667         AUDIT_ARG(fflags, uap->flags);
2668         NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE,
2669             uap->path, td);
2670         if ((error = namei(&nd)) != 0)
2671                 return (error);
2672         NDFREE(&nd, NDF_ONLY_PNBUF);
2673         vfslocked = NDHASGIANT(&nd);
2674         error = setfflags(td, nd.ni_vp, uap->flags);
2675         vrele(nd.ni_vp);
2676         VFS_UNLOCK_GIANT(vfslocked);
2677         return (error);
2678 }
2679
2680 /*
2681  * Same as chflags() but doesn't follow symlinks.
2682  */
2683 int
2684 lchflags(td, uap)
2685         struct thread *td;
2686         register struct lchflags_args /* {
2687                 char *path;
2688                 int flags;
2689         } */ *uap;
2690 {
2691         int error;
2692         struct nameidata nd;
2693         int vfslocked;
2694
2695         AUDIT_ARG(fflags, uap->flags);
2696         NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE,
2697             uap->path, td);
2698         if ((error = namei(&nd)) != 0)
2699                 return (error);
2700         vfslocked = NDHASGIANT(&nd);
2701         NDFREE(&nd, NDF_ONLY_PNBUF);
2702         error = setfflags(td, nd.ni_vp, uap->flags);
2703         vrele(nd.ni_vp);
2704         VFS_UNLOCK_GIANT(vfslocked);
2705         return (error);
2706 }
2707
2708 /*
2709  * Change flags of a file given a file descriptor.
2710  */
2711 #ifndef _SYS_SYSPROTO_H_
2712 struct fchflags_args {
2713         int     fd;
2714         int     flags;
2715 };
2716 #endif
2717 int
2718 fchflags(td, uap)
2719         struct thread *td;
2720         register struct fchflags_args /* {
2721                 int fd;
2722                 int flags;
2723         } */ *uap;
2724 {
2725         struct file *fp;
2726         int vfslocked;
2727         int error;
2728
2729         AUDIT_ARG(fd, uap->fd);
2730         AUDIT_ARG(fflags, uap->flags);
2731         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2732                 return (error);
2733         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2734 #ifdef AUDIT
2735         vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY);
2736         AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1);
2737         VOP_UNLOCK(fp->f_vnode, 0);
2738 #endif
2739         error = setfflags(td, fp->f_vnode, uap->flags);
2740         VFS_UNLOCK_GIANT(vfslocked);
2741         fdrop(fp, td);
2742         return (error);
2743 }
2744
2745 /*
2746  * Common implementation code for chmod(), lchmod() and fchmod().
2747  */
2748 static int
2749 setfmode(td, vp, mode)
2750         struct thread *td;
2751         struct vnode *vp;
2752         int mode;
2753 {
2754         int error;
2755         struct mount *mp;
2756         struct vattr vattr;
2757
2758         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2759                 return (error);
2760         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2761         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2762         VATTR_NULL(&vattr);
2763         vattr.va_mode = mode & ALLPERMS;
2764 #ifdef MAC
2765         error = mac_vnode_check_setmode(td->td_ucred, vp, vattr.va_mode);
2766         if (error == 0)
2767 #endif
2768                 error = VOP_SETATTR(vp, &vattr, td->td_ucred);
2769         VOP_UNLOCK(vp, 0);
2770         vn_finished_write(mp);
2771         return (error);
2772 }
2773
2774 /*
2775  * Change mode of a file given path name.
2776  */
2777 #ifndef _SYS_SYSPROTO_H_
2778 struct chmod_args {
2779         char    *path;
2780         int     mode;
2781 };
2782 #endif
2783 int
2784 chmod(td, uap)
2785         struct thread *td;
2786         register struct chmod_args /* {
2787                 char *path;
2788                 int mode;
2789         } */ *uap;
2790 {
2791
2792         return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode));
2793 }
2794
2795 #ifndef _SYS_SYSPROTO_H_
2796 struct fchmodat_args {
2797         int     dirfd;
2798         char    *path;
2799         mode_t  mode;
2800         int     flag;
2801 }
2802 #endif
2803 int
2804 fchmodat(struct thread *td, struct fchmodat_args *uap)
2805 {
2806         int flag = uap->flag;
2807         int fd = uap->fd;
2808         char *path = uap->path;
2809         mode_t mode = uap->mode;
2810
2811         if (flag & ~AT_SYMLINK_NOFOLLOW)
2812                 return (EINVAL);
2813
2814         return (kern_fchmodat(td, fd, path, UIO_USERSPACE, mode, flag));
2815 }
2816
2817 int
2818 kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode)
2819 {
2820
2821         return (kern_fchmodat(td, AT_FDCWD, path, pathseg, mode, 0));
2822 }
2823
2824 /*
2825  * Change mode of a file given path name (don't follow links.)
2826  */
2827 #ifndef _SYS_SYSPROTO_H_
2828 struct lchmod_args {
2829         char    *path;
2830         int     mode;
2831 };
2832 #endif
2833 int
2834 lchmod(td, uap)
2835         struct thread *td;
2836         register struct lchmod_args /* {
2837                 char *path;
2838                 int mode;
2839         } */ *uap;
2840 {
2841
2842         return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
2843             uap->mode, AT_SYMLINK_NOFOLLOW));
2844 }
2845
2846
2847 int
2848 kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
2849     mode_t mode, int flag)
2850 {
2851         int error;
2852         struct nameidata nd;
2853         int vfslocked;
2854         int follow;
2855
2856         AUDIT_ARG(mode, mode);
2857         follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
2858         NDINIT_AT(&nd, LOOKUP,  follow | MPSAFE | AUDITVNODE1, pathseg, path,
2859             fd, td);
2860         if ((error = namei(&nd)) != 0)
2861                 return (error);
2862         vfslocked = NDHASGIANT(&nd);
2863         NDFREE(&nd, NDF_ONLY_PNBUF);
2864         error = setfmode(td, nd.ni_vp, mode);
2865         vrele(nd.ni_vp);
2866         VFS_UNLOCK_GIANT(vfslocked);
2867         return (error);
2868 }
2869
2870 /*
2871  * Change mode of a file given a file descriptor.
2872  */
2873 #ifndef _SYS_SYSPROTO_H_
2874 struct fchmod_args {
2875         int     fd;
2876         int     mode;
2877 };
2878 #endif
2879 int
2880 fchmod(td, uap)
2881         struct thread *td;
2882         register struct fchmod_args /* {
2883                 int fd;
2884                 int mode;
2885         } */ *uap;
2886 {
2887         struct file *fp;
2888         int vfslocked;
2889         int error;
2890
2891         AUDIT_ARG(fd, uap->fd);
2892         AUDIT_ARG(mode, uap->mode);
2893         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2894                 return (error);
2895         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2896 #ifdef AUDIT
2897         vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY);
2898         AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1);
2899         VOP_UNLOCK(fp->f_vnode, 0);
2900 #endif
2901         error = setfmode(td, fp->f_vnode, uap->mode);
2902         VFS_UNLOCK_GIANT(vfslocked);
2903         fdrop(fp, td);
2904         return (error);
2905 }
2906
2907 /*
2908  * Common implementation for chown(), lchown(), and fchown()
2909  */
2910 static int
2911 setfown(td, vp, uid, gid)
2912         struct thread *td;
2913         struct vnode *vp;
2914         uid_t uid;
2915         gid_t gid;
2916 {
2917         int error;
2918         struct mount *mp;
2919         struct vattr vattr;
2920
2921         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2922                 return (error);
2923         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2924         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2925         VATTR_NULL(&vattr);
2926         vattr.va_uid = uid;
2927         vattr.va_gid = gid;
2928 #ifdef MAC
2929         error = mac_vnode_check_setowner(td->td_ucred, vp, vattr.va_uid,
2930             vattr.va_gid);
2931         if (error == 0)
2932 #endif
2933                 error = VOP_SETATTR(vp, &vattr, td->td_ucred);
2934         VOP_UNLOCK(vp, 0);
2935         vn_finished_write(mp);
2936         return (error);
2937 }
2938
2939 /*
2940  * Set ownership given a path name.
2941  */
2942 #ifndef _SYS_SYSPROTO_H_
2943 struct chown_args {
2944         char    *path;
2945         int     uid;
2946         int     gid;
2947 };
2948 #endif
2949 int
2950 chown(td, uap)
2951         struct thread *td;
2952         register struct chown_args /* {
2953                 char *path;
2954                 int uid;
2955                 int gid;
2956         } */ *uap;
2957 {
2958
2959         return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid));
2960 }
2961
2962 #ifndef _SYS_SYSPROTO_H_
2963 struct fchownat_args {
2964         int fd;
2965         const char * path;
2966         uid_t uid;
2967         gid_t gid;
2968         int flag;
2969 };
2970 #endif
2971 int
2972 fchownat(struct thread *td, struct fchownat_args *uap)
2973 {
2974         int flag;
2975
2976         flag = uap->flag;
2977         if (flag & ~AT_SYMLINK_NOFOLLOW)
2978                 return (EINVAL);
2979
2980         return (kern_fchownat(td, uap->fd, uap->path, UIO_USERSPACE, uap->uid,
2981             uap->gid, uap->flag));
2982 }
2983
2984 int
2985 kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
2986     int gid)
2987 {
2988
2989         return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 0));
2990 }
2991
2992 int
2993 kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
2994     int uid, int gid, int flag)
2995 {
2996         struct nameidata nd;
2997         int error, vfslocked, follow;
2998
2999         AUDIT_ARG(owner, uid, gid);
3000         follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
3001         NDINIT_AT(&nd, LOOKUP, follow | MPSAFE | AUDITVNODE1, pathseg, path,
3002             fd, td);
3003
3004         if ((error = namei(&nd)) != 0)
3005                 return (error);
3006         vfslocked = NDHASGIANT(&nd);
3007         NDFREE(&nd, NDF_ONLY_PNBUF);
3008         error = setfown(td, nd.ni_vp, uid, gid);
3009         vrele(nd.ni_vp);
3010         VFS_UNLOCK_GIANT(vfslocked);
3011         return (error);
3012 }
3013
3014 /*
3015  * Set ownership given a path name, do not cross symlinks.
3016  */
3017 #ifndef _SYS_SYSPROTO_H_
3018 struct lchown_args {
3019         char    *path;
3020         int     uid;
3021         int     gid;
3022 };
3023 #endif
3024 int
3025 lchown(td, uap)
3026         struct thread *td;
3027         register struct lchown_args /* {
3028                 char *path;
3029                 int uid;
3030                 int gid;
3031         } */ *uap;
3032 {
3033
3034         return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid));
3035 }
3036
3037 int
3038 kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
3039     int gid)
3040 {
3041
3042         return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid,
3043             AT_SYMLINK_NOFOLLOW));
3044 }
3045
3046 /*
3047  * Set ownership given a file descriptor.
3048  */
3049 #ifndef _SYS_SYSPROTO_H_
3050 struct fchown_args {
3051         int     fd;
3052         int     uid;
3053         int     gid;
3054 };
3055 #endif
3056 int
3057 fchown(td, uap)
3058         struct thread *td;
3059         register struct fchown_args /* {
3060                 int fd;
3061                 int uid;
3062                 int gid;
3063         } */ *uap;
3064 {
3065         struct file *fp;
3066         int vfslocked;
3067         int error;
3068
3069         AUDIT_ARG(fd, uap->fd);
3070         AUDIT_ARG(owner, uap->uid, uap->gid);
3071         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3072                 return (error);
3073         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
3074 #ifdef AUDIT
3075         vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY);
3076         AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1);
3077         VOP_UNLOCK(fp->f_vnode, 0);
3078 #endif
3079         error = setfown(td, fp->f_vnode, uap->uid, uap->gid);
3080         VFS_UNLOCK_GIANT(vfslocked);
3081         fdrop(fp, td);
3082         return (error);
3083 }
3084
3085 /*
3086  * Common implementation code for utimes(), lutimes(), and futimes().
3087  */
3088 static int
3089 getutimes(usrtvp, tvpseg, tsp)
3090         const struct timeval *usrtvp;
3091         enum uio_seg tvpseg;
3092         struct timespec *tsp;
3093 {
3094         struct timeval tv[2];
3095         const struct timeval *tvp;
3096         int error;
3097
3098         if (usrtvp == NULL) {
3099                 microtime(&tv[0]);
3100                 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
3101                 tsp[1] = tsp[0];
3102         } else {
3103                 if (tvpseg == UIO_SYSSPACE) {
3104                         tvp = usrtvp;
3105                 } else {
3106                         if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0)
3107                                 return (error);
3108                         tvp = tv;
3109                 }
3110
3111                 if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 ||
3112                     tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
3113                         return (EINVAL);
3114                 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]);
3115                 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]);
3116         }
3117         return (0);
3118 }
3119
3120 /*
3121  * Common implementation code for utimes(), lutimes(), and futimes().
3122  */
3123 static int
3124 setutimes(td, vp, ts, numtimes, nullflag)
3125         struct thread *td;
3126         struct vnode *vp;
3127         const struct timespec *ts;
3128         int numtimes;
3129         int nullflag;
3130 {
3131         int error, setbirthtime;
3132         struct mount *mp;
3133         struct vattr vattr;
3134
3135         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3136                 return (error);
3137         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3138         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
3139         setbirthtime = 0;
3140         if (numtimes < 3 && !VOP_GETATTR(vp, &vattr, td->td_ucred) &&
3141             timespeccmp(&ts[1], &vattr.va_birthtime, < ))
3142                 setbirthtime = 1;
3143         VATTR_NULL(&vattr);
3144         vattr.va_atime = ts[0];
3145         vattr.va_mtime = ts[1];
3146         if (setbirthtime)
3147                 vattr.va_birthtime = ts[1];
3148         if (numtimes > 2)
3149                 vattr.va_birthtime = ts[2];
3150         if (nullflag)
3151                 vattr.va_vaflags |= VA_UTIMES_NULL;
3152 #ifdef MAC
3153         error = mac_vnode_check_setutimes(td->td_ucred, vp, vattr.va_atime,
3154             vattr.va_mtime);
3155 #endif
3156         if (error == 0)
3157                 error = VOP_SETATTR(vp, &vattr, td->td_ucred);
3158         VOP_UNLOCK(vp, 0);
3159         vn_finished_write(mp);
3160         return (error);
3161 }
3162
3163 /*
3164  * Set the access and modification times of a file.
3165  */
3166 #ifndef _SYS_SYSPROTO_H_
3167 struct utimes_args {
3168         char    *path;
3169         struct  timeval *tptr;
3170 };
3171 #endif
3172 int
3173 utimes(td, uap)
3174         struct thread *td;
3175         register struct utimes_args /* {
3176                 char *path;
3177                 struct timeval *tptr;
3178         } */ *uap;
3179 {
3180
3181         return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr,
3182             UIO_USERSPACE));
3183 }
3184
3185 #ifndef _SYS_SYSPROTO_H_
3186 struct futimesat_args {
3187         int fd;
3188         const char * path;
3189         const struct timeval * times;
3190 };
3191 #endif
3192 int
3193 futimesat(struct thread *td, struct futimesat_args *uap)
3194 {
3195
3196         return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE,
3197             uap->times, UIO_USERSPACE));
3198 }
3199
3200 int
3201 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg,
3202     struct timeval *tptr, enum uio_seg tptrseg)
3203 {
3204
3205         return (kern_utimesat(td, AT_FDCWD, path, pathseg, tptr, tptrseg));
3206 }
3207
3208 int
3209 kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
3210     struct timeval *tptr, enum uio_seg tptrseg)
3211 {
3212         struct nameidata nd;
3213         struct timespec ts[2];
3214         int error, vfslocked;
3215
3216         if ((error = getutimes(tptr, tptrseg, ts)) != 0)
3217                 return (error);
3218         NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path,
3219             fd, td);
3220
3221         if ((error = namei(&nd)) != 0)
3222                 return (error);
3223         vfslocked = NDHASGIANT(&nd);
3224         NDFREE(&nd, NDF_ONLY_PNBUF);
3225         error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
3226         vrele(nd.ni_vp);
3227         VFS_UNLOCK_GIANT(vfslocked);
3228         return (error);
3229 }
3230
3231 /*
3232  * Set the access and modification times of a file.
3233  */
3234 #ifndef _SYS_SYSPROTO_H_
3235 struct lutimes_args {
3236         char    *path;
3237         struct  timeval *tptr;
3238 };
3239 #endif
3240 int
3241 lutimes(td, uap)
3242         struct thread *td;
3243         register struct lutimes_args /* {
3244                 char *path;
3245                 struct timeval *tptr;
3246         } */ *uap;
3247 {
3248
3249         return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr,
3250             UIO_USERSPACE));
3251 }
3252
3253 int
3254 kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg,
3255     struct timeval *tptr, enum uio_seg tptrseg)
3256 {
3257         struct timespec ts[2];
3258         int error;
3259         struct nameidata nd;
3260         int vfslocked;
3261
3262         if ((error = getutimes(tptr, tptrseg, ts)) != 0)
3263                 return (error);
3264         NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
3265         if ((error = namei(&nd)) != 0)
3266                 return (error);
3267         vfslocked = NDHASGIANT(&nd);
3268         NDFREE(&nd, NDF_ONLY_PNBUF);
3269         error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
3270         vrele(nd.ni_vp);
3271         VFS_UNLOCK_GIANT(vfslocked);
3272         return (error);
3273 }
3274
3275 /*
3276  * Set the access and modification times of a file.
3277  */
3278 #ifndef _SYS_SYSPROTO_H_
3279 struct futimes_args {
3280         int     fd;
3281         struct  timeval *tptr;
3282 };
3283 #endif
3284 int
3285 futimes(td, uap)
3286         struct thread *td;
3287         register struct futimes_args /* {
3288                 int  fd;
3289                 struct timeval *tptr;
3290         } */ *uap;
3291 {
3292
3293         return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE));
3294 }
3295
3296 int
3297 kern_futimes(struct thread *td, int fd, struct timeval *tptr,
3298     enum uio_seg tptrseg)
3299 {
3300         struct timespec ts[2];
3301         struct file *fp;
3302         int vfslocked;
3303         int error;
3304
3305         AUDIT_ARG(fd, fd);
3306         if ((error = getutimes(tptr, tptrseg, ts)) != 0)
3307                 return (error);
3308         if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0)
3309                 return (error);
3310         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
3311 #ifdef AUDIT
3312         vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY);
3313         AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1);
3314         VOP_UNLOCK(fp->f_vnode, 0);
3315 #endif
3316         error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL);
3317         VFS_UNLOCK_GIANT(vfslocked);
3318         fdrop(fp, td);
3319         return (error);
3320 }
3321
3322 /*
3323  * Truncate a file given its path name.
3324  */
3325 #ifndef _SYS_SYSPROTO_H_
3326 struct truncate_args {
3327         char    *path;
3328         int     pad;
3329         off_t   length;
3330 };
3331 #endif
3332 int
3333 truncate(td, uap)
3334         struct thread *td;
3335         register struct truncate_args /* {
3336                 char *path;
3337                 int pad;
3338                 off_t length;
3339         } */ *uap;
3340 {
3341
3342         return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
3343 }
3344
3345 int
3346 kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length)
3347 {
3348         struct mount *mp;
3349         struct vnode *vp;
3350         struct vattr vattr;
3351         int error;
3352         struct nameidata nd;
3353         int vfslocked;
3354
3355         if (length < 0)
3356                 return(EINVAL);
3357         NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
3358         if ((error = namei(&nd)) != 0)
3359                 return (error);
3360         vfslocked = NDHASGIANT(&nd);
3361         vp = nd.ni_vp;
3362         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
3363                 vrele(vp);
3364                 VFS_UNLOCK_GIANT(vfslocked);
3365                 return (error);
3366         }
3367         NDFREE(&nd, NDF_ONLY_PNBUF);
3368         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3369         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
3370         if (vp->v_type == VDIR)
3371                 error = EISDIR;
3372 #ifdef MAC
3373         else if ((error = mac_vnode_check_write(td->td_ucred, NOCRED, vp))) {
3374         }
3375 #endif
3376         else if ((error = vn_writechk(vp)) == 0 &&
3377             (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) {
3378                 VATTR_NULL(&vattr);
3379                 vattr.va_size = length;
3380                 error = VOP_SETATTR(vp, &vattr, td->td_ucred);
3381         }
3382         vput(vp);
3383         vn_finished_write(mp);
3384         VFS_UNLOCK_GIANT(vfslocked);
3385         return (error);
3386 }
3387
3388 #if defined(COMPAT_43)
3389 /*
3390  * Truncate a file given its path name.
3391  */
3392 #ifndef _SYS_SYSPROTO_H_
3393 struct otruncate_args {
3394         char    *path;
3395         long    length;
3396 };
3397 #endif
3398 int
3399 otruncate(td, uap)
3400         struct thread *td;
3401         register struct otruncate_args /* {
3402                 char *path;
3403                 long length;
3404         } */ *uap;
3405 {
3406         struct truncate_args /* {
3407                 char *path;
3408                 int pad;
3409                 off_t length;
3410         } */ nuap;
3411
3412         nuap.path = uap->path;
3413         nuap.length = uap->length;
3414         return (truncate(td, &nuap));
3415 }
3416 #endif /* COMPAT_43 */
3417
3418 /* Versions with the pad argument */
3419 int
3420 freebsd6_truncate(struct thread *td, struct freebsd6_truncate_args *uap)
3421 {
3422         struct truncate_args ouap;
3423
3424         ouap.path = uap->path;
3425         ouap.length = uap->length;
3426         return (truncate(td, &ouap));
3427 }
3428
3429 int
3430 freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap)
3431 {
3432         struct ftruncate_args ouap;
3433
3434         ouap.fd = uap->fd;
3435         ouap.length = uap->length;
3436         return (ftruncate(td, &ouap));
3437 }
3438
3439 /*
3440  * Sync an open file.
3441  */
3442 #ifndef _SYS_SYSPROTO_H_
3443 struct fsync_args {
3444         int     fd;
3445 };
3446 #endif
3447 int
3448 fsync(td, uap)
3449         struct thread *td;
3450         struct fsync_args /* {
3451                 int fd;
3452         } */ *uap;
3453 {
3454         struct vnode *vp;
3455         struct mount *mp;
3456         struct file *fp;
3457         int vfslocked;
3458         int error;
3459
3460         AUDIT_ARG(fd, uap->fd);
3461         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3462                 return (error);
3463         vp = fp->f_vnode;
3464         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3465         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3466                 goto drop;
3467         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
3468         AUDIT_ARG(vnode, vp, ARG_VNODE1);
3469         if (vp->v_object != NULL) {
3470                 VM_OBJECT_LOCK(vp->v_object);
3471                 vm_object_page_clean(vp->v_object, 0, 0, 0);
3472                 VM_OBJECT_UNLOCK(vp->v_object);
3473         }
3474         error = VOP_FSYNC(vp, MNT_WAIT, td);
3475
3476         VOP_UNLOCK(vp, 0);
3477         vn_finished_write(mp);
3478 drop:
3479         VFS_UNLOCK_GIANT(vfslocked);
3480         fdrop(fp, td);
3481         return (error);
3482 }
3483
3484 /*
3485  * Rename files.  Source and destination must either both be directories, or
3486  * both not be directories.  If target is a directory, it must be empty.
3487  */
3488 #ifndef _SYS_SYSPROTO_H_
3489 struct rename_args {
3490         char    *from;
3491         char    *to;
3492 };
3493 #endif
3494 int
3495 rename(td, uap)
3496         struct thread *td;
3497         register struct rename_args /* {
3498                 char *from;
3499                 char *to;
3500         } */ *uap;
3501 {
3502
3503         return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE));
3504 }
3505
3506 #ifndef _SYS_SYSPROTO_H_
3507 struct renameat_args {
3508         int     oldfd;
3509         char    *old;
3510         int     newfd;
3511         char    *new;
3512 };
3513 #endif
3514 int
3515 renameat(struct thread *td, struct renameat_args *uap)
3516 {
3517
3518         return (kern_renameat(td, uap->oldfd, uap->old, uap->newfd, uap->new,
3519             UIO_USERSPACE));
3520 }
3521
3522 int
3523 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg)
3524 {
3525
3526         return (kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, pathseg));
3527 }
3528
3529 int
3530 kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new,
3531     enum uio_seg pathseg)
3532 {
3533         struct mount *mp = NULL;
3534         struct vnode *tvp, *fvp, *tdvp;
3535         struct nameidata fromnd, tond;
3536         int tvfslocked;
3537         int fvfslocked;
3538         int error;
3539
3540         bwillwrite();
3541 #ifdef MAC
3542         NDINIT_AT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE |
3543             AUDITVNODE1, pathseg, old, oldfd, td);
3544 #else
3545         NDINIT_AT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE |
3546             AUDITVNODE1, pathseg, old, oldfd, td);
3547 #endif
3548
3549         if ((error = namei(&fromnd)) != 0)
3550                 return (error);
3551         fvfslocked = NDHASGIANT(&fromnd);
3552         tvfslocked = 0;
3553 #ifdef MAC
3554         error = mac_vnode_check_rename_from(td->td_ucred, fromnd.ni_dvp,
3555             fromnd.ni_vp, &fromnd.ni_cnd);
3556         VOP_UNLOCK(fromnd.ni_dvp, 0);
3557         if (fromnd.ni_dvp != fromnd.ni_vp)
3558                 VOP_UNLOCK(fromnd.ni_vp, 0);
3559 #endif
3560         fvp = fromnd.ni_vp;
3561         if (error == 0)
3562                 error = vn_start_write(fvp, &mp, V_WAIT | PCATCH);
3563         if (error != 0) {
3564                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3565                 vrele(fromnd.ni_dvp);
3566                 vrele(fvp);
3567                 goto out1;
3568         }
3569         NDINIT_AT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART |
3570             MPSAFE | AUDITVNODE2, pathseg, new, newfd, td);
3571         if (fromnd.ni_vp->v_type == VDIR)
3572                 tond.ni_cnd.cn_flags |= WILLBEDIR;
3573         if ((error = namei(&tond)) != 0) {
3574                 /* Translate error code for rename("dir1", "dir2/."). */
3575                 if (error == EISDIR && fvp->v_type == VDIR)
3576                         error = EINVAL;
3577                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3578                 vrele(fromnd.ni_dvp);
3579                 vrele(fvp);
3580                 vn_finished_write(mp);
3581                 goto out1;
3582         }
3583         tvfslocked = NDHASGIANT(&tond);
3584         tdvp = tond.ni_dvp;
3585         tvp = tond.ni_vp;
3586         if (tvp != NULL) {
3587                 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
3588                         error = ENOTDIR;
3589                         goto out;
3590                 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
3591                         error = EISDIR;
3592                         goto out;
3593                 }
3594         }
3595         if (fvp == tdvp) {
3596                 error = EINVAL;
3597                 goto out;
3598         }
3599         /*
3600          * If the source is the same as the destination (that is, if they
3601          * are links to the same vnode), then there is nothing to do.
3602          */
3603         if (fvp == tvp)
3604                 error = -1;
3605 #ifdef MAC
3606         else
3607                 error = mac_vnode_check_rename_to(td->td_ucred, tdvp,
3608                     tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd);
3609 #endif
3610 out:
3611         if (!error) {
3612                 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE);
3613                 if (fromnd.ni_dvp != tdvp) {
3614                         VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3615                 }
3616                 if (tvp) {
3617                         VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE);
3618                 }
3619                 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
3620                                    tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
3621                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3622                 NDFREE(&tond, NDF_ONLY_PNBUF);
3623         } else {
3624                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3625                 NDFREE(&tond, NDF_ONLY_PNBUF);
3626                 if (tvp)
3627                         vput(tvp);
3628                 if (tdvp == tvp)
3629                         vrele(tdvp);
3630                 else
3631                         vput(tdvp);
3632                 vrele(fromnd.ni_dvp);
3633                 vrele(fvp);
3634         }
3635         vrele(tond.ni_startdir);
3636         vn_finished_write(mp);
3637 out1:
3638         if (fromnd.ni_startdir)
3639                 vrele(fromnd.ni_startdir);
3640         VFS_UNLOCK_GIANT(fvfslocked);
3641         VFS_UNLOCK_GIANT(tvfslocked);
3642         if (error == -1)
3643                 return (0);
3644         return (error);
3645 }
3646
3647 /*
3648  * Make a directory file.
3649  */
3650 #ifndef _SYS_SYSPROTO_H_
3651 struct mkdir_args {
3652         char    *path;
3653         int     mode;
3654 };
3655 #endif
3656 int
3657 mkdir(td, uap)
3658         struct thread *td;
3659         register struct mkdir_args /* {
3660                 char *path;
3661                 int mode;
3662         } */ *uap;
3663 {
3664
3665         return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode));
3666 }
3667
3668 #ifndef _SYS_SYSPROTO_H_
3669 struct mkdirat_args {
3670         int     fd;
3671         char    *path;
3672         mode_t  mode;
3673 };
3674 #endif
3675 int
3676 mkdirat(struct thread *td, struct mkdirat_args *uap)
3677 {
3678
3679         return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode));
3680 }
3681
3682 int
3683 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode)
3684 {
3685
3686         return (kern_mkdirat(td, AT_FDCWD, path, segflg, mode));
3687 }
3688
3689 int
3690 kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg,
3691     int mode)
3692 {
3693         struct mount *mp;
3694         struct vnode *vp;
3695         struct vattr vattr;
3696         int error;
3697         struct nameidata nd;
3698         int vfslocked;
3699
3700         AUDIT_ARG(mode, mode);
3701 restart:
3702         bwillwrite();
3703         NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
3704             segflg, path, fd, td);
3705         nd.ni_cnd.cn_flags |= WILLBEDIR;
3706         if ((error = namei(&nd)) != 0)
3707                 return (error);
3708         vfslocked = NDHASGIANT(&nd);
3709         vp = nd.ni_vp;
3710         if (vp != NULL) {
3711                 NDFREE(&nd, NDF_ONLY_PNBUF);
3712                 /*
3713                  * XXX namei called with LOCKPARENT but not LOCKLEAF has
3714                  * the strange behaviour of leaving the vnode unlocked
3715                  * if the target is the same vnode as the parent.
3716                  */
3717                 if (vp == nd.ni_dvp)
3718                         vrele(nd.ni_dvp);
3719                 else
3720                         vput(nd.ni_dvp);
3721                 vrele(vp);
3722                 VFS_UNLOCK_GIANT(vfslocked);
3723                 return (EEXIST);
3724         }
3725         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3726                 NDFREE(&nd, NDF_ONLY_PNBUF);
3727                 vput(nd.ni_dvp);
3728                 VFS_UNLOCK_GIANT(vfslocked);
3729                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3730                         return (error);
3731                 goto restart;
3732         }
3733         VATTR_NULL(&vattr);
3734         vattr.va_type = VDIR;
3735         FILEDESC_SLOCK(td->td_proc->p_fd);
3736         vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask;
3737         FILEDESC_SUNLOCK(td->td_proc->p_fd);
3738 #ifdef MAC
3739         error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
3740             &vattr);
3741         if (error)
3742                 goto out;
3743 #endif
3744         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3745         error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
3746 #ifdef MAC
3747 out:
3748 #endif
3749         NDFREE(&nd, NDF_ONLY_PNBUF);
3750         vput(nd.ni_dvp);
3751         if (!error)
3752                 vput(nd.ni_vp);
3753         vn_finished_write(mp);
3754         VFS_UNLOCK_GIANT(vfslocked);
3755         return (error);
3756 }
3757
3758 /*
3759  * Remove a directory file.
3760  */
3761 #ifndef _SYS_SYSPROTO_H_
3762 struct rmdir_args {
3763         char    *path;
3764 };
3765 #endif
3766 int
3767 rmdir(td, uap)
3768         struct thread *td;
3769         struct rmdir_args /* {
3770                 char *path;
3771         } */ *uap;
3772 {
3773
3774         return (kern_rmdir(td, uap->path, UIO_USERSPACE));
3775 }
3776
3777 int
3778 kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg)
3779 {
3780
3781         return (kern_rmdirat(td, AT_FDCWD, path, pathseg));
3782 }
3783
3784 int
3785 kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg)
3786 {
3787         struct mount *mp;
3788         struct vnode *vp;
3789         int error;
3790         struct nameidata nd;
3791         int vfslocked;
3792
3793 restart:
3794         bwillwrite();
3795         NDINIT_AT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1,
3796             pathseg, path, fd, td);
3797         if ((error = namei(&nd)) != 0)
3798                 return (error);
3799         vfslocked = NDHASGIANT(&nd);
3800         vp = nd.ni_vp;
3801         if (vp->v_type != VDIR) {
3802                 error = ENOTDIR;
3803                 goto out;
3804         }
3805         /*
3806          * No rmdir "." please.
3807          */
3808         if (nd.ni_dvp == vp) {
3809                 error = EINVAL;
3810                 goto out;
3811         }
3812         /*
3813          * The root of a mounted filesystem cannot be deleted.
3814          */
3815         if (vp->v_vflag & VV_ROOT) {
3816                 error = EBUSY;
3817                 goto out;
3818         }
3819 #ifdef MAC
3820         error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp,
3821             &nd.ni_cnd);
3822         if (error)
3823                 goto out;
3824 #endif
3825         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3826                 NDFREE(&nd, NDF_ONLY_PNBUF);
3827                 vput(vp);
3828                 if (nd.ni_dvp == vp)
3829                         vrele(nd.ni_dvp);
3830                 else
3831                         vput(nd.ni_dvp);
3832                 VFS_UNLOCK_GIANT(vfslocked);
3833                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3834                         return (error);
3835                 goto restart;
3836         }
3837         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3838         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3839         error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
3840         vn_finished_write(mp);
3841 out:
3842         NDFREE(&nd, NDF_ONLY_PNBUF);
3843         vput(vp);
3844         if (nd.ni_dvp == vp)
3845                 vrele(nd.ni_dvp);
3846         else
3847                 vput(nd.ni_dvp);
3848         VFS_UNLOCK_GIANT(vfslocked);
3849         return (error);
3850 }
3851
3852 #ifdef COMPAT_43
3853 /*
3854  * Read a block of directory entries in a filesystem independent format.
3855  */
3856 #ifndef _SYS_SYSPROTO_H_
3857 struct ogetdirentries_args {
3858         int     fd;
3859         char    *buf;
3860         u_int   count;
3861         long    *basep;
3862 };
3863 #endif
3864 int
3865 ogetdirentries(td, uap)
3866         struct thread *td;
3867         register struct ogetdirentries_args /* {
3868                 int fd;
3869                 char *buf;
3870                 u_int count;
3871                 long *basep;
3872         } */ *uap;
3873 {
3874         struct vnode *vp;
3875         struct file *fp;
3876         struct uio auio, kuio;
3877         struct iovec aiov, kiov;
3878         struct dirent *dp, *edp;
3879         caddr_t dirbuf;
3880         int error, eofflag, readcnt, vfslocked;
3881         long loff;
3882
3883         /* XXX arbitrary sanity limit on `count'. */
3884         if (uap->count > 64 * 1024)
3885                 return (EINVAL);
3886         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3887                 return (error);
3888         if ((fp->f_flag & FREAD) == 0) {
3889                 fdrop(fp, td);
3890                 return (EBADF);
3891         }
3892         vp = fp->f_vnode;
3893 unionread:
3894         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3895         if (vp->v_type != VDIR) {
3896                 VFS_UNLOCK_GIANT(vfslocked);
3897                 fdrop(fp, td);
3898                 return (EINVAL);
3899         }
3900         aiov.iov_base = uap->buf;
3901         aiov.iov_len = uap->count;
3902         auio.uio_iov = &aiov;
3903         auio.uio_iovcnt = 1;
3904         auio.uio_rw = UIO_READ;
3905         auio.uio_segflg = UIO_USERSPACE;
3906         auio.uio_td = td;
3907         auio.uio_resid = uap->count;
3908         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
3909         loff = auio.uio_offset = fp->f_offset;
3910 #ifdef MAC
3911         error = mac_vnode_check_readdir(td->td_ucred, vp);
3912         if (error) {
3913                 VOP_UNLOCK(vp, 0);
3914                 VFS_UNLOCK_GIANT(vfslocked);
3915                 fdrop(fp, td);
3916                 return (error);
3917         }
3918 #endif
3919 #       if (BYTE_ORDER != LITTLE_ENDIAN)
3920                 if (vp->v_mount->mnt_maxsymlinklen <= 0) {
3921                         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
3922                             NULL, NULL);
3923                         fp->f_offset = auio.uio_offset;
3924                 } else
3925 #       endif
3926         {
3927                 kuio = auio;
3928                 kuio.uio_iov = &kiov;
3929                 kuio.uio_segflg = UIO_SYSSPACE;
3930                 kiov.iov_len = uap->count;
3931                 MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK);
3932                 kiov.iov_base = dirbuf;
3933                 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
3934                             NULL, NULL);
3935                 fp->f_offset = kuio.uio_offset;
3936                 if (error == 0) {
3937                         readcnt = uap->count - kuio.uio_resid;
3938                         edp = (struct dirent *)&dirbuf[readcnt];
3939                         for (dp = (struct dirent *)dirbuf; dp < edp; ) {
3940 #                               if (BYTE_ORDER == LITTLE_ENDIAN)
3941                                         /*
3942                                          * The expected low byte of
3943                                          * dp->d_namlen is our dp->d_type.
3944                                          * The high MBZ byte of dp->d_namlen
3945                                          * is our dp->d_namlen.
3946                                          */
3947                                         dp->d_type = dp->d_namlen;
3948                                         dp->d_namlen = 0;
3949 #                               else
3950                                         /*
3951                                          * The dp->d_type is the high byte
3952                                          * of the expected dp->d_namlen,
3953                                          * so must be zero'ed.
3954                                          */
3955                                         dp->d_type = 0;
3956 #                               endif
3957                                 if (dp->d_reclen > 0) {
3958                                         dp = (struct dirent *)
3959                                             ((char *)dp + dp->d_reclen);
3960                                 } else {
3961                                         error = EIO;
3962                                         break;
3963                                 }
3964                         }
3965                         if (dp >= edp)
3966                                 error = uiomove(dirbuf, readcnt, &auio);
3967                 }
3968                 FREE(dirbuf, M_TEMP);
3969         }
3970         if (error) {
3971                 VOP_UNLOCK(vp, 0);
3972                 VFS_UNLOCK_GIANT(vfslocked);
3973                 fdrop(fp, td);
3974                 return (error);
3975         }
3976         if (uap->count == auio.uio_resid &&
3977             (vp->v_vflag & VV_ROOT) &&
3978             (vp->v_mount->mnt_flag & MNT_UNION)) {
3979                 struct vnode *tvp = vp;
3980                 vp = vp->v_mount->mnt_vnodecovered;
3981                 VREF(vp);
3982                 fp->f_vnode = vp;
3983                 fp->f_data = vp;
3984                 fp->f_offset = 0;
3985                 vput(tvp);
3986                 VFS_UNLOCK_GIANT(vfslocked);
3987                 goto unionread;
3988         }
3989         VOP_UNLOCK(vp, 0);
3990         VFS_UNLOCK_GIANT(vfslocked);
3991         error = copyout(&loff, uap->basep, sizeof(long));
3992         fdrop(fp, td);
3993         td->td_retval[0] = uap->count - auio.uio_resid;
3994         return (error);
3995 }
3996 #endif /* COMPAT_43 */
3997
3998 /*
3999  * Read a block of directory entries in a filesystem independent format.
4000  */
4001 #ifndef _SYS_SYSPROTO_H_
4002 struct getdirentries_args {
4003         int     fd;
4004         char    *buf;
4005         u_int   count;
4006         long    *basep;
4007 };
4008 #endif
4009 int
4010 getdirentries(td, uap)
4011         struct thread *td;
4012         register struct getdirentries_args /* {
4013                 int fd;
4014                 char *buf;
4015                 u_int count;
4016                 long *basep;
4017         } */ *uap;
4018 {
4019         struct vnode *vp;
4020         struct file *fp;
4021         struct uio auio;
4022         struct iovec aiov;
4023         int vfslocked;
4024         long loff;
4025         int error, eofflag;
4026
4027         AUDIT_ARG(fd, uap->fd);
4028         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
4029                 return (error);
4030         if ((fp->f_flag & FREAD) == 0) {
4031                 fdrop(fp, td);
4032                 return (EBADF);
4033         }
4034         vp = fp->f_vnode;
4035 unionread:
4036         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
4037         if (vp->v_type != VDIR) {
4038                 VFS_UNLOCK_GIANT(vfslocked);
4039                 error = EINVAL;
4040                 goto fail;
4041         }
4042         aiov.iov_base = uap->buf;
4043         aiov.iov_len = uap->count;
4044         auio.uio_iov = &aiov;
4045         auio.uio_iovcnt = 1;
4046         auio.uio_rw = UIO_READ;
4047         auio.uio_segflg = UIO_USERSPACE;
4048         auio.uio_td = td;
4049         auio.uio_resid = uap->count;
4050         /* vn_lock(vp, LK_SHARED | LK_RETRY); */
4051         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
4052         AUDIT_ARG(vnode, vp, ARG_VNODE1);
4053         loff = auio.uio_offset = fp->f_offset;
4054 #ifdef MAC
4055         error = mac_vnode_check_readdir(td->td_ucred, vp);
4056         if (error == 0)
4057 #endif
4058                 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL,
4059                     NULL);
4060         fp->f_offset = auio.uio_offset;
4061         if (error) {
4062                 VOP_UNLOCK(vp, 0);
4063                 VFS_UNLOCK_GIANT(vfslocked);
4064                 goto fail;
4065         }
4066         if (uap->count == auio.uio_resid &&
4067             (vp->v_vflag & VV_ROOT) &&
4068             (vp->v_mount->mnt_flag & MNT_UNION)) {
4069                 struct vnode *tvp = vp;
4070                 vp = vp->v_mount->mnt_vnodecovered;
4071                 VREF(vp);
4072                 fp->f_vnode = vp;
4073                 fp->f_data = vp;
4074                 fp->f_offset = 0;
4075                 vput(tvp);
4076                 VFS_UNLOCK_GIANT(vfslocked);
4077                 goto unionread;
4078         }
4079         VOP_UNLOCK(vp, 0);
4080         VFS_UNLOCK_GIANT(vfslocked);
4081         if (uap->basep != NULL) {
4082                 error = copyout(&loff, uap->basep, sizeof(long));
4083         }
4084         td->td_retval[0] = uap->count - auio.uio_resid;
4085 fail:
4086         fdrop(fp, td);
4087         return (error);
4088 }
4089
4090 #ifndef _SYS_SYSPROTO_H_
4091 struct getdents_args {
4092         int fd;
4093         char *buf;
4094         size_t count;
4095 };
4096 #endif
4097 int
4098 getdents(td, uap)
4099         struct thread *td;
4100         register struct getdents_args /* {
4101                 int fd;
4102                 char *buf;
4103                 u_int count;
4104         } */ *uap;
4105 {
4106         struct getdirentries_args ap;
4107         ap.fd = uap->fd;
4108         ap.buf = uap->buf;
4109         ap.count = uap->count;
4110         ap.basep = NULL;
4111         return (getdirentries(td, &ap));
4112 }
4113
4114 /*
4115  * Set the mode mask for creation of filesystem nodes.
4116  */
4117 #ifndef _SYS_SYSPROTO_H_
4118 struct umask_args {
4119         int     newmask;
4120 };
4121 #endif
4122 int
4123 umask(td, uap)
4124         struct thread *td;
4125         struct umask_args /* {
4126                 int newmask;
4127         } */ *uap;
4128 {
4129         register struct filedesc *fdp;
4130
4131         FILEDESC_XLOCK(td->td_proc->p_fd);
4132         fdp = td->td_proc->p_fd;
4133         td->td_retval[0] = fdp->fd_cmask;
4134         fdp->fd_cmask = uap->newmask & ALLPERMS;
4135         FILEDESC_XUNLOCK(td->td_proc->p_fd);
4136         return (0);
4137 }
4138
4139 /*
4140  * Void all references to file by ripping underlying filesystem away from
4141  * vnode.
4142  */
4143 #ifndef _SYS_SYSPROTO_H_
4144 struct revoke_args {
4145         char    *path;
4146 };
4147 #endif
4148 int
4149 revoke(td, uap)
4150         struct thread *td;
4151         register struct revoke_args /* {
4152                 char *path;
4153         } */ *uap;
4154 {
4155         struct vnode *vp;
4156         struct vattr vattr;
4157         int error;
4158         struct nameidata nd;
4159         int vfslocked;
4160
4161         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
4162             UIO_USERSPACE, uap->path, td);
4163         if ((error = namei(&nd)) != 0)
4164                 return (error);
4165         vfslocked = NDHASGIANT(&nd);
4166         vp = nd.ni_vp;
4167         NDFREE(&nd, NDF_ONLY_PNBUF);
4168         if (vp->v_type != VCHR) {
4169                 error = EINVAL;
4170                 goto out;
4171         }
4172 #ifdef MAC
4173         error = mac_vnode_check_revoke(td->td_ucred, vp);
4174         if (error)
4175                 goto out;
4176 #endif
4177         error = VOP_GETATTR(vp, &vattr, td->td_ucred);
4178         if (error)
4179                 goto out;
4180         if (td->td_ucred->cr_uid != vattr.va_uid) {
4181                 error = priv_check(td, PRIV_VFS_ADMIN);
4182                 if (error)
4183                         goto out;
4184         }
4185         if (vcount(vp) > 1)
4186                 VOP_REVOKE(vp, REVOKEALL);
4187 out:
4188         vput(vp);
4189         VFS_UNLOCK_GIANT(vfslocked);
4190         return (error);
4191 }
4192
4193 /*
4194  * Convert a user file descriptor to a kernel file entry.
4195  * A reference on the file entry is held upon returning.
4196  */
4197 int
4198 getvnode(fdp, fd, fpp)
4199         struct filedesc *fdp;
4200         int fd;
4201         struct file **fpp;
4202 {
4203         int error;
4204         struct file *fp;
4205
4206         fp = NULL;
4207         if (fdp == NULL)
4208                 error = EBADF;
4209         else {
4210                 FILEDESC_SLOCK(fdp);
4211                 if ((u_int)fd >= fdp->fd_nfiles ||
4212                     (fp = fdp->fd_ofiles[fd]) == NULL)
4213                         error = EBADF;
4214                 else if (fp->f_vnode == NULL) {
4215                         fp = NULL;
4216                         error = EINVAL;
4217                 } else {
4218                         fhold(fp);
4219                         error = 0;
4220                 }
4221                 FILEDESC_SUNLOCK(fdp);
4222         }
4223         *fpp = fp;
4224         return (error);
4225 }
4226
4227 /*
4228  * Get an (NFS) file handle.
4229  */
4230 #ifndef _SYS_SYSPROTO_H_
4231 struct lgetfh_args {
4232         char    *fname;
4233         fhandle_t *fhp;
4234 };
4235 #endif
4236 int
4237 lgetfh(td, uap)
4238         struct thread *td;
4239         register struct lgetfh_args *uap;
4240 {
4241         struct nameidata nd;
4242         fhandle_t fh;
4243         register struct vnode *vp;
4244         int vfslocked;
4245         int error;
4246
4247         error = priv_check(td, PRIV_VFS_GETFH);
4248         if (error)
4249                 return (error);
4250         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
4251             UIO_USERSPACE, uap->fname, td);
4252         error = namei(&nd);
4253         if (error)
4254                 return (error);
4255         vfslocked = NDHASGIANT(&nd);
4256         NDFREE(&nd, NDF_ONLY_PNBUF);
4257         vp = nd.ni_vp;
4258         bzero(&fh, sizeof(fh));
4259         fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
4260         error = VOP_VPTOFH(vp, &fh.fh_fid);
4261         vput(vp);
4262         VFS_UNLOCK_GIANT(vfslocked);
4263         if (error)
4264                 return (error);
4265         error = copyout(&fh, uap->fhp, sizeof (fh));
4266         return (error);
4267 }
4268
4269 #ifndef _SYS_SYSPROTO_H_
4270 struct getfh_args {
4271         char    *fname;
4272         fhandle_t *fhp;
4273 };
4274 #endif
4275 int
4276 getfh(td, uap)
4277         struct thread *td;
4278         register struct getfh_args *uap;
4279 {
4280         struct nameidata nd;
4281         fhandle_t fh;
4282         register struct vnode *vp;
4283         int vfslocked;
4284         int error;
4285
4286         error = priv_check(td, PRIV_VFS_GETFH);
4287         if (error)
4288                 return (error);
4289         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
4290             UIO_USERSPACE, uap->fname, td);
4291         error = namei(&nd);
4292         if (error)
4293                 return (error);
4294         vfslocked = NDHASGIANT(&nd);
4295         NDFREE(&nd, NDF_ONLY_PNBUF);
4296         vp = nd.ni_vp;
4297         bzero(&fh, sizeof(fh));
4298         fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
4299         error = VOP_VPTOFH(vp, &fh.fh_fid);
4300         vput(vp);
4301         VFS_UNLOCK_GIANT(vfslocked);
4302         if (error)
4303                 return (error);
4304         error = copyout(&fh, uap->fhp, sizeof (fh));
4305         return (error);
4306 }
4307
4308 /*
4309  * syscall for the rpc.lockd to use to translate a NFS file handle into an
4310  * open descriptor.
4311  *
4312  * warning: do not remove the priv_check() call or this becomes one giant
4313  * security hole.
4314  */
4315 #ifndef _SYS_SYSPROTO_H_
4316 struct fhopen_args {
4317         const struct fhandle *u_fhp;
4318         int flags;
4319 };
4320 #endif
4321 int
4322 fhopen(td, uap)
4323         struct thread *td;
4324         struct fhopen_args /* {
4325                 const struct fhandle *u_fhp;
4326                 int flags;
4327         } */ *uap;
4328 {
4329         struct proc *p = td->td_proc;
4330         struct mount *mp;
4331         struct vnode *vp;
4332         struct fhandle fhp;
4333         struct vattr vat;
4334         struct vattr *vap = &vat;
4335         struct flock lf;
4336         struct file *fp;
4337         register struct filedesc *fdp = p->p_fd;
4338         int fmode, mode, error, type;
4339         struct file *nfp;
4340         int vfslocked;
4341         int indx;
4342
4343         error = priv_check(td, PRIV_VFS_FHOPEN);
4344         if (error)
4345                 return (error);
4346         fmode = FFLAGS(uap->flags);
4347         /* why not allow a non-read/write open for our lockd? */
4348         if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
4349                 return (EINVAL);
4350         error = copyin(uap->u_fhp, &fhp, sizeof(fhp));
4351         if (error)
4352                 return(error);
4353         /* find the mount point */
4354         mp = vfs_getvfs(&fhp.fh_fsid);
4355         if (mp == NULL)
4356                 return (ESTALE);
4357         vfslocked = VFS_LOCK_GIANT(mp);
4358         /* now give me my vnode, it gets returned to me locked */
4359         error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
4360         if (error)
4361                 goto out;
4362         /*
4363          * from now on we have to make sure not
4364          * to forget about the vnode
4365          * any error that causes an abort must vput(vp)
4366          * just set error = err and 'goto bad;'.
4367          */
4368
4369         /*
4370          * from vn_open
4371          */
4372         if (vp->v_type == VLNK) {
4373                 error = EMLINK;
4374                 goto bad;
4375         }
4376         if (vp->v_type == VSOCK) {
4377                 error = EOPNOTSUPP;
4378                 goto bad;
4379         }
4380         mode = 0;
4381         if (fmode & (FWRITE | O_TRUNC)) {
4382                 if (vp->v_type == VDIR) {
4383                         error = EISDIR;
4384                         goto bad;
4385                 }
4386                 error = vn_writechk(vp);
4387                 if (error)
4388                         goto bad;
4389                 mode |= VWRITE;
4390         }
4391         if (fmode & FREAD)
4392                 mode |= VREAD;
4393         if (fmode & O_APPEND)
4394                 mode |= VAPPEND;
4395 #ifdef MAC
4396         error = mac_vnode_check_open(td->td_ucred, vp, mode);
4397         if (error)
4398                 goto bad;
4399 #endif
4400         if (mode) {
4401                 error = VOP_ACCESS(vp, mode, td->td_ucred, td);
4402                 if (error)
4403                         goto bad;
4404         }
4405         if (fmode & O_TRUNC) {
4406                 VOP_UNLOCK(vp, 0);                              /* XXX */
4407                 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) {
4408                         vrele(vp);
4409                         goto out;
4410                 }
4411                 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4412                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);   /* XXX */
4413 #ifdef MAC
4414                 /*
4415                  * We don't yet have fp->f_cred, so use td->td_ucred, which
4416                  * should be right.
4417                  */
4418                 error = mac_vnode_check_write(td->td_ucred, td->td_ucred, vp);
4419                 if (error == 0) {
4420 #endif
4421                         VATTR_NULL(vap);
4422                         vap->va_size = 0;
4423                         error = VOP_SETATTR(vp, vap, td->td_ucred);
4424 #ifdef MAC
4425                 }
4426 #endif
4427                 vn_finished_write(mp);
4428                 if (error)
4429                         goto bad;
4430         }
4431         error = VOP_OPEN(vp, fmode, td->td_ucred, td, NULL);
4432         if (error)
4433                 goto bad;
4434
4435         if (fmode & FWRITE)
4436                 vp->v_writecount++;
4437
4438         /*
4439          * end of vn_open code
4440          */
4441
4442         if ((error = falloc(td, &nfp, &indx)) != 0) {
4443                 if (fmode & FWRITE)
4444                         vp->v_writecount--;
4445                 goto bad;
4446         }
4447         /* An extra reference on `nfp' has been held for us by falloc(). */
4448         fp = nfp;
4449         nfp->f_vnode = vp;
4450         finit(nfp, fmode & FMASK, DTYPE_VNODE, vp, &vnops);
4451         if (fmode & (O_EXLOCK | O_SHLOCK)) {
4452                 lf.l_whence = SEEK_SET;
4453                 lf.l_start = 0;
4454                 lf.l_len = 0;
4455                 if (fmode & O_EXLOCK)
4456                         lf.l_type = F_WRLCK;
4457                 else
4458                         lf.l_type = F_RDLCK;
4459                 type = F_FLOCK;
4460                 if ((fmode & FNONBLOCK) == 0)
4461                         type |= F_WAIT;
4462                 VOP_UNLOCK(vp, 0);
4463                 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
4464                             type)) != 0) {
4465                         /*
4466                          * The lock request failed.  Normally close the
4467                          * descriptor but handle the case where someone might
4468                          * have dup()d or close()d it when we weren't looking.
4469                          */
4470                         fdclose(fdp, fp, indx, td);
4471
4472                         /*
4473                          * release our private reference
4474                          */
4475                         fdrop(fp, td);
4476                         goto out;
4477                 }
4478                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
4479                 atomic_set_int(&fp->f_flag, FHASLOCK);
4480         }
4481
4482         VOP_UNLOCK(vp, 0);
4483         fdrop(fp, td);
4484         vfs_rel(mp);
4485         VFS_UNLOCK_GIANT(vfslocked);
4486         td->td_retval[0] = indx;
4487         return (0);
4488
4489 bad:
4490         vput(vp);
4491 out:
4492         vfs_rel(mp);
4493         VFS_UNLOCK_GIANT(vfslocked);
4494         return (error);
4495 }
4496
4497 /*
4498  * Stat an (NFS) file handle.
4499  */
4500 #ifndef _SYS_SYSPROTO_H_
4501 struct fhstat_args {
4502         struct fhandle *u_fhp;
4503         struct stat *sb;
4504 };
4505 #endif
4506 int
4507 fhstat(td, uap)
4508         struct thread *td;
4509         register struct fhstat_args /* {
4510                 struct fhandle *u_fhp;
4511                 struct stat *sb;
4512         } */ *uap;
4513 {
4514         struct stat sb;
4515         fhandle_t fh;
4516         struct mount *mp;
4517         struct vnode *vp;
4518         int vfslocked;
4519         int error;
4520
4521         error = priv_check(td, PRIV_VFS_FHSTAT);
4522         if (error)
4523                 return (error);
4524         error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
4525         if (error)
4526                 return (error);
4527         if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
4528                 return (ESTALE);
4529         vfslocked = VFS_LOCK_GIANT(mp);
4530         if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) {
4531                 vfs_rel(mp);
4532                 VFS_UNLOCK_GIANT(vfslocked);
4533                 return (error);
4534         }
4535         error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
4536         vput(vp);
4537         vfs_rel(mp);
4538         VFS_UNLOCK_GIANT(vfslocked);
4539         if (error)
4540                 return (error);
4541         error = copyout(&sb, uap->sb, sizeof(sb));
4542         return (error);
4543 }
4544
4545 /*
4546  * Implement fstatfs() for (NFS) file handles.
4547  */
4548 #ifndef _SYS_SYSPROTO_H_
4549 struct fhstatfs_args {
4550         struct fhandle *u_fhp;
4551         struct statfs *buf;
4552 };
4553 #endif
4554 int
4555 fhstatfs(td, uap)
4556         struct thread *td;
4557         struct fhstatfs_args /* {
4558                 struct fhandle *u_fhp;
4559                 struct statfs *buf;
4560         } */ *uap;
4561 {
4562         struct statfs sf;
4563         fhandle_t fh;
4564         int error;
4565
4566         error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
4567         if (error)
4568                 return (error);
4569         error = kern_fhstatfs(td, fh, &sf);
4570         if (error)
4571                 return (error);
4572         return (copyout(&sf, uap->buf, sizeof(sf)));
4573 }
4574
4575 int
4576 kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
4577 {
4578         struct statfs *sp;
4579         struct mount *mp;
4580         struct vnode *vp;
4581         int vfslocked;
4582         int error;
4583
4584         error = priv_check(td, PRIV_VFS_FHSTATFS);
4585         if (error)
4586                 return (error);
4587         if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
4588                 return (ESTALE);
4589         vfslocked = VFS_LOCK_GIANT(mp);
4590         error = VFS_FHTOVP(mp, &fh.fh_fid, &vp);
4591         if (error) {
4592                 VFS_UNLOCK_GIANT(vfslocked);
4593                 vfs_rel(mp);
4594                 return (error);
4595         }
4596         vput(vp);
4597         error = prison_canseemount(td->td_ucred, mp);
4598         if (error)
4599                 goto out;
4600 #ifdef MAC
4601         error = mac_mount_check_stat(td->td_ucred, mp);
4602         if (error)
4603                 goto out;
4604 #endif
4605         /*
4606          * Set these in case the underlying filesystem fails to do so.
4607          */
4608         sp = &mp->mnt_stat;
4609         sp->f_version = STATFS_VERSION;
4610         sp->f_namemax = NAME_MAX;
4611         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
4612         error = VFS_STATFS(mp, sp, td);
4613         if (error == 0)
4614                 *buf = *sp;
4615 out:
4616         vfs_rel(mp);
4617         VFS_UNLOCK_GIANT(vfslocked);
4618         return (error);
4619 }