1 /* $NetBSD: yp_first.c,v 1.17 2024/01/03 18:41:53 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt (at) fsa.ca> 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 #if defined(LIBC_SCCS) && !defined(lint) 31 __RCSID("$NetBSD: yp_first.c,v 1.17 2024/01/03 18:41:53 christos Exp $"); 32 #endif 33 34 #include "namespace.h" 35 #include <stdlib.h> 36 #include <string.h> 37 #include <rpc/rpc.h> 38 #include <rpcsvc/yp_prot.h> 39 #include <rpcsvc/ypclnt.h> 40 #include "local.h" 41 42 #ifdef __weak_alias 43 __weak_alias(yp_first,_yp_first) 44 __weak_alias(yp_next,_yp_next) 45 #endif 46 47 int 48 yp_first(const char *indomain, const char *inmap, char **outkey, 49 int *outkeylen, char **outval, int *outvallen) 50 { 51 struct ypresp_key_val yprkv; 52 struct ypreq_nokey yprnk; 53 struct dom_binding *ysd; 54 int r, nerrs = 0; 55 56 if (outkey == NULL || outkeylen == NULL || \ 57 outval == NULL || outvallen == NULL) 58 return YPERR_BADARGS; 59 *outkey = *outval = NULL; 60 *outkeylen = *outvallen = 0; 61 if (_yp_invalid_domain(indomain)) 62 return YPERR_BADARGS; 63 if (inmap == NULL || *inmap == '\0' 64 || strlen(inmap) > YPMAXMAP) 65 return YPERR_BADARGS; 66 67 again: 68 if (_yp_dobind(indomain, &ysd) != 0) 69 return YPERR_DOMAIN; 70 71 yprnk.domain = indomain; 72 yprnk.map = inmap; 73 (void)memset(&yprkv, 0, sizeof yprkv); 74 75 r = clnt_call(ysd->dom_client, (rpcproc_t)YPPROC_FIRST, 76 (xdrproc_t)xdr_ypreq_nokey, 77 &yprnk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, _yplib_timeout); 78 if (r != RPC_SUCCESS) { 79 if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) { 80 clnt_perror(ysd->dom_client, "yp_first: clnt_call"); 81 nerrs = 0; 82 } else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries) 83 return YPERR_YPSERV; 84 ysd->dom_vers = -1; 85 goto again; 86 } 87 if (!(r = ypprot_err(yprkv.status))) { 88 *outkeylen = yprkv.keydat.dsize; 89 if ((*outkey = malloc((size_t)(*outkeylen + 1))) == NULL) 90 r = YPERR_RESRC; 91 else { 92 (void)memcpy(*outkey, yprkv.keydat.dptr, 93 (size_t)*outkeylen); 94 (*outkey)[*outkeylen] = '\0'; 95 } 96 *outvallen = yprkv.valdat.dsize; 97 if ((*outval = malloc((size_t)(*outvallen + 1))) == NULL) 98 r = YPERR_RESRC; 99 else { 100 (void)memcpy(*outval, yprkv.valdat.dptr, 101 (size_t)*outvallen); 102 (*outval)[*outvallen] = '\0'; 103 } 104 } 105 xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)(void *)&yprkv); 106 __yp_unbind(ysd); 107 if (r != 0) { 108 if (*outkey) { 109 free(*outkey); 110 *outkey = NULL; 111 } 112 if (*outval) { 113 free(*outval); 114 *outval = NULL; 115 } 116 } 117 return r; 118 } 119 120 int 121 yp_next(const char *indomain, const char *inmap, const char *inkey, 122 int inkeylen, char **outkey, int *outkeylen, char **outval, int *outvallen) 123 { 124 struct ypresp_key_val yprkv; 125 struct ypreq_key yprk; 126 struct dom_binding *ysd; 127 int r, nerrs = 0; 128 129 if (outkey == NULL || outkeylen == NULL || \ 130 outval == NULL || outvallen == NULL || \ 131 inkey == NULL) 132 return YPERR_BADARGS; 133 *outkey = *outval = NULL; 134 *outkeylen = *outvallen = 0; 135 136 if (_yp_invalid_domain(indomain)) 137 return YPERR_BADARGS; 138 if (inmap == NULL || *inmap == '\0' 139 || strlen(inmap) > YPMAXMAP) 140 return YPERR_BADARGS; 141 142 again: 143 if (_yp_dobind(indomain, &ysd) != 0) 144 return YPERR_DOMAIN; 145 146 yprk.domain = indomain; 147 yprk.map = inmap; 148 yprk.keydat.dptr = inkey; 149 yprk.keydat.dsize = inkeylen; 150 (void)memset(&yprkv, 0, sizeof yprkv); 151 152 r = clnt_call(ysd->dom_client, (rpcproc_t)YPPROC_NEXT, 153 (xdrproc_t)xdr_ypreq_key, 154 &yprk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, _yplib_timeout); 155 if (r != RPC_SUCCESS) { 156 if (_yplib_bindtries <= 0 && ++nerrs == _yplib_nerrs) { 157 clnt_perror(ysd->dom_client, "yp_next: clnt_call"); 158 nerrs = 0; 159 } else if (_yplib_bindtries > 0 && ++nerrs == _yplib_bindtries) 160 return YPERR_YPSERV; 161 ysd->dom_vers = -1; 162 goto again; 163 } 164 if (!(r = ypprot_err(yprkv.status))) { 165 *outkeylen = yprkv.keydat.dsize; 166 if ((*outkey = malloc((size_t)(*outkeylen + 1))) == NULL) 167 r = YPERR_RESRC; 168 else { 169 (void)memcpy(*outkey, yprkv.keydat.dptr, 170 (size_t)*outkeylen); 171 (*outkey)[*outkeylen] = '\0'; 172 } 173 *outvallen = yprkv.valdat.dsize; 174 if ((*outval = malloc((size_t)(*outvallen + 1))) == NULL) 175 r = YPERR_RESRC; 176 else { 177 (void)memcpy(*outval, yprkv.valdat.dptr, 178 (size_t)*outvallen); 179 (*outval)[*outvallen] = '\0'; 180 } 181 } 182 xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)(void *)&yprkv); 183 __yp_unbind(ysd); 184 if (r != 0) { 185 if (*outkey) { 186 free(*outkey); 187 *outkey = NULL; 188 } 189 if (*outval) { 190 free(*outval); 191 *outval = NULL; 192 } 193 } 194 return r; 195 } 196