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