info_nisplus.c revision 119679
1/* 2 * Copyright (c) 1997-2003 Erez Zadok 3 * Copyright (c) 1989 Jan-Simon Pendry 4 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1989 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry at Imperial College, London. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgment: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * %W% (Berkeley) %G% 40 * 41 * $Id: info_nisplus.c,v 1.3.2.4 2002/12/27 22:44:37 ezk Exp $ 42 * 43 */ 44 45/* 46 * Get info from NIS+ (version 3) map 47 */ 48 49#ifdef HAVE_CONFIG_H 50# include <config.h> 51#endif /* HAVE_CONFIG_H */ 52#include <am_defs.h> 53#include <amd.h> 54 55#define NISPLUS_KEY "key=" 56#define NISPLUS_ORGDIR ".org_dir" 57 58struct nis_callback_data { 59 mnt_map *ncd_m; 60 char *ncd_map; 61 void (*ncd_fn)(); 62}; 63 64struct nisplus_search_callback_data { 65 nis_name key; 66 char *value; 67}; 68 69 70static int 71nisplus_callback(const nis_name key, const nis_object *value, voidp opaquedata) 72{ 73 char *kp = strnsave(ENTRY_VAL(value, 0), ENTRY_LEN(value, 0)); 74 char *vp = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1)); 75 struct nis_callback_data *data = (struct nis_callback_data *) opaquedata; 76 77#ifdef DEBUG 78 dlog("NISplus callback for <%s,%s>", kp, vp); 79#endif /* DEBUG */ 80 81 (*data->ncd_fn) (data->ncd_m, kp, vp); 82 83 /* 84 * We want more ... 85 */ 86 return FALSE; 87} 88 89 90int 91nisplus_reload(mnt_map *m, char *map, void (*fn) ()) 92{ 93 int error = 0; 94 struct nis_callback_data data; 95 nis_result *result; 96 char *org; /* if map does not have ".org_dir" then append it */ 97 nis_name map_name; 98 99 org = strstr(map, NISPLUS_ORGDIR); 100 if (org == NULL) 101 org = NISPLUS_ORGDIR; 102 else 103 org = ""; 104 105 /* make some room for the NIS map_name */ 106 map_name = xmalloc(strlen(map) + sizeof(NISPLUS_ORGDIR)); 107 if (map_name == NULL) { 108 plog(XLOG_ERROR, "Unable to create map_name %s: %s", 109 map, strerror(ENOMEM)); 110 return ENOMEM; 111 } 112 sprintf(map_name, "%s%s", map, org); 113 114 data.ncd_m = m; 115 data.ncd_map = map_name; 116 data.ncd_fn = fn; 117 118#ifdef DEBUG 119 dlog("NISplus reload for %s", map); 120#endif /* DEBUG */ 121 122 result = nis_list(map_name, 123 EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH, 124 (int (*)()) nisplus_callback, 125 &data); 126 127 /* free off the NIS map_name */ 128 XFREE(map_name); 129 130 if (result->status != NIS_SUCCESS && result->status != NIS_CBRESULTS) 131 error = 1; 132 133 if (error) 134 plog(XLOG_ERROR, "error grabbing nisplus map of %s: %s", 135 map, 136 nis_sperrno(result->status)); 137 138 nis_freeresult(result); 139 return error; 140} 141 142 143static int 144nisplus_search_callback(const nis_name key, const nis_object *value, voidp opaquedata) 145{ 146 struct nisplus_search_callback_data *data = (struct nisplus_search_callback_data *) opaquedata; 147 148#ifdef DEBUG 149 dlog("NISplus search callback for <%s>", ENTRY_VAL(value, 0)); 150 dlog("NISplus search callback value <%s>", ENTRY_VAL(value, 1)); 151#endif /* DEBUG */ 152 153 data->value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1)); 154 return TRUE; 155} 156 157 158/* 159 * Try to locate a key using NIS+. 160 */ 161int 162nisplus_search(mnt_map *m, char *map, char *key, char **val, time_t *tp) 163{ 164 nis_result *result; 165 int error = 0; 166 struct nisplus_search_callback_data data; 167 nis_name index; 168 char *org; /* if map does not have ".org_dir" then append it */ 169 170 org = strstr(map, NISPLUS_ORGDIR); 171 if (org == NULL) 172 org = NISPLUS_ORGDIR; 173 else 174 org = ""; 175 176 /* make some room for the NIS index */ 177 index = xmalloc(sizeof('[') /* for opening selection criteria */ 178 +sizeof(NISPLUS_KEY) 179 + strlen(key) 180 + sizeof(']') /* for closing selection criteria */ 181 +sizeof(',') /* + 1 for , separator */ 182 +strlen(map) 183 + sizeof(NISPLUS_ORGDIR) 184 ); 185 if (index == NULL) { 186 plog(XLOG_ERROR, 187 "Unable to create index %s: %s", 188 map, 189 strerror(ENOMEM)); 190 return ENOMEM; 191 } 192 sprintf(index, "[%s%s],%s%s", NISPLUS_KEY, key, map, org); 193 194 data.key = key; 195 data.value = NULL; 196 197#ifdef DEBUG 198 dlog("NISplus search for %s", index); 199#endif /* DEBUG */ 200 201 result = nis_list(index, 202 EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH, 203 (int (*)()) nisplus_search_callback, 204 &data); 205 206 /* free off the NIS index */ 207 XFREE(index); 208 209 if (result == NULL) { 210 plog(XLOG_ERROR, "nisplus_search: %s: %s", map, strerror(ENOMEM)); 211 return ENOMEM; 212 } 213 214 /* 215 * Do something interesting with the return code 216 */ 217 switch (result->status) { 218 case NIS_SUCCESS: 219 case NIS_CBRESULTS: 220 221 if (data.value == NULL) { 222 nis_object *value = result->objects.objects_val; 223#ifdef DEBUG 224 dlog("NISplus search found <nothing>"); 225 dlog("NISplus search for %s: %s(%d)", 226 map, nis_sperrno(result->status), result->status); 227#endif /* DEBUG */ 228 229 if (value != NULL) 230 data.value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1)); 231 } 232 *val = data.value; 233 234 if (*val) { 235 error = 0; 236#ifdef DEBUG 237 dlog("NISplus search found %s", *val); 238#endif /* DEBUG */ 239 } else { 240 error = ENOENT; 241#ifdef DEBUG 242 dlog("NISplus search found nothing"); 243#endif /* DEBUG */ 244 } 245 246 *tp = 0; 247 break; 248 249 case NIS_NOSUCHNAME: 250#ifdef DEBUG 251 dlog("NISplus search returned %d", result->status); 252#endif /* DEBUG */ 253 error = ENOENT; 254 break; 255 256 default: 257 plog(XLOG_ERROR, "nisplus_search: %s: %s", map, nis_sperrno(result->status)); 258 error = EIO; 259 break; 260 } 261 nis_freeresult(result); 262 263 return error; 264} 265 266 267int 268nisplus_init(mnt_map *m, char *map, time_t *tp) 269{ 270 nis_result *result; 271 char *org; /* if map does not have ".org_dir" then append it */ 272 nis_name map_name; 273 int error = 0; 274 275 org = strstr(map, NISPLUS_ORGDIR); 276 if (org == NULL) 277 org = NISPLUS_ORGDIR; 278 else 279 org = ""; 280 281 /* make some room for the NIS map_name */ 282 map_name = xmalloc(strlen(map) + sizeof(NISPLUS_ORGDIR)); 283 if (map_name == NULL) { 284 plog(XLOG_ERROR, 285 "Unable to create map_name %s: %s", 286 map, 287 strerror(ENOMEM)); 288 return ENOMEM; 289 } 290 sprintf(map_name, "%s%s", map, org); 291 292 result = nis_lookup(map_name, (EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH)); 293 294 /* free off the NIS map_name */ 295 XFREE(map_name); 296 297 if (result == NULL) { 298 plog(XLOG_ERROR, "NISplus init <%s>: %s", map, strerror(ENOMEM)); 299 return ENOMEM; 300 } 301 302 if (result->status != NIS_SUCCESS) { 303#ifdef DEBUG 304 dlog("NISplus init <%s>: %s (%d)", 305 map, nis_sperrno(result->status), result->status); 306#endif /* DEBUG */ 307 308 error = ENOENT; 309 } 310 311 *tp = 0; /* no time */ 312 nis_freeresult(result); 313 return error; 314} 315 316 317int 318nisplus_mtime(mnt_map *m, char *map, time_t *tp) 319{ 320 return nisplus_init(m,map, tp); 321} 322