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