1 /* $NetBSD: yp_match.c,v 1.19 2012/03/20 16:30:26 matt Exp $ */
4 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
29 #include <sys/cdefs.h>
30 #if defined(LIBC_SCCS) && !defined(lint)
31 __RCSID("$NetBSD: yp_match.c,v 1.19 2012/03/20 16:30:26 matt Exp $");
34 #include "namespace.h"
42 #include <rpcsvc/yp_prot.h>
43 #include <rpcsvc/ypclnt.h>
48 extern struct timeval _yplib_timeout
;
49 extern int _yplib_nerrs
;
50 extern int _yplib_bindtries
;
51 extern char _yp_domain
[];
54 __weak_alias(yp_match
,_yp_match
)
60 static struct ypmatch_ent
{
61 struct ypmatch_ent
*next
;
68 static bool_t
ypmatch_add(const char *, const char *, int, char *, int);
69 static bool_t
ypmatch_find(const char *, const char *, int, const char **,
73 ypmatch_add(const char *map
, const char *key
, int keylen
, char *val
, int vallen
)
75 struct ypmatch_ent
*ep
;
78 _DIAGASSERT(map
!= NULL
);
79 _DIAGASSERT(key
!= NULL
);
80 _DIAGASSERT(val
!= NULL
);
84 for (ep
= ypmc
; ep
; ep
= ep
->next
)
88 if ((ep
= malloc(sizeof *ep
)) == NULL
)
90 (void)memset(ep
, 0, sizeof *ep
);
105 if ((ep
->key
= malloc((size_t)keylen
)) == NULL
)
108 if ((ep
->val
= malloc((size_t)vallen
)) == NULL
) {
117 (void)memcpy(ep
->key
, key
, (size_t)ep
->keylen
);
118 (void)memcpy(ep
->val
, val
, (size_t)ep
->vallen
);
121 if (strcmp(ep
->map
, map
)) {
123 if ((ep
->map
= strdup(map
)) == NULL
)
127 if ((ep
->map
= strdup(map
)) == NULL
)
131 ep
->expire_t
= t
+ _yplib_cache
;
136 ypmatch_find(const char *map
, const char *key
, int keylen
, const char **val
,
139 struct ypmatch_ent
*ep
;
142 _DIAGASSERT(map
!= NULL
);
143 _DIAGASSERT(key
!= NULL
);
144 _DIAGASSERT(val
!= NULL
);
151 for (ep
= ypmc
; ep
; ep
= ep
->next
) {
152 if (ep
->keylen
!= keylen
)
154 if (strcmp(ep
->map
, map
))
156 if (memcmp(ep
->key
, key
, (size_t)keylen
))
158 if (t
> ep
->expire_t
)
162 *vallen
= ep
->vallen
;
170 yp_match(const char *indomain
, const char *inmap
, const char *inkey
,
171 int inkeylen
, char **outval
, int *outvallen
)
173 struct dom_binding
*ysd
;
174 struct ypresp_val yprv
;
175 struct ypreq_key yprk
;
178 if (outval
== NULL
|| outvallen
== NULL
)
179 return YPERR_BADARGS
;
183 if (_yp_invalid_domain(indomain
))
184 return YPERR_BADARGS
;
185 if (inmap
== NULL
|| *inmap
== '\0'
186 || strlen(inmap
) > YPMAXMAP
)
187 return YPERR_BADARGS
;
188 if (inkey
== NULL
|| inkeylen
== 0)
189 return YPERR_BADARGS
;
192 if (_yp_dobind(indomain
, &ysd
) != 0)
196 if (!strcmp(_yp_domain
, indomain
) && ypmatch_find(inmap
, inkey
,
197 inkeylen
, &yprv
.valdat
.dptr
, &yprv
.valdat
.dsize
)) {
198 *outvallen
= yprv
.valdat
.dsize
;
199 if ((*outval
= malloc((size_t)(*outvallen
+ 1))) == NULL
)
201 (void)memcpy(*outval
, yprv
.valdat
.dptr
, (size_t)*outvallen
);
202 (*outval
)[*outvallen
] = '\0';
207 yprk
.domain
= indomain
;
209 yprk
.keydat
.dptr
= __UNCONST(inkey
);
210 yprk
.keydat
.dsize
= inkeylen
;
212 memset(&yprv
, 0, sizeof yprv
);
214 r
= clnt_call(ysd
->dom_client
, (rpcproc_t
)YPPROC_MATCH
,
215 (xdrproc_t
)xdr_ypreq_key
, &yprk
,
216 (xdrproc_t
)xdr_ypresp_val
, &yprv
,
218 if (r
!= RPC_SUCCESS
) {
219 if (_yplib_bindtries
<= 0 && ++nerrs
== _yplib_nerrs
) {
220 clnt_perror(ysd
->dom_client
, "yp_match: clnt_call");
223 else if (_yplib_bindtries
> 0 && ++nerrs
== _yplib_bindtries
) {
229 if (!(r
= ypprot_err(yprv
.status
))) {
230 *outvallen
= yprv
.valdat
.dsize
;
231 if ((*outval
= malloc((size_t)(*outvallen
+ 1))) == NULL
)
233 (void)memcpy(*outval
, yprv
.valdat
.dptr
, (size_t)*outvallen
);
234 (*outval
)[*outvallen
] = '\0';
236 if (strcmp(_yp_domain
, indomain
) == 0)
237 if (!ypmatch_add(inmap
, inkey
, inkeylen
,
238 *outval
, *outvallen
))
242 xdr_free((xdrproc_t
)xdr_ypresp_val
, (char *)(void *)&yprv
);