vfs_lookup.c revision 1.123 1 /* $NetBSD: vfs_lookup.c,v 1.123 2010/11/19 06:44:43 dholland Exp $ */
2
3 /*
4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)vfs_lookup.c 8.10 (Berkeley) 5/27/95
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.123 2010/11/19 06:44:43 dholland Exp $");
41
42 #include "opt_magiclinks.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/syslimits.h>
48 #include <sys/time.h>
49 #include <sys/namei.h>
50 #include <sys/vnode.h>
51 #include <sys/mount.h>
52 #include <sys/errno.h>
53 #include <sys/filedesc.h>
54 #include <sys/hash.h>
55 #include <sys/proc.h>
56 #include <sys/syslog.h>
57 #include <sys/kauth.h>
58 #include <sys/ktrace.h>
59
60 #ifndef MAGICLINKS
61 #define MAGICLINKS 0
62 #endif
63
64 int vfs_magiclinks = MAGICLINKS;
65
66 pool_cache_t pnbuf_cache; /* pathname buffer cache */
67
68 /*
69 * Substitute replacement text for 'magic' strings in symlinks.
70 * Returns 0 if successful, and returns non-zero if an error
71 * occurs. (Currently, the only possible error is running out
72 * of temporary pathname space.)
73 *
74 * Looks for "@<string>" and "@<string>/", where <string> is a
75 * recognized 'magic' string. Replaces the "@<string>" with the
76 * appropriate replacement text. (Note that in some cases the
77 * replacement text may have zero length.)
78 *
79 * This would have been table driven, but the variance in
80 * replacement strings (and replacement string lengths) made
81 * that impractical.
82 */
83 #define VNL(x) \
84 (sizeof(x) - 1)
85
86 #define VO '{'
87 #define VC '}'
88
89 #define MATCH(str) \
90 ((termchar == '/' && i + VNL(str) == *len) || \
91 (i + VNL(str) < *len && \
92 cp[i + VNL(str)] == termchar)) && \
93 !strncmp((str), &cp[i], VNL(str))
94
95 #define SUBSTITUTE(m, s, sl) \
96 if ((newlen + (sl)) >= MAXPATHLEN) \
97 return 1; \
98 i += VNL(m); \
99 if (termchar != '/') \
100 i++; \
101 (void)memcpy(&tmp[newlen], (s), (sl)); \
102 newlen += (sl); \
103 change = 1; \
104 termchar = '/';
105
106 static int
107 symlink_magic(struct proc *p, char *cp, size_t *len)
108 {
109 char *tmp;
110 size_t change, i, newlen, slen;
111 char termchar = '/';
112 char idtmp[11]; /* enough for 32 bit *unsigned* integer */
113
114
115 tmp = PNBUF_GET();
116 for (change = i = newlen = 0; i < *len; ) {
117 if (cp[i] != '@') {
118 tmp[newlen++] = cp[i++];
119 continue;
120 }
121
122 i++;
123
124 /* Check for @{var} syntax. */
125 if (cp[i] == VO) {
126 termchar = VC;
127 i++;
128 }
129
130 /*
131 * The following checks should be ordered according
132 * to frequency of use.
133 */
134 if (MATCH("machine_arch")) {
135 slen = VNL(MACHINE_ARCH);
136 SUBSTITUTE("machine_arch", MACHINE_ARCH, slen);
137 } else if (MATCH("machine")) {
138 slen = VNL(MACHINE);
139 SUBSTITUTE("machine", MACHINE, slen);
140 } else if (MATCH("hostname")) {
141 SUBSTITUTE("hostname", hostname, hostnamelen);
142 } else if (MATCH("osrelease")) {
143 slen = strlen(osrelease);
144 SUBSTITUTE("osrelease", osrelease, slen);
145 } else if (MATCH("emul")) {
146 slen = strlen(p->p_emul->e_name);
147 SUBSTITUTE("emul", p->p_emul->e_name, slen);
148 } else if (MATCH("kernel_ident")) {
149 slen = strlen(kernel_ident);
150 SUBSTITUTE("kernel_ident", kernel_ident, slen);
151 } else if (MATCH("domainname")) {
152 SUBSTITUTE("domainname", domainname, domainnamelen);
153 } else if (MATCH("ostype")) {
154 slen = strlen(ostype);
155 SUBSTITUTE("ostype", ostype, slen);
156 } else if (MATCH("uid")) {
157 slen = snprintf(idtmp, sizeof(idtmp), "%u",
158 kauth_cred_geteuid(kauth_cred_get()));
159 SUBSTITUTE("uid", idtmp, slen);
160 } else if (MATCH("ruid")) {
161 slen = snprintf(idtmp, sizeof(idtmp), "%u",
162 kauth_cred_getuid(kauth_cred_get()));
163 SUBSTITUTE("ruid", idtmp, slen);
164 } else if (MATCH("gid")) {
165 slen = snprintf(idtmp, sizeof(idtmp), "%u",
166 kauth_cred_getegid(kauth_cred_get()));
167 SUBSTITUTE("gid", idtmp, slen);
168 } else if (MATCH("rgid")) {
169 slen = snprintf(idtmp, sizeof(idtmp), "%u",
170 kauth_cred_getgid(kauth_cred_get()));
171 SUBSTITUTE("rgid", idtmp, slen);
172 } else {
173 tmp[newlen++] = '@';
174 if (termchar == VC)
175 tmp[newlen++] = VO;
176 }
177 }
178
179 if (change) {
180 (void)memcpy(cp, tmp, newlen);
181 *len = newlen;
182 }
183 PNBUF_PUT(tmp);
184
185 return 0;
186 }
187
188 #undef VNL
189 #undef VO
190 #undef VC
191 #undef MATCH
192 #undef SUBSTITUTE
193
194 ////////////////////////////////////////////////////////////
195
196 /*
197 * Sealed abstraction for pathnames.
198 *
199 * System-call-layer level code that is going to call namei should
200 * first create a pathbuf and adjust all the bells and whistles on it
201 * as needed by context
202 */
203
204 struct pathbuf {
205 char *pb_path;
206 char *pb_pathcopy;
207 unsigned pb_pathcopyuses;
208 };
209
210 static struct pathbuf *
211 pathbuf_create_raw(void)
212 {
213 struct pathbuf *pb;
214
215 pb = kmem_alloc(sizeof(*pb), KM_SLEEP);
216 if (pb == NULL) {
217 return NULL;
218 }
219 pb->pb_path = PNBUF_GET();
220 if (pb->pb_path == NULL) {
221 kmem_free(pb, sizeof(*pb));
222 return NULL;
223 }
224 pb->pb_pathcopy = NULL;
225 pb->pb_pathcopyuses = 0;
226 return pb;
227 }
228
229 void
230 pathbuf_destroy(struct pathbuf *pb)
231 {
232 KASSERT(pb->pb_pathcopyuses == 0);
233 KASSERT(pb->pb_pathcopy == NULL);
234 PNBUF_PUT(pb->pb_path);
235 kmem_free(pb, sizeof(*pb));
236 }
237
238 struct pathbuf *
239 pathbuf_create(const char *path)
240 {
241 struct pathbuf *pb;
242 int error;
243
244 pb = pathbuf_create_raw();
245 if (pb == NULL) {
246 return NULL;
247 }
248 error = copystr(path, pb->pb_path, PATH_MAX, NULL);
249 if (error != 0) {
250 KASSERT(!"kernel path too long in pathbuf_create");
251 /* make sure it's null-terminated, just in case */
252 pb->pb_path[PATH_MAX-1] = '\0';
253 }
254 return pb;
255 }
256
257 int
258 pathbuf_copyin(const char *userpath, struct pathbuf **ret)
259 {
260 struct pathbuf *pb;
261 int error;
262
263 pb = pathbuf_create_raw();
264 if (pb == NULL) {
265 return ENOMEM;
266 }
267 error = copyinstr(userpath, pb->pb_path, PATH_MAX, NULL);
268 if (error) {
269 pathbuf_destroy(pb);
270 return error;
271 }
272 *ret = pb;
273 return 0;
274 }
275
276 /*
277 * XXX should not exist
278 */
279 int
280 pathbuf_maybe_copyin(const char *path, enum uio_seg seg, struct pathbuf **ret)
281 {
282 if (seg == UIO_USERSPACE) {
283 return pathbuf_copyin(path, ret);
284 } else {
285 *ret = pathbuf_create(path);
286 if (*ret == NULL) {
287 return ENOMEM;
288 }
289 return 0;
290 }
291 }
292
293 /*
294 * Get a copy of the path buffer as it currently exists. If this is
295 * called after namei starts the results may be arbitrary.
296 */
297 void
298 pathbuf_copystring(const struct pathbuf *pb, char *buf, size_t maxlen)
299 {
300 strlcpy(buf, pb->pb_path, maxlen);
301 }
302
303 /*
304 * These two functions allow access to a saved copy of the original
305 * path string. The first copy should be gotten before namei is
306 * called. Each copy that is gotten should be put back.
307 */
308
309 const char *
310 pathbuf_stringcopy_get(struct pathbuf *pb)
311 {
312 if (pb->pb_pathcopyuses == 0) {
313 pb->pb_pathcopy = PNBUF_GET();
314 strcpy(pb->pb_pathcopy, pb->pb_path);
315 }
316 pb->pb_pathcopyuses++;
317 return pb->pb_pathcopy;
318 }
319
320 void
321 pathbuf_stringcopy_put(struct pathbuf *pb, const char *str)
322 {
323 KASSERT(str == pb->pb_pathcopy);
324 KASSERT(pb->pb_pathcopyuses > 0);
325 pb->pb_pathcopyuses--;
326 if (pb->pb_pathcopyuses == 0) {
327 PNBUF_PUT(pb->pb_pathcopy);
328 pb->pb_pathcopy = NULL;
329 }
330 }
331
332
333 ////////////////////////////////////////////////////////////
334
335 /*
336 * Convert a pathname into a pointer to a locked vnode.
337 *
338 * The FOLLOW flag is set when symbolic links are to be followed
339 * when they occur at the end of the name translation process.
340 * Symbolic links are always followed for all other pathname
341 * components other than the last.
342 *
343 * The segflg defines whether the name is to be copied from user
344 * space or kernel space.
345 *
346 * Overall outline of namei:
347 *
348 * copy in name
349 * get starting directory
350 * while (!done && !error) {
351 * call lookup to search path.
352 * if symbolic link, massage name in buffer and continue
353 * }
354 */
355
356 /*
357 * Internal state for a namei operation.
358 */
359 struct namei_state {
360 struct nameidata *ndp;
361 struct componentname *cnp;
362
363 /* used by the pieces of namei */
364 struct vnode *namei_startdir; /* The directory namei() starts from. */
365
366 /* used by the pieces of lookup */
367 int lookup_alldone;
368
369 int docache; /* == 0 do not cache last component */
370 int rdonly; /* lookup read-only flag bit */
371 struct vnode *dp; /* the directory we are searching */
372 int slashes;
373 };
374
375 /* XXX reorder things to make this decl unnecessary */
376 static int do_lookup(struct namei_state *state);
377
378
379 /*
380 * Initialize the namei working state.
381 */
382 static void
383 namei_init(struct namei_state *state, struct nameidata *ndp)
384 {
385 state->ndp = ndp;
386 state->cnp = &ndp->ni_cnd;
387
388 state->namei_startdir = NULL;
389
390 state->lookup_alldone = 0;
391
392 state->docache = 0;
393 state->rdonly = 0;
394 state->dp = NULL;
395 state->slashes = 0;
396 }
397
398 /*
399 * Clean up the working namei state, leaving things ready for return
400 * from namei.
401 */
402 static void
403 namei_cleanup(struct namei_state *state)
404 {
405 KASSERT(state->cnp == &state->ndp->ni_cnd);
406
407 //KASSERT(state->namei_startdir == NULL); // not yet
408
409 /* nothing for now */
410 (void)state;
411 }
412
413 //////////////////////////////
414
415 /*
416 * Start up namei. Early portion.
417 *
418 * This is divided from namei_start2 by the emul_retry: point.
419 */
420 static void
421 namei_start1(struct namei_state *state)
422 {
423
424 #ifdef DIAGNOSTIC
425 if (!state->cnp->cn_cred)
426 panic("namei: bad cred/proc");
427 if (state->cnp->cn_nameiop & (~OPMASK))
428 panic("namei: nameiop contaminated with flags");
429 if (state->cnp->cn_flags & OPMASK)
430 panic("namei: flags contaminated with nameiops");
431 #endif
432
433 /*
434 * Get a buffer for the name to be translated, and copy the
435 * name into the buffer.
436 */
437 if ((state->cnp->cn_flags & HASBUF) == 0)
438 state->cnp->cn_pnbuf = PNBUF_GET();
439 }
440
441 /*
442 * Start up namei. Copy the path, find the root dir and cwd, establish
443 * the starting directory for lookup, and lock it.
444 */
445 static int
446 namei_start2(struct namei_state *state)
447 {
448 struct nameidata *ndp = state->ndp;
449 struct componentname *cnp = state->cnp;
450
451 struct cwdinfo *cwdi; /* pointer to cwd state */
452 struct lwp *self = curlwp; /* thread doing namei() */
453
454 /* as both buffers are size PATH_MAX this cannot overflow */
455 strcpy(cnp->cn_pnbuf, ndp->ni_pathbuf->pb_path);
456
457 /* length includes null terminator (was originally from copyinstr) */
458 ndp->ni_pathlen = strlen(cnp->cn_pnbuf) + 1;
459
460 /*
461 * POSIX.1 requirement: "" is not a valid file name.
462 */
463 if (ndp->ni_pathlen == 1) {
464 PNBUF_PUT(cnp->cn_pnbuf);
465 ndp->ni_vp = NULL;
466 return ENOENT;
467 }
468
469 ndp->ni_loopcnt = 0;
470
471 /*
472 * Get root directory for the translation.
473 */
474 cwdi = self->l_proc->p_cwdi;
475 rw_enter(&cwdi->cwdi_lock, RW_READER);
476 state->namei_startdir = cwdi->cwdi_rdir;
477 if (state->namei_startdir == NULL)
478 state->namei_startdir = rootvnode;
479 ndp->ni_rootdir = state->namei_startdir;
480
481 /*
482 * Check if starting from root directory or current directory.
483 */
484 if (cnp->cn_pnbuf[0] == '/') {
485 if (cnp->cn_flags & TRYEMULROOT) {
486 if (cnp->cn_flags & EMULROOTSET) {
487 /* Called from (eg) emul_find_interp() */
488 state->namei_startdir = ndp->ni_erootdir;
489 } else {
490 if (cwdi->cwdi_edir == NULL
491 || (cnp->cn_pnbuf[1] == '.'
492 && cnp->cn_pnbuf[2] == '.'
493 && cnp->cn_pnbuf[3] == '/')) {
494 ndp->ni_erootdir = NULL;
495 } else {
496 state->namei_startdir = cwdi->cwdi_edir;
497 ndp->ni_erootdir = state->namei_startdir;
498 }
499 }
500 } else {
501 ndp->ni_erootdir = NULL;
502 if (cnp->cn_flags & NOCHROOT)
503 state->namei_startdir = ndp->ni_rootdir = rootvnode;
504 }
505 } else {
506 state->namei_startdir = cwdi->cwdi_cdir;
507 ndp->ni_erootdir = NULL;
508 }
509 vref(state->namei_startdir);
510 rw_exit(&cwdi->cwdi_lock);
511
512 /*
513 * Ktrace it.
514 */
515 if (ktrpoint(KTR_NAMEI)) {
516 if (ndp->ni_erootdir != NULL) {
517 /*
518 * To make any sense, the trace entry need to have the
519 * text of the emulation path prepended.
520 * Usually we can get this from the current process,
521 * but when called from emul_find_interp() it is only
522 * in the exec_package - so we get it passed in ni_next
523 * (this is a hack).
524 */
525 const char *emul_path;
526 if (cnp->cn_flags & EMULROOTSET)
527 emul_path = ndp->ni_next;
528 else
529 emul_path = self->l_proc->p_emul->e_path;
530 ktrnamei2(emul_path, strlen(emul_path),
531 cnp->cn_pnbuf, ndp->ni_pathlen);
532 } else
533 ktrnamei(cnp->cn_pnbuf, ndp->ni_pathlen);
534 }
535
536 vn_lock(state->namei_startdir, LK_EXCLUSIVE | LK_RETRY);
537
538 return 0;
539 }
540
541 /*
542 * Undo namei_start: unlock and release the current lookup directory,
543 * and discard the path buffer.
544 */
545 static void
546 namei_end(struct namei_state *state)
547 {
548 vput(state->namei_startdir);
549 PNBUF_PUT(state->cnp->cn_pnbuf);
550 //state->cnp->cn_pnbuf = NULL; // not yet (just in case) (XXX)
551 }
552
553 /*
554 * Check for being at a symlink.
555 */
556 static inline int
557 namei_atsymlink(struct namei_state *state)
558 {
559 return (state->cnp->cn_flags & ISSYMLINK) != 0;
560 }
561
562 /*
563 * Follow a symlink.
564 */
565 static inline int
566 namei_follow(struct namei_state *state)
567 {
568 struct nameidata *ndp = state->ndp;
569 struct componentname *cnp = state->cnp;
570
571 struct lwp *self = curlwp; /* thread doing namei() */
572 struct iovec aiov; /* uio for reading symbolic links */
573 struct uio auio;
574 char *cp; /* pointer into pathname argument */
575 size_t linklen;
576 int error;
577
578 if (ndp->ni_loopcnt++ >= MAXSYMLINKS) {
579 return ELOOP;
580 }
581 if (ndp->ni_vp->v_mount->mnt_flag & MNT_SYMPERM) {
582 error = VOP_ACCESS(ndp->ni_vp, VEXEC, cnp->cn_cred);
583 if (error != 0)
584 return error;
585 }
586 if (ndp->ni_pathlen > 1)
587 cp = PNBUF_GET();
588 else
589 cp = cnp->cn_pnbuf;
590 aiov.iov_base = cp;
591 aiov.iov_len = MAXPATHLEN;
592 auio.uio_iov = &aiov;
593 auio.uio_iovcnt = 1;
594 auio.uio_offset = 0;
595 auio.uio_rw = UIO_READ;
596 auio.uio_resid = MAXPATHLEN;
597 UIO_SETUP_SYSSPACE(&auio);
598 error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred);
599 if (error) {
600 badlink:
601 if (ndp->ni_pathlen > 1)
602 PNBUF_PUT(cp);
603 return error;
604 }
605 linklen = MAXPATHLEN - auio.uio_resid;
606 if (linklen == 0) {
607 error = ENOENT;
608 goto badlink;
609 }
610
611 /*
612 * Do symlink substitution, if appropriate, and
613 * check length for potential overflow.
614 */
615 if ((vfs_magiclinks &&
616 symlink_magic(self->l_proc, cp, &linklen)) ||
617 (linklen + ndp->ni_pathlen >= MAXPATHLEN)) {
618 error = ENAMETOOLONG;
619 goto badlink;
620 }
621 if (ndp->ni_pathlen > 1) {
622 memcpy(cp + linklen, ndp->ni_next, ndp->ni_pathlen);
623 PNBUF_PUT(cnp->cn_pnbuf);
624 cnp->cn_pnbuf = cp;
625 } else
626 cnp->cn_pnbuf[linklen] = '\0';
627 ndp->ni_pathlen += linklen;
628 vput(ndp->ni_vp);
629 state->namei_startdir = ndp->ni_dvp;
630
631 /*
632 * Check if root directory should replace current directory.
633 */
634 if (cnp->cn_pnbuf[0] == '/') {
635 vput(state->namei_startdir);
636 /* Keep absolute symbolic links inside emulation root */
637 state->namei_startdir = ndp->ni_erootdir;
638 if (state->namei_startdir == NULL || (cnp->cn_pnbuf[1] == '.'
639 && cnp->cn_pnbuf[2] == '.'
640 && cnp->cn_pnbuf[3] == '/')) {
641 ndp->ni_erootdir = NULL;
642 state->namei_startdir = ndp->ni_rootdir;
643 }
644 vref(state->namei_startdir);
645 vn_lock(state->namei_startdir, LK_EXCLUSIVE | LK_RETRY);
646 }
647
648 return 0;
649 }
650
651 //////////////////////////////
652
653 static int
654 do_namei(struct namei_state *state)
655 {
656 int error;
657
658 struct nameidata *ndp = state->ndp;
659 struct componentname *cnp = state->cnp;
660
661 KASSERT(cnp == &ndp->ni_cnd);
662
663 namei_start1(state);
664
665 emul_retry:
666
667 error = namei_start2(state);
668 if (error) {
669 return error;
670 }
671
672 /* Loop through symbolic links */
673 for (;;) {
674 if (state->namei_startdir->v_mount == NULL) {
675 /* Give up if the directory is no longer mounted */
676 namei_end(state);
677 return (ENOENT);
678 }
679 cnp->cn_nameptr = cnp->cn_pnbuf;
680 ndp->ni_startdir = state->namei_startdir;
681 error = do_lookup(state);
682 if (error != 0) {
683 /* XXX this should use namei_end() */
684 if (ndp->ni_dvp) {
685 vput(ndp->ni_dvp);
686 }
687 if (ndp->ni_erootdir != NULL) {
688 /* Retry the whole thing from the normal root */
689 cnp->cn_flags &= ~TRYEMULROOT;
690 goto emul_retry;
691 }
692 PNBUF_PUT(cnp->cn_pnbuf);
693 return (error);
694 }
695
696 /*
697 * Check for symbolic link
698 */
699 if (namei_atsymlink(state)) {
700 error = namei_follow(state);
701 if (error) {
702 KASSERT(ndp->ni_dvp != ndp->ni_vp);
703 vput(ndp->ni_dvp);
704 vput(ndp->ni_vp);
705 ndp->ni_vp = NULL;
706 PNBUF_PUT(cnp->cn_pnbuf);
707 return error;
708 }
709 }
710 else {
711 break;
712 }
713 }
714
715 /*
716 * Done
717 */
718
719 if ((cnp->cn_flags & LOCKPARENT) == 0 && ndp->ni_dvp) {
720 if (ndp->ni_dvp == ndp->ni_vp) {
721 vrele(ndp->ni_dvp);
722 } else {
723 vput(ndp->ni_dvp);
724 }
725 }
726 if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0) {
727 PNBUF_PUT(cnp->cn_pnbuf);
728 #if defined(DIAGNOSTIC)
729 cnp->cn_pnbuf = NULL;
730 #endif /* defined(DIAGNOSTIC) */
731 } else {
732 cnp->cn_flags |= HASBUF;
733 }
734
735 return 0;
736 }
737
738 int
739 namei(struct nameidata *ndp)
740 {
741 struct namei_state state;
742 int error;
743
744 namei_init(&state, ndp);
745 error = do_namei(&state);
746 namei_cleanup(&state);
747
748 return error;
749 }
750
751 /*
752 * Determine the namei hash (for cn_hash) for name.
753 * If *ep != NULL, hash from name to ep-1.
754 * If *ep == NULL, hash from name until the first NUL or '/', and
755 * return the location of this termination character in *ep.
756 *
757 * This function returns an equivalent hash to the MI hash32_strn().
758 * The latter isn't used because in the *ep == NULL case, determining
759 * the length of the string to the first NUL or `/' and then calling
760 * hash32_strn() involves unnecessary double-handling of the data.
761 */
762 uint32_t
763 namei_hash(const char *name, const char **ep)
764 {
765 uint32_t hash;
766
767 hash = HASH32_STR_INIT;
768 if (*ep != NULL) {
769 for (; name < *ep; name++)
770 hash = hash * 33 + *(const uint8_t *)name;
771 } else {
772 for (; *name != '\0' && *name != '/'; name++)
773 hash = hash * 33 + *(const uint8_t *)name;
774 *ep = name;
775 }
776 return (hash + (hash >> 5));
777 }
778
779 /*
780 * Search a pathname.
781 * This is a very central and rather complicated routine.
782 *
783 * The pathname is pointed to by ni_ptr and is of length ni_pathlen.
784 * The starting directory is taken from ni_startdir. The pathname is
785 * descended until done, or a symbolic link is encountered. The variable
786 * ni_more is clear if the path is completed; it is set to one if a
787 * symbolic link needing interpretation is encountered.
788 *
789 * The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
790 * whether the name is to be looked up, created, renamed, or deleted.
791 * When CREATE, RENAME, or DELETE is specified, information usable in
792 * creating, renaming, or deleting a directory entry may be calculated.
793 * If flag has LOCKPARENT or'ed into it, the parent directory is returned
794 * locked. Otherwise the parent directory is not returned. If the target
795 * of the pathname exists and LOCKLEAF is or'ed into the flag the target
796 * is returned locked, otherwise it is returned unlocked. When creating
797 * or renaming and LOCKPARENT is specified, the target may not be ".".
798 * When deleting and LOCKPARENT is specified, the target may be ".".
799 *
800 * Overall outline of lookup:
801 *
802 * dirloop:
803 * identify next component of name at ndp->ni_ptr
804 * handle degenerate case where name is null string
805 * if .. and crossing mount points and on mounted filesys, find parent
806 * call VOP_LOOKUP routine for next component name
807 * directory vnode returned in ni_dvp, locked.
808 * component vnode returned in ni_vp (if it exists), locked.
809 * if result vnode is mounted on and crossing mount points,
810 * find mounted on vnode
811 * if more components of name, do next level at dirloop
812 * return the answer in ni_vp, locked if LOCKLEAF set
813 * if LOCKPARENT set, return locked parent in ni_dvp
814 */
815
816 /*
817 * Begin lookup().
818 */
819 static int
820 lookup_start(struct namei_state *state)
821 {
822 const char *cp; /* pointer into pathname argument */
823
824 struct componentname *cnp = state->cnp;
825 struct nameidata *ndp = state->ndp;
826
827 KASSERT(cnp == &ndp->ni_cnd);
828
829 state->lookup_alldone = 0;
830 state->dp = NULL;
831
832 /*
833 * Setup: break out flag bits into variables.
834 */
835 state->docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
836 if (cnp->cn_nameiop == DELETE)
837 state->docache = 0;
838 state->rdonly = cnp->cn_flags & RDONLY;
839 ndp->ni_dvp = NULL;
840 cnp->cn_flags &= ~ISSYMLINK;
841 state->dp = ndp->ni_startdir;
842 ndp->ni_startdir = NULLVP;
843
844 /*
845 * If we have a leading string of slashes, remove them, and just make
846 * sure the current node is a directory.
847 */
848 cp = cnp->cn_nameptr;
849 if (*cp == '/') {
850 do {
851 cp++;
852 } while (*cp == '/');
853 ndp->ni_pathlen -= cp - cnp->cn_nameptr;
854 cnp->cn_nameptr = cp;
855
856 if (state->dp->v_type != VDIR) {
857 vput(state->dp);
858 return ENOTDIR;
859 }
860
861 /*
862 * If we've exhausted the path name, then just return the
863 * current node.
864 */
865 if (cnp->cn_nameptr[0] == '\0') {
866 ndp->ni_vp = state->dp;
867 cnp->cn_flags |= ISLASTCN;
868
869 /* bleh */
870 state->lookup_alldone = 1;
871 return 0;
872 }
873 }
874
875 return 0;
876 }
877
878 static int
879 lookup_parsepath(struct namei_state *state)
880 {
881 const char *cp; /* pointer into pathname argument */
882
883 struct componentname *cnp = state->cnp;
884 struct nameidata *ndp = state->ndp;
885
886 KASSERT(cnp == &ndp->ni_cnd);
887
888 /*
889 * Search a new directory.
890 *
891 * The cn_hash value is for use by vfs_cache.
892 * The last component of the filename is left accessible via
893 * cnp->cn_nameptr for callers that need the name. Callers needing
894 * the name set the SAVENAME flag. When done, they assume
895 * responsibility for freeing the pathname buffer.
896 *
897 * At this point, our only vnode state is that "dp" is held and locked.
898 */
899 cnp->cn_consume = 0;
900 cp = NULL;
901 cnp->cn_hash = namei_hash(cnp->cn_nameptr, &cp);
902 cnp->cn_namelen = cp - cnp->cn_nameptr;
903 if (cnp->cn_namelen > NAME_MAX) {
904 vput(state->dp);
905 ndp->ni_dvp = NULL;
906 return ENAMETOOLONG;
907 }
908 #ifdef NAMEI_DIAGNOSTIC
909 { char c = *cp;
910 *(char *)cp = '\0';
911 printf("{%s}: ", cnp->cn_nameptr);
912 *(char *)cp = c; }
913 #endif /* NAMEI_DIAGNOSTIC */
914 ndp->ni_pathlen -= cnp->cn_namelen;
915 ndp->ni_next = cp;
916 /*
917 * If this component is followed by a slash, then move the pointer to
918 * the next component forward, and remember that this component must be
919 * a directory.
920 */
921 if (*cp == '/') {
922 do {
923 cp++;
924 } while (*cp == '/');
925 state->slashes = cp - ndp->ni_next;
926 ndp->ni_pathlen -= state->slashes;
927 ndp->ni_next = cp;
928 cnp->cn_flags |= REQUIREDIR;
929 } else {
930 state->slashes = 0;
931 cnp->cn_flags &= ~REQUIREDIR;
932 }
933 /*
934 * We do special processing on the last component, whether or not it's
935 * a directory. Cache all intervening lookups, but not the final one.
936 */
937 if (*cp == '\0') {
938 if (state->docache)
939 cnp->cn_flags |= MAKEENTRY;
940 else
941 cnp->cn_flags &= ~MAKEENTRY;
942 cnp->cn_flags |= ISLASTCN;
943 } else {
944 cnp->cn_flags |= MAKEENTRY;
945 cnp->cn_flags &= ~ISLASTCN;
946 }
947 if (cnp->cn_namelen == 2 &&
948 cnp->cn_nameptr[1] == '.' && cnp->cn_nameptr[0] == '.')
949 cnp->cn_flags |= ISDOTDOT;
950 else
951 cnp->cn_flags &= ~ISDOTDOT;
952
953 return 0;
954 }
955
956 static int
957 lookup_once(struct namei_state *state)
958 {
959 struct vnode *tdp; /* saved dp */
960 struct mount *mp; /* mount table entry */
961 struct lwp *l = curlwp;
962 int error;
963
964 struct componentname *cnp = state->cnp;
965 struct nameidata *ndp = state->ndp;
966
967 KASSERT(cnp == &ndp->ni_cnd);
968
969 /*
970 * Handle "..": two special cases.
971 * 1. If at root directory (e.g. after chroot)
972 * or at absolute root directory
973 * then ignore it so can't get out.
974 * 1a. If at the root of the emulation filesystem go to the real
975 * root. So "/../<path>" is always absolute.
976 * 1b. If we have somehow gotten out of a jail, warn
977 * and also ignore it so we can't get farther out.
978 * 2. If this vnode is the root of a mounted
979 * filesystem, then replace it with the
980 * vnode which was mounted on so we take the
981 * .. in the other file system.
982 */
983 if (cnp->cn_flags & ISDOTDOT) {
984 struct proc *p = l->l_proc;
985
986 for (;;) {
987 if (state->dp == ndp->ni_rootdir || state->dp == rootvnode) {
988 ndp->ni_dvp = state->dp;
989 ndp->ni_vp = state->dp;
990 vref(state->dp);
991 return 0;
992 }
993 if (ndp->ni_rootdir != rootvnode) {
994 int retval;
995
996 VOP_UNLOCK(state->dp);
997 retval = vn_isunder(state->dp, ndp->ni_rootdir, l);
998 vn_lock(state->dp, LK_EXCLUSIVE | LK_RETRY);
999 if (!retval) {
1000 /* Oops! We got out of jail! */
1001 log(LOG_WARNING,
1002 "chrooted pid %d uid %d (%s) "
1003 "detected outside of its chroot\n",
1004 p->p_pid, kauth_cred_geteuid(l->l_cred),
1005 p->p_comm);
1006 /* Put us at the jail root. */
1007 vput(state->dp);
1008 state->dp = ndp->ni_rootdir;
1009 ndp->ni_dvp = state->dp;
1010 ndp->ni_vp = state->dp;
1011 vref(state->dp);
1012 vref(state->dp);
1013 vn_lock(state->dp, LK_EXCLUSIVE | LK_RETRY);
1014 return 0;
1015 }
1016 }
1017 if ((state->dp->v_vflag & VV_ROOT) == 0 ||
1018 (cnp->cn_flags & NOCROSSMOUNT))
1019 break;
1020 tdp = state->dp;
1021 state->dp = state->dp->v_mount->mnt_vnodecovered;
1022 vput(tdp);
1023 vref(state->dp);
1024 vn_lock(state->dp, LK_EXCLUSIVE | LK_RETRY);
1025 }
1026 }
1027
1028 /*
1029 * We now have a segment name to search for, and a directory to search.
1030 * Again, our only vnode state is that "dp" is held and locked.
1031 */
1032 unionlookup:
1033 ndp->ni_dvp = state->dp;
1034 ndp->ni_vp = NULL;
1035 error = VOP_LOOKUP(state->dp, &ndp->ni_vp, cnp);
1036 if (error != 0) {
1037 #ifdef DIAGNOSTIC
1038 if (ndp->ni_vp != NULL)
1039 panic("leaf `%s' should be empty", cnp->cn_nameptr);
1040 #endif /* DIAGNOSTIC */
1041 #ifdef NAMEI_DIAGNOSTIC
1042 printf("not found\n");
1043 #endif /* NAMEI_DIAGNOSTIC */
1044 if ((error == ENOENT) &&
1045 (state->dp->v_vflag & VV_ROOT) &&
1046 (state->dp->v_mount->mnt_flag & MNT_UNION)) {
1047 tdp = state->dp;
1048 state->dp = state->dp->v_mount->mnt_vnodecovered;
1049 vput(tdp);
1050 vref(state->dp);
1051 vn_lock(state->dp, LK_EXCLUSIVE | LK_RETRY);
1052 goto unionlookup;
1053 }
1054
1055 if (error != EJUSTRETURN)
1056 return error;
1057
1058 /*
1059 * If this was not the last component, or there were trailing
1060 * slashes, and we are not going to create a directory,
1061 * then the name must exist.
1062 */
1063 if ((cnp->cn_flags & (REQUIREDIR | CREATEDIR)) == REQUIREDIR) {
1064 return ENOENT;
1065 }
1066
1067 /*
1068 * If creating and at end of pathname, then can consider
1069 * allowing file to be created.
1070 */
1071 if (state->rdonly) {
1072 return EROFS;
1073 }
1074
1075 /*
1076 * We return with ni_vp NULL to indicate that the entry
1077 * doesn't currently exist, leaving a pointer to the
1078 * (possibly locked) directory vnode in ndp->ni_dvp.
1079 */
1080 if (cnp->cn_flags & SAVESTART) {
1081 ndp->ni_startdir = ndp->ni_dvp;
1082 vref(ndp->ni_startdir);
1083 }
1084 state->lookup_alldone = 1;
1085 return (0);
1086 }
1087 #ifdef NAMEI_DIAGNOSTIC
1088 printf("found\n");
1089 #endif /* NAMEI_DIAGNOSTIC */
1090
1091 /*
1092 * Take into account any additional components consumed by the
1093 * underlying filesystem. This will include any trailing slashes after
1094 * the last component consumed.
1095 */
1096 if (cnp->cn_consume > 0) {
1097 ndp->ni_pathlen -= cnp->cn_consume - state->slashes;
1098 ndp->ni_next += cnp->cn_consume - state->slashes;
1099 cnp->cn_consume = 0;
1100 if (ndp->ni_next[0] == '\0')
1101 cnp->cn_flags |= ISLASTCN;
1102 }
1103
1104 state->dp = ndp->ni_vp;
1105
1106 /*
1107 * "state->dp" and "ndp->ni_dvp" are both locked and held,
1108 * and may be the same vnode.
1109 */
1110
1111 /*
1112 * Check to see if the vnode has been mounted on;
1113 * if so find the root of the mounted file system.
1114 */
1115 while (state->dp->v_type == VDIR && (mp = state->dp->v_mountedhere) &&
1116 (cnp->cn_flags & NOCROSSMOUNT) == 0) {
1117 error = vfs_busy(mp, NULL);
1118 if (error != 0) {
1119 vput(state->dp);
1120 return error;
1121 }
1122 KASSERT(ndp->ni_dvp != state->dp);
1123 VOP_UNLOCK(ndp->ni_dvp);
1124 vput(state->dp);
1125 error = VFS_ROOT(mp, &tdp);
1126 vfs_unbusy(mp, false, NULL);
1127 if (error) {
1128 vn_lock(ndp->ni_dvp, LK_EXCLUSIVE | LK_RETRY);
1129 return error;
1130 }
1131 VOP_UNLOCK(tdp);
1132 ndp->ni_vp = state->dp = tdp;
1133 vn_lock(ndp->ni_dvp, LK_EXCLUSIVE | LK_RETRY);
1134 vn_lock(ndp->ni_vp, LK_EXCLUSIVE | LK_RETRY);
1135 }
1136
1137 return 0;
1138 }
1139
1140 static int
1141 do_lookup(struct namei_state *state)
1142 {
1143 int error = 0;
1144
1145 struct componentname *cnp = state->cnp;
1146 struct nameidata *ndp = state->ndp;
1147
1148 KASSERT(cnp == &ndp->ni_cnd);
1149
1150 error = lookup_start(state);
1151 if (error) {
1152 goto bad;
1153 }
1154 // XXX: this case should not be necessary given proper handling
1155 // of slashes elsewhere.
1156 if (state->lookup_alldone) {
1157 goto terminal;
1158 }
1159
1160 dirloop:
1161 error = lookup_parsepath(state);
1162 if (error) {
1163 goto bad;
1164 }
1165
1166 error = lookup_once(state);
1167 if (error) {
1168 goto bad;
1169 }
1170 // XXX ought to be able to avoid this case too
1171 if (state->lookup_alldone) {
1172 /* this should NOT be "goto terminal;" */
1173 return 0;
1174 }
1175
1176 /*
1177 * Check for symbolic link. Back up over any slashes that we skipped,
1178 * as we will need them again.
1179 */
1180 if ((state->dp->v_type == VLNK) && (cnp->cn_flags & (FOLLOW|REQUIREDIR))) {
1181 ndp->ni_pathlen += state->slashes;
1182 ndp->ni_next -= state->slashes;
1183 cnp->cn_flags |= ISSYMLINK;
1184 return (0);
1185 }
1186
1187 /*
1188 * Check for directory, if the component was followed by a series of
1189 * slashes.
1190 */
1191 if ((state->dp->v_type != VDIR) && (cnp->cn_flags & REQUIREDIR)) {
1192 error = ENOTDIR;
1193 KASSERT(state->dp != ndp->ni_dvp);
1194 vput(state->dp);
1195 goto bad;
1196 }
1197
1198 /*
1199 * Not a symbolic link. If this was not the last component, then
1200 * continue at the next component, else return.
1201 */
1202 if (!(cnp->cn_flags & ISLASTCN)) {
1203 cnp->cn_nameptr = ndp->ni_next;
1204 if (ndp->ni_dvp == state->dp) {
1205 vrele(ndp->ni_dvp);
1206 } else {
1207 vput(ndp->ni_dvp);
1208 }
1209 goto dirloop;
1210 }
1211
1212 terminal:
1213 if (state->dp == ndp->ni_erootdir) {
1214 /*
1215 * We are about to return the emulation root.
1216 * This isn't a good idea because code might repeatedly
1217 * lookup ".." until the file matches that returned
1218 * for "/" and loop forever.
1219 * So convert it to the real root.
1220 */
1221 if (ndp->ni_dvp == state->dp)
1222 vrele(state->dp);
1223 else
1224 if (ndp->ni_dvp != NULL)
1225 vput(ndp->ni_dvp);
1226 ndp->ni_dvp = NULL;
1227 vput(state->dp);
1228 state->dp = ndp->ni_rootdir;
1229 vref(state->dp);
1230 vn_lock(state->dp, LK_EXCLUSIVE | LK_RETRY);
1231 ndp->ni_vp = state->dp;
1232 }
1233
1234 /*
1235 * If the caller requested the parent node (i.e.
1236 * it's a CREATE, DELETE, or RENAME), and we don't have one
1237 * (because this is the root directory), then we must fail.
1238 */
1239 if (ndp->ni_dvp == NULL && cnp->cn_nameiop != LOOKUP) {
1240 switch (cnp->cn_nameiop) {
1241 case CREATE:
1242 error = EEXIST;
1243 break;
1244 case DELETE:
1245 case RENAME:
1246 error = EBUSY;
1247 break;
1248 default:
1249 KASSERT(0);
1250 }
1251 vput(state->dp);
1252 goto bad;
1253 }
1254
1255 /*
1256 * Disallow directory write attempts on read-only lookups.
1257 * Prefers EEXIST over EROFS for the CREATE case.
1258 */
1259 if (state->rdonly &&
1260 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
1261 error = EROFS;
1262 if (state->dp != ndp->ni_dvp) {
1263 vput(state->dp);
1264 }
1265 goto bad;
1266 }
1267 if (ndp->ni_dvp != NULL) {
1268 if (cnp->cn_flags & SAVESTART) {
1269 ndp->ni_startdir = ndp->ni_dvp;
1270 vref(ndp->ni_startdir);
1271 }
1272 }
1273 if ((cnp->cn_flags & LOCKLEAF) == 0) {
1274 VOP_UNLOCK(state->dp);
1275 }
1276 return (0);
1277
1278 bad:
1279 ndp->ni_vp = NULL;
1280 return (error);
1281 }
1282
1283 /*
1284 * Externally visible interfaces used by nfsd (bletch, yuk, XXX)
1285 *
1286 * The "index" version differs from the "main" version in that it's
1287 * called from a different place in a different context. For now I
1288 * want to be able to shuffle code in from one call site without
1289 * affecting the other.
1290 */
1291
1292 int
1293 lookup_for_nfsd(struct nameidata *ndp, struct vnode *dp, int neverfollow)
1294 {
1295 struct namei_state state;
1296 int error;
1297
1298 struct iovec aiov;
1299 struct uio auio;
1300 int linklen;
1301 char *cp;
1302
1303 /* For now at least we don't have to frob the state */
1304 namei_init(&state, ndp);
1305
1306 /*
1307 * BEGIN wodge of code from nfsd
1308 */
1309
1310 vref(dp);
1311 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY);
1312
1313 for (;;) {
1314
1315 state.cnp->cn_nameptr = state.cnp->cn_pnbuf;
1316 state.ndp->ni_startdir = dp;
1317
1318 /*
1319 * END wodge of code from nfsd
1320 */
1321
1322 error = do_lookup(&state);
1323 if (error) {
1324 /* BEGIN from nfsd */
1325 if (ndp->ni_dvp) {
1326 vput(ndp->ni_dvp);
1327 }
1328 PNBUF_PUT(state.cnp->cn_pnbuf);
1329 /* END from nfsd */
1330 namei_cleanup(&state);
1331 return error;
1332 }
1333
1334 /*
1335 * BEGIN wodge of code from nfsd
1336 */
1337
1338 /*
1339 * Check for encountering a symbolic link
1340 */
1341 if ((state.cnp->cn_flags & ISSYMLINK) == 0) {
1342 if ((state.cnp->cn_flags & LOCKPARENT) == 0 && state.ndp->ni_dvp) {
1343 if (state.ndp->ni_dvp == state.ndp->ni_vp) {
1344 vrele(state.ndp->ni_dvp);
1345 } else {
1346 vput(state.ndp->ni_dvp);
1347 }
1348 }
1349 if (state.cnp->cn_flags & (SAVENAME | SAVESTART)) {
1350 state.cnp->cn_flags |= HASBUF;
1351 } else {
1352 PNBUF_PUT(state.cnp->cn_pnbuf);
1353 #if defined(DIAGNOSTIC)
1354 state.cnp->cn_pnbuf = NULL;
1355 #endif /* defined(DIAGNOSTIC) */
1356 }
1357 return (0);
1358 } else {
1359 if (neverfollow) {
1360 error = EINVAL;
1361 goto out;
1362 }
1363 if (state.ndp->ni_loopcnt++ >= MAXSYMLINKS) {
1364 error = ELOOP;
1365 goto out;
1366 }
1367 if (state.ndp->ni_vp->v_mount->mnt_flag & MNT_SYMPERM) {
1368 error = VOP_ACCESS(ndp->ni_vp, VEXEC, state.cnp->cn_cred);
1369 if (error != 0)
1370 goto out;
1371 }
1372 if (state.ndp->ni_pathlen > 1)
1373 cp = PNBUF_GET();
1374 else
1375 cp = state.cnp->cn_pnbuf;
1376 aiov.iov_base = cp;
1377 aiov.iov_len = MAXPATHLEN;
1378 auio.uio_iov = &aiov;
1379 auio.uio_iovcnt = 1;
1380 auio.uio_offset = 0;
1381 auio.uio_rw = UIO_READ;
1382 auio.uio_resid = MAXPATHLEN;
1383 UIO_SETUP_SYSSPACE(&auio);
1384 error = VOP_READLINK(ndp->ni_vp, &auio, state.cnp->cn_cred);
1385 if (error) {
1386 badlink:
1387 if (ndp->ni_pathlen > 1)
1388 PNBUF_PUT(cp);
1389 goto out;
1390 }
1391 linklen = MAXPATHLEN - auio.uio_resid;
1392 if (linklen == 0) {
1393 error = ENOENT;
1394 goto badlink;
1395 }
1396 if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
1397 error = ENAMETOOLONG;
1398 goto badlink;
1399 }
1400 if (ndp->ni_pathlen > 1) {
1401 memcpy(cp + linklen, ndp->ni_next, ndp->ni_pathlen);
1402 PNBUF_PUT(state.cnp->cn_pnbuf);
1403 state.cnp->cn_pnbuf = cp;
1404 } else
1405 state.cnp->cn_pnbuf[linklen] = '\0';
1406 state.ndp->ni_pathlen += linklen;
1407 vput(state.ndp->ni_vp);
1408 dp = state.ndp->ni_dvp;
1409
1410 /*
1411 * Check if root directory should replace current directory.
1412 */
1413 if (state.cnp->cn_pnbuf[0] == '/') {
1414 vput(dp);
1415 dp = ndp->ni_rootdir;
1416 vref(dp);
1417 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY);
1418 }
1419 }
1420
1421 }
1422 out:
1423 vput(state.ndp->ni_vp);
1424 vput(state.ndp->ni_dvp);
1425 state.ndp->ni_vp = NULL;
1426 PNBUF_PUT(state.cnp->cn_pnbuf);
1427
1428 /*
1429 * END wodge of code from nfsd
1430 */
1431 namei_cleanup(&state);
1432
1433 return error;
1434 }
1435
1436 int
1437 lookup_for_nfsd_index(struct nameidata *ndp)
1438 {
1439 struct namei_state state;
1440 int error;
1441
1442 /* For now at least we don't have to frob the state */
1443 namei_init(&state, ndp);
1444 error = do_lookup(&state);
1445 namei_cleanup(&state);
1446
1447 return error;
1448 }
1449
1450 /*
1451 * Reacquire a path name component.
1452 * dvp is locked on entry and exit.
1453 * *vpp is locked on exit unless it's NULL.
1454 */
1455 int
1456 relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
1457 {
1458 int rdonly; /* lookup read-only flag bit */
1459 int error = 0;
1460 #ifdef DEBUG
1461 uint32_t newhash; /* DEBUG: check name hash */
1462 const char *cp; /* DEBUG: check name ptr/len */
1463 #endif /* DEBUG */
1464
1465 /*
1466 * Setup: break out flag bits into variables.
1467 */
1468 rdonly = cnp->cn_flags & RDONLY;
1469 cnp->cn_flags &= ~ISSYMLINK;
1470
1471 /*
1472 * Search a new directory.
1473 *
1474 * The cn_hash value is for use by vfs_cache.
1475 * The last component of the filename is left accessible via
1476 * cnp->cn_nameptr for callers that need the name. Callers needing
1477 * the name set the SAVENAME flag. When done, they assume
1478 * responsibility for freeing the pathname buffer.
1479 */
1480 #ifdef DEBUG
1481 cp = NULL;
1482 newhash = namei_hash(cnp->cn_nameptr, &cp);
1483 if ((uint32_t)newhash != (uint32_t)cnp->cn_hash)
1484 panic("relookup: bad hash");
1485 if (cnp->cn_namelen != cp - cnp->cn_nameptr)
1486 panic("relookup: bad len");
1487 while (*cp == '/')
1488 cp++;
1489 if (*cp != 0)
1490 panic("relookup: not last component");
1491 #endif /* DEBUG */
1492
1493 /*
1494 * Check for degenerate name (e.g. / or "")
1495 * which is a way of talking about a directory,
1496 * e.g. like "/." or ".".
1497 */
1498 if (cnp->cn_nameptr[0] == '\0')
1499 panic("relookup: null name");
1500
1501 if (cnp->cn_flags & ISDOTDOT)
1502 panic("relookup: lookup on dot-dot");
1503
1504 /*
1505 * We now have a segment name to search for, and a directory to search.
1506 */
1507 if ((error = VOP_LOOKUP(dvp, vpp, cnp)) != 0) {
1508 #ifdef DIAGNOSTIC
1509 if (*vpp != NULL)
1510 panic("leaf `%s' should be empty", cnp->cn_nameptr);
1511 #endif
1512 if (error != EJUSTRETURN)
1513 goto bad;
1514 }
1515
1516 #ifdef DIAGNOSTIC
1517 /*
1518 * Check for symbolic link
1519 */
1520 if (*vpp && (*vpp)->v_type == VLNK && (cnp->cn_flags & FOLLOW))
1521 panic("relookup: symlink found");
1522 #endif
1523
1524 /*
1525 * Check for read-only lookups.
1526 */
1527 if (rdonly && cnp->cn_nameiop != LOOKUP) {
1528 error = EROFS;
1529 if (*vpp) {
1530 vput(*vpp);
1531 }
1532 goto bad;
1533 }
1534 if (cnp->cn_flags & SAVESTART)
1535 vref(dvp);
1536 return (0);
1537
1538 bad:
1539 *vpp = NULL;
1540 return (error);
1541 }
1542
1543 /*
1544 * namei_simple - simple forms of namei.
1545 *
1546 * These are wrappers to allow the simple case callers of namei to be
1547 * left alone while everything else changes under them.
1548 */
1549
1550 /* Flags */
1551 struct namei_simple_flags_type {
1552 int dummy;
1553 };
1554 static const struct namei_simple_flags_type ns_nn, ns_nt, ns_fn, ns_ft;
1555 const namei_simple_flags_t NSM_NOFOLLOW_NOEMULROOT = &ns_nn;
1556 const namei_simple_flags_t NSM_NOFOLLOW_TRYEMULROOT = &ns_nt;
1557 const namei_simple_flags_t NSM_FOLLOW_NOEMULROOT = &ns_fn;
1558 const namei_simple_flags_t NSM_FOLLOW_TRYEMULROOT = &ns_ft;
1559
1560 static
1561 int
1562 namei_simple_convert_flags(namei_simple_flags_t sflags)
1563 {
1564 if (sflags == NSM_NOFOLLOW_NOEMULROOT)
1565 return NOFOLLOW | 0;
1566 if (sflags == NSM_NOFOLLOW_TRYEMULROOT)
1567 return NOFOLLOW | TRYEMULROOT;
1568 if (sflags == NSM_FOLLOW_NOEMULROOT)
1569 return FOLLOW | 0;
1570 if (sflags == NSM_FOLLOW_TRYEMULROOT)
1571 return FOLLOW | TRYEMULROOT;
1572 panic("namei_simple_convert_flags: bogus sflags\n");
1573 return 0;
1574 }
1575
1576 int
1577 namei_simple_kernel(const char *path, namei_simple_flags_t sflags,
1578 struct vnode **vp_ret)
1579 {
1580 struct nameidata nd;
1581 struct pathbuf *pb;
1582 int err;
1583
1584 pb = pathbuf_create(path);
1585 if (pb == NULL) {
1586 return ENOMEM;
1587 }
1588
1589 NDINIT(&nd,
1590 LOOKUP,
1591 namei_simple_convert_flags(sflags),
1592 pb);
1593 err = namei(&nd);
1594 if (err != 0) {
1595 pathbuf_destroy(pb);
1596 return err;
1597 }
1598 *vp_ret = nd.ni_vp;
1599 pathbuf_destroy(pb);
1600 return 0;
1601 }
1602
1603 int
1604 namei_simple_user(const char *path, namei_simple_flags_t sflags,
1605 struct vnode **vp_ret)
1606 {
1607 struct pathbuf *pb;
1608 struct nameidata nd;
1609 int err;
1610
1611 err = pathbuf_copyin(path, &pb);
1612 if (err) {
1613 return err;
1614 }
1615
1616 NDINIT(&nd,
1617 LOOKUP,
1618 namei_simple_convert_flags(sflags),
1619 pb);
1620 err = namei(&nd);
1621 if (err != 0) {
1622 pathbuf_destroy(pb);
1623 return err;
1624 }
1625 *vp_ret = nd.ni_vp;
1626 pathbuf_destroy(pb);
1627 return 0;
1628 }
1629