1 /* $NetBSD: yplib_host.c,v 1.1.1.1 1996/08/09 10:14:51 thorpej 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/param.h> 35 #include <sys/types.h> 36 #include <sys/socket.h> 37 #include <sys/file.h> 38 #include <sys/uio.h> 39 40 #include <netinet/in.h> 41 #include <arpa/inet.h> 42 43 #include <errno.h> 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <string.h> 47 #include <netdb.h> 48 #include <unistd.h> 49 50 #include <rpc/rpc.h> 51 #include <rpc/xdr.h> 52 #include <rpcsvc/yp_prot.h> 53 #include <rpcsvc/ypclnt.h> 54 55 struct timeval _yplib_host_timeout = { 10, 0 }; 56 57 CLIENT * 58 yp_bind_host(server, program, version, port, usetcp) 59 char *server; 60 u_int program, version; 61 u_short port; 62 int usetcp; 63 { 64 struct sockaddr_in rsrv_sin; 65 int rsrv_sock; 66 struct hostent *h; 67 static CLIENT *client; 68 69 memset(&rsrv_sin, 0, sizeof rsrv_sin); 70 rsrv_sin.sin_len = sizeof rsrv_sin; 71 rsrv_sin.sin_family = AF_INET; 72 rsrv_sock = RPC_ANYSOCK; 73 if (port != 0) { 74 rsrv_sin.sin_port = htons(port); 75 } 76 77 if (isdigit(*server)) { 78 if (inet_aton(server,&rsrv_sin.sin_addr) == 0) { 79 errx(1, "invalid IP address `%s'", server); 80 } 81 } else { 82 h = gethostbyname(server); 83 if(h == NULL) { 84 errx(1, "unknown host `%s'", server); 85 } 86 memcpy(&rsrv_sin.sin_addr.s_addr, h->h_addr_list[0], 87 h->h_length); 88 } 89 90 if (usetcp) 91 client = clnttcp_create(&rsrv_sin, program, version, 92 &rsrv_sock, 0, 0); 93 else 94 client = clntudp_create(&rsrv_sin, program, version, 95 _yplib_host_timeout, &rsrv_sock); 96 97 if (client == NULL) 98 errx(1, "%s: no contact with host `%s'", 99 usetcp ? "clnttcp_create" : "clntudp_create", server); 100 101 return(client); 102 } 103 104 CLIENT * 105 yp_bind_local(program, version) 106 u_int program, version; 107 { 108 struct sockaddr_in rsrv_sin; 109 int rsrv_sock; 110 static CLIENT *client; 111 112 memset(&rsrv_sin, 0, sizeof rsrv_sin); 113 rsrv_sin.sin_len = sizeof rsrv_sin; 114 rsrv_sin.sin_family = AF_INET; 115 rsrv_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 116 rsrv_sock = RPC_ANYSOCK; 117 118 client = clntudp_create(&rsrv_sin, program, version, 119 _yplib_host_timeout, &rsrv_sock); 120 if (client == NULL) 121 errx(1, "clntudp_create: no contact with localhost"); 122 123 return(client); 124 } 125 126 int 127 yp_match_host(client, indomain, inmap, inkey, inkeylen, outval, outvallen) 128 CLIENT *client; 129 char *indomain; 130 char *inmap; 131 const char *inkey; 132 int inkeylen; 133 char **outval; 134 int *outvallen; 135 { 136 struct ypresp_val yprv; 137 struct ypreq_key yprk; 138 int r; 139 140 *outval = NULL; 141 *outvallen = 0; 142 143 yprk.domain = indomain; 144 yprk.map = inmap; 145 yprk.keydat.dptr = (char *)inkey; 146 yprk.keydat.dsize = inkeylen; 147 148 memset(&yprv, 0, sizeof yprv); 149 150 r = clnt_call(client, YPPROC_MATCH, xdr_ypreq_key, &yprk, 151 xdr_ypresp_val, &yprv, _yplib_host_timeout); 152 if(r != RPC_SUCCESS) 153 clnt_perror(client, "yp_match_host: clnt_call"); 154 155 if(!(r=ypprot_err(yprv.status)) ) { 156 *outvallen = yprv.valdat.dsize; 157 *outval = (char *)malloc(*outvallen+1); 158 memcpy(*outval, yprv.valdat.dptr, *outvallen); 159 (*outval)[*outvallen] = '\0'; 160 } 161 xdr_free(xdr_ypresp_val, (char *)&yprv); 162 return r; 163 } 164 165 int 166 yp_first_host(client, indomain, inmap, outkey, outkeylen, outval, outvallen) 167 CLIENT *client; 168 char *indomain; 169 char *inmap; 170 char **outkey; 171 int *outkeylen; 172 char **outval; 173 int *outvallen; 174 { 175 struct ypresp_key_val yprkv; 176 struct ypreq_nokey yprnk; 177 int r; 178 179 *outkey = *outval = NULL; 180 *outkeylen = *outvallen = 0; 181 182 yprnk.domain = indomain; 183 yprnk.map = inmap; 184 memset(&yprkv, 0, sizeof yprkv); 185 186 r = clnt_call(client, YPPROC_FIRST, xdr_ypreq_nokey, &yprnk, 187 xdr_ypresp_key_val, &yprkv, _yplib_host_timeout); 188 if (r != RPC_SUCCESS) 189 clnt_perror(client, "yp_first_host: clnt_call"); 190 191 if(!(r=ypprot_err(yprkv.status)) ) { 192 *outkeylen = yprkv.keydat.dsize; 193 *outkey = (char *)malloc(*outkeylen+1); 194 memcpy(*outkey, yprkv.keydat.dptr, *outkeylen); 195 (*outkey)[*outkeylen] = '\0'; 196 *outvallen = yprkv.valdat.dsize; 197 *outval = (char *)malloc(*outvallen+1); 198 memcpy(*outval, yprkv.valdat.dptr, *outvallen); 199 (*outval)[*outvallen] = '\0'; 200 } 201 xdr_free(xdr_ypresp_key_val, (char *)&yprkv); 202 return r; 203 } 204 205 int 206 yp_next_host(client, indomain, inmap, inkey, inkeylen, outkey, 207 outkeylen, outval, outvallen) 208 CLIENT *client; 209 char *indomain; 210 char *inmap; 211 char *inkey; 212 int inkeylen; 213 char **outkey; 214 int *outkeylen; 215 char **outval; 216 int *outvallen; 217 { 218 struct ypresp_key_val yprkv; 219 struct ypreq_key yprk; 220 int r; 221 222 *outkey = *outval = NULL; 223 *outkeylen = *outvallen = 0; 224 225 yprk.domain = indomain; 226 yprk.map = inmap; 227 yprk.keydat.dptr = inkey; 228 yprk.keydat.dsize = inkeylen; 229 memset(&yprkv, 0, sizeof yprkv); 230 231 r = clnt_call(client, YPPROC_NEXT, xdr_ypreq_key, &yprk, 232 xdr_ypresp_key_val, &yprkv, _yplib_host_timeout); 233 if (r != RPC_SUCCESS) 234 clnt_perror(client, "yp_next_host: clnt_call"); 235 236 if(!(r=ypprot_err(yprkv.status)) ) { 237 *outkeylen = yprkv.keydat.dsize; 238 *outkey = (char *)malloc(*outkeylen+1); 239 memcpy(*outkey, yprkv.keydat.dptr, *outkeylen); 240 (*outkey)[*outkeylen] = '\0'; 241 *outvallen = yprkv.valdat.dsize; 242 *outval = (char *)malloc(*outvallen+1); 243 memcpy(*outval, yprkv.valdat.dptr, *outvallen); 244 (*outval)[*outvallen] = '\0'; 245 } 246 xdr_free(xdr_ypresp_key_val, (char *)&yprkv); 247 return r; 248 } 249 250 int 251 yp_all_host(client, indomain, inmap, incallback) 252 CLIENT *client; 253 char *indomain; 254 char *inmap; 255 struct ypall_callback *incallback; 256 { 257 struct ypreq_nokey yprnk; 258 int status; 259 260 yprnk.domain = indomain; 261 yprnk.map = inmap; 262 263 status = clnt_call(client, YPPROC_ALL, xdr_ypreq_nokey, &yprnk, 264 xdr_ypall, (char *)incallback, _yplib_host_timeout); 265 266 if (status != RPC_SUCCESS) 267 return YPERR_RPC; 268 269 return 0; 270 } 271 272 int 273 yp_order_host(client, indomain, inmap, outorder) 274 CLIENT *client; 275 char *indomain; 276 char *inmap; 277 int *outorder; 278 { 279 struct ypresp_order ypro; 280 struct ypreq_nokey yprnk; 281 int r; 282 283 yprnk.domain = indomain; 284 yprnk.map = inmap; 285 286 memset(&ypro, 0, sizeof ypro); 287 288 r = clnt_call(client, YPPROC_ORDER, xdr_ypreq_nokey, &yprnk, 289 xdr_ypresp_order, &ypro, _yplib_host_timeout); 290 if(r != RPC_SUCCESS) 291 clnt_perror(client, "yp_order_host: clnt_call"); 292 293 *outorder = ypro.ordernum; 294 xdr_free(xdr_ypresp_order, (char *)&ypro); 295 return ypprot_err(ypro.status); 296 } 297 298 int 299 yp_master_host(client, indomain, inmap, outname) 300 CLIENT *client; 301 char *indomain; 302 char *inmap; 303 char **outname; 304 { 305 struct ypresp_master yprm; 306 struct ypreq_nokey yprnk; 307 int r; 308 309 yprnk.domain = indomain; 310 yprnk.map = inmap; 311 312 memset(&yprm, 0, sizeof yprm); 313 314 r = clnt_call(client, YPPROC_MASTER, xdr_ypreq_nokey, &yprnk, 315 xdr_ypresp_master, &yprm, _yplib_host_timeout); 316 if (r != RPC_SUCCESS) 317 clnt_perror(client, "yp_master: clnt_call"); 318 319 if(!(r=ypprot_err(yprm.status)) ) { 320 *outname = (char *)strdup(yprm.master); 321 } 322 xdr_free(xdr_ypresp_master, (char *)&yprm); 323 return r; 324 } 325 326 int 327 yp_maplist_host(client, indomain, outmaplist) 328 CLIENT *client; 329 char *indomain; 330 struct ypmaplist **outmaplist; 331 { 332 struct ypresp_maplist ypml; 333 int r; 334 335 memset(&ypml, 0, sizeof ypml); 336 337 r = clnt_call(client, YPPROC_MAPLIST, xdr_ypdomain_wrap_string, 338 indomain, xdr_ypresp_maplist, &ypml, _yplib_host_timeout); 339 if (r != RPC_SUCCESS) 340 clnt_perror(client, "yp_maplist: clnt_call"); 341 342 *outmaplist = ypml.list; 343 /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/ 344 return ypprot_err(ypml.status); 345 } 346