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 */
determine_nis_domain(P_void)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 */
callback(status,key,kl,val,vl,data)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)()));
nis_reload(m,map,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));
nis_search(m,map,key,val,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));
nis_init(map,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