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