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