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 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <stdio.h> 31 #include <ctype.h> 32 #include <string.h> 33 #include <syslog.h> 34 #include <errno.h> 35 #include <locale.h> 36 #include <stdlib.h> 37 #include <unistd.h> 38 #include <assert.h> 39 #include "automount.h" 40 41 int 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 /* 64 * Default action is for no work to be done by kernel AUTOFS. 65 */ 66 *action = AUTOFS_NONE; 67 68 /* 69 * Is there a cache for this map? 70 */ 71 rw_rdlock(&rddir_cache_lock); 72 err = rddir_cache_lookup(mapname, &rdcp); 73 if (!err && rdcp->full) { 74 rw_unlock(&rddir_cache_lock); 75 /* 76 * Try to lock readdir cache entry for reading, if 77 * the entry can not be locked, then avoid blocking 78 * and go to the name service. I'm assuming it is 79 * faster to go to the name service than to wait for 80 * the cache to be populated. 81 */ 82 if (rw_tryrdlock(&rdcp->rwlock) == 0) { 83 found = (rddir_entry_lookup(key, rdcp->entp) != NULL); 84 rw_unlock(&rdcp->rwlock); 85 } 86 } else 87 rw_unlock(&rddir_cache_lock); 88 89 if (!err) { 90 /* 91 * release reference on cache entry 92 */ 93 mutex_lock(&rdcp->lock); 94 rdcp->in_use--; 95 assert(rdcp->in_use >= 0); 96 mutex_unlock(&rdcp->lock); 97 } 98 99 if (found) 100 return (0); 101 102 /* 103 * entry not found in cache, try the name service now 104 */ 105 err = 0; 106 107 /* initialize the stack of open files for this thread */ 108 stack_op(INIT, NULL, stack, &stkptr); 109 110 err = getmapent(key, mapname, &ml, stack, &stkptr, &iswildcard, 111 isrestricted); 112 if (err == 0) /* call parser w default mount_access = TRUE */ 113 mapents = parse_entry(key, mapname, mapopts, &ml, 114 subdir, isdirect, TRUE); 115 116 /* 117 * Now we indulge in a bit of hanky-panky. 118 * If the entry isn't found in the map and the 119 * name begins with an "=" then we assume that 120 * the name is an undocumented control message 121 * for the daemon. This is accessible only 122 * to superusers. 123 */ 124 if (mapents == NULL && *action == AUTOFS_NONE) { 125 if (*key == '=' && cred->aup_uid == 0) { 126 if (isdigit(*(key+1))) { 127 /* 128 * If next character is a digit 129 * then set the trace level. 130 */ 131 trace = atoi(key+1); 132 trace_prt(1, "Automountd: trace level = %d\n", 133 trace); 134 } else if (*(key+1) == 'v') { 135 /* 136 * If it's a "v" then 137 * toggle verbose mode. 138 */ 139 verbose = !verbose; 140 trace_prt(1, "Automountd: verbose %s\n", 141 verbose ? "on" : "off"); 142 } 143 } 144 145 err = ENOENT; 146 goto done; 147 } 148 149 /* 150 * Each mapent in the list describes a mount to be done. 151 * Since I'm only doing a lookup, I only care whether a mapentry 152 * was found or not. The mount will be done on a later RPC to 153 * do_mount1. 154 */ 155 if (mapents == NULL && *action == AUTOFS_NONE) 156 err = ENOENT; 157 158 done: if (mapents) 159 free_mapent(mapents); 160 161 if (*action == AUTOFS_NONE && (iswildcard == TRUE)) { 162 *action = AUTOFS_MOUNT_RQ; 163 } 164 if (trace > 1) { 165 trace_prt(1, " do_lookup1: action=%d wildcard=%s error=%d\n", 166 *action, iswildcard ? "TRUE" : "FALSE", err); 167 } 168 return (err); 169 } 170