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