]> sourceware.org Git - glibc.git/blame - nis/ypclnt.c
Update.
[glibc.git] / nis / ypclnt.c
CommitLineData
af69217f 1/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
6259ec0d
UD
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19
ee74a442 20#include <errno.h>
cc3fa755 21#include <fcntl.h>
6259ec0d
UD
22#include <string.h>
23#include <unistd.h>
26dee9c4 24#include <rpc/rpc.h>
f21acc89 25#include <rpcsvc/nis.h>
6259ec0d
UD
26#include <rpcsvc/yp.h>
27#include <rpcsvc/ypclnt.h>
28#include <rpcsvc/ypupd.h>
9931ba24 29#include <sys/uio.h>
cc3fa755 30#include <bits/libc-lock.h>
6259ec0d 31
9931ba24
UD
32/* This should only be defined on systems with a BSD compatible ypbind */
33#ifndef BINDINGDIR
34# define BINDINGDIR "/var/yp/binding"
35#endif
36
6259ec0d
UD
37struct dom_binding
38 {
39 struct dom_binding *dom_pnext;
40 char dom_domain[YPMAXDOMAIN + 1];
41 struct sockaddr_in dom_server_addr;
42 int dom_socket;
43 CLIENT *dom_client;
44 long int dom_vers;
45 };
46typedef struct dom_binding dom_binding;
47
cc3fa755
UD
48static struct timeval RPCTIMEOUT = {25, 0};
49static struct timeval UDPTIMEOUT = {5, 0};
6259ec0d 50static int const MAXTRIES = 5;
f21acc89 51static char __ypdomainname[NIS_MAXNAMELEN + 1] = "\0";
6259ec0d
UD
52__libc_lock_define_initialized (static, ypbindlist_lock)
53static dom_binding *__ypbindlist = NULL;
54
f8b87ef0 55
6259ec0d 56static int
cc3fa755 57__yp_bind (const char *domain, dom_binding **ypdb)
6259ec0d
UD
58{
59 struct sockaddr_in clnt_saddr;
60 struct ypbind_resp ypbr;
cc3fa755 61 dom_binding *ysd = NULL;
6259ec0d
UD
62 int clnt_sock;
63 CLIENT *client;
64 int is_new = 0;
65 int try;
66
a53bad16 67 if ((domain == NULL) || (domain[0] == '\0'))
6259ec0d
UD
68 return YPERR_BADARGS;
69
cc3fa755 70 if (ypdb != NULL)
6259ec0d 71 {
cc3fa755
UD
72 ysd = *ypdb;
73 while (ysd != NULL)
74 {
75 if (strcmp (domain, ysd->dom_domain) == 0)
76 break;
77 ysd = ysd->dom_pnext;
78 }
6259ec0d
UD
79 }
80
81 if (ysd == NULL)
82 {
83 is_new = 1;
bd355af0 84 ysd = (dom_binding *) calloc (1, sizeof *ysd);
6259ec0d
UD
85 ysd->dom_socket = -1;
86 ysd->dom_vers = -1;
87 }
88
89 try = 0;
90
91 do
92 {
0c6cee5d 93 ++try;
6259ec0d
UD
94 if (try > MAXTRIES)
95 {
96 if (is_new)
97 free (ysd);
98 return YPERR_YPBIND;
99 }
100
9931ba24 101#if USE_BINDINGDIR
0c6cee5d 102 if (ysd->dom_vers < 1 && try == 1) /* Try binding dir only first time */
9931ba24
UD
103 {
104 char path[sizeof (BINDINGDIR) - 1 + strlen (domain) + 10];
105 struct iovec vec[2];
106 u_short port;
107 int fd;
108
109 sprintf (path, "%s/%s.%ld", BINDINGDIR, domain, YPBINDVERS);
110 fd = open (path, O_RDONLY);
111 if (fd >= 0)
112 {
113 /* We have a binding file and could save a RPC call */
114 vec[0].iov_base = &port;
115 vec[0].iov_len = sizeof (port);
116 vec[1].iov_base = &ypbr;
117 vec[1].iov_len = sizeof (ypbr);
118
119 if (readv (fd, vec, 2) == vec[0].iov_len + vec[1].iov_len)
120 {
121 memset (&ysd->dom_server_addr, '\0',
122 sizeof ysd->dom_server_addr);
123 ysd->dom_server_addr.sin_family = AF_INET;
124 memcpy (&ysd->dom_server_addr.sin_port,
125 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
126 sizeof (ysd->dom_server_addr.sin_port));
127 memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
128 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
129 sizeof (ysd->dom_server_addr.sin_addr.s_addr));
130 ysd->dom_vers = YPVERS;
131 strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
132 ysd->dom_domain[YPMAXDOMAIN] = '\0';
133 }
134 close (fd);
135 }
136 }
137#endif /* USE_BINDINGDIR */
138
6259ec0d 139 if (ysd->dom_vers == -1)
36a8586d 140 {
36a8586d
UD
141 if(ysd->dom_client)
142 {
143 clnt_destroy(ysd->dom_client);
144 ysd->dom_client = NULL;
145 ysd->dom_socket = -1;
146 }
6259ec0d
UD
147 memset (&clnt_saddr, '\0', sizeof clnt_saddr);
148 clnt_saddr.sin_family = AF_INET;
149 clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
150 clnt_sock = RPC_ANYSOCK;
151 client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
152 &clnt_sock, 0, 0);
153 if (client == NULL)
154 {
155 if (is_new)
156 free (ysd);
157 return YPERR_YPBIND;
158 }
159 /*
160 ** Check the port number -- should be < IPPORT_RESERVED.
161 ** If not, it's possible someone has registered a bogus
162 ** ypbind with the portmapper and is trying to trick us.
163 */
9931ba24 164 if (ntohs (clnt_saddr.sin_port) >= IPPORT_RESERVED)
6259ec0d 165 {
9931ba24 166 clnt_destroy (client);
6259ec0d 167 if (is_new)
9931ba24
UD
168 free (ysd);
169 return YPERR_YPBIND;
6259ec0d
UD
170 }
171
172 if (clnt_call (client, YPBINDPROC_DOMAIN,
3e5f5557 173 (xdrproc_t) xdr_domainname, (caddr_t) &domain,
6259ec0d 174 (xdrproc_t) xdr_ypbind_resp,
cc3fa755 175 (caddr_t) &ypbr, RPCTIMEOUT) != RPC_SUCCESS)
6259ec0d
UD
176 {
177 clnt_destroy (client);
3996f34b 178 close (clnt_sock);
6259ec0d
UD
179 if (is_new)
180 free (ysd);
181 return YPERR_YPBIND;
182 }
183
184 clnt_destroy (client);
3996f34b
UD
185 close (clnt_sock);
186
6259ec0d
UD
187 if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
188 {
cc3fa755
UD
189 fprintf (stderr, _("YPBINDPROC_DOMAIN: %s\n"),
190 ypbinderr_string (ypbr.ypbind_resp_u.ypbind_error));
191 if (is_new)
192 free (ysd);
193 return YPERR_DOMAIN;
194 }
6259ec0d
UD
195 memset (&ysd->dom_server_addr, '\0', sizeof ysd->dom_server_addr);
196 ysd->dom_server_addr.sin_family = AF_INET;
197 memcpy (&ysd->dom_server_addr.sin_port,
198 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
199 sizeof (ysd->dom_server_addr.sin_port));
200 memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
201 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
202 sizeof (ysd->dom_server_addr.sin_addr.s_addr));
203 ysd->dom_vers = YPVERS;
0d8733c4
UD
204 strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
205 ysd->dom_domain[YPMAXDOMAIN] = '\0';
6259ec0d
UD
206 }
207
208 if (ysd->dom_client)
3996f34b
UD
209 {
210 clnt_destroy (ysd->dom_client);
211 close (ysd->dom_socket);
212 }
6259ec0d
UD
213 ysd->dom_socket = RPC_ANYSOCK;
214 ysd->dom_client = clntudp_create (&ysd->dom_server_addr, YPPROG, YPVERS,
cc3fa755 215 UDPTIMEOUT, &ysd->dom_socket);
6259ec0d
UD
216 if (ysd->dom_client == NULL)
217 ysd->dom_vers = -1;
218
219 }
220 while (ysd->dom_client == NULL);
221
222 /* If the program exists, close the socket */
223 if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
d111572f 224 perror ("fcntl: F_SETFD");
6259ec0d 225
cc3fa755 226 if (is_new && ypdb != NULL)
6259ec0d 227 {
cc3fa755
UD
228 ysd->dom_pnext = *ypdb;
229 *ypdb = ysd;
6259ec0d
UD
230 }
231
6259ec0d
UD
232 return YPERR_SUCCESS;
233}
234
235static void
236__yp_unbind (dom_binding *ydb)
237{
238 clnt_destroy (ydb->dom_client);
239 ydb->dom_client = NULL;
240 ydb->dom_socket = -1;
241}
242
243static int
244do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
245 caddr_t req, xdrproc_t xres, caddr_t resp)
246{
247 dom_binding *ydb = NULL;
cc3fa755 248 bool_t use_ypbindlist = FALSE;
d111572f
UD
249 int try, status;
250 enum clnt_stat result;
a788b6c2 251 int saved_errno = errno;
6259ec0d
UD
252
253 try = 0;
d111572f 254 status = YPERR_YPERR;
6259ec0d 255
cc3fa755
UD
256 __libc_lock_lock (ypbindlist_lock);
257 if (__ypbindlist != NULL)
6259ec0d 258 {
cc3fa755
UD
259 ydb = __ypbindlist;
260 while (ydb != NULL)
261 {
262 if (strcmp (domain, ydb->dom_domain) == 0)
263 break;
264 ydb = ydb->dom_pnext;
265 }
266 if (ydb != NULL)
267 use_ypbindlist = TRUE;
268 else
269 __libc_lock_unlock (ypbindlist_lock);
270 }
271 else
272 __libc_lock_unlock (ypbindlist_lock);
6259ec0d 273
a588b67d 274 while (try < MAXTRIES && status != YPERR_SUCCESS)
cc3fa755 275 {
6259ec0d
UD
276 if (__yp_bind (domain, &ydb) != 0)
277 {
cc3fa755
UD
278 if (use_ypbindlist)
279 __libc_lock_unlock (ypbindlist_lock);
a788b6c2 280 __set_errno (saved_errno);
6259ec0d
UD
281 return YPERR_DOMAIN;
282 }
283
284 result = clnt_call (ydb->dom_client, prog,
cc3fa755 285 xargs, req, xres, resp, RPCTIMEOUT);
6259ec0d
UD
286
287 if (result != RPC_SUCCESS)
288 {
289 clnt_perror (ydb->dom_client, "do_ypcall: clnt_call");
290 ydb->dom_vers = -1;
cc3fa755
UD
291 if (!use_ypbindlist)
292 {
293 __yp_unbind (ydb);
294 free (ydb);
295 ydb = NULL;
296 }
d111572f 297 status = YPERR_RPC;;
6259ec0d 298 }
d111572f
UD
299 else
300 status = YPERR_SUCCESS;
301
6259ec0d
UD
302 try++;
303 }
cc3fa755
UD
304 if (use_ypbindlist)
305 {
306 __libc_lock_unlock (ypbindlist_lock);
307 use_ypbindlist = FALSE;
308 }
309 else
bd355af0
UD
310 if (ydb != NULL)
311 {
312 __yp_unbind (ydb);
313 free (ydb);
314 ydb = NULL;
315 }
6259ec0d 316
a788b6c2
UD
317 __set_errno (saved_errno);
318
d111572f 319 return status;
6259ec0d
UD
320}
321
322int
323yp_bind (const char *indomain)
324{
325 int status;
326
327 __libc_lock_lock (ypbindlist_lock);
328
cc3fa755 329 status = __yp_bind (indomain, &__ypbindlist);
6259ec0d
UD
330
331 __libc_lock_unlock (ypbindlist_lock);
332
333 return status;
334}
335
336void
337yp_unbind (const char *indomain)
338{
339 dom_binding *ydbptr, *ydbptr2;
340
341 __libc_lock_lock (ypbindlist_lock);
342
343 ydbptr2 = NULL;
344 ydbptr = __ypbindlist;
345 while (ydbptr != NULL)
346 {
347 if (strcmp (ydbptr->dom_domain, indomain) == 0)
348 {
349 dom_binding *work;
350
351 work = ydbptr;
352 if (ydbptr2 == NULL)
353 __ypbindlist = __ypbindlist->dom_pnext;
354 else
355 ydbptr2 = ydbptr->dom_pnext;
356 __yp_unbind (work);
357 free (work);
358 break;
359 }
360 ydbptr2 = ydbptr;
361 ydbptr = ydbptr->dom_pnext;
362 }
363
364 __libc_lock_unlock (ypbindlist_lock);
365
366 return;
367}
368
369__libc_lock_define_initialized (static, domainname_lock)
370
371int
372yp_get_default_domain (char **outdomain)
373{
374 int result = YPERR_SUCCESS;;
375 *outdomain = NULL;
376
377 __libc_lock_lock (domainname_lock);
378
379 if (__ypdomainname[0] == '\0')
380 {
f21acc89 381 if (getdomainname (__ypdomainname, NIS_MAXNAMELEN))
6259ec0d 382 result = YPERR_NODOM;
ee74a442
UD
383 else if (strcmp (__ypdomainname, "(none)") == 0)
384 {
385 /* If domainname is not set, some Systems will return "(none)" */
386 __ypdomainname[0] = '\0';
387 result = YPERR_NODOM;
388 }
6259ec0d
UD
389 else
390 *outdomain = __ypdomainname;
391 }
392 else
393 *outdomain = __ypdomainname;
394
395 __libc_lock_unlock (domainname_lock);
396
397 return result;
398}
399
400int
401__yp_check (char **domain)
402{
403 char *unused;
404
405 if (__ypdomainname[0] == '\0')
406 if (yp_get_default_domain (&unused))
407 return 0;
6259ec0d
UD
408
409 if (domain)
410 *domain = __ypdomainname;
411
412 if (yp_bind (__ypdomainname) == 0)
413 return 1;
414 return 0;
415}
416
417int
418yp_match (const char *indomain, const char *inmap, const char *inkey,
419 const int inkeylen, char **outval, int *outvallen)
420{
421 ypreq_key req;
422 ypresp_val resp;
d111572f 423 enum clnt_stat result;
6259ec0d
UD
424
425 if (indomain == NULL || indomain[0] == '\0' ||
426 inmap == NULL || inmap[0] == '\0' ||
427 inkey == NULL || inkey[0] == '\0' || inkeylen <= 0)
428 return YPERR_BADARGS;
429
68dbb3a6
UD
430 req.domain = (char *) indomain;
431 req.map = (char *) inmap;
432 req.key.keydat_val = (char *) inkey;
6259ec0d
UD
433 req.key.keydat_len = inkeylen;
434
435 *outval = NULL;
436 *outvallen = 0;
437 memset (&resp, '\0', sizeof (resp));
438
439 result = do_ypcall (indomain, YPPROC_MATCH, (xdrproc_t) xdr_ypreq_key,
440 (caddr_t) & req, (xdrproc_t) xdr_ypresp_val,
441 (caddr_t) & resp);
442
4bca4c17
UD
443 if (result != YPERR_SUCCESS)
444 return result;
6259ec0d
UD
445 if (resp.stat != YP_TRUE)
446 return ypprot_err (resp.stat);
447
448 *outvallen = resp.val.valdat_len;
449 *outval = malloc (*outvallen + 1);
450 memcpy (*outval, resp.val.valdat_val, *outvallen);
451 (*outval)[*outvallen] = '\0';
452
453 xdr_free ((xdrproc_t) xdr_ypresp_val, (char *) &resp);
454
455 return YPERR_SUCCESS;
456}
457
458int
459yp_first (const char *indomain, const char *inmap, char **outkey,
460 int *outkeylen, char **outval, int *outvallen)
461{
462 ypreq_nokey req;
463 ypresp_key_val resp;
d111572f 464 enum clnt_stat result;
6259ec0d
UD
465
466 if (indomain == NULL || indomain[0] == '\0' ||
467 inmap == NULL || inmap[0] == '\0')
468 return YPERR_BADARGS;
469
68dbb3a6
UD
470 req.domain = (char *) indomain;
471 req.map = (char *) inmap;
6259ec0d
UD
472
473 *outkey = *outval = NULL;
474 *outkeylen = *outvallen = 0;
475 memset (&resp, '\0', sizeof (resp));
476
477 result = do_ypcall (indomain, YPPROC_FIRST, (xdrproc_t) xdr_ypreq_nokey,
478 (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
479 (caddr_t) & resp);
480
481 if (result != RPC_SUCCESS)
d111572f 482 return YPERR_RPC;
6259ec0d
UD
483 if (resp.stat != YP_TRUE)
484 return ypprot_err (resp.stat);
485
486 *outkeylen = resp.key.keydat_len;
487 *outkey = malloc (*outkeylen + 1);
488 memcpy (*outkey, resp.key.keydat_val, *outkeylen);
489 (*outkey)[*outkeylen] = '\0';
490 *outvallen = resp.val.valdat_len;
491 *outval = malloc (*outvallen + 1);
492 memcpy (*outval, resp.val.valdat_val, *outvallen);
493 (*outval)[*outvallen] = '\0';
494
495 xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
496
497 return YPERR_SUCCESS;
498}
499
500int
501yp_next (const char *indomain, const char *inmap, const char *inkey,
502 const int inkeylen, char **outkey, int *outkeylen, char **outval,
503 int *outvallen)
504{
505 ypreq_key req;
506 ypresp_key_val resp;
d111572f 507 enum clnt_stat result;
6259ec0d
UD
508
509 if (indomain == NULL || indomain[0] == '\0' ||
510 inmap == NULL || inmap[0] == '\0' ||
511 inkeylen <= 0 || inkey == NULL || inkey[0] == '\0')
512 return YPERR_BADARGS;
513
68dbb3a6
UD
514 req.domain = (char *) indomain;
515 req.map = (char *) inmap;
516 req.key.keydat_val = (char *) inkey;
6259ec0d
UD
517 req.key.keydat_len = inkeylen;
518
519 *outkey = *outval = NULL;
520 *outkeylen = *outvallen = 0;
521 memset (&resp, '\0', sizeof (resp));
522
523 result = do_ypcall (indomain, YPPROC_NEXT, (xdrproc_t) xdr_ypreq_key,
524 (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
525 (caddr_t) & resp);
526
4bca4c17
UD
527 if (result != YPERR_SUCCESS)
528 return result;
6259ec0d
UD
529 if (resp.stat != YP_TRUE)
530 return ypprot_err (resp.stat);
531
532 *outkeylen = resp.key.keydat_len;
533 *outkey = malloc (*outkeylen + 1);
534 memcpy (*outkey, resp.key.keydat_val, *outkeylen);
535 (*outkey)[*outkeylen] = '\0';
536 *outvallen = resp.val.valdat_len;
537 *outval = malloc (*outvallen + 1);
538 memcpy (*outval, resp.val.valdat_val, *outvallen);
539 (*outval)[*outvallen] = '\0';
540
541 xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
542
543 return YPERR_SUCCESS;
544}
545
546int
547yp_master (const char *indomain, const char *inmap, char **outname)
548{
549 ypreq_nokey req;
550 ypresp_master resp;
d111572f 551 enum clnt_stat result;
6259ec0d
UD
552
553 if (indomain == NULL || indomain[0] == '\0' ||
554 inmap == NULL || inmap[0] == '\0')
555 return YPERR_BADARGS;
556
68dbb3a6
UD
557 req.domain = (char *) indomain;
558 req.map = (char *) inmap;
6259ec0d
UD
559
560 memset (&resp, '\0', sizeof (ypresp_master));
561
562 result = do_ypcall (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey,
563 (caddr_t) & req, (xdrproc_t) xdr_ypresp_master, (caddr_t) & resp);
564
4bca4c17
UD
565 if (result != YPERR_SUCCESS)
566 return result;
6259ec0d
UD
567 if (resp.stat != YP_TRUE)
568 return ypprot_err (resp.stat);
569
570 *outname = strdup (resp.peer);
571 xdr_free ((xdrproc_t) xdr_ypresp_master, (char *) &resp);
572
d111572f 573 return *outname == NULL ? YPERR_YPERR : YPERR_SUCCESS;
6259ec0d
UD
574}
575
576int
577yp_order (const char *indomain, const char *inmap, unsigned int *outorder)
578{
579 struct ypreq_nokey req;
580 struct ypresp_order resp;
d111572f 581 enum clnt_stat result;
6259ec0d
UD
582
583 if (indomain == NULL || indomain[0] == '\0' ||
584 inmap == NULL || inmap == '\0')
585 return YPERR_BADARGS;
586
68dbb3a6
UD
587 req.domain = (char *) indomain;
588 req.map = (char *) inmap;
6259ec0d
UD
589
590 memset (&resp, '\0', sizeof (resp));
591
592 result = do_ypcall (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey,
593 (caddr_t) & req, (xdrproc_t) xdr_ypresp_order, (caddr_t) & resp);
594
4bca4c17
UD
595 if (result != YPERR_SUCCESS)
596 return result;
6259ec0d
UD
597 if (resp.stat != YP_TRUE)
598 return ypprot_err (resp.stat);
599
600 *outorder = resp.ordernum;
601 xdr_free ((xdrproc_t) xdr_ypresp_order, (char *) &resp);
602
603 return YPERR_SUCCESS;
604}
605
606static void *ypall_data;
3e5f5557
UD
607static int (*ypall_foreach) __P ((int status, char *key, int keylen,
608 char *val, int vallen, char *data));
6259ec0d
UD
609
610static bool_t
611__xdr_ypresp_all (XDR * xdrs, u_long * objp)
612{
613 while (1)
614 {
615 struct ypresp_all resp;
616
617 memset (&resp, '\0', sizeof (struct ypresp_all));
618 if (!xdr_ypresp_all (xdrs, &resp))
619 {
620 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
621 *objp = YP_YPERR;
d111572f 622 return FALSE;
6259ec0d
UD
623 }
624 if (resp.more == 0)
625 {
626 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
627 *objp = YP_NOMORE;
d111572f 628 return TRUE;
6259ec0d
UD
629 }
630
631 switch (resp.ypresp_all_u.val.stat)
632 {
633 case YP_TRUE:
634 {
635 char key[resp.ypresp_all_u.val.key.keydat_len + 1];
636 char val[resp.ypresp_all_u.val.val.valdat_len + 1];
637 int keylen = resp.ypresp_all_u.val.key.keydat_len;
638 int vallen = resp.ypresp_all_u.val.val.valdat_len;
639
640 *objp = YP_TRUE;
641 memcpy (key, resp.ypresp_all_u.val.key.keydat_val, keylen);
642 key[keylen] = '\0';
643 memcpy (val, resp.ypresp_all_u.val.val.valdat_val, vallen);
644 val[vallen] = '\0';
645 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
646 if ((*ypall_foreach) (*objp, key, keylen,
647 val, vallen, ypall_data))
648 return TRUE;
649 }
650 break;
651 case YP_NOMORE:
652 *objp = YP_NOMORE;
653 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
654 return TRUE;
655 break;
656 default:
657 *objp = resp.ypresp_all_u.val.stat;
658 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
659 return TRUE;
660 }
661 }
662}
663
664int
665yp_all (const char *indomain, const char *inmap,
666 const struct ypall_callback *incallback)
667{
668 struct ypreq_nokey req;
cc3fa755 669 dom_binding *ydb = NULL;
d111572f
UD
670 int try, res;
671 enum clnt_stat result;
6259ec0d
UD
672 struct sockaddr_in clnt_sin;
673 CLIENT *clnt;
674 unsigned long status;
675 int clnt_sock;
a788b6c2 676 int saved_errno = errno;
6259ec0d
UD
677
678 if (indomain == NULL || indomain[0] == '\0' ||
679 inmap == NULL || inmap == '\0')
680 return YPERR_BADARGS;
681
682 try = 0;
d111572f 683 res = YPERR_YPERR;
6259ec0d 684
d111572f 685 while (try < MAXTRIES && res != YPERR_SUCCESS)
6259ec0d 686 {
6259ec0d
UD
687 if (__yp_bind (indomain, &ydb) != 0)
688 {
a788b6c2 689 __set_errno (saved_errno);
6259ec0d
UD
690 return YPERR_DOMAIN;
691 }
692
693 /* YPPROC_ALL get its own TCP channel to ypserv */
694 clnt_sock = RPC_ANYSOCK;
695 clnt_sin = ydb->dom_server_addr;
696 clnt_sin.sin_port = 0;
697 clnt = clnttcp_create (&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
698 if (clnt == NULL)
a788b6c2
UD
699 {
700 __set_errno (saved_errno);
701 return YPERR_PMAP;
702 }
68dbb3a6
UD
703 req.domain = (char *) indomain;
704 req.map = (char *) inmap;
6259ec0d
UD
705
706 ypall_foreach = incallback->foreach;
707 ypall_data = (void *) incallback->data;
708
3e5f5557
UD
709 result = clnt_call (clnt, YPPROC_ALL, (xdrproc_t) xdr_ypreq_nokey,
710 (caddr_t) &req, (xdrproc_t) __xdr_ypresp_all,
cc3fa755 711 (caddr_t) &status, RPCTIMEOUT);
6259ec0d
UD
712
713 if (result != RPC_SUCCESS)
714 {
d111572f
UD
715 clnt_perror (clnt, "yp_all: clnt_call");
716 res = YPERR_RPC;
6259ec0d
UD
717 }
718 else
d111572f
UD
719 res = YPERR_SUCCESS;
720
721 clnt_destroy (clnt);
722 close (clnt_sock);
6259ec0d 723
6259ec0d 724 if (status != YP_NOMORE)
a788b6c2
UD
725 {
726 __set_errno (saved_errno);
727 return ypprot_err (status);
728 }
729 ++try;
6259ec0d
UD
730 }
731
a788b6c2
UD
732 __set_errno (saved_errno);
733
d111572f 734 return res;
6259ec0d
UD
735}
736
737int
738yp_maplist (const char *indomain, struct ypmaplist **outmaplist)
739{
740 struct ypresp_maplist resp;
d111572f 741 enum clnt_stat result;
6259ec0d
UD
742
743 if (indomain == NULL || indomain[0] == '\0')
744 return YPERR_BADARGS;
745
746 memset (&resp, '\0', sizeof (resp));
747
748 result = do_ypcall (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname,
749 (caddr_t) & indomain, (xdrproc_t) xdr_ypresp_maplist, (caddr_t) & resp);
750
4bca4c17
UD
751 if (result != YPERR_SUCCESS)
752 return result;
6259ec0d
UD
753 if (resp.stat != YP_TRUE)
754 return ypprot_err (resp.stat);
755
756 *outmaplist = resp.maps;
757 /* We give the list not free, this will be done by ypserv
758 xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
759
760 return YPERR_SUCCESS;
761}
762
763const char *
764yperr_string (const int error)
765{
766 switch (error)
767 {
768 case YPERR_SUCCESS:
769 return _("Success");
770 case YPERR_BADARGS:
771 return _("Request arguments bad");
772 case YPERR_RPC:
773 return _("RPC failure on NIS operation");
774 case YPERR_DOMAIN:
775 return _("Can't bind to server which serves this domain");
776 case YPERR_MAP:
777 return _("No such map in server's domain");
778 case YPERR_KEY:
779 return _("No such key in map");
780 case YPERR_YPERR:
781 return _("Internal NIS error");
782 case YPERR_RESRC:
783 return _("Local resource allocation failure");
784 case YPERR_NOMORE:
785 return _("No more records in map database");
786 case YPERR_PMAP:
787 return _("Can't communicate with portmapper");
788 case YPERR_YPBIND:
789 return _("Can't communicate with ypbind");
790 case YPERR_YPSERV:
791 return _("Can't communicate with ypserv");
792 case YPERR_NODOM:
793 return _("Local domain name not set");
794 case YPERR_BADDB:
bd355af0 795 return _("NIS map database is bad");
6259ec0d
UD
796 case YPERR_VERS:
797 return _("NIS client/server version mismatch - can't supply service");
798 case YPERR_ACCESS:
799 return _("Permission denied");
800 case YPERR_BUSY:
801 return _("Database is busy");
802 }
803 return _("Unknown NIS error code");
804}
805
806int
807ypprot_err (const int code)
808{
809 switch (code)
810 {
811 case YP_TRUE:
812 return YPERR_SUCCESS;
813 case YP_NOMORE:
814 return YPERR_NOMORE;
815 case YP_FALSE:
816 return YPERR_YPERR;
817 case YP_NOMAP:
818 return YPERR_MAP;
819 case YP_NODOM:
820 return YPERR_DOMAIN;
821 case YP_NOKEY:
822 return YPERR_KEY;
823 case YP_BADOP:
824 return YPERR_YPERR;
825 case YP_BADDB:
826 return YPERR_BADDB;
827 case YP_YPERR:
828 return YPERR_YPERR;
829 case YP_BADARGS:
830 return YPERR_BADARGS;
831 case YP_VERS:
832 return YPERR_VERS;
833 }
834 return YPERR_YPERR;
835}
836
837const char *
838ypbinderr_string (const int error)
839{
840 switch (error)
841 {
842 case 0:
843 return _("Success");
844 case YPBIND_ERR_ERR:
845 return _("Internal ypbind error");
846 case YPBIND_ERR_NOSERV:
847 return _("Domain not bound");
848 case YPBIND_ERR_RESC:
849 return _("System resource allocation failure");
850 default:
851 return _("Unknown ypbind error");
852 }
853}
854
855
856#define WINDOW 60
857
858int
859yp_update (char *domain, char *map, unsigned ypop,
860 char *key, int keylen, char *data, int datalen)
861{
6259ec0d
UD
862 union
863 {
864 ypupdate_args update_args;
865 ypdelete_args delete_args;
866 }
867 args;
868 xdrproc_t xdr_argument;
869 unsigned res = 0;
870 CLIENT *clnt;
871 char *master;
872 struct sockaddr saddr;
873 char servername[MAXNETNAMELEN + 1];
874 int r;
875
876 if (!domain || !map || !key || (ypop != YPOP_DELETE && !data))
877 return YPERR_BADARGS;
878
879 args.update_args.mapname = map;
880 args.update_args.key.yp_buf_len = keylen;
881 args.update_args.key.yp_buf_val = key;
882 args.update_args.datum.yp_buf_len = datalen;
883 args.update_args.datum.yp_buf_val = data;
884
885 if ((r = yp_master (domain, map, &master)) != 0)
886 return r;
887
888 if (!host2netname (servername, master, domain))
889 {
890 fputs (_("yp_update: cannot convert host to netname\n"), stderr);
891 return YPERR_YPERR;
892 }
893
894 if ((clnt = clnt_create (master, YPU_PROG, YPU_VERS, "tcp")) == NULL)
895 {
896 clnt_pcreateerror ("yp_update: clnt_create");
897 return YPERR_RPC;
898 }
899
900 if (!clnt_control (clnt, CLGET_SERVER_ADDR, (char *) &saddr))
901 {
902 fputs (_("yp_update: cannot get server address\n"), stderr);
903 return YPERR_RPC;
904 }
905
906 switch (ypop)
907 {
908 case YPOP_CHANGE:
909 case YPOP_INSERT:
910 case YPOP_STORE:
911 xdr_argument = (xdrproc_t) xdr_ypupdate_args;
912 break;
913 case YPOP_DELETE:
914 xdr_argument = (xdrproc_t) xdr_ypdelete_args;
915 break;
916 default:
917 return YPERR_BADARGS;
918 break;
919 }
920
921 clnt->cl_auth = authdes_create (servername, WINDOW, &saddr, NULL);
922
923 if (clnt->cl_auth == NULL)
924 clnt->cl_auth = authunix_create_default ();
925
926again:
26dee9c4 927 r = clnt_call (clnt, ypop, xdr_argument, (caddr_t) &args,
cc3fa755 928 (xdrproc_t) xdr_u_int, (caddr_t) &res, RPCTIMEOUT);
6259ec0d
UD
929
930 if (r == RPC_AUTHERROR)
931 {
932 if (clnt->cl_auth->ah_cred.oa_flavor == AUTH_DES)
933 {
934 clnt->cl_auth = authunix_create_default ();
935 goto again;
936 }
937 else
938 return YPERR_ACCESS;
939 }
940 if (r != RPC_SUCCESS)
941 {
942 clnt_perror (clnt, "yp_update: clnt_call");
943 return YPERR_RPC;
944 }
945 return res;
6259ec0d 946}
This page took 0.136936 seconds and 5 git commands to generate.