1 /* Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@suse.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 Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 #include <rpcsvc/nis.h>
27 #include <rpcsvc/yp.h>
28 #include <rpcsvc/ypclnt.h>
29 #include <rpcsvc/ypupd.h>
31 #include <bits/libc-lock.h>
33 /* This should only be defined on systems with a BSD compatible ypbind */
35 # define BINDINGDIR "/var/yp/binding"
40 struct dom_binding
*dom_pnext
;
41 char dom_domain
[YPMAXDOMAIN
+ 1];
42 struct sockaddr_in dom_server_addr
;
46 typedef struct dom_binding dom_binding
;
48 static struct timeval RPCTIMEOUT
= {25, 0};
49 static struct timeval UDPTIMEOUT
= {5, 0};
50 static int const MAXTRIES
= 2;
51 static char __ypdomainname
[NIS_MAXNAMELEN
+ 1] = "\0";
52 __libc_lock_define_initialized (static, ypbindlist_lock
)
53 static dom_binding
*__ypbindlist
= NULL
;
57 __yp_bind (const char *domain
, dom_binding
**ypdb
)
59 struct sockaddr_in clnt_saddr
;
60 struct ypbind_resp ypbr
;
61 dom_binding
*ysd
= NULL
;
66 if (domain
== NULL
|| domain
[0] == '\0')
72 if (strcmp (domain
, ysd
->dom_domain
) == 0)
80 ysd
= (dom_binding
*) calloc (1, sizeof *ysd
);
81 if (__builtin_expect (ysd
== NULL
, 0))
86 if (ysd
->dom_client
== NULL
)
88 /* Try binding dir at first if we have no binding */
89 char path
[sizeof (BINDINGDIR
) + strlen (domain
) + 10];
94 sprintf (path
, "%s/%s.%d", BINDINGDIR
, domain
, YPBINDVERS
);
95 fd
= open (path
, O_RDONLY
);
98 /* We have a binding file and could save a RPC call */
99 vec
[0].iov_base
= &port
;
100 vec
[0].iov_len
= sizeof (port
);
101 vec
[1].iov_base
= &ypbr
;
102 vec
[1].iov_len
= sizeof (ypbr
);
104 if (readv (fd
, vec
, 2) == sizeof (port
) + sizeof (ypbr
))
106 ysd
->dom_server_addr
.sin_family
= AF_INET
;
107 memcpy (&ysd
->dom_server_addr
.sin_port
,
108 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_port
,
109 sizeof (ysd
->dom_server_addr
.sin_port
));
110 memcpy (&ysd
->dom_server_addr
.sin_addr
.s_addr
,
111 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_addr
,
112 sizeof (ysd
->dom_server_addr
.sin_addr
.s_addr
));
113 strncpy (ysd
->dom_domain
, domain
, YPMAXDOMAIN
);
114 ysd
->dom_domain
[YPMAXDOMAIN
] = '\0';
116 ysd
->dom_socket
= RPC_ANYSOCK
;
117 ysd
->dom_client
= clntudp_create (&ysd
->dom_server_addr
, YPPROG
,
121 if (ysd
->dom_client
!= NULL
)
122 /* If the program exits, close the socket */
123 if (fcntl (ysd
->dom_socket
, F_SETFD
, 1) == -1)
124 perror ("fcntl: F_SETFD");
129 #endif /* USE_BINDINGDIR */
131 if (ysd
->dom_client
== NULL
)
133 memset (&clnt_saddr
, '\0', sizeof clnt_saddr
);
134 clnt_saddr
.sin_family
= AF_INET
;
135 clnt_saddr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
136 clnt_sock
= RPC_ANYSOCK
;
137 client
= clnttcp_create (&clnt_saddr
, YPBINDPROG
, YPBINDVERS
,
145 /* Check the port number -- should be < IPPORT_RESERVED.
146 If not, it's possible someone has registered a bogus
147 ypbind with the portmapper and is trying to trick us. */
148 if (ntohs (clnt_saddr
.sin_port
) >= IPPORT_RESERVED
)
150 clnt_destroy (client
);
156 if (clnt_call (client
, YPBINDPROC_DOMAIN
,
157 (xdrproc_t
) xdr_domainname
, (caddr_t
) &domain
,
158 (xdrproc_t
) xdr_ypbind_resp
,
159 (caddr_t
) &ypbr
, RPCTIMEOUT
) != RPC_SUCCESS
)
161 clnt_destroy (client
);
167 clnt_destroy (client
);
169 if (ypbr
.ypbind_status
!= YPBIND_SUCC_VAL
)
171 fprintf (stderr
, _("YPBINDPROC_DOMAIN: %s\n"),
172 ypbinderr_string (ypbr
.ypbind_resp_u
.ypbind_error
));
177 memset (&ysd
->dom_server_addr
, '\0', sizeof ysd
->dom_server_addr
);
178 ysd
->dom_server_addr
.sin_family
= AF_INET
;
179 memcpy (&ysd
->dom_server_addr
.sin_port
,
180 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_port
,
181 sizeof (ysd
->dom_server_addr
.sin_port
));
182 memcpy (&ysd
->dom_server_addr
.sin_addr
.s_addr
,
183 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_addr
,
184 sizeof (ysd
->dom_server_addr
.sin_addr
.s_addr
));
185 strncpy (ysd
->dom_domain
, domain
, YPMAXDOMAIN
);
186 ysd
->dom_domain
[YPMAXDOMAIN
] = '\0';
188 ysd
->dom_socket
= RPC_ANYSOCK
;
189 ysd
->dom_client
= clntudp_create (&ysd
->dom_server_addr
, YPPROG
, YPVERS
,
190 UDPTIMEOUT
, &ysd
->dom_socket
);
192 if (ysd
->dom_client
!= NULL
)
193 /* If the program exits, close the socket */
194 if (fcntl (ysd
->dom_socket
, F_SETFD
, 1) == -1)
195 perror ("fcntl: F_SETFD");
198 if (ysd
->dom_client
== NULL
)
207 ysd
->dom_pnext
= *ypdb
;
211 return YPERR_SUCCESS
;
215 __yp_unbind (dom_binding
*ydb
)
217 clnt_destroy (ydb
->dom_client
);
218 ydb
->dom_client
= NULL
;
223 yp_bind (const char *indomain
)
227 __libc_lock_lock (ypbindlist_lock
);
229 status
= __yp_bind (indomain
, &__ypbindlist
);
231 __libc_lock_unlock (ypbindlist_lock
);
237 yp_unbind_locked (const char *indomain
)
239 dom_binding
*ydbptr
, *ydbptr2
;
242 ydbptr
= __ypbindlist
;
244 while (ydbptr
!= NULL
)
246 if (strcmp (ydbptr
->dom_domain
, indomain
) == 0)
252 __ypbindlist
= __ypbindlist
->dom_pnext
;
254 ydbptr2
= ydbptr
->dom_pnext
;
259 ydbptr
= ydbptr
->dom_pnext
;
264 yp_unbind (const char *indomain
)
266 __libc_lock_lock (ypbindlist_lock
);
268 yp_unbind_locked (indomain
);
270 __libc_lock_unlock (ypbindlist_lock
);
276 do_ypcall (const char *domain
, u_long prog
, xdrproc_t xargs
,
277 caddr_t req
, xdrproc_t xres
, caddr_t resp
)
279 dom_binding
*ydb
= NULL
;
280 bool_t use_ypbindlist
= FALSE
;
282 enum clnt_stat result
;
283 int saved_errno
= errno
;
286 status
= YPERR_YPERR
;
288 __libc_lock_lock (ypbindlist_lock
);
289 if (__ypbindlist
!= NULL
)
294 if (strcmp (domain
, ydb
->dom_domain
) == 0)
296 ydb
= ydb
->dom_pnext
;
299 use_ypbindlist
= TRUE
;
301 __libc_lock_unlock (ypbindlist_lock
);
304 __libc_lock_unlock (ypbindlist_lock
);
306 while (try < MAXTRIES
&& status
!= YPERR_SUCCESS
)
308 if (__yp_bind (domain
, &ydb
) != 0)
311 __libc_lock_unlock (ypbindlist_lock
);
312 __set_errno (saved_errno
);
316 result
= clnt_call (ydb
->dom_client
, prog
,
317 xargs
, req
, xres
, resp
, RPCTIMEOUT
);
319 if (result
!= RPC_SUCCESS
)
321 /* Don't print the error message on the first try. It
322 could be that we use cached data which is now invalid. */
324 clnt_perror (ydb
->dom_client
, "do_ypcall: clnt_call");
328 /* We use ypbindlist, and the old cached data is
329 invalid. unbind now and create a new binding */
330 yp_unbind_locked (domain
);
331 __libc_lock_unlock (ypbindlist_lock
);
332 use_ypbindlist
= FALSE
;
341 status
= YPERR_SUCCESS
;
347 __libc_lock_unlock (ypbindlist_lock
);
348 use_ypbindlist
= FALSE
;
354 __set_errno (saved_errno
);
360 __libc_lock_define_initialized (static, domainname_lock
)
363 yp_get_default_domain (char **outdomain
)
365 int result
= YPERR_SUCCESS
;;
368 __libc_lock_lock (domainname_lock
);
370 if (__ypdomainname
[0] == '\0')
372 if (getdomainname (__ypdomainname
, NIS_MAXNAMELEN
))
373 result
= YPERR_NODOM
;
374 else if (strcmp (__ypdomainname
, "(none)") == 0)
376 /* If domainname is not set, some systems will return "(none)" */
377 __ypdomainname
[0] = '\0';
378 result
= YPERR_NODOM
;
381 *outdomain
= __ypdomainname
;
384 *outdomain
= __ypdomainname
;
386 __libc_lock_unlock (domainname_lock
);
392 __yp_check (char **domain
)
396 if (__ypdomainname
[0] == '\0')
397 if (yp_get_default_domain (&unused
))
401 *domain
= __ypdomainname
;
403 if (yp_bind (__ypdomainname
) == 0)
409 yp_match (const char *indomain
, const char *inmap
, const char *inkey
,
410 const int inkeylen
, char **outval
, int *outvallen
)
414 enum clnt_stat result
;
416 if (indomain
== NULL
|| indomain
[0] == '\0' ||
417 inmap
== NULL
|| inmap
[0] == '\0' ||
418 inkey
== NULL
|| inkey
[0] == '\0' || inkeylen
<= 0)
419 return YPERR_BADARGS
;
421 req
.domain
= (char *) indomain
;
422 req
.map
= (char *) inmap
;
423 req
.key
.keydat_val
= (char *) inkey
;
424 req
.key
.keydat_len
= inkeylen
;
428 memset (&resp
, '\0', sizeof (resp
));
430 result
= do_ypcall (indomain
, YPPROC_MATCH
, (xdrproc_t
) xdr_ypreq_key
,
431 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_val
,
434 if (result
!= YPERR_SUCCESS
)
436 if (resp
.stat
!= YP_TRUE
)
437 return ypprot_err (resp
.stat
);
439 *outvallen
= resp
.val
.valdat_len
;
440 *outval
= malloc (*outvallen
+ 1);
441 if (__builtin_expect (*outval
== NULL
, 0))
443 memcpy (*outval
, resp
.val
.valdat_val
, *outvallen
);
444 (*outval
)[*outvallen
] = '\0';
446 xdr_free ((xdrproc_t
) xdr_ypresp_val
, (char *) &resp
);
448 return YPERR_SUCCESS
;
452 yp_first (const char *indomain
, const char *inmap
, char **outkey
,
453 int *outkeylen
, char **outval
, int *outvallen
)
457 enum clnt_stat result
;
459 if (indomain
== NULL
|| indomain
[0] == '\0' ||
460 inmap
== NULL
|| inmap
[0] == '\0')
461 return YPERR_BADARGS
;
463 req
.domain
= (char *) indomain
;
464 req
.map
= (char *) inmap
;
466 *outkey
= *outval
= NULL
;
467 *outkeylen
= *outvallen
= 0;
468 memset (&resp
, '\0', sizeof (resp
));
470 result
= do_ypcall (indomain
, YPPROC_FIRST
, (xdrproc_t
) xdr_ypreq_nokey
,
471 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_key_val
,
474 if (result
!= RPC_SUCCESS
)
476 if (resp
.stat
!= YP_TRUE
)
477 return ypprot_err (resp
.stat
);
479 *outkeylen
= resp
.key
.keydat_len
;
480 *outkey
= malloc (*outkeylen
+ 1);
481 if (__builtin_expect (*outkey
== NULL
, 0))
483 memcpy (*outkey
, resp
.key
.keydat_val
, *outkeylen
);
484 (*outkey
)[*outkeylen
] = '\0';
485 *outvallen
= resp
.val
.valdat_len
;
486 *outval
= malloc (*outvallen
+ 1);
487 if (__builtin_expect (*outval
== NULL
, 0))
489 memcpy (*outval
, resp
.val
.valdat_val
, *outvallen
);
490 (*outval
)[*outvallen
] = '\0';
492 xdr_free ((xdrproc_t
) xdr_ypresp_key_val
, (char *) &resp
);
494 return YPERR_SUCCESS
;
498 yp_next (const char *indomain
, const char *inmap
, const char *inkey
,
499 const int inkeylen
, char **outkey
, int *outkeylen
, char **outval
,
504 enum clnt_stat result
;
506 if (indomain
== NULL
|| indomain
[0] == '\0' ||
507 inmap
== NULL
|| inmap
[0] == '\0' ||
508 inkeylen
<= 0 || inkey
== NULL
|| inkey
[0] == '\0')
509 return YPERR_BADARGS
;
511 req
.domain
= (char *) indomain
;
512 req
.map
= (char *) inmap
;
513 req
.key
.keydat_val
= (char *) inkey
;
514 req
.key
.keydat_len
= inkeylen
;
516 *outkey
= *outval
= NULL
;
517 *outkeylen
= *outvallen
= 0;
518 memset (&resp
, '\0', sizeof (resp
));
520 result
= do_ypcall (indomain
, YPPROC_NEXT
, (xdrproc_t
) xdr_ypreq_key
,
521 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_key_val
,
524 if (result
!= YPERR_SUCCESS
)
526 if (resp
.stat
!= YP_TRUE
)
527 return ypprot_err (resp
.stat
);
529 *outkeylen
= resp
.key
.keydat_len
;
530 *outkey
= malloc (*outkeylen
+ 1);
531 if (__builtin_expect (*outkey
== NULL
, 0))
533 memcpy (*outkey
, resp
.key
.keydat_val
, *outkeylen
);
534 (*outkey
)[*outkeylen
] = '\0';
535 *outvallen
= resp
.val
.valdat_len
;
536 *outval
= malloc (*outvallen
+ 1);
537 if (__builtin_expect (*outval
== NULL
, 0))
539 memcpy (*outval
, resp
.val
.valdat_val
, *outvallen
);
540 (*outval
)[*outvallen
] = '\0';
542 xdr_free ((xdrproc_t
) xdr_ypresp_key_val
, (char *) &resp
);
544 return YPERR_SUCCESS
;
548 yp_master (const char *indomain
, const char *inmap
, char **outname
)
552 enum clnt_stat result
;
554 if (indomain
== NULL
|| indomain
[0] == '\0' ||
555 inmap
== NULL
|| inmap
[0] == '\0')
556 return YPERR_BADARGS
;
558 req
.domain
= (char *) indomain
;
559 req
.map
= (char *) inmap
;
561 memset (&resp
, '\0', sizeof (ypresp_master
));
563 result
= do_ypcall (indomain
, YPPROC_MASTER
, (xdrproc_t
) xdr_ypreq_nokey
,
564 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_master
, (caddr_t
) & resp
);
566 if (result
!= YPERR_SUCCESS
)
568 if (resp
.stat
!= YP_TRUE
)
569 return ypprot_err (resp
.stat
);
571 *outname
= strdup (resp
.peer
);
572 xdr_free ((xdrproc_t
) xdr_ypresp_master
, (char *) &resp
);
574 return *outname
== NULL
? YPERR_YPERR
: YPERR_SUCCESS
;
578 yp_order (const char *indomain
, const char *inmap
, unsigned int *outorder
)
580 struct ypreq_nokey req
;
581 struct ypresp_order resp
;
582 enum clnt_stat result
;
584 if (indomain
== NULL
|| indomain
[0] == '\0' ||
585 inmap
== NULL
|| inmap
== '\0')
586 return YPERR_BADARGS
;
588 req
.domain
= (char *) indomain
;
589 req
.map
= (char *) inmap
;
591 memset (&resp
, '\0', sizeof (resp
));
593 result
= do_ypcall (indomain
, YPPROC_ORDER
, (xdrproc_t
) xdr_ypreq_nokey
,
594 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_order
, (caddr_t
) & resp
);
596 if (result
!= YPERR_SUCCESS
)
598 if (resp
.stat
!= YP_TRUE
)
599 return ypprot_err (resp
.stat
);
601 *outorder
= resp
.ordernum
;
602 xdr_free ((xdrproc_t
) xdr_ypresp_order
, (char *) &resp
);
604 return YPERR_SUCCESS
;
607 static void *ypall_data
;
608 static int (*ypall_foreach
) (int status
, char *key
, int keylen
,
609 char *val
, int vallen
, char *data
);
612 __xdr_ypresp_all (XDR
*xdrs
, u_long
*objp
)
616 struct ypresp_all resp
;
618 memset (&resp
, '\0', sizeof (struct ypresp_all
));
619 if (!xdr_ypresp_all (xdrs
, &resp
))
621 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
627 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
632 switch (resp
.ypresp_all_u
.val
.stat
)
636 char key
[resp
.ypresp_all_u
.val
.key
.keydat_len
+ 1];
637 char val
[resp
.ypresp_all_u
.val
.val
.valdat_len
+ 1];
638 int keylen
= resp
.ypresp_all_u
.val
.key
.keydat_len
;
639 int vallen
= resp
.ypresp_all_u
.val
.val
.valdat_len
;
641 /* We are not allowed to modify the key and val data.
642 But we are allowed to add data behind the buffer,
643 if we don't modify the length. So add an extra NUL
644 character to avoid trouble with broken code. */
646 memcpy (key
, resp
.ypresp_all_u
.val
.key
.keydat_val
, keylen
);
648 memcpy (val
, resp
.ypresp_all_u
.val
.val
.valdat_val
, vallen
);
650 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
651 if ((*ypall_foreach
) (*objp
, key
, keylen
,
652 val
, vallen
, ypall_data
))
657 *objp
= resp
.ypresp_all_u
.val
.stat
;
658 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
659 /* Sun says we don't need to make this call, but must return
660 immediatly. Since Solaris makes this call, we will call
661 the callback function, too. */
662 (*ypall_foreach
) (*objp
, NULL
, 0, NULL
, 0, ypall_data
);
669 yp_all (const char *indomain
, const char *inmap
,
670 const struct ypall_callback
*incallback
)
672 struct ypreq_nokey req
;
673 dom_binding
*ydb
= NULL
;
675 enum clnt_stat result
;
676 struct sockaddr_in clnt_sin
;
678 unsigned long status
;
680 int saved_errno
= errno
;
682 if (indomain
== NULL
|| indomain
[0] == '\0' ||
683 inmap
== NULL
|| inmap
== '\0')
684 return YPERR_BADARGS
;
689 while (try < MAXTRIES
&& res
!= YPERR_SUCCESS
)
691 if (__yp_bind (indomain
, &ydb
) != 0)
693 __set_errno (saved_errno
);
697 clnt_sock
= RPC_ANYSOCK
;
698 clnt_sin
= ydb
->dom_server_addr
;
699 clnt_sin
.sin_port
= 0;
701 /* We don't need the UDP connection anymore. */
705 clnt
= clnttcp_create (&clnt_sin
, YPPROG
, YPVERS
, &clnt_sock
, 0, 0);
708 __set_errno (saved_errno
);
711 req
.domain
= (char *) indomain
;
712 req
.map
= (char *) inmap
;
714 ypall_foreach
= incallback
->foreach
;
715 ypall_data
= (void *) incallback
->data
;
717 result
= clnt_call (clnt
, YPPROC_ALL
, (xdrproc_t
) xdr_ypreq_nokey
,
718 (caddr_t
) &req
, (xdrproc_t
) __xdr_ypresp_all
,
719 (caddr_t
) &status
, RPCTIMEOUT
);
721 if (result
!= RPC_SUCCESS
)
723 /* Print the error message only on the last try */
724 if (try == MAXTRIES
- 1)
725 clnt_perror (clnt
, "yp_all: clnt_call");
733 if (res
== YPERR_SUCCESS
&& status
!= YP_NOMORE
)
735 __set_errno (saved_errno
);
736 return ypprot_err (status
);
741 __set_errno (saved_errno
);
747 yp_maplist (const char *indomain
, struct ypmaplist
**outmaplist
)
749 struct ypresp_maplist resp
;
750 enum clnt_stat result
;
752 if (indomain
== NULL
|| indomain
[0] == '\0')
753 return YPERR_BADARGS
;
755 memset (&resp
, '\0', sizeof (resp
));
757 result
= do_ypcall (indomain
, YPPROC_MAPLIST
, (xdrproc_t
) xdr_domainname
,
758 (caddr_t
) & indomain
, (xdrproc_t
) xdr_ypresp_maplist
, (caddr_t
) & resp
);
760 if (result
!= YPERR_SUCCESS
)
762 if (resp
.stat
!= YP_TRUE
)
763 return ypprot_err (resp
.stat
);
765 *outmaplist
= resp
.maps
;
766 /* We give the list not free, this will be done by ypserv
767 xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
769 return YPERR_SUCCESS
;
773 yperr_string (const int error
)
780 return _("Request arguments bad");
782 return _("RPC failure on NIS operation");
784 return _("Can't bind to server which serves this domain");
786 return _("No such map in server's domain");
788 return _("No such key in map");
790 return _("Internal NIS error");
792 return _("Local resource allocation failure");
794 return _("No more records in map database");
796 return _("Can't communicate with portmapper");
798 return _("Can't communicate with ypbind");
800 return _("Can't communicate with ypserv");
802 return _("Local domain name not set");
804 return _("NIS map database is bad");
806 return _("NIS client/server version mismatch - can't supply service");
808 return _("Permission denied");
810 return _("Database is busy");
812 return _("Unknown NIS error code");
816 ypprot_err (const int code
)
821 return YPERR_SUCCESS
;
839 return YPERR_BADARGS
;
847 ypbinderr_string (const int error
)
854 return _("Internal ypbind error");
855 case YPBIND_ERR_NOSERV
:
856 return _("Domain not bound");
857 case YPBIND_ERR_RESC
:
858 return _("System resource allocation failure");
860 return _("Unknown ypbind error");
868 yp_update (char *domain
, char *map
, unsigned ypop
,
869 char *key
, int keylen
, char *data
, int datalen
)
873 ypupdate_args update_args
;
874 ypdelete_args delete_args
;
877 xdrproc_t xdr_argument
;
881 struct sockaddr saddr
;
882 char servername
[MAXNETNAMELEN
+ 1];
885 if (!domain
|| !map
|| !key
|| (ypop
!= YPOP_DELETE
&& !data
))
886 return YPERR_BADARGS
;
888 args
.update_args
.mapname
= map
;
889 args
.update_args
.key
.yp_buf_len
= keylen
;
890 args
.update_args
.key
.yp_buf_val
= key
;
891 args
.update_args
.datum
.yp_buf_len
= datalen
;
892 args
.update_args
.datum
.yp_buf_val
= data
;
894 if ((r
= yp_master (domain
, map
, &master
)) != 0)
897 if (!host2netname (servername
, master
, domain
))
899 fputs (_("yp_update: cannot convert host to netname\n"), stderr
);
903 if ((clnt
= clnt_create (master
, YPU_PROG
, YPU_VERS
, "tcp")) == NULL
)
905 clnt_pcreateerror ("yp_update: clnt_create");
909 if (!clnt_control (clnt
, CLGET_SERVER_ADDR
, (char *) &saddr
))
911 fputs (_("yp_update: cannot get server address\n"), stderr
);
920 xdr_argument
= (xdrproc_t
) xdr_ypupdate_args
;
923 xdr_argument
= (xdrproc_t
) xdr_ypdelete_args
;
926 return YPERR_BADARGS
;
930 clnt
->cl_auth
= authdes_create (servername
, WINDOW
, &saddr
, NULL
);
932 if (clnt
->cl_auth
== NULL
)
933 clnt
->cl_auth
= authunix_create_default ();
936 r
= clnt_call (clnt
, ypop
, xdr_argument
, (caddr_t
) &args
,
937 (xdrproc_t
) xdr_u_int
, (caddr_t
) &res
, RPCTIMEOUT
);
939 if (r
== RPC_AUTHERROR
)
941 if (clnt
->cl_auth
->ah_cred
.oa_flavor
== AUTH_DES
)
943 clnt
->cl_auth
= authunix_create_default ();
949 if (r
!= RPC_SUCCESS
)
951 clnt_perror (clnt
, "yp_update: clnt_call");