1 /* Copyright (C) 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>, 1997.
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. */
23 #include <rpcsvc/nis.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include "nis_intern.h"
29 static struct timeval TIMEOUT
= {25, 0};
30 static int const MAXTRIES
= 3;
33 inetstr2int (const char *str
)
35 char buffer
[strlen (str
) + 3];
39 buflen
= stpcpy (buffer
, str
) - buffer
;
42 for (i
= 0; i
< buflen
; ++i
)
53 return inet_addr (buffer
);
57 __nis_dobind (const nis_server
*server
, u_long flags
)
59 struct sockaddr_in clnt_saddr
;
62 CLIENT
*client
= NULL
;
64 memset (&clnt_saddr
, '\0', sizeof clnt_saddr
);
65 clnt_saddr
.sin_family
= AF_INET
;
66 for (i
= 0; i
< server
->ep
.ep_len
; i
++)
68 if (strcmp (server
->ep
.ep_val
[i
].family
,"loopback") == 0)
70 if (server
->ep
.ep_val
[i
].uaddr
[i
] == '-')
71 clnt_saddr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
73 if (strcmp (server
->ep
.ep_val
[i
].proto
,"udp") == 0)
75 if ((flags
& USE_DGRAM
) == USE_DGRAM
)
76 clnt_saddr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
81 if (strcmp (server
->ep
.ep_val
[i
].proto
,"tcp") == 0)
83 if ((flags
& USE_DGRAM
) == USE_DGRAM
)
86 clnt_saddr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
90 if (strcmp (server
->ep
.ep_val
[i
].family
,"inet") == 0)
92 if (server
->ep
.ep_val
[i
].uaddr
[i
] == '-')
93 clnt_saddr
.sin_addr
.s_addr
=
94 inetstr2int (server
->ep
.ep_val
[i
].uaddr
);
96 if (strcmp (server
->ep
.ep_val
[i
].proto
,"udp") == 0)
98 if ((flags
& USE_DGRAM
) == USE_DGRAM
)
99 clnt_saddr
.sin_addr
.s_addr
=
100 inetstr2int (server
->ep
.ep_val
[i
].uaddr
);
105 if (strcmp (server
->ep
.ep_val
[i
].proto
,"tcp") == 0)
107 if ((flags
& USE_DGRAM
) == USE_DGRAM
)
110 clnt_saddr
.sin_addr
.s_addr
=
111 inetstr2int (server
->ep
.ep_val
[i
].uaddr
);
117 clnt_sock
= RPC_ANYSOCK
;
118 if ((flags
& USE_DGRAM
) == USE_DGRAM
)
119 client
= clntudp_create (&clnt_saddr
, NIS_PROG
, NIS_VERSION
,
120 TIMEOUT
, &clnt_sock
);
122 client
= clnttcp_create (&clnt_saddr
, NIS_PROG
, NIS_VERSION
,
127 if (clnt_call (client
, 0, (xdrproc_t
) xdr_void
, NULL
,
128 (xdrproc_t
) xdr_void
, NULL
, TIMEOUT
) != RPC_SUCCESS
)
130 clnt_destroy (client
);
134 if ((flags
& NO_AUTHINFO
) != NO_AUTHINFO
)
136 #if defined(HAVE_SECURE_RPC)
137 if (server
->key_type
== NIS_PK_DH
)
139 char netname
[MAXNETNAMELEN
+1];
142 p
= stpcpy (netname
, "unix.");
143 strncpy (p
, server
->name
,MAXNETNAMELEN
-5);
144 netname
[MAXNETNAMELEN
] = '\0';
145 p
= strchr (netname
, '.');
148 authdes_pk_create (netname
, &server
->pkey
, 300, NULL
, NULL
);
149 if (!client
->cl_auth
)
150 client
->cl_auth
= authunix_create_default ();
154 client
->cl_auth
= authunix_create_default ();
163 __do_niscall (const nis_server
*serv
, int serv_len
, u_long prog
,
164 xdrproc_t xargs
, caddr_t req
, xdrproc_t xres
, caddr_t resp
,
168 directory_obj
*dir
= NULL
;
169 const nis_server
*server
;
171 unsigned int server_len
;
173 if (serv
== NULL
|| serv_len
== 0)
175 dir
= readColdStartFile ();
178 fputs (_("Error: could not find a NIS_COLD_START file\n"), stderr
);
181 server
= dir
->do_servers
.do_servers_val
;
182 server_len
= dir
->do_servers
.do_servers_len
;
187 server_len
= serv_len
;
190 if (((flags
& MASTER_ONLY
) == MASTER_ONLY
) && server_len
> 1)
191 server_len
= 1; /* The first entry is the master */
194 result
= NIS_NAMEUNREACHABLE
;
196 while (try < MAXTRIES
&& result
!= RPC_SUCCESS
)
200 if ((flags
& HARD_LOOKUP
) == 0)
203 for (i
= 0; i
< server_len
; i
++)
205 if ((clnt
= __nis_dobind (&server
[i
], flags
)) == NULL
)
208 result
= clnt_call (clnt
, prog
, xargs
, req
, xres
, resp
, TIMEOUT
);
210 if (result
!= RPC_SUCCESS
)
212 clnt_perror (clnt
, "do_niscall: clnt_call");
214 result
= NIS_RPCERROR
;
222 nis_free_directory (dir
);