]>
git.saurik.com Git - apple/libinfo.git/blob - nis.subproj/yp_bind.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1996 Theo de Raadt <deraadt@theos.com>
27 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
28 * All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by Theo de Raadt.
41 * 4. The name of the author may not be used to endorse or promote products
42 * derived from this software without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
45 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
48 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 #if defined(LIBC_SCCS) && !defined(lint)
58 static char *rcsid
= "$OpenBSD: yp_bind.c,v 1.9 1997/04/29 21:25:20 deraadt Exp $";
59 #endif /* LIBC_SCCS and not lint */
61 #include <sys/param.h>
62 #include <sys/types.h>
63 #include <sys/socket.h>
73 #include <rpcsvc/yp.h>
74 #include <rpcsvc/ypclnt.h>
75 #include "ypinternal.h"
77 struct dom_binding
*_ypbindlist
= NULL
;
78 char _yp_domain
[MAXHOSTNAMELEN
] = { '\0' };
80 int _yplib_timeout
= 10;
85 struct dom_binding
**ypdb
;
88 char path
[MAXPATHLEN
];
89 struct dom_binding
*ysd
, *ysd2
;
90 struct ypbind_resp ypbr
;
92 struct sockaddr_in clnt_sin
;
93 struct ypbind_binding
*bn
;
94 int clnt_sock
, fd
, gpid
;
101 * test if YP is running or not
103 if ((fd
= open(YPBINDLOCK
, O_RDONLY
)) == -1)
105 if (!(flock(fd
, LOCK_EX
| LOCK_NB
) == -1 && errno
== EWOULDBLOCK
)) {
112 if (!(pid
== -1 || pid
== gpid
)) {
116 clnt_destroy(ysd
->dom_client
);
117 ysd2
= ysd
->dom_pnext
;
128 if (dom
== NULL
|| strlen(dom
) == 0)
129 return YPERR_BADARGS
;
131 for (ysd
= _ypbindlist
; ysd
; ysd
= ysd
->dom_pnext
)
132 if (strcmp(dom
, ysd
->dom_domain
) == 0)
135 if ((ysd
= malloc(sizeof *ysd
)) == NULL
)
137 (void)memset(ysd
, 0, sizeof *ysd
);
138 ysd
->dom_socket
= -1;
143 if (ysd
->dom_vers
== 0) {
144 (void) snprintf(path
, sizeof(path
), "%s/%s.%d",
146 if ((fd
= open(path
, O_RDONLY
)) == -1) {
148 * no binding file, YP is dead, or not yet fully
153 if (flock(fd
, LOCK_EX
| LOCK_NB
) == -1 &&
154 errno
== EWOULDBLOCK
) {
159 * we fetch the ypbind port number, but do
162 iov
[0].iov_base
= (caddr_t
) &ypb_port
;
163 iov
[0].iov_len
= sizeof ypb_port
;
164 iov
[1].iov_base
= (caddr_t
) &ypbr
;
165 iov
[1].iov_len
= sizeof ypbr
;
167 r
= readv(fd
, iov
, 2);
168 if (r
!= iov
[0].iov_len
+ iov
[1].iov_len
) {
176 /* no lock on binding file, YP is dead. */
184 if (ysd
->dom_vers
== -1 || ysd
->dom_vers
== 0) {
185 (void)memset(&clnt_sin
, 0, sizeof clnt_sin
);
186 clnt_sin
.sin_len
= sizeof(struct sockaddr_in
);
187 clnt_sin
.sin_family
= AF_INET
;
188 clnt_sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
190 clnt_sock
= RPC_ANYSOCK
;
191 client
= clnttcp_create(&clnt_sin
, YPBINDPROG
, YPBINDVERS
,
193 if (client
== NULL
) {
194 clnt_pcreateerror("clnttcp_create");
199 if (ntohs(clnt_sin
.sin_port
) >= IPPORT_RESERVED
||
200 ntohs(clnt_sin
.sin_port
) == 20) {
202 * YP was not running, but someone has registered
203 * ypbind with portmap -- this simply means YP is
206 clnt_destroy(client
);
211 tv
.tv_sec
= _yplib_timeout
;
213 r
= clnt_call(client
, YPBINDPROC_DOMAIN
, xdr_domainname
,
214 &dom
, xdr_ypbind_resp
, &ypbr
, tv
);
215 if (r
!= RPC_SUCCESS
) {
216 if (new == 0 || count
)
218 "YP server for domain %s not responding, still trying\n",
221 clnt_destroy(client
);
225 clnt_destroy(client
);
227 bn
= &ypbr
.ypbind_resp_u
.ypbind_bindinfo
;
228 memcpy(&port
, &bn
->ypbind_binding_port
, sizeof port
);
229 if (ntohs(port
) >= IPPORT_RESERVED
||
232 * This is bogus -- the ypbind wants me to
233 * communicate to an insecure ypserv. We are
234 * within rights to syslog this as an attack,
235 * but for now we'll simply ignore it; real YP
236 * is obviously not running.
242 (void)memset(&ysd
->dom_server_addr
, 0,
243 sizeof ysd
->dom_server_addr
);
244 ysd
->dom_server_addr
.sin_len
= sizeof(struct sockaddr_in
);
245 ysd
->dom_server_addr
.sin_family
= AF_INET
;
246 memcpy(&ysd
->dom_server_addr
.sin_port
,
247 &bn
->ypbind_binding_port
,
248 sizeof(ysd
->dom_server_addr
.sin_port
));
249 memcpy(&ysd
->dom_server_addr
.sin_addr
.s_addr
,
250 &bn
->ypbind_binding_addr
,
251 sizeof(ysd
->dom_server_addr
.sin_addr
.s_addr
));
252 ysd
->dom_server_port
= ysd
->dom_server_addr
.sin_port
;
253 ysd
->dom_vers
= YPVERS
;
254 (void)strncpy(ysd
->dom_domain
, dom
, sizeof ysd
->dom_domain
-1);
255 ysd
->dom_domain
[sizeof ysd
->dom_domain
-1] = '\0';
257 tv
.tv_sec
= _yplib_timeout
/ 2;
260 clnt_destroy(ysd
->dom_client
);
261 ysd
->dom_socket
= RPC_ANYSOCK
;
262 ysd
->dom_client
= clntudp_create(&ysd
->dom_server_addr
,
263 YPPROG
, YPVERS
, tv
, &ysd
->dom_socket
);
264 if (ysd
->dom_client
== NULL
) {
265 clnt_pcreateerror("clntudp_create");
269 if (fcntl(ysd
->dom_socket
, F_SETFD
, 1) == -1)
270 perror("fcntl: F_SETFD");
273 ysd
->dom_pnext
= _ypbindlist
;
283 struct dom_binding
*ypb
;
285 if (ypb
->dom_client
) clnt_destroy(ypb
->dom_client
);
286 ypb
->dom_client
= NULL
;
287 ypb
->dom_socket
= -1;
294 return _yp_dobind(dom
, NULL
);
301 struct dom_binding
*ypb
, *ypbp
;
304 for (ypb
= _ypbindlist
; ypb
; ypb
= ypb
->dom_pnext
) {
305 if (strcmp(dom
, ypb
->dom_domain
) == 0) {
306 if (ypb
->dom_client
) clnt_destroy(ypb
->dom_client
);
308 ypbp
->dom_pnext
= ypb
->dom_pnext
;
310 _ypbindlist
= ypb
->dom_pnext
;