1 /* 2 * Copyright (c) 1989 Jan-Simon Pendry 3 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 4 * Copyright (c) 1989 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Jan-Simon Pendry at Imperial College, London. 9 * 10 * %sccs.include.redist.c% 11 * 12 * @(#)info_nis.c 5.3 (Berkeley) 05/12/91 13 * 14 * $Id: info_nis.c,v 5.2.1.4 91/05/07 22:18:01 jsp Alpha $ 15 * 16 */ 17 18 /* 19 * Get info from NIS map 20 */ 21 22 #include "am.h" 23 24 #ifdef HAS_NIS_MAPS 25 #include <rpcsvc/yp_prot.h> 26 #include <rpcsvc/ypclnt.h> 27 28 /* 29 * Figure out the nis domain name 30 */ 31 static int determine_nis_domain(P_void) 32 { 33 char default_domain[YPMAXDOMAIN]; 34 35 if (getdomainname(default_domain, sizeof(default_domain)) < 0) { 36 plog(XLOG_ERROR, "getdomainname: %m"); 37 return EIO; 38 } 39 40 if (!*default_domain) { 41 plog(XLOG_ERROR, "NIS domain name is not set"); 42 return ENOENT; 43 } 44 domain = strdup(default_domain); 45 46 return 0; 47 } 48 49 50 #ifdef HAS_NIS_RELOAD 51 struct nis_callback_data { 52 mnt_map *ncd_m; 53 char *ncd_map; 54 void (*ncd_fn)(); 55 }; 56 57 /* 58 * Callback from yp_all 59 */ 60 static int callback(status, key, kl, val, vl, data) 61 int status; 62 char *key; 63 int kl; 64 char *val; 65 int vl; 66 struct nis_callback_data *data; 67 { 68 if (status == YP_TRUE) { 69 /* 70 * Add to list of maps 71 */ 72 char *kp = strnsave(key, kl); 73 char *vp = strnsave(val, vl); 74 (*data->ncd_fn)(data->ncd_m, kp, vp); 75 76 /* 77 * We want more ... 78 */ 79 return FALSE; 80 } else { 81 /* 82 * NOMORE means end of map - otherwise log error 83 */ 84 if (status != YP_NOMORE) { 85 /* 86 * Check what went wrong 87 */ 88 int e = ypprot_err(status); 89 90 #ifdef DEBUG 91 plog(XLOG_ERROR, "yp enumeration of %s: %s, status=%d, e=%d", 92 data->ncd_map, yperr_string(e), status, e); 93 #else 94 plog(XLOG_ERROR, "yp enumeration of %s: %s", data->ncd_map, yperr_string(e)); 95 #endif 96 } 97 98 return TRUE; 99 } 100 } 101 102 int nis_reload P((mnt_map *m, char *map, void (*fn)())); 103 int nis_reload(m, map, fn) 104 mnt_map *m; 105 char *map; 106 void (*fn)(); 107 { 108 struct ypall_callback cbinfo; 109 int error; 110 struct nis_callback_data data; 111 112 if (!domain) { 113 error = determine_nis_domain(); 114 if (error) 115 return error; 116 } 117 118 data.ncd_m = m; 119 data.ncd_map = map; 120 data.ncd_fn = fn; 121 cbinfo.data = (voidp) &data; 122 cbinfo.foreach = callback; 123 124 error = yp_all(domain, map, &cbinfo); 125 126 if (error) 127 plog(XLOG_ERROR, "error grabbing nis map of %s: %s", map, yperr_string(ypprot_err(error))); 128 129 return error; 130 } 131 #endif /* HAS_NIS_RELOAD */ 132 133 /* 134 * Try to locate a key using NIS. 135 */ 136 int nis_search P((mnt_map *m, char *map, char *key, char **val, time_t *tp)); 137 int nis_search(m, map, key, val, tp) 138 mnt_map *m; 139 char *map; 140 char *key; 141 char **val; 142 time_t *tp; 143 { 144 int outlen; 145 int res; 146 int order; 147 148 /* 149 * Make sure domain initialised 150 */ 151 if (!domain) { 152 int error = determine_nis_domain(); 153 if (error) 154 return error; 155 } 156 157 /* 158 * Check if map has changed 159 */ 160 if (yp_order(domain, map, &order)) 161 return EIO; 162 if ((time_t) order > *tp) { 163 *tp = (time_t) order; 164 return -1; 165 } 166 167 /* 168 * Lookup key 169 */ 170 res = yp_match(domain, map, key, strlen(key), val, &outlen); 171 172 /* 173 * Do something interesting with the return code 174 */ 175 switch (res) { 176 case 0: 177 return 0; 178 179 case YPERR_KEY: 180 return ENOENT; 181 182 default: 183 plog(XLOG_ERROR, "%s: %s", map, yperr_string(res)); 184 return EIO; 185 } 186 } 187 188 int nis_init P((char *map, time_t *tp)); 189 int nis_init(map, tp) 190 char *map; 191 time_t *tp; 192 { 193 int order; 194 195 if (!domain) { 196 int error = determine_nis_domain(); 197 if (error) 198 return error; 199 } 200 201 /* 202 * To see if the map exists, try to find 203 * a master for it. 204 */ 205 if (yp_order(domain, map, &order)) 206 return ENOENT; 207 *tp = (time_t) order; 208 #ifdef DEBUG 209 dlog("NIS master for %s@%s has order %d", map, domain, order); 210 #endif 211 return 0; 212 } 213 #endif /* HAS_NIS_MAPS */ 214