1 /* $OpenBSD: yp_all.c,v 1.13 2015/09/28 14:51:04 deraadt Exp $ */ 2 /* 3 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/types.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <limits.h> 33 #include <rpc/rpc.h> 34 #include <rpc/xdr.h> 35 #include <rpcsvc/yp.h> 36 #include <rpcsvc/ypclnt.h> 37 #include "ypinternal.h" 38 39 static int (*ypresp_allfn)(u_long, char *, int, char *, int, void *); 40 static void *ypresp_data; 41 42 static bool_t 43 _xdr_ypresp_all_seq(XDR *xdrs, u_long *objp) 44 { 45 struct ypresp_all out; 46 u_long status; 47 char *key, *val; 48 int size; 49 int done = 0; /* set to 1 when the user does not want more data */ 50 bool_t rc = TRUE; /* FALSE at the end of loop signals failure */ 51 52 memset(&out, 0, sizeof out); 53 while (rc && !done) { 54 rc = FALSE; 55 if (!xdr_ypresp_all(xdrs, &out)) { 56 *objp = (u_long)YP_YPERR; 57 goto fail; 58 } 59 if (out.more == 0) 60 goto fail; 61 status = out.ypresp_all_u.val.stat; 62 if (status == YP_TRUE) { 63 size = out.ypresp_all_u.val.key.keydat_len; 64 if ((key = malloc(size + 1)) == NULL) { 65 *objp = (u_long)YP_YPERR; 66 goto fail; 67 } 68 (void)memcpy(key, out.ypresp_all_u.val.key.keydat_val, 69 size); 70 key[size] = '\0'; 71 72 size = out.ypresp_all_u.val.val.valdat_len; 73 if ((val = malloc(size + 1)) == NULL) { 74 free(key); 75 *objp = (u_long)YP_YPERR; 76 goto fail; 77 } 78 (void)memcpy(val, out.ypresp_all_u.val.val.valdat_val, 79 size); 80 val[size] = '\0'; 81 82 done = (*ypresp_allfn)(status, key, 83 out.ypresp_all_u.val.key.keydat_len, val, 84 out.ypresp_all_u.val.val.valdat_len, ypresp_data); 85 free(key); 86 free(val); 87 } else 88 done = 1; 89 if (status != YP_NOMORE) 90 *objp = status; 91 rc = TRUE; 92 fail: 93 xdr_free(xdr_ypresp_all, (char *)&out); 94 } 95 return rc; 96 } 97 98 int 99 yp_all(const char *indomain, const char *inmap, struct ypall_callback *incallback) 100 { 101 struct ypreq_nokey yprnk; 102 struct dom_binding *ysd; 103 struct timeval tv; 104 struct sockaddr_in clnt_sin; 105 CLIENT *clnt; 106 u_long status; 107 int clnt_sock; 108 int r = 0; 109 110 if (indomain == NULL || *indomain == '\0' || 111 strlen(indomain) > YPMAXDOMAIN || inmap == NULL || 112 *inmap == '\0' || strlen(inmap) > YPMAXMAP || incallback == NULL) 113 return YPERR_BADARGS; 114 115 if (_yp_dobind(indomain, &ysd) != 0) 116 return YPERR_DOMAIN; 117 118 tv.tv_sec = _yplib_timeout; 119 tv.tv_usec = 0; 120 clnt_sock = RPC_ANYSOCK; 121 clnt_sin = ysd->dom_server_addr; 122 clnt_sin.sin_port = 0; 123 clnt = clnttcp_create(&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0); 124 if (clnt == NULL) { 125 printf("clnttcp_create failed\n"); 126 r = YPERR_PMAP; 127 goto out; 128 } 129 yprnk.domain = (char *)indomain; 130 yprnk.map = (char *)inmap; 131 ypresp_allfn = incallback->foreach; 132 ypresp_data = (void *) incallback->data; 133 134 (void) clnt_call(clnt, YPPROC_ALL, 135 xdr_ypreq_nokey, &yprnk, _xdr_ypresp_all_seq, &status, tv); 136 clnt_destroy(clnt); 137 if (status != YP_FALSE) 138 r = ypprot_err(status); 139 out: 140 _yp_unbind(ysd); 141 return r; 142 } 143