Update.
[glibc.git] / nis / ypclnt.c
blob98f1506241211c7dc51262514fbac85c22f361a1
1 /* Copyright (C) 1996, 1997, 1998 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.
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.
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.
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. */
20 #include <fcntl.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <rpc/rpc.h>
24 #include <rpcsvc/yp.h>
25 #include <rpcsvc/ypclnt.h>
26 #include <rpcsvc/ypupd.h>
27 #include <sys/uio.h>
28 #include <libc-lock.h>
30 #ifndef NIS_MAXNAMELEN
31 #define NIS_MAXNAMELEN 1024
32 #endif
34 /* This should only be defined on systems with a BSD compatible ypbind */
35 #ifndef BINDINGDIR
36 # define BINDINGDIR "/var/yp/binding"
37 #endif
39 struct dom_binding
41 struct dom_binding *dom_pnext;
42 char dom_domain[YPMAXDOMAIN + 1];
43 struct sockaddr_in dom_server_addr;
44 int dom_socket;
45 CLIENT *dom_client;
46 long int dom_vers;
48 typedef struct dom_binding dom_binding;
50 static struct timeval RPCTIMEOUT = {25, 0};
51 static struct timeval UDPTIMEOUT = {5, 0};
52 static int const MAXTRIES = 5;
53 static char __ypdomainname[NIS_MAXNAMELEN + 1] = "\0";
54 __libc_lock_define_initialized (static, ypbindlist_lock)
55 static dom_binding *__ypbindlist = NULL;
58 static int
59 __yp_bind (const char *domain, dom_binding **ypdb)
61 struct sockaddr_in clnt_saddr;
62 struct ypbind_resp ypbr;
63 dom_binding *ysd = NULL;
64 int clnt_sock;
65 CLIENT *client;
66 int is_new = 0;
67 int try;
69 if ((domain == NULL) || (strlen (domain) == 0))
70 return YPERR_BADARGS;
72 if (ypdb != NULL)
74 ysd = *ypdb;
75 while (ysd != NULL)
77 if (strcmp (domain, ysd->dom_domain) == 0)
78 break;
79 ysd = ysd->dom_pnext;
83 if (ysd == NULL)
85 is_new = 1;
86 ysd = (dom_binding *) calloc (1, sizeof *ysd);
87 ysd->dom_socket = -1;
88 ysd->dom_vers = -1;
91 try = 0;
95 try++;
96 if (try > MAXTRIES)
98 if (is_new)
99 free (ysd);
100 return YPERR_YPBIND;
103 #if USE_BINDINGDIR
104 if (ysd->dom_vers < 1 && try < 3)
106 char path[strlen (BINDINGDIR) + strlen (domain) + 10];
107 struct iovec vec[2];
108 u_short port;
109 int fd;
111 sprintf (path, "%s/%s.%ld", BINDINGDIR, domain, YPBINDVERS);
112 fd = open (path, O_RDONLY);
113 if (fd >= 0)
115 /* We have a binding file and could save a RPC call */
116 vec[0].iov_base = &port;
117 vec[0].iov_len = sizeof (port);
118 vec[1].iov_base = &ypbr;
119 vec[1].iov_len = sizeof (ypbr);
121 if (readv (fd, vec, 2) == vec[0].iov_len + vec[1].iov_len)
123 memset (&ysd->dom_server_addr, '\0',
124 sizeof ysd->dom_server_addr);
125 ysd->dom_server_addr.sin_family = AF_INET;
126 memcpy (&ysd->dom_server_addr.sin_port,
127 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
128 sizeof (ysd->dom_server_addr.sin_port));
129 memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
130 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
131 sizeof (ysd->dom_server_addr.sin_addr.s_addr));
132 ysd->dom_vers = YPVERS;
133 strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
134 ysd->dom_domain[YPMAXDOMAIN] = '\0';
136 close (fd);
139 #endif /* USE_BINDINGDIR */
141 if (ysd->dom_vers == -1)
143 if(ysd->dom_client)
145 clnt_destroy(ysd->dom_client);
146 ysd->dom_client = NULL;
147 ysd->dom_socket = -1;
149 memset (&clnt_saddr, '\0', sizeof clnt_saddr);
150 clnt_saddr.sin_family = AF_INET;
151 clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
152 clnt_sock = RPC_ANYSOCK;
153 client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
154 &clnt_sock, 0, 0);
155 if (client == NULL)
157 if (is_new)
158 free (ysd);
159 return YPERR_YPBIND;
162 ** Check the port number -- should be < IPPORT_RESERVED.
163 ** If not, it's possible someone has registered a bogus
164 ** ypbind with the portmapper and is trying to trick us.
166 if (ntohs(clnt_saddr.sin_port) >= IPPORT_RESERVED)
168 clnt_destroy(client);
169 if (is_new)
170 free(ysd);
171 return(YPERR_YPBIND);
174 if (clnt_call (client, YPBINDPROC_DOMAIN,
175 (xdrproc_t) xdr_domainname, (caddr_t) &domain,
176 (xdrproc_t) xdr_ypbind_resp,
177 (caddr_t) &ypbr, RPCTIMEOUT) != RPC_SUCCESS)
179 clnt_destroy (client);
180 close (clnt_sock);
181 if (is_new)
182 free (ysd);
183 return YPERR_YPBIND;
186 clnt_destroy (client);
187 close (clnt_sock);
189 if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
191 fprintf (stderr, _("YPBINDPROC_DOMAIN: %s\n"),
192 ypbinderr_string (ypbr.ypbind_resp_u.ypbind_error));
193 if (is_new)
194 free (ysd);
195 return YPERR_DOMAIN;
197 memset (&ysd->dom_server_addr, '\0', sizeof ysd->dom_server_addr);
198 ysd->dom_server_addr.sin_family = AF_INET;
199 memcpy (&ysd->dom_server_addr.sin_port,
200 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
201 sizeof (ysd->dom_server_addr.sin_port));
202 memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
203 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
204 sizeof (ysd->dom_server_addr.sin_addr.s_addr));
205 ysd->dom_vers = YPVERS;
206 strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
207 ysd->dom_domain[YPMAXDOMAIN] = '\0';
210 if (ysd->dom_client)
212 clnt_destroy (ysd->dom_client);
213 close (ysd->dom_socket);
215 ysd->dom_socket = RPC_ANYSOCK;
216 ysd->dom_client = clntudp_create (&ysd->dom_server_addr, YPPROG, YPVERS,
217 UDPTIMEOUT, &ysd->dom_socket);
218 if (ysd->dom_client == NULL)
219 ysd->dom_vers = -1;
222 while (ysd->dom_client == NULL);
224 /* If the program exists, close the socket */
225 if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
226 perror (_("fcntl: F_SETFD"));
228 if (is_new && ypdb != NULL)
230 ysd->dom_pnext = *ypdb;
231 *ypdb = ysd;
234 return YPERR_SUCCESS;
237 static void
238 __yp_unbind (dom_binding *ydb)
240 clnt_destroy (ydb->dom_client);
241 ydb->dom_client = NULL;
242 ydb->dom_socket = -1;
245 static int
246 do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
247 caddr_t req, xdrproc_t xres, caddr_t resp)
249 dom_binding *ydb = NULL;
250 bool_t use_ypbindlist = FALSE;
251 int try, status;
252 enum clnt_stat result;
254 try = 0;
255 status = YPERR_YPERR;
257 __libc_lock_lock (ypbindlist_lock);
258 if (__ypbindlist != NULL)
260 ydb = __ypbindlist;
261 while (ydb != NULL)
263 if (strcmp (domain, ydb->dom_domain) == 0)
264 break;
265 ydb = ydb->dom_pnext;
267 if (ydb != NULL)
268 use_ypbindlist = TRUE;
269 else
270 __libc_lock_unlock (ypbindlist_lock);
272 else
273 __libc_lock_unlock (ypbindlist_lock);
275 while (try < MAXTRIES && status != YPERR_SUCCESS)
277 if (__yp_bind (domain, &ydb) != 0)
279 if (use_ypbindlist)
280 __libc_lock_unlock (ypbindlist_lock);
281 return YPERR_DOMAIN;
284 result = clnt_call (ydb->dom_client, prog,
285 xargs, req, xres, resp, RPCTIMEOUT);
287 if (result != RPC_SUCCESS)
289 clnt_perror (ydb->dom_client, "do_ypcall: clnt_call");
290 ydb->dom_vers = -1;
291 if (!use_ypbindlist)
293 __yp_unbind (ydb);
294 free (ydb);
295 ydb = NULL;
297 status = YPERR_RPC;
299 else
300 status = YPERR_SUCCESS;
302 try++;
304 if (use_ypbindlist)
306 __libc_lock_unlock (ypbindlist_lock);
307 use_ypbindlist = FALSE;
309 else
310 if (ydb != NULL)
312 __yp_unbind (ydb);
313 free (ydb);
314 ydb = NULL;
317 return status;
321 yp_bind (const char *indomain)
323 int status;
325 __libc_lock_lock (ypbindlist_lock);
327 status = __yp_bind (indomain, &__ypbindlist);
329 __libc_lock_unlock (ypbindlist_lock);
331 return status;
334 void
335 yp_unbind (const char *indomain)
337 dom_binding *ydbptr, *ydbptr2;
339 __libc_lock_lock (ypbindlist_lock);
341 ydbptr2 = NULL;
342 ydbptr = __ypbindlist;
343 while (ydbptr != NULL)
345 if (strcmp (ydbptr->dom_domain, indomain) == 0)
347 dom_binding *work;
349 work = ydbptr;
350 if (ydbptr2 == NULL)
351 __ypbindlist = __ypbindlist->dom_pnext;
352 else
353 ydbptr2 = ydbptr->dom_pnext;
354 __yp_unbind (work);
355 free (work);
356 break;
358 ydbptr2 = ydbptr;
359 ydbptr = ydbptr->dom_pnext;
362 __libc_lock_unlock (ypbindlist_lock);
364 return;
367 __libc_lock_define_initialized (static, domainname_lock)
370 yp_get_default_domain (char **outdomain)
372 int result = YPERR_SUCCESS;;
373 *outdomain = NULL;
375 __libc_lock_lock (domainname_lock);
377 if (__ypdomainname[0] == '\0')
379 if (getdomainname (__ypdomainname, NIS_MAXNAMELEN))
380 result = YPERR_NODOM;
381 else
382 *outdomain = __ypdomainname;
384 else
385 *outdomain = __ypdomainname;
387 __libc_lock_unlock (domainname_lock);
389 return result;
393 __yp_check (char **domain)
395 char *unused;
397 if (__ypdomainname[0] == '\0')
398 if (yp_get_default_domain (&unused))
399 return 0;
400 else if (strcmp (__ypdomainname, "(none)") == 0)
401 return 0;
403 if (domain)
404 *domain = __ypdomainname;
406 if (yp_bind (__ypdomainname) == 0)
407 return 1;
408 return 0;
412 yp_match (const char *indomain, const char *inmap, const char *inkey,
413 const int inkeylen, char **outval, int *outvallen)
415 ypreq_key req;
416 ypresp_val resp;
417 enum clnt_stat result;
419 if (indomain == NULL || indomain[0] == '\0' ||
420 inmap == NULL || inmap[0] == '\0' ||
421 inkey == NULL || inkey[0] == '\0' || inkeylen <= 0)
422 return YPERR_BADARGS;
424 req.domain = (char *) indomain;
425 req.map = (char *) inmap;
426 req.key.keydat_val = (char *) inkey;
427 req.key.keydat_len = inkeylen;
429 *outval = NULL;
430 *outvallen = 0;
431 memset (&resp, '\0', sizeof (resp));
433 result = do_ypcall (indomain, YPPROC_MATCH, (xdrproc_t) xdr_ypreq_key,
434 (caddr_t) & req, (xdrproc_t) xdr_ypresp_val,
435 (caddr_t) & resp);
437 if (result != RPC_SUCCESS)
438 return YPERR_RPC;
439 if (resp.stat != YP_TRUE)
440 return ypprot_err (resp.stat);
442 *outvallen = resp.val.valdat_len;
443 *outval = malloc (*outvallen + 1);
444 memcpy (*outval, resp.val.valdat_val, *outvallen);
445 (*outval)[*outvallen] = '\0';
447 xdr_free ((xdrproc_t) xdr_ypresp_val, (char *) &resp);
449 return YPERR_SUCCESS;
453 yp_first (const char *indomain, const char *inmap, char **outkey,
454 int *outkeylen, char **outval, int *outvallen)
456 ypreq_nokey req;
457 ypresp_key_val resp;
458 enum clnt_stat result;
460 if (indomain == NULL || indomain[0] == '\0' ||
461 inmap == NULL || inmap[0] == '\0')
462 return YPERR_BADARGS;
464 req.domain = (char *) indomain;
465 req.map = (char *) inmap;
467 *outkey = *outval = NULL;
468 *outkeylen = *outvallen = 0;
469 memset (&resp, '\0', sizeof (resp));
471 result = do_ypcall (indomain, YPPROC_FIRST, (xdrproc_t) xdr_ypreq_nokey,
472 (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
473 (caddr_t) & resp);
475 if (result != RPC_SUCCESS)
476 return YPERR_RPC;
477 if (resp.stat != YP_TRUE)
478 return ypprot_err (resp.stat);
480 *outkeylen = resp.key.keydat_len;
481 *outkey = malloc (*outkeylen + 1);
482 memcpy (*outkey, resp.key.keydat_val, *outkeylen);
483 (*outkey)[*outkeylen] = '\0';
484 *outvallen = resp.val.valdat_len;
485 *outval = malloc (*outvallen + 1);
486 memcpy (*outval, resp.val.valdat_val, *outvallen);
487 (*outval)[*outvallen] = '\0';
489 xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
491 return YPERR_SUCCESS;
495 yp_next (const char *indomain, const char *inmap, const char *inkey,
496 const int inkeylen, char **outkey, int *outkeylen, char **outval,
497 int *outvallen)
499 ypreq_key req;
500 ypresp_key_val resp;
501 enum clnt_stat result;
503 if (indomain == NULL || indomain[0] == '\0' ||
504 inmap == NULL || inmap[0] == '\0' ||
505 inkeylen <= 0 || inkey == NULL || inkey[0] == '\0')
506 return YPERR_BADARGS;
508 req.domain = (char *) indomain;
509 req.map = (char *) inmap;
510 req.key.keydat_val = (char *) inkey;
511 req.key.keydat_len = inkeylen;
513 *outkey = *outval = NULL;
514 *outkeylen = *outvallen = 0;
515 memset (&resp, '\0', sizeof (resp));
517 result = do_ypcall (indomain, YPPROC_NEXT, (xdrproc_t) xdr_ypreq_key,
518 (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
519 (caddr_t) & resp);
521 if (result != RPC_SUCCESS)
522 return YPERR_RPC;
523 if (resp.stat != YP_TRUE)
524 return ypprot_err (resp.stat);
526 *outkeylen = resp.key.keydat_len;
527 *outkey = malloc (*outkeylen + 1);
528 memcpy (*outkey, resp.key.keydat_val, *outkeylen);
529 (*outkey)[*outkeylen] = '\0';
530 *outvallen = resp.val.valdat_len;
531 *outval = malloc (*outvallen + 1);
532 memcpy (*outval, resp.val.valdat_val, *outvallen);
533 (*outval)[*outvallen] = '\0';
535 xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
537 return YPERR_SUCCESS;
541 yp_master (const char *indomain, const char *inmap, char **outname)
543 ypreq_nokey req;
544 ypresp_master resp;
545 enum clnt_stat result;
547 if (indomain == NULL || indomain[0] == '\0' ||
548 inmap == NULL || inmap[0] == '\0')
549 return YPERR_BADARGS;
551 req.domain = (char *) indomain;
552 req.map = (char *) inmap;
554 memset (&resp, '\0', sizeof (ypresp_master));
556 result = do_ypcall (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey,
557 (caddr_t) & req, (xdrproc_t) xdr_ypresp_master, (caddr_t) & resp);
559 if (result != RPC_SUCCESS)
560 return YPERR_RPC;
561 if (resp.stat != YP_TRUE)
562 return ypprot_err (resp.stat);
564 *outname = strdup (resp.peer);
565 xdr_free ((xdrproc_t) xdr_ypresp_master, (char *) &resp);
567 return YPERR_SUCCESS;
571 yp_order (const char *indomain, const char *inmap, unsigned int *outorder)
573 struct ypreq_nokey req;
574 struct ypresp_order resp;
575 enum clnt_stat result;
577 if (indomain == NULL || indomain[0] == '\0' ||
578 inmap == NULL || inmap == '\0')
579 return YPERR_BADARGS;
581 req.domain = (char *) indomain;
582 req.map = (char *) inmap;
584 memset (&resp, '\0', sizeof (resp));
586 result = do_ypcall (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey,
587 (caddr_t) & req, (xdrproc_t) xdr_ypresp_order, (caddr_t) & resp);
589 if (result != RPC_SUCCESS)
590 return YPERR_RPC;
591 if (resp.stat != YP_TRUE)
592 return ypprot_err (resp.stat);
594 *outorder = resp.ordernum;
595 xdr_free ((xdrproc_t) xdr_ypresp_order, (char *) &resp);
597 return YPERR_SUCCESS;
600 static void *ypall_data;
601 static int (*ypall_foreach) __P ((int status, char *key, int keylen,
602 char *val, int vallen, char *data));
604 static bool_t
605 __xdr_ypresp_all (XDR * xdrs, u_long * objp)
607 while (1)
609 struct ypresp_all resp;
611 memset (&resp, '\0', sizeof (struct ypresp_all));
612 if (!xdr_ypresp_all (xdrs, &resp))
614 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
615 *objp = YP_YPERR;
616 return FALSE;
618 if (resp.more == 0)
620 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
621 *objp = YP_NOMORE;
622 return TRUE;
625 switch (resp.ypresp_all_u.val.stat)
627 case YP_TRUE:
629 char key[resp.ypresp_all_u.val.key.keydat_len + 1];
630 char val[resp.ypresp_all_u.val.val.valdat_len + 1];
631 int keylen = resp.ypresp_all_u.val.key.keydat_len;
632 int vallen = resp.ypresp_all_u.val.val.valdat_len;
634 *objp = YP_TRUE;
635 memcpy (key, resp.ypresp_all_u.val.key.keydat_val, keylen);
636 key[keylen] = '\0';
637 memcpy (val, resp.ypresp_all_u.val.val.valdat_val, vallen);
638 val[vallen] = '\0';
639 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
640 if ((*ypall_foreach) (*objp, key, keylen,
641 val, vallen, ypall_data))
642 return TRUE;
644 break;
645 case YP_NOMORE:
646 *objp = YP_NOMORE;
647 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
648 return TRUE;
649 break;
650 default:
651 *objp = resp.ypresp_all_u.val.stat;
652 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
653 return TRUE;
659 yp_all (const char *indomain, const char *inmap,
660 const struct ypall_callback *incallback)
662 struct ypreq_nokey req;
663 dom_binding *ydb = NULL;
664 int try, res;
665 enum clnt_stat result;
666 struct sockaddr_in clnt_sin;
667 CLIENT *clnt;
668 unsigned long status;
669 int clnt_sock;
671 if (indomain == NULL || indomain[0] == '\0' ||
672 inmap == NULL || inmap == '\0')
673 return YPERR_BADARGS;
675 try = 0;
676 res = YPERR_YPERR;
678 while (try < MAXTRIES && res != YPERR_SUCCESS)
680 if (__yp_bind (indomain, &ydb) != 0)
682 return YPERR_DOMAIN;
685 /* YPPROC_ALL get its own TCP channel to ypserv */
686 clnt_sock = RPC_ANYSOCK;
687 clnt_sin = ydb->dom_server_addr;
688 clnt_sin.sin_port = 0;
689 clnt = clnttcp_create (&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
690 if (clnt == NULL)
691 return YPERR_PMAP;
692 req.domain = (char *) indomain;
693 req.map = (char *) inmap;
695 ypall_foreach = incallback->foreach;
696 ypall_data = (void *) incallback->data;
698 result = clnt_call (clnt, YPPROC_ALL, (xdrproc_t) xdr_ypreq_nokey,
699 (caddr_t) &req, (xdrproc_t) __xdr_ypresp_all,
700 (caddr_t) &status, RPCTIMEOUT);
702 if (result != RPC_SUCCESS)
704 clnt_perror (clnt, "yp_all: clnt_call");
705 res = YPERR_RPC;
707 else
708 res = YPERR_SUCCESS;
710 clnt_destroy (clnt);
711 close (clnt_sock);
713 if (status != YP_NOMORE)
714 return ypprot_err (status);
715 try++;
718 return res;
722 yp_maplist (const char *indomain, struct ypmaplist **outmaplist)
724 struct ypresp_maplist resp;
725 enum clnt_stat result;
727 if (indomain == NULL || indomain[0] == '\0')
728 return YPERR_BADARGS;
730 memset (&resp, '\0', sizeof (resp));
732 result = do_ypcall (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname,
733 (caddr_t) & indomain, (xdrproc_t) xdr_ypresp_maplist, (caddr_t) & resp);
735 if (result != RPC_SUCCESS)
736 return YPERR_RPC;
737 if (resp.stat != YP_TRUE)
738 return ypprot_err (resp.stat);
740 *outmaplist = resp.maps;
741 /* We give the list not free, this will be done by ypserv
742 xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
744 return YPERR_SUCCESS;
747 const char *
748 yperr_string (const int error)
750 switch (error)
752 case YPERR_SUCCESS:
753 return _("Success");
754 case YPERR_BADARGS:
755 return _("Request arguments bad");
756 case YPERR_RPC:
757 return _("RPC failure on NIS operation");
758 case YPERR_DOMAIN:
759 return _("Can't bind to server which serves this domain");
760 case YPERR_MAP:
761 return _("No such map in server's domain");
762 case YPERR_KEY:
763 return _("No such key in map");
764 case YPERR_YPERR:
765 return _("Internal NIS error");
766 case YPERR_RESRC:
767 return _("Local resource allocation failure");
768 case YPERR_NOMORE:
769 return _("No more records in map database");
770 case YPERR_PMAP:
771 return _("Can't communicate with portmapper");
772 case YPERR_YPBIND:
773 return _("Can't communicate with ypbind");
774 case YPERR_YPSERV:
775 return _("Can't communicate with ypserv");
776 case YPERR_NODOM:
777 return _("Local domain name not set");
778 case YPERR_BADDB:
779 return _("NIS map data base is bad");
780 case YPERR_VERS:
781 return _("NIS client/server version mismatch - can't supply service");
782 case YPERR_ACCESS:
783 return _("Permission denied");
784 case YPERR_BUSY:
785 return _("Database is busy");
787 return _("Unknown NIS error code");
791 ypprot_err (const int code)
793 switch (code)
795 case YP_TRUE:
796 return YPERR_SUCCESS;
797 case YP_NOMORE:
798 return YPERR_NOMORE;
799 case YP_FALSE:
800 return YPERR_YPERR;
801 case YP_NOMAP:
802 return YPERR_MAP;
803 case YP_NODOM:
804 return YPERR_DOMAIN;
805 case YP_NOKEY:
806 return YPERR_KEY;
807 case YP_BADOP:
808 return YPERR_YPERR;
809 case YP_BADDB:
810 return YPERR_BADDB;
811 case YP_YPERR:
812 return YPERR_YPERR;
813 case YP_BADARGS:
814 return YPERR_BADARGS;
815 case YP_VERS:
816 return YPERR_VERS;
818 return YPERR_YPERR;
821 const char *
822 ypbinderr_string (const int error)
824 switch (error)
826 case 0:
827 return _("Success");
828 case YPBIND_ERR_ERR:
829 return _("Internal ypbind error");
830 case YPBIND_ERR_NOSERV:
831 return _("Domain not bound");
832 case YPBIND_ERR_RESC:
833 return _("System resource allocation failure");
834 default:
835 return _("Unknown ypbind error");
840 #define WINDOW 60
843 yp_update (char *domain, char *map, unsigned ypop,
844 char *key, int keylen, char *data, int datalen)
846 #if 0
847 union
849 ypupdate_args update_args;
850 ypdelete_args delete_args;
852 args;
853 xdrproc_t xdr_argument;
854 unsigned res = 0;
855 CLIENT *clnt;
856 char *master;
857 struct sockaddr saddr;
858 char servername[MAXNETNAMELEN + 1];
859 int r;
861 if (!domain || !map || !key || (ypop != YPOP_DELETE && !data))
862 return YPERR_BADARGS;
864 args.update_args.mapname = map;
865 args.update_args.key.yp_buf_len = keylen;
866 args.update_args.key.yp_buf_val = key;
867 args.update_args.datum.yp_buf_len = datalen;
868 args.update_args.datum.yp_buf_val = data;
870 if ((r = yp_master (domain, map, &master)) != 0)
871 return r;
873 if (!host2netname (servername, master, domain))
875 fputs (_("yp_update: cannot convert host to netname\n"), stderr);
876 return YPERR_YPERR;
879 if ((clnt = clnt_create (master, YPU_PROG, YPU_VERS, "tcp")) == NULL)
881 clnt_pcreateerror ("yp_update: clnt_create");
882 return YPERR_RPC;
885 if (!clnt_control (clnt, CLGET_SERVER_ADDR, (char *) &saddr))
887 fputs (_("yp_update: cannot get server address\n"), stderr);
888 return YPERR_RPC;
891 switch (ypop)
893 case YPOP_CHANGE:
894 case YPOP_INSERT:
895 case YPOP_STORE:
896 xdr_argument = (xdrproc_t) xdr_ypupdate_args;
897 break;
898 case YPOP_DELETE:
899 xdr_argument = (xdrproc_t) xdr_ypdelete_args;
900 break;
901 default:
902 return YPERR_BADARGS;
903 break;
906 clnt->cl_auth = authdes_create (servername, WINDOW, &saddr, NULL);
908 if (clnt->cl_auth == NULL)
909 clnt->cl_auth = authunix_create_default ();
911 again:
912 r = clnt_call (clnt, ypop, xdr_argument, (caddr_t) &args,
913 (xdrproc_t) xdr_u_int, (caddr_t) &res, RPCTIMEOUT);
915 if (r == RPC_AUTHERROR)
917 if (clnt->cl_auth->ah_cred.oa_flavor == AUTH_DES)
919 clnt->cl_auth = authunix_create_default ();
920 goto again;
922 else
923 return YPERR_ACCESS;
925 if (r != RPC_SUCCESS)
927 clnt_perror (clnt, "yp_update: clnt_call");
928 return YPERR_RPC;
930 return res;
931 #else
932 return YPERR_YPERR;
933 #endif