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