xref: /trueos/contrib/amd/amd/info_nisplus.c (revision 2e06911c043c995eb8eb5f67a778b74564d0c018)
1 /*
2  * Copyright (c) 1997-2006 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  *
40  * File: am-utils/amd/info_nisplus.c
41  *
42  */
43 
44 /*
45  * Get info from NIS+ (version 3) map
46  */
47 
48 #ifdef HAVE_CONFIG_H
49 # include <config.h>
50 #endif /* HAVE_CONFIG_H */
51 #include <am_defs.h>
52 #include <amd.h>
53 
54 #define NISPLUS_KEY "key="
55 #define NISPLUS_ORGDIR ".org_dir"
56 
57 struct nis_callback_data {
58   mnt_map *ncd_m;
59   char *ncd_map;
60   void (*ncd_fn)();
61 };
62 
63 struct nisplus_search_callback_data {
64   nis_name key;
65   char *value;
66 };
67 
68 
69 static int
nisplus_callback(const nis_name key,const nis_object * value,voidp opaquedata)70 nisplus_callback(const nis_name key, const nis_object *value, voidp opaquedata)
71 {
72   char *kp = strnsave(ENTRY_VAL(value, 0), ENTRY_LEN(value, 0));
73   char *vp = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
74   struct nis_callback_data *data = (struct nis_callback_data *) opaquedata;
75 
76   dlog("NISplus callback for <%s,%s>", kp, vp);
77 
78   (*data->ncd_fn) (data->ncd_m, kp, vp);
79 
80   /*
81    * We want more ...
82    */
83   return FALSE;
84 }
85 
86 
87 int
nisplus_reload(mnt_map * m,char * map,void (* fn)())88 nisplus_reload(mnt_map *m, char *map, void (*fn) ())
89 {
90   int error = 0;
91   struct nis_callback_data data;
92   nis_result *result;
93   char *org;		/* if map does not have ".org_dir" then append it */
94   nis_name map_name;
95   size_t l;
96 
97   org = strstr(map, NISPLUS_ORGDIR);
98   if (org == NULL)
99     org = NISPLUS_ORGDIR;
100   else
101     org = "";
102 
103   /* make some room for the NIS map_name */
104   l = strlen(map) + sizeof(NISPLUS_ORGDIR);
105   map_name = xmalloc(l);
106   if (map_name == NULL) {
107     plog(XLOG_ERROR, "Unable to create map_name %s: %s",
108 	 map, strerror(ENOMEM));
109     return ENOMEM;
110   }
111   xsnprintf(map_name, l, "%s%s", map, org);
112 
113   data.ncd_m = m;
114   data.ncd_map = map_name;
115   data.ncd_fn = fn;
116 
117   dlog("NISplus reload for %s", map);
118 
119   result = nis_list(map_name,
120 		    EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH,
121 		    (int (*)()) nisplus_callback,
122 		    &data);
123 
124   /* free off the NIS map_name */
125   XFREE(map_name);
126 
127   if (result->status != NIS_SUCCESS && result->status != NIS_CBRESULTS)
128     error = 1;
129 
130   if (error)
131     plog(XLOG_ERROR, "error grabbing nisplus map of %s: %s",
132 	 map,
133 	 nis_sperrno(result->status));
134 
135   nis_freeresult(result);
136   return error;
137 }
138 
139 
140 static int
nisplus_search_callback(const nis_name key,const nis_object * value,voidp opaquedata)141 nisplus_search_callback(const nis_name key, const nis_object *value, voidp opaquedata)
142 {
143   struct nisplus_search_callback_data *data = (struct nisplus_search_callback_data *) opaquedata;
144 
145   dlog("NISplus search callback for <%s>", ENTRY_VAL(value, 0));
146   dlog("NISplus search callback value <%s>", ENTRY_VAL(value, 1));
147 
148   data->value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
149   return TRUE;
150 }
151 
152 
153 /*
154  * Try to locate a key using NIS+.
155  */
156 int
nisplus_search(mnt_map * m,char * map,char * key,char ** val,time_t * tp)157 nisplus_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
158 {
159   nis_result *result;
160   int error = 0;
161   struct nisplus_search_callback_data data;
162   nis_name index;
163   char *org;		/* if map does not have ".org_dir" then append it */
164   size_t l;
165 
166   org = strstr(map, NISPLUS_ORGDIR);
167   if (org == NULL)
168     org = NISPLUS_ORGDIR;
169   else
170     org = "";
171 
172   /* make some room for the NIS index */
173   l = sizeof('[')		/* for opening selection criteria */
174     + sizeof(NISPLUS_KEY)
175     + strlen(key)
176     + sizeof(']')		/* for closing selection criteria */
177     + sizeof(',')		/* + 1 for , separator */
178     + strlen(map)
179     + sizeof(NISPLUS_ORGDIR);
180   index = xmalloc(l);
181   if (index == NULL) {
182     plog(XLOG_ERROR,
183 	 "Unable to create index %s: %s",
184 	 map,
185 	 strerror(ENOMEM));
186     return ENOMEM;
187   }
188   xsnprintf(index, l, "[%s%s],%s%s", NISPLUS_KEY, key, map, org);
189 
190   data.key = key;
191   data.value = NULL;
192 
193   dlog("NISplus search for %s", index);
194 
195   result = nis_list(index,
196 		    EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH,
197 		    (int (*)()) nisplus_search_callback,
198 		    &data);
199 
200   /* free off the NIS index */
201   XFREE(index);
202 
203   if (result == NULL) {
204     plog(XLOG_ERROR, "nisplus_search: %s: %s", map, strerror(ENOMEM));
205     return ENOMEM;
206   }
207 
208   /*
209    * Do something interesting with the return code
210    */
211   switch (result->status) {
212   case NIS_SUCCESS:
213   case NIS_CBRESULTS:
214 
215     if (data.value == NULL) {
216       nis_object *value = result->objects.objects_val;
217       dlog("NISplus search found <nothing>");
218       dlog("NISplus search for %s: %s(%d)",
219 	   map, nis_sperrno(result->status), result->status);
220 
221       if (value != NULL)
222 	data.value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
223     }
224     *val = data.value;
225 
226     if (*val) {
227       error = 0;
228       dlog("NISplus search found %s", *val);
229     } else {
230       error = ENOENT;
231       dlog("NISplus search found nothing");
232     }
233 
234     *tp = 0;
235     break;
236 
237   case NIS_NOSUCHNAME:
238     dlog("NISplus search returned %d", result->status);
239     error = ENOENT;
240     break;
241 
242   default:
243     plog(XLOG_ERROR, "nisplus_search: %s: %s", map, nis_sperrno(result->status));
244     error = EIO;
245     break;
246   }
247   nis_freeresult(result);
248 
249   return error;
250 }
251 
252 
253 int
nisplus_init(mnt_map * m,char * map,time_t * tp)254 nisplus_init(mnt_map *m, char *map, time_t *tp)
255 {
256   nis_result *result;
257   char *org;		/* if map does not have ".org_dir" then append it */
258   nis_name map_name;
259   int error = 0;
260   size_t l;
261 
262   org = strstr(map, NISPLUS_ORGDIR);
263   if (org == NULL)
264     org = NISPLUS_ORGDIR;
265   else
266     org = "";
267 
268   /* make some room for the NIS map_name */
269   l = strlen(map) + sizeof(NISPLUS_ORGDIR);
270   map_name = xmalloc(l);
271   if (map_name == NULL) {
272     plog(XLOG_ERROR,
273 	 "Unable to create map_name %s: %s",
274 	 map,
275 	 strerror(ENOMEM));
276     return ENOMEM;
277   }
278   xsnprintf(map_name, l, "%s%s", map, org);
279 
280   result = nis_lookup(map_name, (EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH));
281 
282   /* free off the NIS map_name */
283   XFREE(map_name);
284 
285   if (result == NULL) {
286     plog(XLOG_ERROR, "NISplus init <%s>: %s", map, strerror(ENOMEM));
287     return ENOMEM;
288   }
289 
290   if (result->status != NIS_SUCCESS) {
291     dlog("NISplus init <%s>: %s (%d)",
292 	 map, nis_sperrno(result->status), result->status);
293 
294     error = ENOENT;
295   }
296 
297   *tp = 0;			/* no time */
298   nis_freeresult(result);
299   return error;
300 }
301 
302 
303 int
nisplus_mtime(mnt_map * m,char * map,time_t * tp)304 nisplus_mtime(mnt_map *m, char *map, time_t *tp)
305 {
306   return nisplus_init(m,map, tp);
307 }
308