1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * autod_lookup.c 23 * 24 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #include <stdio.h> 29 #include <ctype.h> 30 #include <string.h> 31 #include <syslog.h> 32 #include <errno.h> 33 #include <locale.h> 34 #include <stdlib.h> 35 #include <unistd.h> 36 #include <assert.h> 37 #include "automount.h" 38 39 int 40 do_lookup1( 41 char *mapname, 42 char *key, 43 char *subdir, 44 char *mapopts, 45 char *path, 46 uint_t isdirect, 47 uid_t uid, 48 autofs_action_t *action, 49 struct linka *linkp) 50 { 51 struct mapline ml; 52 struct mapent *mapents = NULL; 53 int err; 54 struct autofs_rddir_cache *rdcp; 55 int found = 0; 56 bool_t iswildcard = FALSE; 57 bool_t isrestricted = hasrestrictopt(mapopts); 58 char *stack[STACKSIZ]; 59 char **stkptr = stack; 60 61 /* 62 * Default action is for no work to be done by kernel AUTOFS. 63 */ 64 *action = AUTOFS_NONE; 65 66 /* 67 * Is there a cache for this map? 68 */ 69 rw_rdlock(&autofs_rddir_cache_lock); 70 err = autofs_rddir_cache_lookup(mapname, &rdcp); 71 if (!err && rdcp->full) { 72 rw_unlock(&autofs_rddir_cache_lock); 73 /* 74 * Try to lock readdir cache entry for reading, if 75 * the entry can not be locked, then avoid blocking 76 * and go to the name service. I'm assuming it is 77 * faster to go to the name service than to wait for 78 * the cache to be populated. 79 */ 80 if (rw_tryrdlock(&rdcp->rwlock) == 0) { 81 found = (rddir_entry_lookup(key, rdcp->entp) != NULL); 82 rw_unlock(&rdcp->rwlock); 83 } 84 } else 85 rw_unlock(&autofs_rddir_cache_lock); 86 87 if (!err) { 88 /* 89 * release reference on cache entry 90 */ 91 mutex_lock(&rdcp->lock); 92 rdcp->in_use--; 93 assert(rdcp->in_use >= 0); 94 mutex_unlock(&rdcp->lock); 95 } 96 97 if (found) 98 return (0); 99 100 /* 101 * entry not found in cache, try the name service now 102 */ 103 err = 0; 104 105 /* initialize the stack of open files for this thread */ 106 stack_op(INIT, NULL, stack, &stkptr); 107 108 err = getmapent(key, mapname, &ml, stack, &stkptr, &iswildcard, 109 isrestricted); 110 if (err == 0) /* call parser w default mount_access = TRUE */ 111 mapents = parse_entry(key, mapname, mapopts, &ml, 112 subdir, isdirect, TRUE); 113 114 /* 115 * Now we indulge in a bit of hanky-panky. 116 * If the entry isn't found in the map and the 117 * name begins with an "=" then we assume that 118 * the name is an undocumented control message 119 * for the daemon. This is accessible only 120 * to superusers. 121 */ 122 if (mapents == NULL && *action == AUTOFS_NONE) { 123 if (*key == '=' && uid == 0) { 124 if (isdigit(*(key+1))) { 125 /* 126 * If next character is a digit 127 * then set the trace level. 128 */ 129 trace = atoi(key+1); 130 trace_prt(1, "Automountd: trace level = %d\n", 131 trace); 132 } else if (*(key+1) == 'v') { 133 /* 134 * If it's a "v" then 135 * toggle verbose mode. 136 */ 137 verbose = !verbose; 138 trace_prt(1, "Automountd: verbose %s\n", 139 verbose ? "on" : "off"); 140 } 141 } 142 143 err = ENOENT; 144 goto done; 145 } 146 147 /* 148 * Each mapent in the list describes a mount to be done. 149 * Since I'm only doing a lookup, I only care whether a mapentry 150 * was found or not. The mount will be done on a later RPC to 151 * do_mount1. 152 */ 153 if (mapents == NULL && *action == AUTOFS_NONE) 154 err = ENOENT; 155 156 done: if (mapents) 157 free_mapent(mapents); 158 159 if (*action == AUTOFS_NONE && (iswildcard == TRUE)) { 160 *action = AUTOFS_MOUNT_RQ; 161 } 162 if (trace > 1) { 163 trace_prt(1, " do_lookup1: action=%d wildcard=%s error=%d\n", 164 *action, iswildcard ? "TRUE" : "FALSE", err); 165 } 166 return (err); 167 } 168