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 * ns_generic.c 24 * 25 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29/* 30 * Portions Copyright 2007-2011 Apple Inc. 31 */ 32 33#pragma ident "@(#)ns_generic.c 1.33 05/06/08 SMI" 34 35#include <stdio.h> 36#include <syslog.h> 37#include <string.h> 38#include <stdlib.h> 39#include <errno.h> 40#include <assert.h> 41#include <mntopts.h> 42#include "autofs.h" 43#include "automount.h" 44#include "auto_mntopts.h" 45 46/* 47 * Each name service is represented by a ns_info structure. 48 */ 49struct ns_info { 50 char *ns_name; /* service name */ 51 void (*ns_init)(char **, char ***); 52 /* initialization routine */ 53 int (*ns_getmapent)(const char *, const char *, struct mapline *, 54 char **, char ***, bool_t *, bool_t); 55 /* get map entry given key */ 56 int (*ns_loadmaster)(char *, char *, char **, char ***); 57 /* load master map */ 58 int (*ns_loaddirect)(char *, char *, char *, 59 char **, char ***); /* load direct map */ 60 int (*ns_getmapkeys)(char *, struct dir_entry **, 61 int *, int *, char **, char ***); 62 /* readdir */ 63}; 64 65static struct ns_info ns_info[] = { 66 67 { "files", init_files, getmapent_files, 68 loadmaster_files, loaddirect_files, 69 getmapkeys_files }, 70 71 { "od", init_od, getmapent_od, 72 loadmaster_od, loaddirect_od, 73 getmapkeys_od }, 74 75 { NULL, NULL, NULL, NULL, NULL, NULL } 76}; 77 78void 79ns_setup(char **stack, char ***stkptr) 80{ 81 struct ns_info *nsp; 82 83 for (nsp = ns_info; nsp->ns_name; nsp++) { 84 nsp->ns_init(stack, stkptr); 85 } 86} 87 88int 89getmapent(key, mapname, ml, stack, stkptr, iswildcard, isrestricted) 90 const char *key, *mapname; 91 struct mapline *ml; 92 char **stack, ***stkptr; 93 bool_t *iswildcard; 94 bool_t isrestricted; 95{ 96 int ns_err, err; 97 struct ns_info *nsp; 98 99 if (*mapname == '/') /* must be a file */ 100 return (getmapent_files(key, mapname, ml, stack, stkptr, 101 iswildcard, isrestricted)); 102 103 ns_err = __NSW_NOTFOUND; 104 for (nsp = ns_info; nsp->ns_name; nsp++) { 105 err = nsp->ns_getmapent(key, mapname, ml, stack, stkptr, 106 iswildcard, isrestricted); 107 if (err == __NSW_SUCCESS) 108 return (__NSW_SUCCESS); 109 if (err != __NSW_NOTFOUND) 110 ns_err = err; 111 } 112 113 return (ns_err); 114} 115 116int 117loadmaster_map(mapname, defopts, stack, stkptr) 118 char *mapname, *defopts; 119 char **stack, ***stkptr; 120{ 121 int ns_err; 122 struct ns_info *nsp; 123 124 if (*mapname == '/') /* must be a file */ 125 return (loadmaster_files(mapname, defopts, stack, stkptr)); 126 127 for (nsp = ns_info; nsp->ns_name; nsp++) { 128 ns_err = nsp->ns_loadmaster(mapname, defopts, stack, stkptr); 129 if (ns_err == __NSW_SUCCESS) 130 return (__NSW_SUCCESS); 131 } 132 133 return (__NSW_UNAVAIL); 134} 135 136int 137loaddirect_map(mapname, localmap, defopts, stack, stkptr) 138 char *mapname, *localmap, *defopts; 139 char **stack, ***stkptr; 140{ 141 int ns_err = __NSW_SUCCESS; 142 struct ns_info *nsp; 143 144 if (*mapname == '/') /* must be a file */ 145 return (loaddirect_files(mapname, localmap, defopts, 146 stack, stkptr)); 147 if (strcmp(mapname, "-static") == 0) { 148 return (loaddirect_static(localmap, defopts, stack, stkptr)); 149 } 150 151 for (nsp = ns_info; nsp->ns_name; nsp++) { 152 ns_err = nsp->ns_loaddirect(mapname, localmap, defopts, stack, 153 stkptr); 154 if (ns_err == __NSW_SUCCESS) 155 return (__NSW_SUCCESS); 156 } 157 158 return (__NSW_UNAVAIL); 159} 160 161/* 162 * XXX - this assumes that gethostent() returns a pointer to 163 * thread-specific data. It currently does.... 164 */ 165static int 166gethostkeys(struct dir_entry **list, int *error, int *cache_time) 167{ 168 char **p; 169 struct dir_entry *last = NULL; 170 struct hostent *ent; 171 int err; 172 173 *cache_time = RDDIR_CACHE_TIME * 2; 174 *error = 0; 175 if (trace > 1) 176 trace_prt(1, "gethostkeys called\n"); 177 178 sethostent(1); 179 180 while ((ent = gethostent()) != NULL) { 181 /* 182 * add canonical name 183 * 184 * A return of -1 means the name isn't valid. 185 */ 186 err = add_dir_entry(ent->h_name, NULL, NULL, list, &last); 187 if (err == -1) 188 continue; 189 if (err != 0) { 190 *error = err; 191 goto done; 192 } 193 if (ent->h_aliases == NULL) 194 goto done; /* no aliases */ 195 for (p = ent->h_aliases; *p != 0; p++) { 196 if (strcmp(*p, ent->h_name) != 0) { 197 /* 198 * add alias only if different 199 * from canonical name 200 */ 201 err = add_dir_entry(*p, NULL, NULL, list, 202 &last); 203 if (err == -1) 204 continue; 205 if (err != 0) { 206 *error = err; 207 goto done; 208 } 209 } 210 } 211 assert(last != NULL); 212 } 213done: if (*list != NULL) { 214 /* 215 * list of entries found 216 */ 217 *error = 0; 218 } 219 endhostent(); 220 221 return (__NSW_SUCCESS); 222} 223 224/* 225 * enumerate all entries in the map in the various name services. 226 */ 227int 228getmapkeys(mapname, list, error, cache_time, stack, stkptr) 229 char *mapname; 230 struct dir_entry **list; 231 int *error; 232 int *cache_time; 233 char **stack, ***stkptr; 234 235{ 236 int ns_err = __NSW_SUCCESS; 237 int success = 0; 238 struct ns_info *nsp; 239 240 if (*mapname == '/') /* must be a file */ 241 return (getmapkeys_files(mapname, list, error, cache_time, 242 stack, stkptr)); 243 if (strcmp(mapname, "-hosts") == 0) { 244 return (gethostkeys(list, error, cache_time)); 245 } 246 if (strcmp(mapname, "-static") == 0) { 247 pr_msg("-static is a collection of direct maps"); 248 return (__NSW_UNAVAIL); 249 } 250 if (strcmp(mapname, "-fstab") == 0) { 251 return (getfstabkeys(list, error, cache_time)); 252 } 253 254 for (nsp = ns_info; nsp->ns_name; nsp++) { 255 ns_err = nsp->ns_getmapkeys(mapname, list, error, 256 cache_time, stack, stkptr); 257 if (*error == 0) { 258 /* 259 * return success if listing was successful 260 * for at least one name service 261 */ 262 success++; 263 } 264 265 /* 266 * XXX force next name service 267 */ 268 if (ns_err != __NSW_UNAVAIL) 269 ns_err = __NSW_NOTFOUND; 270 } 271 if (success) { 272 /* 273 * if succeeded at least once, return error=0 274 */ 275 *error = 0; 276 }; 277 278 return (success ? __NSW_SUCCESS : __NSW_NOTFOUND); 279} 280