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