1 /* $NetBSD: vfs_lookup.c,v 1.131 2011/01/04 07:43:42 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.131 2011/01/04 07:43:42 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 * 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