1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 * Reserved. This file contains Original Code and/or Modifications of 8 * Original Code as defined in and that are subject to the Apple Public 9 * Source License Version 1.0 (the 'License'). You may not use this file 10 * except in compliance with the License. Please obtain a copy of the 11 * License at http://www.apple.com/publicsource and read it before using 12 * this file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 19 * License for the specific language governing rights and limitations 20 * under the License." 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24/* $OpenBSD: yplib_host.c,v 1.7 1997/06/23 01:11:12 deraadt Exp $ */ 25 26/* 27 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com> 28 * All rights reserved. 29 * 30 * Redistribution and use in source and binary forms, with or without 31 * modification, are permitted provided that the following conditions 32 * are met: 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. 43 * 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 54 * SUCH DAMAGE. 55 */ 56 57#include <sys/cdefs.h> 58#ifndef LINT 59__unused static char *rcsid = "$OpenBSD: yplib_host.c,v 1.7 1997/06/23 01:11:12 deraadt Exp $"; 60#endif 61 62#include <sys/param.h> 63#include <sys/types.h> 64#include <sys/socket.h> 65#include <sys/file.h> 66#include <sys/uio.h> 67#include <errno.h> 68#include <stdio.h> 69#include <stdlib.h> 70#include <string.h> 71#include <netinet/in.h> 72#include <arpa/inet.h> 73#include <sys/socket.h> 74#include <netdb.h> 75#include <unistd.h> 76#include <rpc/rpc.h> 77#include <rpc/xdr.h> 78#include <rpcsvc/yp.h> 79#include <rpcsvc/ypclnt.h> 80 81extern bool_t xdr_domainname(), xdr_ypbind_resp(); 82extern bool_t xdr_ypreq_key(), xdr_ypresp_val(); 83extern bool_t xdr_ypreq_nokey(), xdr_ypresp_key_val(); 84extern bool_t xdr_ypresp_all(), xdr_ypresp_all_seq(); 85extern bool_t xdr_ypresp_master(); 86 87extern int (*ypresp_allfn)(); 88extern void *ypresp_data; 89 90int _yplib_host_timeout = 10; 91 92CLIENT * 93yp_bind_host(server,program,version,port,usetcp) 94char *server; 95u_long program,version; 96u_short port; 97int usetcp; 98{ 99 struct sockaddr_in rsrv_sin; 100 int rsrv_sock; 101 struct hostent *h; 102 struct timeval tv; 103 static CLIENT *client; 104 105 memset(&rsrv_sin, 0, sizeof rsrv_sin); 106 rsrv_sin.sin_len = sizeof rsrv_sin; 107 rsrv_sin.sin_family = AF_INET; 108 rsrv_sock = RPC_ANYSOCK; 109 if (port != 0) { 110 rsrv_sin.sin_port = htons(port); 111 } 112 113 if ((*server >= '0') && (*server <= '9')) { 114 if(inet_aton(server,&rsrv_sin.sin_addr) == 0) { 115 fprintf(stderr, "inet_aton: invalid address %s.\n", 116 server); 117 exit(1); 118 } 119 } else { 120 h = gethostbyname(server); 121 if(h == NULL) { 122 fprintf(stderr, "gethostbyname: unknown host %s.\n", 123 server); 124 exit(1); 125 } 126 rsrv_sin.sin_addr.s_addr = *(u_int32_t *)h->h_addr; 127 } 128 129 tv.tv_sec = 10; 130 tv.tv_usec = 0; 131 132 if (usetcp) { 133 client = clnttcp_create(&rsrv_sin, program, version, 134 &rsrv_sock, 0, 0); 135 } else { 136 client = clntudp_create(&rsrv_sin, program, version, tv, 137 &rsrv_sock); 138 } 139 140 if (client == NULL) { 141 fprintf(stderr, "clntudp_create: no contact with host %s.\n", 142 server); 143 exit(1); 144 } 145 146 return(client); 147 148} 149 150CLIENT * 151yp_bind_local(program,version) 152u_long program,version; 153{ 154 struct sockaddr_in rsrv_sin; 155 int rsrv_sock; 156 struct timeval tv; 157 static CLIENT *client; 158 159 memset(&rsrv_sin, 0, sizeof rsrv_sin); 160 rsrv_sin.sin_len = sizeof rsrv_sin; 161 rsrv_sin.sin_family = AF_INET; 162 rsrv_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 163 rsrv_sock = RPC_ANYSOCK; 164 165 tv.tv_sec = 10; 166 tv.tv_usec = 0; 167 168 client = clntudp_create(&rsrv_sin, program, version, tv, &rsrv_sock); 169 if (client == NULL) { 170 fprintf(stderr,"clntudp_create: no contact with localhost.\n"); 171 exit(1); 172 } 173 174 return(client); 175 176} 177 178int 179yp_match_host(client, indomain, inmap, inkey, inkeylen, outval, outvallen) 180CLIENT *client; 181char *indomain; 182char *inmap; 183const char *inkey; 184int inkeylen; 185char **outval; 186int *outvallen; 187{ 188 struct ypresp_val yprv; 189 struct timeval tv; 190 struct ypreq_key yprk; 191 int r; 192 193 *outval = NULL; 194 *outvallen = 0; 195 196 tv.tv_sec = _yplib_host_timeout; 197 tv.tv_usec = 0; 198 199 yprk.domain = indomain; 200 yprk.map = inmap; 201 yprk.key.keydat_val = (char *)inkey; 202 yprk.key.keydat_len = inkeylen; 203 204 memset(&yprv, 0, sizeof yprv); 205 206 r = clnt_call(client, YPPROC_MATCH, 207 (xdrproc_t)xdr_ypreq_key, &yprk, (xdrproc_t)xdr_ypresp_val, &yprv, tv); 208 if(r != RPC_SUCCESS) { 209 clnt_perror(client, "yp_match_host: clnt_call"); 210 } 211 if( !(r=ypprot_err(yprv.stat)) ) { 212 *outvallen = yprv.val.valdat_len; 213 *outval = (char *)malloc(*outvallen+1); 214 memcpy(*outval, yprv.val.valdat_val, *outvallen); 215 (*outval)[*outvallen] = '\0'; 216 } 217 xdr_free((xdrproc_t)xdr_ypresp_val, (char *)&yprv); 218 return r; 219} 220 221int 222yp_first_host(client, indomain, inmap, outkey, outkeylen, outval, outvallen) 223CLIENT *client; 224char *indomain; 225char *inmap; 226char **outkey; 227int *outkeylen; 228char **outval; 229int *outvallen; 230{ 231 struct ypresp_key_val yprkv; 232 struct ypreq_nokey yprnk; 233 struct timeval tv; 234 int r; 235 236 *outkey = *outval = NULL; 237 *outkeylen = *outvallen = 0; 238 239 tv.tv_sec = _yplib_host_timeout; 240 tv.tv_usec = 0; 241 242 yprnk.domain = indomain; 243 yprnk.map = inmap; 244 memset(&yprkv, 0, sizeof yprkv); 245 246 r = clnt_call(client, YPPROC_FIRST, 247 (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, tv); 248 if(r != RPC_SUCCESS) { 249 clnt_perror(client, "yp_first_host: clnt_call"); 250 } 251 if( !(r=ypprot_err(yprkv.stat)) ) { 252 *outkeylen = yprkv.key.keydat_len; 253 *outkey = (char *)malloc(*outkeylen+1); 254 memcpy(*outkey, yprkv.key.keydat_val, *outkeylen); 255 (*outkey)[*outkeylen] = '\0'; 256 *outvallen = yprkv.val.valdat_len; 257 *outval = (char *)malloc(*outvallen+1); 258 memcpy(*outval, yprkv.val.valdat_val, *outvallen); 259 (*outval)[*outvallen] = '\0'; 260 } 261 xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)&yprkv); 262 return r; 263} 264 265int 266yp_next_host(client, indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen) 267CLIENT *client; 268char *indomain; 269char *inmap; 270char *inkey; 271int inkeylen; 272char **outkey; 273int *outkeylen; 274char **outval; 275int *outvallen; 276{ 277 struct ypresp_key_val yprkv; 278 struct ypreq_key yprk; 279 struct timeval tv; 280 int r; 281 282 *outkey = *outval = NULL; 283 *outkeylen = *outvallen = 0; 284 285 tv.tv_sec = _yplib_host_timeout; 286 tv.tv_usec = 0; 287 288 yprk.domain = indomain; 289 yprk.map = inmap; 290 yprk.key.keydat_val = inkey; 291 yprk.key.keydat_len = inkeylen; 292 memset(&yprkv, 0, sizeof yprkv); 293 294 r = clnt_call(client, YPPROC_NEXT, 295 (xdrproc_t)xdr_ypreq_key, &yprk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, tv); 296 if(r != RPC_SUCCESS) { 297 clnt_perror(client, "yp_next_host: clnt_call"); 298 } 299 if( !(r=ypprot_err(yprkv.stat)) ) { 300 *outkeylen = yprkv.key.keydat_len; 301 *outkey = (char *)malloc(*outkeylen+1); 302 memcpy(*outkey, yprkv.key.keydat_val, *outkeylen); 303 (*outkey)[*outkeylen] = '\0'; 304 *outvallen = yprkv.val.valdat_len; 305 *outval = (char *)malloc(*outvallen+1); 306 memcpy(*outval, yprkv.val.valdat_val, *outvallen); 307 (*outval)[*outvallen] = '\0'; 308 } 309 xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)&yprkv); 310 return r; 311} 312 313int 314yp_all_host(client, indomain, inmap, incallback) 315CLIENT *client; 316char *indomain; 317char *inmap; 318struct ypall_callback *incallback; 319{ 320 struct ypreq_nokey yprnk; 321 struct timeval tv; 322 u_long status; 323 324 tv.tv_sec = _yplib_host_timeout; 325 tv.tv_usec = 0; 326 327 yprnk.domain = indomain; 328 yprnk.map = inmap; 329 ypresp_allfn = incallback->foreach; 330 ypresp_data = (void *)incallback->data; 331 332 (void) clnt_call(client, YPPROC_ALL, 333 (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_all_seq, &status, tv); 334 xdr_free((xdrproc_t)xdr_ypresp_all_seq, (char *)&status); /* not really needed... */ 335 336 if(status != YP_FALSE) 337 return ypprot_err(status); 338 return 0; 339} 340 341int 342yp_order_host(client, indomain, inmap, outorder) 343CLIENT *client; 344char *indomain; 345char *inmap; 346u_int32_t *outorder; 347{ 348 struct ypresp_order ypro; 349 struct ypreq_nokey yprnk; 350 struct timeval tv; 351 int r; 352 353 tv.tv_sec = _yplib_host_timeout; 354 tv.tv_usec = 0; 355 356 yprnk.domain = indomain; 357 yprnk.map = inmap; 358 359 memset(&ypro, 0, sizeof ypro); 360 361 r = clnt_call(client, YPPROC_ORDER, 362 (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_order, &ypro, tv); 363 if(r != RPC_SUCCESS) { 364 clnt_perror(client, "yp_order_host: clnt_call"); 365 } 366 367 *outorder = ypro.ordernum; 368 xdr_free((xdrproc_t)xdr_ypresp_order, (char *)&ypro); 369 return ypprot_err(ypro.stat); 370} 371 372int 373yp_master_host(client, indomain, inmap, outname) 374CLIENT *client; 375char *indomain; 376char *inmap; 377char **outname; 378{ 379 struct ypresp_master yprm; 380 struct ypreq_nokey yprnk; 381 struct timeval tv; 382 int r; 383 384 tv.tv_sec = _yplib_host_timeout; 385 tv.tv_usec = 0; 386 387 yprnk.domain = indomain; 388 yprnk.map = inmap; 389 390 memset(&yprm, 0, sizeof yprm); 391 392 r = clnt_call(client, YPPROC_MASTER, 393 (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_master, &yprm, tv); 394 if(r != RPC_SUCCESS) { 395 clnt_perror(client, "yp_master: clnt_call"); 396 } 397 if( !(r=ypprot_err(yprm.stat)) ) { 398 *outname = (char *)strdup(yprm.peer); 399 } 400 xdr_free((xdrproc_t)xdr_ypresp_master, (char *)&yprm); 401 return r; 402} 403 404int 405yp_maplist_host(client, indomain, outmaplist) 406CLIENT *client; 407char *indomain; 408struct ypmaplist **outmaplist; 409{ 410 struct ypresp_maplist ypml; 411 struct timeval tv; 412 int r; 413 414 tv.tv_sec = _yplib_host_timeout; 415 tv.tv_usec = 0; 416 417 memset(&ypml, 0, sizeof ypml); 418 419 r = clnt_call(client, YPPROC_MAPLIST, 420 (xdrproc_t)xdr_domainname, &indomain, (xdrproc_t)xdr_ypresp_maplist, &ypml, tv); 421 if (r != RPC_SUCCESS) { 422 clnt_perror(client, "yp_maplist: clnt_call"); 423 } 424 *outmaplist = ypml.maps; 425 /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/ 426 return ypprot_err(ypml.stat); 427} 428 429