1 /* Copyright (C) 1996-2001, 2002 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')
74 if (strcmp (domain
, ysd
->dom_domain
) == 0)
83 ysd
= (dom_binding
*) calloc (1, sizeof *ysd
);
84 if (__builtin_expect (ysd
== NULL
, 0))
89 if (ysd
->dom_client
== NULL
)
91 /* Try binding dir at first if we have no binding */
92 char path
[sizeof (BINDINGDIR
) + strlen (domain
) + 10];
97 sprintf (path
, "%s/%s.%d", BINDINGDIR
, domain
, YPBINDVERS
);
98 fd
= open (path
, O_RDONLY
);
101 /* We have a binding file and could save a RPC call */
102 vec
[0].iov_base
= &port
;
103 vec
[0].iov_len
= sizeof (port
);
104 vec
[1].iov_base
= &ypbr
;
105 vec
[1].iov_len
= sizeof (ypbr
);
107 if (readv (fd
, vec
, 2) == sizeof (port
) + sizeof (ypbr
))
109 ysd
->dom_server_addr
.sin_family
= AF_INET
;
110 memcpy (&ysd
->dom_server_addr
.sin_port
,
111 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_port
,
112 sizeof (ysd
->dom_server_addr
.sin_port
));
113 memcpy (&ysd
->dom_server_addr
.sin_addr
.s_addr
,
114 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_addr
,
115 sizeof (ysd
->dom_server_addr
.sin_addr
.s_addr
));
116 strncpy (ysd
->dom_domain
, domain
, YPMAXDOMAIN
);
117 ysd
->dom_domain
[YPMAXDOMAIN
] = '\0';
119 ysd
->dom_socket
= RPC_ANYSOCK
;
120 ysd
->dom_client
= clntudp_create (&ysd
->dom_server_addr
, YPPROG
,
124 if (ysd
->dom_client
!= NULL
)
125 /* If the program exits, close the socket */
126 if (fcntl (ysd
->dom_socket
, F_SETFD
, 1) == -1)
127 perror ("fcntl: F_SETFD");
132 #endif /* USE_BINDINGDIR */
134 if (ysd
->dom_client
== NULL
)
136 memset (&clnt_saddr
, '\0', sizeof clnt_saddr
);
137 clnt_saddr
.sin_family
= AF_INET
;
138 clnt_saddr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
139 clnt_sock
= RPC_ANYSOCK
;
140 client
= clnttcp_create (&clnt_saddr
, YPBINDPROG
, YPBINDVERS
,
148 /* Check the port number -- should be < IPPORT_RESERVED.
149 If not, it's possible someone has registered a bogus
150 ypbind with the portmapper and is trying to trick us. */
151 if (ntohs (clnt_saddr
.sin_port
) >= IPPORT_RESERVED
)
153 clnt_destroy (client
);
159 if (clnt_call (client
, YPBINDPROC_DOMAIN
,
160 (xdrproc_t
) xdr_domainname
, (caddr_t
) &domain
,
161 (xdrproc_t
) xdr_ypbind_resp
,
162 (caddr_t
) &ypbr
, RPCTIMEOUT
) != RPC_SUCCESS
)
164 clnt_destroy (client
);
170 clnt_destroy (client
);
172 if (ypbr
.ypbind_status
!= YPBIND_SUCC_VAL
)
174 fprintf (stderr
, _("YPBINDPROC_DOMAIN: %s\n"),
175 ypbinderr_string (ypbr
.ypbind_resp_u
.ypbind_error
));
180 memset (&ysd
->dom_server_addr
, '\0', sizeof ysd
->dom_server_addr
);
181 ysd
->dom_server_addr
.sin_family
= AF_INET
;
182 memcpy (&ysd
->dom_server_addr
.sin_port
,
183 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_port
,
184 sizeof (ysd
->dom_server_addr
.sin_port
));
185 memcpy (&ysd
->dom_server_addr
.sin_addr
.s_addr
,
186 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_addr
,
187 sizeof (ysd
->dom_server_addr
.sin_addr
.s_addr
));
188 strncpy (ysd
->dom_domain
, domain
, YPMAXDOMAIN
);
189 ysd
->dom_domain
[YPMAXDOMAIN
] = '\0';
191 ysd
->dom_socket
= RPC_ANYSOCK
;
192 ysd
->dom_client
= clntudp_create (&ysd
->dom_server_addr
, YPPROG
, YPVERS
,
193 UDPTIMEOUT
, &ysd
->dom_socket
);
195 if (ysd
->dom_client
!= NULL
)
196 /* If the program exits, close the socket */
197 if (fcntl (ysd
->dom_socket
, F_SETFD
, 1) == -1)
198 perror ("fcntl: F_SETFD");
201 if (ysd
->dom_client
== NULL
)
208 if (is_new
&& ypdb
!= NULL
)
210 ysd
->dom_pnext
= *ypdb
;
214 return YPERR_SUCCESS
;
218 __yp_unbind (dom_binding
*ydb
)
220 clnt_destroy (ydb
->dom_client
);
221 ydb
->dom_client
= NULL
;
225 yp_bind (const char *indomain
)
229 __libc_lock_lock (ypbindlist_lock
);
231 status
= __yp_bind (indomain
, &__ypbindlist
);
233 __libc_lock_unlock (ypbindlist_lock
);
239 yp_unbind_locked (const char *indomain
)
241 dom_binding
*ydbptr
, *ydbptr2
;
244 ydbptr
= __ypbindlist
;
246 while (ydbptr
!= NULL
)
248 if (strcmp (ydbptr
->dom_domain
, indomain
) == 0)
254 __ypbindlist
= __ypbindlist
->dom_pnext
;
256 ydbptr2
= ydbptr
->dom_pnext
;
262 ydbptr
= ydbptr
->dom_pnext
;
267 yp_unbind (const char *indomain
)
269 __libc_lock_lock (ypbindlist_lock
);
271 yp_unbind_locked (indomain
);
273 __libc_lock_unlock (ypbindlist_lock
);
279 do_ypcall (const char *domain
, u_long prog
, xdrproc_t xargs
,
280 caddr_t req
, xdrproc_t xres
, caddr_t resp
)
282 dom_binding
*ydb
= NULL
;
283 bool_t use_ypbindlist
= FALSE
;
285 enum clnt_stat result
;
286 int saved_errno
= errno
;
289 status
= YPERR_YPERR
;
291 __libc_lock_lock (ypbindlist_lock
);
292 if (__ypbindlist
!= NULL
)
297 if (strcmp (domain
, ydb
->dom_domain
) == 0)
299 ydb
= ydb
->dom_pnext
;
302 use_ypbindlist
= TRUE
;
304 __libc_lock_unlock (ypbindlist_lock
);
307 __libc_lock_unlock (ypbindlist_lock
);
309 while (try < MAXTRIES
&& status
!= YPERR_SUCCESS
)
311 if (__yp_bind (domain
, &ydb
) != 0)
314 __libc_lock_unlock (ypbindlist_lock
);
315 __set_errno (saved_errno
);
319 result
= clnt_call (ydb
->dom_client
, prog
,
320 xargs
, req
, xres
, resp
, RPCTIMEOUT
);
322 if (result
!= RPC_SUCCESS
)
324 /* Don't print the error message on the first try. It
325 could be that we use cached data which is now invalid. */
327 clnt_perror (ydb
->dom_client
, "do_ypcall: clnt_call");
331 /* We use ypbindlist, and the old cached data is
332 invalid. unbind now and create a new binding */
333 yp_unbind_locked (domain
);
334 __libc_lock_unlock (ypbindlist_lock
);
335 use_ypbindlist
= FALSE
;
347 status
= YPERR_SUCCESS
;
353 __libc_lock_unlock (ypbindlist_lock
);
354 use_ypbindlist
= FALSE
;
364 __set_errno (saved_errno
);
370 __libc_lock_define_initialized (static, domainname_lock
)
373 yp_get_default_domain (char **outdomain
)
375 int result
= YPERR_SUCCESS
;;
378 __libc_lock_lock (domainname_lock
);
380 if (__ypdomainname
[0] == '\0')
382 if (getdomainname (__ypdomainname
, NIS_MAXNAMELEN
))
383 result
= YPERR_NODOM
;
384 else if (strcmp (__ypdomainname
, "(none)") == 0)
386 /* If domainname is not set, some systems will return "(none)" */
387 __ypdomainname
[0] = '\0';
388 result
= YPERR_NODOM
;
391 *outdomain
= __ypdomainname
;
394 *outdomain
= __ypdomainname
;
396 __libc_lock_unlock (domainname_lock
);
402 __yp_check (char **domain
)
406 if (__ypdomainname
[0] == '\0')
407 if (yp_get_default_domain (&unused
))
411 *domain
= __ypdomainname
;
413 if (yp_bind (__ypdomainname
) == 0)
419 yp_match (const char *indomain
, const char *inmap
, const char *inkey
,
420 const int inkeylen
, char **outval
, int *outvallen
)
424 enum clnt_stat result
;
426 if (indomain
== NULL
|| indomain
[0] == '\0' ||
427 inmap
== NULL
|| inmap
[0] == '\0' ||
428 inkey
== NULL
|| inkey
[0] == '\0' || inkeylen
<= 0)
429 return YPERR_BADARGS
;
431 req
.domain
= (char *) indomain
;
432 req
.map
= (char *) inmap
;
433 req
.key
.keydat_val
= (char *) inkey
;
434 req
.key
.keydat_len
= inkeylen
;
438 memset (&resp
, '\0', sizeof (resp
));
440 result
= do_ypcall (indomain
, YPPROC_MATCH
, (xdrproc_t
) xdr_ypreq_key
,
441 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_val
,
444 if (result
!= YPERR_SUCCESS
)
446 if (resp
.stat
!= YP_TRUE
)
447 return ypprot_err (resp
.stat
);
449 *outvallen
= resp
.val
.valdat_len
;
450 *outval
= malloc (*outvallen
+ 1);
451 if (__builtin_expect (*outval
== NULL
, 0))
453 memcpy (*outval
, resp
.val
.valdat_val
, *outvallen
);
454 (*outval
)[*outvallen
] = '\0';
456 xdr_free ((xdrproc_t
) xdr_ypresp_val
, (char *) &resp
);
458 return YPERR_SUCCESS
;
462 yp_first (const char *indomain
, const char *inmap
, char **outkey
,
463 int *outkeylen
, char **outval
, int *outvallen
)
467 enum clnt_stat result
;
469 if (indomain
== NULL
|| indomain
[0] == '\0' ||
470 inmap
== NULL
|| inmap
[0] == '\0')
471 return YPERR_BADARGS
;
473 req
.domain
= (char *) indomain
;
474 req
.map
= (char *) inmap
;
476 *outkey
= *outval
= NULL
;
477 *outkeylen
= *outvallen
= 0;
478 memset (&resp
, '\0', sizeof (resp
));
480 result
= do_ypcall (indomain
, YPPROC_FIRST
, (xdrproc_t
) xdr_ypreq_nokey
,
481 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_key_val
,
484 if (result
!= RPC_SUCCESS
)
486 if (resp
.stat
!= YP_TRUE
)
487 return ypprot_err (resp
.stat
);
489 *outkeylen
= resp
.key
.keydat_len
;
490 *outkey
= malloc (*outkeylen
+ 1);
491 if (__builtin_expect (*outkey
== NULL
, 0))
493 memcpy (*outkey
, resp
.key
.keydat_val
, *outkeylen
);
494 (*outkey
)[*outkeylen
] = '\0';
495 *outvallen
= resp
.val
.valdat_len
;
496 *outval
= malloc (*outvallen
+ 1);
497 if (__builtin_expect (*outval
== NULL
, 0))
499 memcpy (*outval
, resp
.val
.valdat_val
, *outvallen
);
500 (*outval
)[*outvallen
] = '\0';
502 xdr_free ((xdrproc_t
) xdr_ypresp_key_val
, (char *) &resp
);
504 return YPERR_SUCCESS
;
508 yp_next (const char *indomain
, const char *inmap
, const char *inkey
,
509 const int inkeylen
, char **outkey
, int *outkeylen
, char **outval
,
514 enum clnt_stat result
;
516 if (indomain
== NULL
|| indomain
[0] == '\0' ||
517 inmap
== NULL
|| inmap
[0] == '\0' ||
518 inkeylen
<= 0 || inkey
== NULL
|| inkey
[0] == '\0')
519 return YPERR_BADARGS
;
521 req
.domain
= (char *) indomain
;
522 req
.map
= (char *) inmap
;
523 req
.key
.keydat_val
= (char *) inkey
;
524 req
.key
.keydat_len
= inkeylen
;
526 *outkey
= *outval
= NULL
;
527 *outkeylen
= *outvallen
= 0;
528 memset (&resp
, '\0', sizeof (resp
));
530 result
= do_ypcall (indomain
, YPPROC_NEXT
, (xdrproc_t
) xdr_ypreq_key
,
531 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_key_val
,
534 if (result
!= YPERR_SUCCESS
)
536 if (resp
.stat
!= YP_TRUE
)
537 return ypprot_err (resp
.stat
);
539 *outkeylen
= resp
.key
.keydat_len
;
540 *outkey
= malloc (*outkeylen
+ 1);
541 if (__builtin_expect (*outkey
== NULL
, 0))
543 memcpy (*outkey
, resp
.key
.keydat_val
, *outkeylen
);
544 (*outkey
)[*outkeylen
] = '\0';
545 *outvallen
= resp
.val
.valdat_len
;
546 *outval
= malloc (*outvallen
+ 1);
547 if (__builtin_expect (*outval
== NULL
, 0))
549 memcpy (*outval
, resp
.val
.valdat_val
, *outvallen
);
550 (*outval
)[*outvallen
] = '\0';
552 xdr_free ((xdrproc_t
) xdr_ypresp_key_val
, (char *) &resp
);
554 return YPERR_SUCCESS
;
558 yp_master (const char *indomain
, const char *inmap
, char **outname
)
562 enum clnt_stat result
;
564 if (indomain
== NULL
|| indomain
[0] == '\0' ||
565 inmap
== NULL
|| inmap
[0] == '\0')
566 return YPERR_BADARGS
;
568 req
.domain
= (char *) indomain
;
569 req
.map
= (char *) inmap
;
571 memset (&resp
, '\0', sizeof (ypresp_master
));
573 result
= do_ypcall (indomain
, YPPROC_MASTER
, (xdrproc_t
) xdr_ypreq_nokey
,
574 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_master
, (caddr_t
) & resp
);
576 if (result
!= YPERR_SUCCESS
)
578 if (resp
.stat
!= YP_TRUE
)
579 return ypprot_err (resp
.stat
);
581 *outname
= strdup (resp
.peer
);
582 xdr_free ((xdrproc_t
) xdr_ypresp_master
, (char *) &resp
);
584 return *outname
== NULL
? YPERR_YPERR
: YPERR_SUCCESS
;
588 yp_order (const char *indomain
, const char *inmap
, unsigned int *outorder
)
590 struct ypreq_nokey req
;
591 struct ypresp_order resp
;
592 enum clnt_stat result
;
594 if (indomain
== NULL
|| indomain
[0] == '\0' ||
595 inmap
== NULL
|| inmap
== '\0')
596 return YPERR_BADARGS
;
598 req
.domain
= (char *) indomain
;
599 req
.map
= (char *) inmap
;
601 memset (&resp
, '\0', sizeof (resp
));
603 result
= do_ypcall (indomain
, YPPROC_ORDER
, (xdrproc_t
) xdr_ypreq_nokey
,
604 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_order
, (caddr_t
) & resp
);
606 if (result
!= YPERR_SUCCESS
)
608 if (resp
.stat
!= YP_TRUE
)
609 return ypprot_err (resp
.stat
);
611 *outorder
= resp
.ordernum
;
612 xdr_free ((xdrproc_t
) xdr_ypresp_order
, (char *) &resp
);
614 return YPERR_SUCCESS
;
617 static void *ypall_data
;
618 static int (*ypall_foreach
) (int status
, char *key
, int keylen
,
619 char *val
, int vallen
, char *data
);
622 __xdr_ypresp_all (XDR
*xdrs
, u_long
*objp
)
626 struct ypresp_all resp
;
628 memset (&resp
, '\0', sizeof (struct ypresp_all
));
629 if (!xdr_ypresp_all (xdrs
, &resp
))
631 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
637 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
642 switch (resp
.ypresp_all_u
.val
.stat
)
646 char key
[resp
.ypresp_all_u
.val
.key
.keydat_len
+ 1];
647 char val
[resp
.ypresp_all_u
.val
.val
.valdat_len
+ 1];
648 int keylen
= resp
.ypresp_all_u
.val
.key
.keydat_len
;
649 int vallen
= resp
.ypresp_all_u
.val
.val
.valdat_len
;
651 /* We are not allowed to modify the key and val data.
652 But we are allowed to add data behind the buffer,
653 if we don't modify the length. So add an extra NUL
654 character to avoid trouble with broken code. */
656 memcpy (key
, resp
.ypresp_all_u
.val
.key
.keydat_val
, keylen
);
658 memcpy (val
, resp
.ypresp_all_u
.val
.val
.valdat_val
, vallen
);
660 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
661 if ((*ypall_foreach
) (*objp
, key
, keylen
,
662 val
, vallen
, ypall_data
))
667 *objp
= resp
.ypresp_all_u
.val
.stat
;
668 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
669 /* Sun says we don't need to make this call, but must return
670 immediatly. Since Solaris makes this call, we will call
671 the callback function, too. */
672 (*ypall_foreach
) (*objp
, NULL
, 0, NULL
, 0, ypall_data
);
679 yp_all (const char *indomain
, const char *inmap
,
680 const struct ypall_callback
*incallback
)
682 struct ypreq_nokey req
;
683 dom_binding
*ydb
= NULL
;
685 enum clnt_stat result
;
686 struct sockaddr_in clnt_sin
;
688 unsigned long status
;
690 int saved_errno
= errno
;
692 if (indomain
== NULL
|| indomain
[0] == '\0' ||
693 inmap
== NULL
|| inmap
== '\0')
694 return YPERR_BADARGS
;
699 while (try < MAXTRIES
&& res
!= YPERR_SUCCESS
)
701 if (__yp_bind (indomain
, &ydb
) != 0)
703 __set_errno (saved_errno
);
707 clnt_sock
= RPC_ANYSOCK
;
708 clnt_sin
= ydb
->dom_server_addr
;
709 clnt_sin
.sin_port
= 0;
711 /* We don't need the UDP connection anymore. */
714 clnt
= clnttcp_create (&clnt_sin
, YPPROG
, YPVERS
, &clnt_sock
, 0, 0);
717 __set_errno (saved_errno
);
720 req
.domain
= (char *) indomain
;
721 req
.map
= (char *) inmap
;
723 ypall_foreach
= incallback
->foreach
;
724 ypall_data
= (void *) incallback
->data
;
726 result
= clnt_call (clnt
, YPPROC_ALL
, (xdrproc_t
) xdr_ypreq_nokey
,
727 (caddr_t
) &req
, (xdrproc_t
) __xdr_ypresp_all
,
728 (caddr_t
) &status
, RPCTIMEOUT
);
730 if (result
!= RPC_SUCCESS
)
732 /* Print the error message only on the last try */
733 if (try == MAXTRIES
- 1)
734 clnt_perror (clnt
, "yp_all: clnt_call");
742 if (res
== YPERR_SUCCESS
&& status
!= YP_NOMORE
)
744 __set_errno (saved_errno
);
745 return ypprot_err (status
);
750 __set_errno (saved_errno
);
756 yp_maplist (const char *indomain
, struct ypmaplist
**outmaplist
)
758 struct ypresp_maplist resp
;
759 enum clnt_stat result
;
761 if (indomain
== NULL
|| indomain
[0] == '\0')
762 return YPERR_BADARGS
;
764 memset (&resp
, '\0', sizeof (resp
));
766 result
= do_ypcall (indomain
, YPPROC_MAPLIST
, (xdrproc_t
) xdr_domainname
,
767 (caddr_t
) & indomain
, (xdrproc_t
) xdr_ypresp_maplist
, (caddr_t
) & resp
);
769 if (result
!= YPERR_SUCCESS
)
771 if (resp
.stat
!= YP_TRUE
)
772 return ypprot_err (resp
.stat
);
774 *outmaplist
= resp
.maps
;
775 /* We give the list not free, this will be done by ypserv
776 xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
778 return YPERR_SUCCESS
;
782 yperr_string (const int error
)
789 return _("Request arguments bad");
791 return _("RPC failure on NIS operation");
793 return _("Can't bind to server which serves this domain");
795 return _("No such map in server's domain");
797 return _("No such key in map");
799 return _("Internal NIS error");
801 return _("Local resource allocation failure");
803 return _("No more records in map database");
805 return _("Can't communicate with portmapper");
807 return _("Can't communicate with ypbind");
809 return _("Can't communicate with ypserv");
811 return _("Local domain name not set");
813 return _("NIS map database is bad");
815 return _("NIS client/server version mismatch - can't supply service");
817 return _("Permission denied");
819 return _("Database is busy");
821 return _("Unknown NIS error code");
825 ypprot_err (const int code
)
830 return YPERR_SUCCESS
;
848 return YPERR_BADARGS
;
856 ypbinderr_string (const int error
)
863 return _("Internal ypbind error");
864 case YPBIND_ERR_NOSERV
:
865 return _("Domain not bound");
866 case YPBIND_ERR_RESC
:
867 return _("System resource allocation failure");
869 return _("Unknown ypbind error");
877 yp_update (char *domain
, char *map
, unsigned ypop
,
878 char *key
, int keylen
, char *data
, int datalen
)
882 ypupdate_args update_args
;
883 ypdelete_args delete_args
;
886 xdrproc_t xdr_argument
;
890 struct sockaddr saddr
;
891 char servername
[MAXNETNAMELEN
+ 1];
894 if (!domain
|| !map
|| !key
|| (ypop
!= YPOP_DELETE
&& !data
))
895 return YPERR_BADARGS
;
897 args
.update_args
.mapname
= map
;
898 args
.update_args
.key
.yp_buf_len
= keylen
;
899 args
.update_args
.key
.yp_buf_val
= key
;
900 args
.update_args
.datum
.yp_buf_len
= datalen
;
901 args
.update_args
.datum
.yp_buf_val
= data
;
903 if ((r
= yp_master (domain
, map
, &master
)) != 0)
906 if (!host2netname (servername
, master
, domain
))
908 fputs (_("yp_update: cannot convert host to netname\n"), stderr
);
912 if ((clnt
= clnt_create (master
, YPU_PROG
, YPU_VERS
, "tcp")) == NULL
)
914 clnt_pcreateerror ("yp_update: clnt_create");
918 if (!clnt_control (clnt
, CLGET_SERVER_ADDR
, (char *) &saddr
))
920 fputs (_("yp_update: cannot get server address\n"), stderr
);
929 xdr_argument
= (xdrproc_t
) xdr_ypupdate_args
;
932 xdr_argument
= (xdrproc_t
) xdr_ypdelete_args
;
935 return YPERR_BADARGS
;
939 clnt
->cl_auth
= authdes_create (servername
, WINDOW
, &saddr
, NULL
);
941 if (clnt
->cl_auth
== NULL
)
942 clnt
->cl_auth
= authunix_create_default ();
945 r
= clnt_call (clnt
, ypop
, xdr_argument
, (caddr_t
) &args
,
946 (xdrproc_t
) xdr_u_int
, (caddr_t
) &res
, RPCTIMEOUT
);
948 if (r
== RPC_AUTHERROR
)
950 if (clnt
->cl_auth
->ah_cred
.oa_flavor
== AUTH_DES
)
952 clnt
->cl_auth
= authunix_create_default ();
958 if (r
!= RPC_SUCCESS
)
960 clnt_perror (clnt
, "yp_update: clnt_call");