1 /* $NetBSD: yplib_host.c,v 1.4 1999/01/31 10:14:02 mrg Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Theo de Raadt. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 #ifndef lint 36 __RCSID("$NetBSD: yplib_host.c,v 1.4 1999/01/31 10:14:02 mrg Exp $"); 37 #endif 38 39 #include <sys/param.h> 40 #include <sys/types.h> 41 #include <sys/socket.h> 42 #include <sys/file.h> 43 #include <sys/uio.h> 44 45 #include <netinet/in.h> 46 #include <arpa/inet.h> 47 48 #include <ctype.h> 49 #include <err.h> 50 #include <errno.h> 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <string.h> 54 #include <netdb.h> 55 #include <unistd.h> 56 57 #include <rpc/rpc.h> 58 #include <rpc/xdr.h> 59 #include <rpcsvc/yp_prot.h> 60 #include <rpcsvc/ypclnt.h> 61 62 #include "yplib_host.h" 63 64 struct timeval _yplib_host_timeout = { 10, 0 }; 65 66 CLIENT * 67 yp_bind_host(server, program, version, port, usetcp) 68 char *server; 69 u_int program, version; 70 u_short port; 71 int usetcp; 72 { 73 struct sockaddr_in rsrv_sin; 74 int rsrv_sock; 75 struct hostent *h; 76 static CLIENT *client; 77 78 memset(&rsrv_sin, 0, sizeof rsrv_sin); 79 rsrv_sin.sin_len = sizeof rsrv_sin; 80 rsrv_sin.sin_family = AF_INET; 81 rsrv_sock = RPC_ANYSOCK; 82 if (port != 0) { 83 rsrv_sin.sin_port = htons(port); 84 } 85 86 if (isdigit(*server)) { 87 if (inet_aton(server,&rsrv_sin.sin_addr) == 0) { 88 errx(1, "invalid IP address `%s'", server); 89 } 90 } else { 91 h = gethostbyname(server); 92 if(h == NULL) { 93 errx(1, "unknown host `%s'", server); 94 } 95 memcpy(&rsrv_sin.sin_addr.s_addr, h->h_addr_list[0], 96 h->h_length); 97 } 98 99 if (usetcp) 100 client = clnttcp_create(&rsrv_sin, program, version, 101 &rsrv_sock, 0, 0); 102 else 103 client = clntudp_create(&rsrv_sin, program, version, 104 _yplib_host_timeout, &rsrv_sock); 105 106 if (client == NULL) 107 errx(1, "%s: no contact with host `%s'", 108 usetcp ? "clnttcp_create" : "clntudp_create", server); 109 110 return(client); 111 } 112 113 CLIENT * 114 yp_bind_local(program, version) 115 u_int program, version; 116 { 117 struct sockaddr_in rsrv_sin; 118 int rsrv_sock; 119 static CLIENT *client; 120 121 memset(&rsrv_sin, 0, sizeof rsrv_sin); 122 rsrv_sin.sin_len = sizeof rsrv_sin; 123 rsrv_sin.sin_family = AF_INET; 124 rsrv_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 125 rsrv_sock = RPC_ANYSOCK; 126 127 client = clntudp_create(&rsrv_sin, program, version, 128 _yplib_host_timeout, &rsrv_sock); 129 if (client == NULL) 130 errx(1, "clntudp_create: no contact with localhost"); 131 132 return(client); 133 } 134 135 int 136 yp_match_host(client, indomain, inmap, inkey, inkeylen, outval, outvallen) 137 CLIENT *client; 138 char *indomain; 139 char *inmap; 140 const char *inkey; 141 int inkeylen; 142 char **outval; 143 int *outvallen; 144 { 145 struct ypresp_val yprv; 146 struct ypreq_key yprk; 147 int r; 148 149 *outval = NULL; 150 *outvallen = 0; 151 152 yprk.domain = indomain; 153 yprk.map = inmap; 154 yprk.keydat.dptr = (char *)inkey; 155 yprk.keydat.dsize = inkeylen; 156 157 memset(&yprv, 0, sizeof yprv); 158 159 r = clnt_call(client, YPPROC_MATCH, xdr_ypreq_key, &yprk, 160 xdr_ypresp_val, &yprv, _yplib_host_timeout); 161 if(r != RPC_SUCCESS) 162 clnt_perror(client, "yp_match_host: clnt_call"); 163 164 if(!(r=ypprot_err(yprv.status)) ) { 165 *outvallen = yprv.valdat.dsize; 166 *outval = (char *)malloc(*outvallen+1); 167 memcpy(*outval, yprv.valdat.dptr, *outvallen); 168 (*outval)[*outvallen] = '\0'; 169 } 170 xdr_free(xdr_ypresp_val, (char *)&yprv); 171 return r; 172 } 173 174 int 175 yp_first_host(client, indomain, inmap, outkey, outkeylen, outval, outvallen) 176 CLIENT *client; 177 char *indomain; 178 char *inmap; 179 char **outkey; 180 int *outkeylen; 181 char **outval; 182 int *outvallen; 183 { 184 struct ypresp_key_val yprkv; 185 struct ypreq_nokey yprnk; 186 int r; 187 188 *outkey = *outval = NULL; 189 *outkeylen = *outvallen = 0; 190 191 yprnk.domain = indomain; 192 yprnk.map = inmap; 193 memset(&yprkv, 0, sizeof yprkv); 194 195 r = clnt_call(client, YPPROC_FIRST, xdr_ypreq_nokey, &yprnk, 196 xdr_ypresp_key_val, &yprkv, _yplib_host_timeout); 197 if (r != RPC_SUCCESS) 198 clnt_perror(client, "yp_first_host: clnt_call"); 199 200 if(!(r=ypprot_err(yprkv.status)) ) { 201 *outkeylen = yprkv.keydat.dsize; 202 *outkey = (char *)malloc(*outkeylen+1); 203 memcpy(*outkey, yprkv.keydat.dptr, *outkeylen); 204 (*outkey)[*outkeylen] = '\0'; 205 *outvallen = yprkv.valdat.dsize; 206 *outval = (char *)malloc(*outvallen+1); 207 memcpy(*outval, yprkv.valdat.dptr, *outvallen); 208 (*outval)[*outvallen] = '\0'; 209 } 210 xdr_free(xdr_ypresp_key_val, (char *)&yprkv); 211 return r; 212 } 213 214 int 215 yp_next_host(client, indomain, inmap, inkey, inkeylen, outkey, 216 outkeylen, outval, outvallen) 217 CLIENT *client; 218 char *indomain; 219 char *inmap; 220 char *inkey; 221 int inkeylen; 222 char **outkey; 223 int *outkeylen; 224 char **outval; 225 int *outvallen; 226 { 227 struct ypresp_key_val yprkv; 228 struct ypreq_key yprk; 229 int r; 230 231 *outkey = *outval = NULL; 232 *outkeylen = *outvallen = 0; 233 234 yprk.domain = indomain; 235 yprk.map = inmap; 236 yprk.keydat.dptr = inkey; 237 yprk.keydat.dsize = inkeylen; 238 memset(&yprkv, 0, sizeof yprkv); 239 240 r = clnt_call(client, YPPROC_NEXT, xdr_ypreq_key, &yprk, 241 xdr_ypresp_key_val, &yprkv, _yplib_host_timeout); 242 if (r != RPC_SUCCESS) 243 clnt_perror(client, "yp_next_host: clnt_call"); 244 245 if(!(r=ypprot_err(yprkv.status)) ) { 246 *outkeylen = yprkv.keydat.dsize; 247 *outkey = (char *)malloc(*outkeylen+1); 248 memcpy(*outkey, yprkv.keydat.dptr, *outkeylen); 249 (*outkey)[*outkeylen] = '\0'; 250 *outvallen = yprkv.valdat.dsize; 251 *outval = (char *)malloc(*outvallen+1); 252 memcpy(*outval, yprkv.valdat.dptr, *outvallen); 253 (*outval)[*outvallen] = '\0'; 254 } 255 xdr_free(xdr_ypresp_key_val, (char *)&yprkv); 256 return r; 257 } 258 259 int 260 yp_all_host(client, indomain, inmap, incallback) 261 CLIENT *client; 262 char *indomain; 263 char *inmap; 264 struct ypall_callback *incallback; 265 { 266 struct ypreq_nokey yprnk; 267 int status; 268 269 yprnk.domain = indomain; 270 yprnk.map = inmap; 271 272 status = clnt_call(client, YPPROC_ALL, xdr_ypreq_nokey, &yprnk, 273 xdr_ypall, (char *)incallback, _yplib_host_timeout); 274 275 if (status != RPC_SUCCESS) 276 return YPERR_RPC; 277 278 return 0; 279 } 280 281 int 282 yp_order_host(client, indomain, inmap, outorder) 283 CLIENT *client; 284 char *indomain; 285 char *inmap; 286 int *outorder; 287 { 288 struct ypresp_order ypro; 289 struct ypreq_nokey yprnk; 290 int r; 291 292 yprnk.domain = indomain; 293 yprnk.map = inmap; 294 295 memset(&ypro, 0, sizeof ypro); 296 297 r = clnt_call(client, YPPROC_ORDER, xdr_ypreq_nokey, &yprnk, 298 xdr_ypresp_order, &ypro, _yplib_host_timeout); 299 if (r != RPC_SUCCESS) 300 clnt_perror(client, "yp_order_host: clnt_call"); 301 302 *outorder = ypro.ordernum; 303 xdr_free(xdr_ypresp_order, (char *)&ypro); 304 return ypprot_err(ypro.status); 305 } 306 307 int 308 yp_master_host(client, indomain, inmap, outname) 309 CLIENT *client; 310 char *indomain; 311 char *inmap; 312 char **outname; 313 { 314 struct ypresp_master yprm; 315 struct ypreq_nokey yprnk; 316 int r; 317 318 yprnk.domain = indomain; 319 yprnk.map = inmap; 320 321 memset(&yprm, 0, sizeof yprm); 322 323 r = clnt_call(client, YPPROC_MASTER, xdr_ypreq_nokey, &yprnk, 324 xdr_ypresp_master, &yprm, _yplib_host_timeout); 325 if (r != RPC_SUCCESS) 326 clnt_perror(client, "yp_master: clnt_call"); 327 328 if (!(r = ypprot_err(yprm.status))) { 329 *outname = (char *)strdup(yprm.master); 330 } 331 xdr_free(xdr_ypresp_master, (char *)&yprm); 332 return r; 333 } 334 335 int 336 yp_maplist_host(client, indomain, outmaplist) 337 CLIENT *client; 338 char *indomain; 339 struct ypmaplist **outmaplist; 340 { 341 struct ypresp_maplist ypml; 342 int r; 343 344 memset(&ypml, 0, sizeof ypml); 345 346 r = clnt_call(client, YPPROC_MAPLIST, xdr_ypdomain_wrap_string, 347 indomain, xdr_ypresp_maplist, &ypml, _yplib_host_timeout); 348 if (r != RPC_SUCCESS) 349 clnt_perror(client, "yp_maplist: clnt_call"); 350 351 *outmaplist = ypml.list; 352 /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/ 353 return ypprot_err(ypml.status); 354 } 355