1d915a14eSPedro F. Giffuni /*-
2d915a14eSPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
3d915a14eSPedro F. Giffuni *
44415cd19SGarrett Wollman * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
54e6ace08SBill Paul * Copyright (c) 1998 Bill Paul <wpaul@ctr.columbia.edu>
64415cd19SGarrett Wollman * All rights reserved.
74415cd19SGarrett Wollman *
84415cd19SGarrett Wollman * Redistribution and use in source and binary forms, with or without
94415cd19SGarrett Wollman * modification, are permitted provided that the following conditions
104415cd19SGarrett Wollman * are met:
114415cd19SGarrett Wollman * 1. Redistributions of source code must retain the above copyright
124415cd19SGarrett Wollman * notice, this list of conditions and the following disclaimer.
134415cd19SGarrett Wollman * 2. Redistributions in binary form must reproduce the above copyright
144415cd19SGarrett Wollman * notice, this list of conditions and the following disclaimer in the
154415cd19SGarrett Wollman * documentation and/or other materials provided with the distribution.
164415cd19SGarrett Wollman * 3. The name of the author may not be used to endorse or promote
174415cd19SGarrett Wollman * products derived from this software without specific prior written
184415cd19SGarrett Wollman * permission.
194415cd19SGarrett Wollman *
204415cd19SGarrett Wollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
214415cd19SGarrett Wollman * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
224415cd19SGarrett Wollman * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234415cd19SGarrett Wollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
244415cd19SGarrett Wollman * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
254415cd19SGarrett Wollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
264415cd19SGarrett Wollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
274415cd19SGarrett Wollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
284415cd19SGarrett Wollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
294415cd19SGarrett Wollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
304415cd19SGarrett Wollman * SUCH DAMAGE.
314415cd19SGarrett Wollman */
324415cd19SGarrett Wollman
33d201fe46SDaniel Eischen #include "namespace.h"
34069eb2caSHajimu UMEMOTO #include "reentrant.h"
354415cd19SGarrett Wollman #include <sys/param.h>
364415cd19SGarrett Wollman #include <sys/socket.h>
374415cd19SGarrett Wollman #include <sys/file.h>
384415cd19SGarrett Wollman #include <sys/uio.h>
39fd8e4ebcSMike Barcroft #include <arpa/inet.h>
404415cd19SGarrett Wollman #include <errno.h>
414415cd19SGarrett Wollman #include <stdio.h>
424415cd19SGarrett Wollman #include <string.h>
43b9729ac2SBill Paul #include <stdlib.h>
44b9729ac2SBill Paul #include <unistd.h>
454415cd19SGarrett Wollman #include <rpc/rpc.h>
464415cd19SGarrett Wollman #include <rpc/xdr.h>
470e276383SBill Paul #include <rpcsvc/yp.h>
48d201fe46SDaniel Eischen #include "un-namespace.h"
49d201fe46SDaniel Eischen #include "libc_private.h"
500e276383SBill Paul
510e276383SBill Paul /*
520e276383SBill Paul * We have to define these here due to clashes between yp_prot.h and
530e276383SBill Paul * yp.h.
540e276383SBill Paul */
550e276383SBill Paul
564e6ace08SBill Paul #define YPMATCHCACHE
574e6ace08SBill Paul
584e6ace08SBill Paul #ifdef YPMATCHCACHE
594e6ace08SBill Paul struct ypmatch_ent {
604e6ace08SBill Paul char *ypc_map;
614e6ace08SBill Paul keydat ypc_key;
624e6ace08SBill Paul valdat ypc_val;
634e6ace08SBill Paul time_t ypc_expire_t;
644e6ace08SBill Paul struct ypmatch_ent *ypc_next;
654e6ace08SBill Paul };
664e6ace08SBill Paul #define YPLIB_MAXCACHE 5 /* At most 5 entries */
674e6ace08SBill Paul #define YPLIB_EXPIRE 5 /* Expire after 5 seconds */
684e6ace08SBill Paul #endif
694e6ace08SBill Paul
700e276383SBill Paul struct dom_binding {
710e276383SBill Paul struct dom_binding *dom_pnext;
720e276383SBill Paul char dom_domain[YPMAXDOMAIN + 1];
730e276383SBill Paul struct sockaddr_in dom_server_addr;
740e276383SBill Paul u_short dom_server_port;
750e276383SBill Paul int dom_socket;
760e276383SBill Paul CLIENT *dom_client;
77a2308772SBill Paul u_short dom_local_port; /* now I finally know what this is for. */
780e276383SBill Paul long dom_vers;
794e6ace08SBill Paul #ifdef YPMATCHCACHE
804e6ace08SBill Paul struct ypmatch_ent *cache;
814e6ace08SBill Paul int ypmatch_cachecnt;
824e6ace08SBill Paul #endif
830e276383SBill Paul };
840e276383SBill Paul
854415cd19SGarrett Wollman #include <rpcsvc/ypclnt.h>
864415cd19SGarrett Wollman
874415cd19SGarrett Wollman #ifndef BINDINGDIR
884415cd19SGarrett Wollman #define BINDINGDIR "/var/yp/binding"
894415cd19SGarrett Wollman #endif
90456ebbf8SBill Paul #define MAX_RETRIES 20
914415cd19SGarrett Wollman
92ba5070abSMateusz Guzik bool_t xdr_ypresp_all_seq(XDR *xdrs, u_long *objp);
934415cd19SGarrett Wollman
94*6bd60e15SMinsoo Choo int (*ypresp_allfn)(unsigned long, char *, int, char *, int, void *);
954415cd19SGarrett Wollman void *ypresp_data;
964415cd19SGarrett Wollman
97ed4d1c46SDag-Erling Smørgrav static void _yp_unbind(struct dom_binding *);
984415cd19SGarrett Wollman struct dom_binding *_ypbindlist;
994415cd19SGarrett Wollman static char _yp_domain[MAXHOSTNAMELEN];
1002861f68dSSimon L. B. Nielsen int _yplib_timeout = 20;
1014415cd19SGarrett Wollman
1021b482912SHajimu UMEMOTO static mutex_t _ypmutex = MUTEX_INITIALIZER;
103069eb2caSHajimu UMEMOTO #define YPLOCK() mutex_lock(&_ypmutex);
104069eb2caSHajimu UMEMOTO #define YPUNLOCK() mutex_unlock(&_ypmutex);
105069eb2caSHajimu UMEMOTO
1064415cd19SGarrett Wollman #ifdef YPMATCHCACHE
107dc584ddbSDag-Erling Smørgrav static void
ypmatch_cache_delete(struct dom_binding * ypdb,struct ypmatch_ent * prev,struct ypmatch_ent * cur)108dc584ddbSDag-Erling Smørgrav ypmatch_cache_delete(struct dom_binding *ypdb, struct ypmatch_ent *prev,
109dc584ddbSDag-Erling Smørgrav struct ypmatch_ent *cur)
1104415cd19SGarrett Wollman {
1114e6ace08SBill Paul if (prev == NULL)
1124e6ace08SBill Paul ypdb->cache = cur->ypc_next;
1134e6ace08SBill Paul else
1144e6ace08SBill Paul prev->ypc_next = cur->ypc_next;
1154e6ace08SBill Paul
1164e6ace08SBill Paul free(cur->ypc_map);
1174e6ace08SBill Paul free(cur->ypc_key.keydat_val);
1184e6ace08SBill Paul free(cur->ypc_val.valdat_val);
1194e6ace08SBill Paul free(cur);
1204e6ace08SBill Paul
1214e6ace08SBill Paul ypdb->ypmatch_cachecnt--;
1224e6ace08SBill Paul
1234e6ace08SBill Paul return;
1244e6ace08SBill Paul }
1254e6ace08SBill Paul
126dc584ddbSDag-Erling Smørgrav static void
ypmatch_cache_flush(struct dom_binding * ypdb)127dc584ddbSDag-Erling Smørgrav ypmatch_cache_flush(struct dom_binding *ypdb)
1284e6ace08SBill Paul {
1294e6ace08SBill Paul struct ypmatch_ent *n, *c = ypdb->cache;
1304e6ace08SBill Paul
1314e6ace08SBill Paul while (c != NULL) {
1324e6ace08SBill Paul n = c->ypc_next;
1334e6ace08SBill Paul ypmatch_cache_delete(ypdb, NULL, c);
1344e6ace08SBill Paul c = n;
1354e6ace08SBill Paul }
1364e6ace08SBill Paul
1374e6ace08SBill Paul return;
1384e6ace08SBill Paul }
1394e6ace08SBill Paul
140dc584ddbSDag-Erling Smørgrav static void
ypmatch_cache_expire(struct dom_binding * ypdb)141dc584ddbSDag-Erling Smørgrav ypmatch_cache_expire(struct dom_binding *ypdb)
1424e6ace08SBill Paul {
1434e6ace08SBill Paul struct ypmatch_ent *c = ypdb->cache;
1444e6ace08SBill Paul struct ypmatch_ent *n, *p = NULL;
1454415cd19SGarrett Wollman time_t t;
1464415cd19SGarrett Wollman
1474415cd19SGarrett Wollman time(&t);
1484415cd19SGarrett Wollman
1494e6ace08SBill Paul while (c != NULL) {
1504e6ace08SBill Paul if (t >= c->ypc_expire_t) {
1514e6ace08SBill Paul n = c->ypc_next;
1524e6ace08SBill Paul ypmatch_cache_delete(ypdb, p, c);
1534e6ace08SBill Paul c = n;
1544415cd19SGarrett Wollman } else {
1554e6ace08SBill Paul p = c;
1564e6ace08SBill Paul c = c->ypc_next;
1574e6ace08SBill Paul }
1584415cd19SGarrett Wollman }
1594415cd19SGarrett Wollman
1604e6ace08SBill Paul return;
1614415cd19SGarrett Wollman }
1624415cd19SGarrett Wollman
163dc584ddbSDag-Erling Smørgrav static void
ypmatch_cache_insert(struct dom_binding * ypdb,char * map,keydat * key,valdat * val)164dc584ddbSDag-Erling Smørgrav ypmatch_cache_insert(struct dom_binding *ypdb, char *map, keydat *key,
165dc584ddbSDag-Erling Smørgrav valdat *val)
1664415cd19SGarrett Wollman {
1674e6ace08SBill Paul struct ypmatch_ent *new;
1684415cd19SGarrett Wollman
1694e6ace08SBill Paul /* Do an expire run to maybe open up a slot. */
1704e6ace08SBill Paul if (ypdb->ypmatch_cachecnt)
1714e6ace08SBill Paul ypmatch_cache_expire(ypdb);
1724415cd19SGarrett Wollman
1734e6ace08SBill Paul /*
1744e6ace08SBill Paul * If there are no slots free, then force an expire of
1754e6ace08SBill Paul * the least recently used entry.
1764e6ace08SBill Paul */
1774e6ace08SBill Paul if (ypdb->ypmatch_cachecnt >= YPLIB_MAXCACHE) {
1784e6ace08SBill Paul struct ypmatch_ent *o = NULL, *c = ypdb->cache;
1794e6ace08SBill Paul time_t oldest = 0;
1804415cd19SGarrett Wollman
1814e6ace08SBill Paul oldest = ~oldest;
1824415cd19SGarrett Wollman
1834e6ace08SBill Paul while (c != NULL) {
1844e6ace08SBill Paul if (c->ypc_expire_t < oldest) {
1854e6ace08SBill Paul oldest = c->ypc_expire_t;
1864e6ace08SBill Paul o = c;
1874415cd19SGarrett Wollman }
1884e6ace08SBill Paul c = c->ypc_next;
1894e6ace08SBill Paul }
1904e6ace08SBill Paul
1914e6ace08SBill Paul if (o == NULL)
1924e6ace08SBill Paul return;
1934e6ace08SBill Paul o->ypc_expire_t = 0;
1944e6ace08SBill Paul ypmatch_cache_expire(ypdb);
1954e6ace08SBill Paul }
1964e6ace08SBill Paul
1974e6ace08SBill Paul new = malloc(sizeof(struct ypmatch_ent));
1984e6ace08SBill Paul if (new == NULL)
1994e6ace08SBill Paul return;
2004e6ace08SBill Paul
2014e6ace08SBill Paul new->ypc_map = strdup(map);
2024e6ace08SBill Paul if (new->ypc_map == NULL) {
2034e6ace08SBill Paul free(new);
2044e6ace08SBill Paul return;
2054e6ace08SBill Paul }
2064e6ace08SBill Paul new->ypc_key.keydat_val = malloc(key->keydat_len);
2074e6ace08SBill Paul if (new->ypc_key.keydat_val == NULL) {
2084e6ace08SBill Paul free(new->ypc_map);
2094e6ace08SBill Paul free(new);
2104e6ace08SBill Paul return;
2114e6ace08SBill Paul }
2124e6ace08SBill Paul new->ypc_val.valdat_val = malloc(val->valdat_len);
2134e6ace08SBill Paul if (new->ypc_val.valdat_val == NULL) {
2144e6ace08SBill Paul free(new->ypc_val.valdat_val);
2154e6ace08SBill Paul free(new->ypc_map);
2164e6ace08SBill Paul free(new);
2174e6ace08SBill Paul return;
2184e6ace08SBill Paul }
2194e6ace08SBill Paul
2204e6ace08SBill Paul new->ypc_expire_t = time(NULL) + YPLIB_EXPIRE;
2214e6ace08SBill Paul new->ypc_key.keydat_len = key->keydat_len;
2224e6ace08SBill Paul new->ypc_val.valdat_len = val->valdat_len;
2234e6ace08SBill Paul bcopy(key->keydat_val, new->ypc_key.keydat_val, key->keydat_len);
2244e6ace08SBill Paul bcopy(val->valdat_val, new->ypc_val.valdat_val, val->valdat_len);
2254e6ace08SBill Paul
2264e6ace08SBill Paul new->ypc_next = ypdb->cache;
2274e6ace08SBill Paul ypdb->cache = new;
2284e6ace08SBill Paul
2294e6ace08SBill Paul ypdb->ypmatch_cachecnt++;
2304e6ace08SBill Paul
2314e6ace08SBill Paul return;
2324e6ace08SBill Paul }
2334e6ace08SBill Paul
234dc584ddbSDag-Erling Smørgrav static bool_t
ypmatch_cache_lookup(struct dom_binding * ypdb,char * map,keydat * key,valdat * val)235dc584ddbSDag-Erling Smørgrav ypmatch_cache_lookup(struct dom_binding *ypdb, char *map, keydat *key,
236dc584ddbSDag-Erling Smørgrav valdat *val)
2374e6ace08SBill Paul {
2380c0349bfSGarrett Wollman struct ypmatch_ent *c;
2394e6ace08SBill Paul
2404e6ace08SBill Paul ypmatch_cache_expire(ypdb);
2414e6ace08SBill Paul
2424e6ace08SBill Paul for (c = ypdb->cache; c != NULL; c = c->ypc_next) {
2434e6ace08SBill Paul if (strcmp(map, c->ypc_map))
2444e6ace08SBill Paul continue;
2454e6ace08SBill Paul if (key->keydat_len != c->ypc_key.keydat_len)
2464e6ace08SBill Paul continue;
2474e6ace08SBill Paul if (bcmp(key->keydat_val, c->ypc_key.keydat_val,
2484e6ace08SBill Paul key->keydat_len))
2494e6ace08SBill Paul continue;
2504e6ace08SBill Paul }
2514e6ace08SBill Paul
2524e6ace08SBill Paul if (c == NULL)
2534e6ace08SBill Paul return(FALSE);
2544e6ace08SBill Paul
2554e6ace08SBill Paul val->valdat_len = c->ypc_val.valdat_len;
2564e6ace08SBill Paul val->valdat_val = c->ypc_val.valdat_val;
2574e6ace08SBill Paul
2584e6ace08SBill Paul return(TRUE);
2594415cd19SGarrett Wollman }
2604415cd19SGarrett Wollman #endif
2614415cd19SGarrett Wollman
262f249dbccSDag-Erling Smørgrav const char *
ypbinderr_string(int incode)263dc584ddbSDag-Erling Smørgrav ypbinderr_string(int incode)
26464416168SBill Paul {
26564416168SBill Paul static char err[80];
26664416168SBill Paul switch (incode) {
26764416168SBill Paul case 0:
268ed4d1c46SDag-Erling Smørgrav return ("Success");
26962967ca2SBill Paul case YPBIND_ERR_ERR:
270ed4d1c46SDag-Erling Smørgrav return ("Internal ypbind error");
27162967ca2SBill Paul case YPBIND_ERR_NOSERV:
272ed4d1c46SDag-Erling Smørgrav return ("Domain not bound");
27362967ca2SBill Paul case YPBIND_ERR_RESC:
274ed4d1c46SDag-Erling Smørgrav return ("System resource allocation failure");
27564416168SBill Paul }
27662967ca2SBill Paul sprintf(err, "Unknown ypbind error: #%d\n", incode);
277ed4d1c46SDag-Erling Smørgrav return (err);
27864416168SBill Paul }
27964416168SBill Paul
2804415cd19SGarrett Wollman int
_yp_dobind(char * dom,struct dom_binding ** ypdb)281dc584ddbSDag-Erling Smørgrav _yp_dobind(char *dom, struct dom_binding **ypdb)
2824415cd19SGarrett Wollman {
283e75ad74aSJames Raynard static pid_t pid = -1;
2844415cd19SGarrett Wollman char path[MAXPATHLEN];
2854415cd19SGarrett Wollman struct dom_binding *ysd, *ysd2;
2869d80b1ddSBill Paul struct ypbind_resp ypbr;
2874415cd19SGarrett Wollman struct timeval tv;
2884415cd19SGarrett Wollman struct sockaddr_in clnt_sin;
28951295a4dSJordan K. Hubbard int clnt_sock, fd;
290ccbcef60SJames Raynard pid_t gpid;
2914415cd19SGarrett Wollman CLIENT *client;
2924415cd19SGarrett Wollman int new = 0, r;
293456ebbf8SBill Paul int retries = 0;
294a2308772SBill Paul struct sockaddr_in check;
295595e5323SStefan Farfeleder socklen_t checklen = sizeof(struct sockaddr_in);
2964415cd19SGarrett Wollman
2976e8caff7SBill Paul /* Not allowed; bad doggie. Bad. */
2986e8caff7SBill Paul if (strchr(dom, '/') != NULL)
2996e8caff7SBill Paul return(YPERR_BADARGS);
3006e8caff7SBill Paul
3014415cd19SGarrett Wollman gpid = getpid();
3024415cd19SGarrett Wollman if (!(pid == -1 || pid == gpid)) {
3034415cd19SGarrett Wollman ysd = _ypbindlist;
3044415cd19SGarrett Wollman while (ysd) {
3059fa75c15SBill Paul if (ysd->dom_client != NULL)
306cc64a2bfSBill Paul _yp_unbind(ysd);
3074415cd19SGarrett Wollman ysd2 = ysd->dom_pnext;
3084415cd19SGarrett Wollman free(ysd);
3094415cd19SGarrett Wollman ysd = ysd2;
3104415cd19SGarrett Wollman }
3114415cd19SGarrett Wollman _ypbindlist = NULL;
3124415cd19SGarrett Wollman }
3134415cd19SGarrett Wollman pid = gpid;
3144415cd19SGarrett Wollman
3154415cd19SGarrett Wollman if (ypdb != NULL)
3164415cd19SGarrett Wollman *ypdb = NULL;
3174415cd19SGarrett Wollman
3184415cd19SGarrett Wollman if (dom == NULL || strlen(dom) == 0)
319ed4d1c46SDag-Erling Smørgrav return (YPERR_BADARGS);
3204415cd19SGarrett Wollman
3214415cd19SGarrett Wollman for (ysd = _ypbindlist; ysd; ysd = ysd->dom_pnext)
3224415cd19SGarrett Wollman if (strcmp(dom, ysd->dom_domain) == 0)
3234415cd19SGarrett Wollman break;
324a169c9b1SBill Paul
325a2308772SBill Paul
3264415cd19SGarrett Wollman if (ysd == NULL) {
3274415cd19SGarrett Wollman ysd = (struct dom_binding *)malloc(sizeof *ysd);
3286890d156SGuy Helmer if (ysd == NULL)
3296890d156SGuy Helmer return (YPERR_RESRC);
3304415cd19SGarrett Wollman bzero((char *)ysd, sizeof *ysd);
3314415cd19SGarrett Wollman ysd->dom_socket = -1;
3324415cd19SGarrett Wollman ysd->dom_vers = 0;
3334415cd19SGarrett Wollman new = 1;
334a2308772SBill Paul } else {
335a2308772SBill Paul /* Check the socket -- may have been hosed by the caller. */
336d201fe46SDaniel Eischen if (_getsockname(ysd->dom_socket, (struct sockaddr *)&check,
337a2308772SBill Paul &checklen) == -1 || check.sin_family != AF_INET ||
338a2308772SBill Paul check.sin_port != ysd->dom_local_port) {
339a2308772SBill Paul /* Socket became bogus somehow... need to rebind. */
340a2308772SBill Paul int save, sock;
341a2308772SBill Paul
342a2308772SBill Paul sock = ysd->dom_socket;
343d201fe46SDaniel Eischen save = _dup(ysd->dom_socket);
3449fa75c15SBill Paul if (ysd->dom_client != NULL)
345a2308772SBill Paul clnt_destroy(ysd->dom_client);
346a2308772SBill Paul ysd->dom_vers = 0;
347a2308772SBill Paul ysd->dom_client = NULL;
348d201fe46SDaniel Eischen sock = _dup2(save, sock);
3499233c4d9SJason Evans _close(save);
350a2308772SBill Paul }
3514415cd19SGarrett Wollman }
3520f98415eSBill Paul
3534415cd19SGarrett Wollman again:
354456ebbf8SBill Paul retries++;
355456ebbf8SBill Paul if (retries > MAX_RETRIES) {
356456ebbf8SBill Paul if (new)
357456ebbf8SBill Paul free(ysd);
358456ebbf8SBill Paul return(YPERR_YPBIND);
359456ebbf8SBill Paul }
3604415cd19SGarrett Wollman #ifdef BINDINGDIR
3614415cd19SGarrett Wollman if (ysd->dom_vers == 0) {
362a169c9b1SBill Paul /*
363a169c9b1SBill Paul * We're trying to make a new binding: zorch the
364a169c9b1SBill Paul * existing handle now (if any).
365a169c9b1SBill Paul */
3669fa75c15SBill Paul if (ysd->dom_client != NULL) {
367a169c9b1SBill Paul clnt_destroy(ysd->dom_client);
368a169c9b1SBill Paul ysd->dom_client = NULL;
369a2308772SBill Paul ysd->dom_socket = -1;
370a169c9b1SBill Paul }
37183ac6cdcSKris Kennaway snprintf(path, sizeof(path), "%s/%s.%d", BINDINGDIR, dom, 2);
37205eb11cbSJilles Tjoelker if ((fd = _open(path, O_RDONLY | O_CLOEXEC)) == -1) {
3734415cd19SGarrett Wollman /* no binding file, YP is dead. */
374456ebbf8SBill Paul /* Try to bring it back to life. */
3759233c4d9SJason Evans _close(fd);
376b9729ac2SBill Paul goto skipit;
3774415cd19SGarrett Wollman }
378d201fe46SDaniel Eischen if (_flock(fd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK) {
3794415cd19SGarrett Wollman struct iovec iov[2];
3809d80b1ddSBill Paul struct ypbind_resp ybr;
3814415cd19SGarrett Wollman u_short ypb_port;
3824415cd19SGarrett Wollman
3834415cd19SGarrett Wollman iov[0].iov_base = (caddr_t)&ypb_port;
3844415cd19SGarrett Wollman iov[0].iov_len = sizeof ypb_port;
3854415cd19SGarrett Wollman iov[1].iov_base = (caddr_t)&ybr;
3864415cd19SGarrett Wollman iov[1].iov_len = sizeof ybr;
3874415cd19SGarrett Wollman
388d201fe46SDaniel Eischen r = _readv(fd, iov, 2);
3894415cd19SGarrett Wollman if (r != iov[0].iov_len + iov[1].iov_len) {
3909233c4d9SJason Evans _close(fd);
3914415cd19SGarrett Wollman ysd->dom_vers = -1;
3924415cd19SGarrett Wollman goto again;
3934415cd19SGarrett Wollman }
3944415cd19SGarrett Wollman
3954415cd19SGarrett Wollman bzero(&ysd->dom_server_addr, sizeof ysd->dom_server_addr);
3964415cd19SGarrett Wollman ysd->dom_server_addr.sin_family = AF_INET;
3974415cd19SGarrett Wollman ysd->dom_server_addr.sin_len = sizeof(struct sockaddr_in);
3987b5f5922SJohn Baldwin bcopy(&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
3997b5f5922SJohn Baldwin &ysd->dom_server_addr.sin_addr.s_addr,
4007b5f5922SJohn Baldwin sizeof(ysd->dom_server_addr.sin_addr.s_addr));
4017b5f5922SJohn Baldwin bcopy(&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
4027b5f5922SJohn Baldwin &ysd->dom_server_addr.sin_port,
4037b5f5922SJohn Baldwin sizeof(ysd->dom_server_addr.sin_port));
4044415cd19SGarrett Wollman
4054415cd19SGarrett Wollman ysd->dom_server_port = ysd->dom_server_addr.sin_port;
4069233c4d9SJason Evans _close(fd);
4074415cd19SGarrett Wollman goto gotit;
4084415cd19SGarrett Wollman } else {
4094415cd19SGarrett Wollman /* no lock on binding file, YP is dead. */
410456ebbf8SBill Paul /* Try to bring it back to life. */
4119233c4d9SJason Evans _close(fd);
412456ebbf8SBill Paul goto skipit;
413f067dfeaSBill Paul }
414f067dfeaSBill Paul }
415b9729ac2SBill Paul skipit:
4164415cd19SGarrett Wollman #endif
4174415cd19SGarrett Wollman if (ysd->dom_vers == -1 || ysd->dom_vers == 0) {
418a169c9b1SBill Paul /*
419a169c9b1SBill Paul * We're trying to make a new binding: zorch the
420a169c9b1SBill Paul * existing handle now (if any).
421a169c9b1SBill Paul */
4229fa75c15SBill Paul if (ysd->dom_client != NULL) {
423a169c9b1SBill Paul clnt_destroy(ysd->dom_client);
424a169c9b1SBill Paul ysd->dom_client = NULL;
425a2308772SBill Paul ysd->dom_socket = -1;
426a169c9b1SBill Paul }
4274415cd19SGarrett Wollman bzero((char *)&clnt_sin, sizeof clnt_sin);
4284415cd19SGarrett Wollman clnt_sin.sin_family = AF_INET;
4294415cd19SGarrett Wollman clnt_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4304415cd19SGarrett Wollman
4314415cd19SGarrett Wollman clnt_sock = RPC_ANYSOCK;
4324415cd19SGarrett Wollman client = clnttcp_create(&clnt_sin, YPBINDPROG, YPBINDVERS, &clnt_sock,
4334415cd19SGarrett Wollman 0, 0);
4344415cd19SGarrett Wollman if (client == NULL) {
43520e4b00aSBill Paul /*
43620e4b00aSBill Paul * These conditions indicate ypbind just isn't
43720e4b00aSBill Paul * alive -- we probably don't want to shoot our
438a169c9b1SBill Paul * mouth off in this case; instead generate error
43920e4b00aSBill Paul * messages only for really exotic problems.
44020e4b00aSBill Paul */
44120e4b00aSBill Paul if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED &&
44220e4b00aSBill Paul (rpc_createerr.cf_stat != RPC_SYSTEMERROR &&
44320e4b00aSBill Paul rpc_createerr.cf_error.re_errno == ECONNREFUSED))
4444415cd19SGarrett Wollman clnt_pcreateerror("clnttcp_create");
4454415cd19SGarrett Wollman if (new)
4464415cd19SGarrett Wollman free(ysd);
447456ebbf8SBill Paul return (YPERR_YPBIND);
4484415cd19SGarrett Wollman }
4494415cd19SGarrett Wollman
45056d18edaSBill Paul /*
45156d18edaSBill Paul * Check the port number -- should be < IPPORT_RESERVED.
45256d18edaSBill Paul * If not, it's possible someone has registered a bogus
45356d18edaSBill Paul * ypbind with the portmapper and is trying to trick us.
45456d18edaSBill Paul */
45556d18edaSBill Paul if (ntohs(clnt_sin.sin_port) >= IPPORT_RESERVED) {
4569fa75c15SBill Paul if (client != NULL)
45756d18edaSBill Paul clnt_destroy(client);
45856d18edaSBill Paul if (new)
45956d18edaSBill Paul free(ysd);
46056d18edaSBill Paul return(YPERR_YPBIND);
46156d18edaSBill Paul }
462456ebbf8SBill Paul tv.tv_sec = _yplib_timeout/2;
4634415cd19SGarrett Wollman tv.tv_usec = 0;
4644415cd19SGarrett Wollman r = clnt_call(client, YPBINDPROC_DOMAIN,
465f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_domainname, &dom,
466f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypbind_resp, &ypbr, tv);
4674415cd19SGarrett Wollman if (r != RPC_SUCCESS) {
4684415cd19SGarrett Wollman clnt_destroy(client);
4694415cd19SGarrett Wollman ysd->dom_vers = -1;
470a2308772SBill Paul if (r == RPC_PROGUNAVAIL || r == RPC_PROCUNAVAIL) {
471a2308772SBill Paul if (new)
472a2308772SBill Paul free(ysd);
47320e4b00aSBill Paul return(YPERR_YPBIND);
474a2308772SBill Paul }
47520e4b00aSBill Paul fprintf(stderr,
47620e4b00aSBill Paul "YP: server for domain %s not responding, retrying\n", dom);
4774415cd19SGarrett Wollman goto again;
47864416168SBill Paul } else {
47964416168SBill Paul if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
4809233c4d9SJason Evans struct timespec time_to_sleep, time_remaining;
4819233c4d9SJason Evans
482456ebbf8SBill Paul clnt_destroy(client);
483456ebbf8SBill Paul ysd->dom_vers = -1;
4849233c4d9SJason Evans
4859233c4d9SJason Evans time_to_sleep.tv_sec = _yplib_timeout/2;
4869233c4d9SJason Evans time_to_sleep.tv_nsec = 0;
4879233c4d9SJason Evans _nanosleep(&time_to_sleep,
4889233c4d9SJason Evans &time_remaining);
489456ebbf8SBill Paul goto again;
49064416168SBill Paul }
4914415cd19SGarrett Wollman }
4924415cd19SGarrett Wollman clnt_destroy(client);
4934415cd19SGarrett Wollman
4944415cd19SGarrett Wollman bzero((char *)&ysd->dom_server_addr, sizeof ysd->dom_server_addr);
4954415cd19SGarrett Wollman ysd->dom_server_addr.sin_family = AF_INET;
4967b5f5922SJohn Baldwin bcopy(&ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
4977b5f5922SJohn Baldwin &ysd->dom_server_addr.sin_port,
4987b5f5922SJohn Baldwin sizeof(ysd->dom_server_addr.sin_port));
4997b5f5922SJohn Baldwin bcopy(&ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
5007b5f5922SJohn Baldwin &ysd->dom_server_addr.sin_addr.s_addr,
5017b5f5922SJohn Baldwin sizeof(ysd->dom_server_addr.sin_addr.s_addr));
50256d18edaSBill Paul
50356d18edaSBill Paul /*
50456d18edaSBill Paul * We could do a reserved port check here too, but this
50556d18edaSBill Paul * could pose compatibility problems. The local ypbind is
50656d18edaSBill Paul * supposed to decide whether or not to trust yp servers
50756d18edaSBill Paul * on insecure ports. For now, we trust its judgement.
50856d18edaSBill Paul */
5094415cd19SGarrett Wollman ysd->dom_server_port =
5109d80b1ddSBill Paul *(u_short *)&ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port;
5114415cd19SGarrett Wollman gotit:
5124415cd19SGarrett Wollman ysd->dom_vers = YPVERS;
513d0509082SJacques Vidrine strlcpy(ysd->dom_domain, dom, sizeof(ysd->dom_domain));
5144415cd19SGarrett Wollman }
5154415cd19SGarrett Wollman
516a169c9b1SBill Paul /* Don't rebuild the connection to the server unless we have to. */
517a169c9b1SBill Paul if (ysd->dom_client == NULL) {
5184415cd19SGarrett Wollman tv.tv_sec = _yplib_timeout/2;
5194415cd19SGarrett Wollman tv.tv_usec = 0;
5204415cd19SGarrett Wollman ysd->dom_socket = RPC_ANYSOCK;
5214e6ace08SBill Paul ysd->dom_client = clntudp_bufcreate(&ysd->dom_server_addr,
522505a58ecSKonstantin Belousov YPPROG, YPVERS, tv, &ysd->dom_socket, 65507, 65507);
5234415cd19SGarrett Wollman if (ysd->dom_client == NULL) {
5244415cd19SGarrett Wollman clnt_pcreateerror("clntudp_create");
5254415cd19SGarrett Wollman ysd->dom_vers = -1;
5264415cd19SGarrett Wollman goto again;
5274415cd19SGarrett Wollman }
5289233c4d9SJason Evans if (_fcntl(ysd->dom_socket, F_SETFD, 1) == -1)
5294415cd19SGarrett Wollman perror("fcntl: F_SETFD");
530a2308772SBill Paul /*
531a2308772SBill Paul * We want a port number associated with this socket
532a2308772SBill Paul * so that we can check its authenticity later.
533a2308772SBill Paul */
534a2308772SBill Paul checklen = sizeof(struct sockaddr_in);
535a2308772SBill Paul bzero((char *)&check, checklen);
536d201fe46SDaniel Eischen _bind(ysd->dom_socket, (struct sockaddr *)&check, checklen);
537a2308772SBill Paul check.sin_family = AF_INET;
538d201fe46SDaniel Eischen if (!_getsockname(ysd->dom_socket,
539a2308772SBill Paul (struct sockaddr *)&check, &checklen)) {
540a2308772SBill Paul ysd->dom_local_port = check.sin_port;
541a2308772SBill Paul } else {
542a2308772SBill Paul clnt_destroy(ysd->dom_client);
543a2308772SBill Paul if (new)
544a2308772SBill Paul free(ysd);
545a2308772SBill Paul return(YPERR_YPBIND);
546a2308772SBill Paul }
547a169c9b1SBill Paul }
5484415cd19SGarrett Wollman
5494415cd19SGarrett Wollman if (new) {
5504415cd19SGarrett Wollman ysd->dom_pnext = _ypbindlist;
5514415cd19SGarrett Wollman _ypbindlist = ysd;
5524415cd19SGarrett Wollman }
5534415cd19SGarrett Wollman
55433e6f9c1SSimon L. B. Nielsen /*
55533e6f9c1SSimon L. B. Nielsen * Set low retry timeout to realistically handle UDP packet
55633e6f9c1SSimon L. B. Nielsen * loss for YP packet bursts.
55733e6f9c1SSimon L. B. Nielsen */
55833e6f9c1SSimon L. B. Nielsen tv.tv_sec = 1;
55933e6f9c1SSimon L. B. Nielsen tv.tv_usec = 0;
56033e6f9c1SSimon L. B. Nielsen clnt_control(ysd->dom_client, CLSET_RETRY_TIMEOUT, (char*)&tv);
56133e6f9c1SSimon L. B. Nielsen
5624415cd19SGarrett Wollman if (ypdb != NULL)
5634415cd19SGarrett Wollman *ypdb = ysd;
564ed4d1c46SDag-Erling Smørgrav return (0);
5654415cd19SGarrett Wollman }
5664415cd19SGarrett Wollman
5674415cd19SGarrett Wollman static void
_yp_unbind(struct dom_binding * ypb)568dc584ddbSDag-Erling Smørgrav _yp_unbind(struct dom_binding *ypb)
5694415cd19SGarrett Wollman {
5709fa75c15SBill Paul struct sockaddr_in check;
571595e5323SStefan Farfeleder socklen_t checklen = sizeof(struct sockaddr_in);
5729fa75c15SBill Paul
5739fa75c15SBill Paul if (ypb->dom_client != NULL) {
5749fa75c15SBill Paul /* Check the socket -- may have been hosed by the caller. */
575d201fe46SDaniel Eischen if (_getsockname(ypb->dom_socket, (struct sockaddr *)&check,
5769fa75c15SBill Paul &checklen) == -1 || check.sin_family != AF_INET ||
5779fa75c15SBill Paul check.sin_port != ypb->dom_local_port) {
5789fa75c15SBill Paul int save, sock;
5799fa75c15SBill Paul
5809fa75c15SBill Paul sock = ypb->dom_socket;
581d201fe46SDaniel Eischen save = _dup(ypb->dom_socket);
5824415cd19SGarrett Wollman clnt_destroy(ypb->dom_client);
583d201fe46SDaniel Eischen sock = _dup2(save, sock);
5849233c4d9SJason Evans _close(save);
5859fa75c15SBill Paul } else
5869fa75c15SBill Paul clnt_destroy(ypb->dom_client);
5879fa75c15SBill Paul }
5889fa75c15SBill Paul
5894415cd19SGarrett Wollman ypb->dom_client = NULL;
5904415cd19SGarrett Wollman ypb->dom_socket = -1;
5912694f9b9SBill Paul ypb->dom_vers = -1;
5924e6ace08SBill Paul #ifdef YPMATCHCACHE
5934e6ace08SBill Paul ypmatch_cache_flush(ypb);
5944e6ace08SBill Paul #endif
5954415cd19SGarrett Wollman }
5964415cd19SGarrett Wollman
597d21de89aSHajimu UMEMOTO static int
yp_bind_locked(char * dom)598d21de89aSHajimu UMEMOTO yp_bind_locked(char *dom)
5994415cd19SGarrett Wollman {
600ed4d1c46SDag-Erling Smørgrav return (_yp_dobind(dom, NULL));
6014415cd19SGarrett Wollman }
6024415cd19SGarrett Wollman
603d21de89aSHajimu UMEMOTO int
yp_bind(char * dom)604d21de89aSHajimu UMEMOTO yp_bind(char *dom)
605d21de89aSHajimu UMEMOTO {
606d21de89aSHajimu UMEMOTO int r;
607d21de89aSHajimu UMEMOTO
608d21de89aSHajimu UMEMOTO YPLOCK();
609d21de89aSHajimu UMEMOTO r = yp_bind_locked(dom);
610d21de89aSHajimu UMEMOTO YPUNLOCK();
611d21de89aSHajimu UMEMOTO return (r);
612d21de89aSHajimu UMEMOTO }
613d21de89aSHajimu UMEMOTO
614d21de89aSHajimu UMEMOTO static void
yp_unbind_locked(char * dom)615d21de89aSHajimu UMEMOTO yp_unbind_locked(char *dom)
6164415cd19SGarrett Wollman {
6174415cd19SGarrett Wollman struct dom_binding *ypb, *ypbp;
6184415cd19SGarrett Wollman
6194415cd19SGarrett Wollman ypbp = NULL;
6204415cd19SGarrett Wollman for (ypb = _ypbindlist; ypb; ypb = ypb->dom_pnext) {
6214415cd19SGarrett Wollman if (strcmp(dom, ypb->dom_domain) == 0) {
6222694f9b9SBill Paul _yp_unbind(ypb);
6234415cd19SGarrett Wollman if (ypbp)
6244415cd19SGarrett Wollman ypbp->dom_pnext = ypb->dom_pnext;
6254415cd19SGarrett Wollman else
6264415cd19SGarrett Wollman _ypbindlist = ypb->dom_pnext;
6274415cd19SGarrett Wollman free(ypb);
6284415cd19SGarrett Wollman return;
6294415cd19SGarrett Wollman }
6304415cd19SGarrett Wollman ypbp = ypb;
6314415cd19SGarrett Wollman }
6324415cd19SGarrett Wollman return;
6334415cd19SGarrett Wollman }
6344415cd19SGarrett Wollman
635d21de89aSHajimu UMEMOTO void
yp_unbind(char * dom)636d21de89aSHajimu UMEMOTO yp_unbind(char *dom)
637d21de89aSHajimu UMEMOTO {
638d21de89aSHajimu UMEMOTO YPLOCK();
639d21de89aSHajimu UMEMOTO yp_unbind_locked(dom);
640d21de89aSHajimu UMEMOTO YPUNLOCK();
641d21de89aSHajimu UMEMOTO }
642d21de89aSHajimu UMEMOTO
6434415cd19SGarrett Wollman int
yp_match(char * indomain,char * inmap,const char * inkey,int inkeylen,char ** outval,int * outvallen)644dc584ddbSDag-Erling Smørgrav yp_match(char *indomain, char *inmap, const char *inkey, int inkeylen,
645dc584ddbSDag-Erling Smørgrav char **outval, int *outvallen)
6464415cd19SGarrett Wollman {
6474415cd19SGarrett Wollman struct dom_binding *ysd;
6484415cd19SGarrett Wollman struct ypresp_val yprv;
6494415cd19SGarrett Wollman struct timeval tv;
6504415cd19SGarrett Wollman struct ypreq_key yprk;
6514415cd19SGarrett Wollman int r;
652c1dfca84SMarcelo Araujo int retries = 0;
6534415cd19SGarrett Wollman *outval = NULL;
6544415cd19SGarrett Wollman *outvallen = 0;
6554415cd19SGarrett Wollman
65606643071SBill Paul /* Sanity check */
657e17334c3SBill Paul
65806643071SBill Paul if (inkey == NULL || !strlen(inkey) || inkeylen <= 0 ||
65906643071SBill Paul inmap == NULL || !strlen(inmap) ||
66006643071SBill Paul indomain == NULL || !strlen(indomain))
661ed4d1c46SDag-Erling Smørgrav return (YPERR_BADARGS);
662e17334c3SBill Paul
663d21de89aSHajimu UMEMOTO YPLOCK();
664d21de89aSHajimu UMEMOTO if (_yp_dobind(indomain, &ysd) != 0) {
665d21de89aSHajimu UMEMOTO YPUNLOCK();
6664e6ace08SBill Paul return(YPERR_DOMAIN);
667d21de89aSHajimu UMEMOTO }
6684e6ace08SBill Paul
6694e6ace08SBill Paul yprk.domain = indomain;
6704e6ace08SBill Paul yprk.map = inmap;
6714e6ace08SBill Paul yprk.key.keydat_val = (char *)inkey;
6724e6ace08SBill Paul yprk.key.keydat_len = inkeylen;
6734e6ace08SBill Paul
6744415cd19SGarrett Wollman #ifdef YPMATCHCACHE
6754e6ace08SBill Paul if (ypmatch_cache_lookup(ysd, yprk.map, &yprk.key, &yprv.val) == TRUE) {
6764e6ace08SBill Paul /*
6774415cd19SGarrett Wollman if (!strcmp(_yp_domain, indomain) && ypmatch_find(inmap, inkey,
6780e276383SBill Paul inkeylen, &yprv.val.valdat_val, &yprv.val.valdat_len)) {
6794e6ace08SBill Paul */
6800e276383SBill Paul *outvallen = yprv.val.valdat_len;
6814415cd19SGarrett Wollman *outval = (char *)malloc(*outvallen+1);
6826890d156SGuy Helmer if (*outval == NULL) {
6836890d156SGuy Helmer _yp_unbind(ysd);
6846890d156SGuy Helmer *outvallen = 0;
6856890d156SGuy Helmer YPUNLOCK();
6866890d156SGuy Helmer return (YPERR_RESRC);
6876890d156SGuy Helmer }
6880e276383SBill Paul bcopy(yprv.val.valdat_val, *outval, *outvallen);
6894415cd19SGarrett Wollman (*outval)[*outvallen] = '\0';
690d21de89aSHajimu UMEMOTO YPUNLOCK();
691ed4d1c46SDag-Erling Smørgrav return (0);
6924415cd19SGarrett Wollman }
6936890d156SGuy Helmer _yp_unbind(ysd);
6944415cd19SGarrett Wollman #endif
6954415cd19SGarrett Wollman
6964cc738f7SBill Paul again:
697c1dfca84SMarcelo Araujo if (retries > MAX_RETRIES) {
698c1dfca84SMarcelo Araujo YPUNLOCK();
699c1dfca84SMarcelo Araujo return (YPERR_RPC);
700c1dfca84SMarcelo Araujo }
701c1dfca84SMarcelo Araujo
702d21de89aSHajimu UMEMOTO if (_yp_dobind(indomain, &ysd) != 0) {
703d21de89aSHajimu UMEMOTO YPUNLOCK();
704ed4d1c46SDag-Erling Smørgrav return (YPERR_DOMAIN);
705d21de89aSHajimu UMEMOTO }
7064cc738f7SBill Paul
7074415cd19SGarrett Wollman tv.tv_sec = _yplib_timeout;
7084415cd19SGarrett Wollman tv.tv_usec = 0;
7094415cd19SGarrett Wollman
7104415cd19SGarrett Wollman bzero((char *)&yprv, sizeof yprv);
7114415cd19SGarrett Wollman
7124415cd19SGarrett Wollman r = clnt_call(ysd->dom_client, YPPROC_MATCH,
713f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypreq_key, &yprk,
714f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypresp_val, &yprv, tv);
7154415cd19SGarrett Wollman if (r != RPC_SUCCESS) {
7164415cd19SGarrett Wollman clnt_perror(ysd->dom_client, "yp_match: clnt_call");
7172694f9b9SBill Paul _yp_unbind(ysd);
718c1dfca84SMarcelo Araujo retries++;
7194415cd19SGarrett Wollman goto again;
7204415cd19SGarrett Wollman }
721a169c9b1SBill Paul
7220e276383SBill Paul if (!(r = ypprot_err(yprv.stat))) {
7230e276383SBill Paul *outvallen = yprv.val.valdat_len;
7244415cd19SGarrett Wollman *outval = (char *)malloc(*outvallen+1);
7256890d156SGuy Helmer if (*outval == NULL) {
7266890d156SGuy Helmer _yp_unbind(ysd);
7276890d156SGuy Helmer *outvallen = 0;
7286890d156SGuy Helmer xdr_free((xdrproc_t)xdr_ypresp_val, &yprv);
7296890d156SGuy Helmer YPUNLOCK();
7306890d156SGuy Helmer return (YPERR_RESRC);
7316890d156SGuy Helmer }
7320e276383SBill Paul bcopy(yprv.val.valdat_val, *outval, *outvallen);
7334415cd19SGarrett Wollman (*outval)[*outvallen] = '\0';
7344415cd19SGarrett Wollman #ifdef YPMATCHCACHE
7354e6ace08SBill Paul ypmatch_cache_insert(ysd, yprk.map, &yprk.key, &yprv.val);
7364415cd19SGarrett Wollman #endif
7372694f9b9SBill Paul }
738a169c9b1SBill Paul
739f249dbccSDag-Erling Smørgrav xdr_free((xdrproc_t)xdr_ypresp_val, &yprv);
740d21de89aSHajimu UMEMOTO YPUNLOCK();
741ed4d1c46SDag-Erling Smørgrav return (r);
7424415cd19SGarrett Wollman }
7434415cd19SGarrett Wollman
744069eb2caSHajimu UMEMOTO static int
yp_get_default_domain_locked(char ** domp)745069eb2caSHajimu UMEMOTO yp_get_default_domain_locked(char **domp)
7464415cd19SGarrett Wollman {
7474415cd19SGarrett Wollman *domp = NULL;
7484415cd19SGarrett Wollman if (_yp_domain[0] == '\0')
7494415cd19SGarrett Wollman if (getdomainname(_yp_domain, sizeof _yp_domain))
750ed4d1c46SDag-Erling Smørgrav return (YPERR_NODOM);
7514415cd19SGarrett Wollman *domp = _yp_domain;
752ed4d1c46SDag-Erling Smørgrav return (0);
7534415cd19SGarrett Wollman }
7544415cd19SGarrett Wollman
7554415cd19SGarrett Wollman int
yp_get_default_domain(char ** domp)756069eb2caSHajimu UMEMOTO yp_get_default_domain(char **domp)
757069eb2caSHajimu UMEMOTO {
758069eb2caSHajimu UMEMOTO int r;
759069eb2caSHajimu UMEMOTO
760069eb2caSHajimu UMEMOTO YPLOCK();
761069eb2caSHajimu UMEMOTO r = yp_get_default_domain_locked(domp);
762069eb2caSHajimu UMEMOTO YPUNLOCK();
763069eb2caSHajimu UMEMOTO return (r);
764069eb2caSHajimu UMEMOTO }
765069eb2caSHajimu UMEMOTO
766069eb2caSHajimu UMEMOTO int
yp_first(char * indomain,char * inmap,char ** outkey,int * outkeylen,char ** outval,int * outvallen)767dc584ddbSDag-Erling Smørgrav yp_first(char *indomain, char *inmap, char **outkey, int *outkeylen,
768dc584ddbSDag-Erling Smørgrav char **outval, int *outvallen)
7694415cd19SGarrett Wollman {
7704415cd19SGarrett Wollman struct ypresp_key_val yprkv;
7714415cd19SGarrett Wollman struct ypreq_nokey yprnk;
7724415cd19SGarrett Wollman struct dom_binding *ysd;
7734415cd19SGarrett Wollman struct timeval tv;
7744415cd19SGarrett Wollman int r;
775c1dfca84SMarcelo Araujo int retries = 0;
77606643071SBill Paul /* Sanity check */
77706643071SBill Paul
77806643071SBill Paul if (indomain == NULL || !strlen(indomain) ||
77906643071SBill Paul inmap == NULL || !strlen(inmap))
780ed4d1c46SDag-Erling Smørgrav return (YPERR_BADARGS);
78106643071SBill Paul
7824415cd19SGarrett Wollman *outkey = *outval = NULL;
7834415cd19SGarrett Wollman *outkeylen = *outvallen = 0;
7844415cd19SGarrett Wollman
785d21de89aSHajimu UMEMOTO YPLOCK();
7864415cd19SGarrett Wollman again:
787c1dfca84SMarcelo Araujo if (retries > MAX_RETRIES) {
788c1dfca84SMarcelo Araujo YPUNLOCK();
789c1dfca84SMarcelo Araujo return (YPERR_RPC);
790c1dfca84SMarcelo Araujo }
791c1dfca84SMarcelo Araujo
792d21de89aSHajimu UMEMOTO if (_yp_dobind(indomain, &ysd) != 0) {
793d21de89aSHajimu UMEMOTO YPUNLOCK();
794ed4d1c46SDag-Erling Smørgrav return (YPERR_DOMAIN);
795d21de89aSHajimu UMEMOTO }
7964415cd19SGarrett Wollman
7974415cd19SGarrett Wollman tv.tv_sec = _yplib_timeout;
7984415cd19SGarrett Wollman tv.tv_usec = 0;
7994415cd19SGarrett Wollman
8004415cd19SGarrett Wollman yprnk.domain = indomain;
8014415cd19SGarrett Wollman yprnk.map = inmap;
8024415cd19SGarrett Wollman bzero((char *)&yprkv, sizeof yprkv);
8034415cd19SGarrett Wollman
8044415cd19SGarrett Wollman r = clnt_call(ysd->dom_client, YPPROC_FIRST,
805f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypreq_nokey, &yprnk,
806f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypresp_key_val, &yprkv, tv);
8074415cd19SGarrett Wollman if (r != RPC_SUCCESS) {
8084415cd19SGarrett Wollman clnt_perror(ysd->dom_client, "yp_first: clnt_call");
8092694f9b9SBill Paul _yp_unbind(ysd);
810c1dfca84SMarcelo Araujo retries++;
8114415cd19SGarrett Wollman goto again;
8124415cd19SGarrett Wollman }
8130e276383SBill Paul if (!(r = ypprot_err(yprkv.stat))) {
8140e276383SBill Paul *outkeylen = yprkv.key.keydat_len;
8154415cd19SGarrett Wollman *outkey = (char *)malloc(*outkeylen+1);
8166890d156SGuy Helmer if (*outkey == NULL) {
8176890d156SGuy Helmer _yp_unbind(ysd);
8186890d156SGuy Helmer *outkeylen = 0;
8196890d156SGuy Helmer xdr_free((xdrproc_t)xdr_ypresp_key_val, &yprkv);
8206890d156SGuy Helmer YPUNLOCK();
8216890d156SGuy Helmer return (YPERR_RESRC);
8226890d156SGuy Helmer }
8230e276383SBill Paul bcopy(yprkv.key.keydat_val, *outkey, *outkeylen);
8244415cd19SGarrett Wollman (*outkey)[*outkeylen] = '\0';
8250e276383SBill Paul *outvallen = yprkv.val.valdat_len;
8264415cd19SGarrett Wollman *outval = (char *)malloc(*outvallen+1);
8276890d156SGuy Helmer if (*outval == NULL) {
8286890d156SGuy Helmer free(*outkey);
8296890d156SGuy Helmer _yp_unbind(ysd);
8306890d156SGuy Helmer *outkeylen = *outvallen = 0;
8316890d156SGuy Helmer xdr_free((xdrproc_t)xdr_ypresp_key_val, &yprkv);
8326890d156SGuy Helmer YPUNLOCK();
8336890d156SGuy Helmer return (YPERR_RESRC);
8346890d156SGuy Helmer }
8350e276383SBill Paul bcopy(yprkv.val.valdat_val, *outval, *outvallen);
8364415cd19SGarrett Wollman (*outval)[*outvallen] = '\0';
8372694f9b9SBill Paul }
838a169c9b1SBill Paul
839f249dbccSDag-Erling Smørgrav xdr_free((xdrproc_t)xdr_ypresp_key_val, &yprkv);
840d21de89aSHajimu UMEMOTO YPUNLOCK();
841ed4d1c46SDag-Erling Smørgrav return (r);
8424415cd19SGarrett Wollman }
8434415cd19SGarrett Wollman
8444415cd19SGarrett Wollman int
yp_next(char * indomain,char * inmap,char * inkey,int inkeylen,char ** outkey,int * outkeylen,char ** outval,int * outvallen)845dc584ddbSDag-Erling Smørgrav yp_next(char *indomain, char *inmap, char *inkey, int inkeylen,
846dc584ddbSDag-Erling Smørgrav char **outkey, int *outkeylen, char **outval, int *outvallen)
8474415cd19SGarrett Wollman {
8484415cd19SGarrett Wollman struct ypresp_key_val yprkv;
8494415cd19SGarrett Wollman struct ypreq_key yprk;
8504415cd19SGarrett Wollman struct dom_binding *ysd;
8514415cd19SGarrett Wollman struct timeval tv;
8524415cd19SGarrett Wollman int r;
853c1dfca84SMarcelo Araujo int retries = 0;
85406643071SBill Paul /* Sanity check */
85506643071SBill Paul
85606643071SBill Paul if (inkey == NULL || !strlen(inkey) || inkeylen <= 0 ||
85706643071SBill Paul inmap == NULL || !strlen(inmap) ||
85806643071SBill Paul indomain == NULL || !strlen(indomain))
859ed4d1c46SDag-Erling Smørgrav return (YPERR_BADARGS);
86006643071SBill Paul
8614415cd19SGarrett Wollman *outkey = *outval = NULL;
8624415cd19SGarrett Wollman *outkeylen = *outvallen = 0;
8634415cd19SGarrett Wollman
864d21de89aSHajimu UMEMOTO YPLOCK();
8654415cd19SGarrett Wollman again:
866c1dfca84SMarcelo Araujo if (retries > MAX_RETRIES) {
867c1dfca84SMarcelo Araujo YPUNLOCK();
868c1dfca84SMarcelo Araujo return (YPERR_RPC);
869c1dfca84SMarcelo Araujo }
870c1dfca84SMarcelo Araujo
871d21de89aSHajimu UMEMOTO if (_yp_dobind(indomain, &ysd) != 0) {
872d21de89aSHajimu UMEMOTO YPUNLOCK();
873ed4d1c46SDag-Erling Smørgrav return (YPERR_DOMAIN);
874d21de89aSHajimu UMEMOTO }
8754415cd19SGarrett Wollman
8764415cd19SGarrett Wollman tv.tv_sec = _yplib_timeout;
8774415cd19SGarrett Wollman tv.tv_usec = 0;
8784415cd19SGarrett Wollman
8794415cd19SGarrett Wollman yprk.domain = indomain;
8804415cd19SGarrett Wollman yprk.map = inmap;
8810e276383SBill Paul yprk.key.keydat_val = inkey;
8820e276383SBill Paul yprk.key.keydat_len = inkeylen;
8834415cd19SGarrett Wollman bzero((char *)&yprkv, sizeof yprkv);
8844415cd19SGarrett Wollman
8854415cd19SGarrett Wollman r = clnt_call(ysd->dom_client, YPPROC_NEXT,
886f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypreq_key, &yprk,
887f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypresp_key_val, &yprkv, tv);
8884415cd19SGarrett Wollman if (r != RPC_SUCCESS) {
8894415cd19SGarrett Wollman clnt_perror(ysd->dom_client, "yp_next: clnt_call");
8902694f9b9SBill Paul _yp_unbind(ysd);
891c1dfca84SMarcelo Araujo retries++;
8924415cd19SGarrett Wollman goto again;
8934415cd19SGarrett Wollman }
8940e276383SBill Paul if (!(r = ypprot_err(yprkv.stat))) {
8950e276383SBill Paul *outkeylen = yprkv.key.keydat_len;
8964415cd19SGarrett Wollman *outkey = (char *)malloc(*outkeylen+1);
8976890d156SGuy Helmer if (*outkey == NULL) {
8986890d156SGuy Helmer _yp_unbind(ysd);
8996890d156SGuy Helmer *outkeylen = 0;
9006890d156SGuy Helmer xdr_free((xdrproc_t)xdr_ypresp_key_val, &yprkv);
9016890d156SGuy Helmer YPUNLOCK();
9026890d156SGuy Helmer return (YPERR_RESRC);
9036890d156SGuy Helmer }
9040e276383SBill Paul bcopy(yprkv.key.keydat_val, *outkey, *outkeylen);
9054415cd19SGarrett Wollman (*outkey)[*outkeylen] = '\0';
9060e276383SBill Paul *outvallen = yprkv.val.valdat_len;
9074415cd19SGarrett Wollman *outval = (char *)malloc(*outvallen+1);
9086890d156SGuy Helmer if (*outval == NULL) {
9096890d156SGuy Helmer free(*outkey);
9106890d156SGuy Helmer _yp_unbind(ysd);
9116890d156SGuy Helmer *outkeylen = *outvallen = 0;
9126890d156SGuy Helmer xdr_free((xdrproc_t)xdr_ypresp_key_val, &yprkv);
9136890d156SGuy Helmer YPUNLOCK();
9146890d156SGuy Helmer return (YPERR_RESRC);
9156890d156SGuy Helmer }
9160e276383SBill Paul bcopy(yprkv.val.valdat_val, *outval, *outvallen);
9174415cd19SGarrett Wollman (*outval)[*outvallen] = '\0';
9182694f9b9SBill Paul }
919a169c9b1SBill Paul
920f249dbccSDag-Erling Smørgrav xdr_free((xdrproc_t)xdr_ypresp_key_val, &yprkv);
921d21de89aSHajimu UMEMOTO YPUNLOCK();
922ed4d1c46SDag-Erling Smørgrav return (r);
9234415cd19SGarrett Wollman }
9244415cd19SGarrett Wollman
9254415cd19SGarrett Wollman int
yp_all(char * indomain,char * inmap,struct ypall_callback * incallback)926dc584ddbSDag-Erling Smørgrav yp_all(char *indomain, char *inmap, struct ypall_callback *incallback)
9274415cd19SGarrett Wollman {
9284415cd19SGarrett Wollman struct ypreq_nokey yprnk;
9294415cd19SGarrett Wollman struct dom_binding *ysd;
9304415cd19SGarrett Wollman struct timeval tv;
9314415cd19SGarrett Wollman struct sockaddr_in clnt_sin;
9324415cd19SGarrett Wollman CLIENT *clnt;
93308aff01bSBill Paul u_long status, savstat;
9344415cd19SGarrett Wollman int clnt_sock;
935c1dfca84SMarcelo Araujo int retries = 0;
93606643071SBill Paul /* Sanity check */
93706643071SBill Paul
93806643071SBill Paul if (indomain == NULL || !strlen(indomain) ||
93906643071SBill Paul inmap == NULL || !strlen(inmap))
940ed4d1c46SDag-Erling Smørgrav return (YPERR_BADARGS);
94106643071SBill Paul
942d21de89aSHajimu UMEMOTO YPLOCK();
9432694f9b9SBill Paul again:
944c1dfca84SMarcelo Araujo if (retries > MAX_RETRIES) {
945c1dfca84SMarcelo Araujo YPUNLOCK();
946c1dfca84SMarcelo Araujo return (YPERR_RPC);
947c1dfca84SMarcelo Araujo }
9482694f9b9SBill Paul
949d21de89aSHajimu UMEMOTO if (_yp_dobind(indomain, &ysd) != 0) {
950d21de89aSHajimu UMEMOTO YPUNLOCK();
951ed4d1c46SDag-Erling Smørgrav return (YPERR_DOMAIN);
952d21de89aSHajimu UMEMOTO }
9534415cd19SGarrett Wollman
9544415cd19SGarrett Wollman tv.tv_sec = _yplib_timeout;
9554415cd19SGarrett Wollman tv.tv_usec = 0;
9562694f9b9SBill Paul
9572694f9b9SBill Paul /* YPPROC_ALL manufactures its own channel to ypserv using TCP */
9582694f9b9SBill Paul
9594415cd19SGarrett Wollman clnt_sock = RPC_ANYSOCK;
9604415cd19SGarrett Wollman clnt_sin = ysd->dom_server_addr;
9614415cd19SGarrett Wollman clnt_sin.sin_port = 0;
9624415cd19SGarrett Wollman clnt = clnttcp_create(&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
9634415cd19SGarrett Wollman if (clnt == NULL) {
964d21de89aSHajimu UMEMOTO YPUNLOCK();
9654415cd19SGarrett Wollman printf("clnttcp_create failed\n");
966ed4d1c46SDag-Erling Smørgrav return (YPERR_PMAP);
9674415cd19SGarrett Wollman }
9684415cd19SGarrett Wollman
9694415cd19SGarrett Wollman yprnk.domain = indomain;
9704415cd19SGarrett Wollman yprnk.map = inmap;
9714415cd19SGarrett Wollman ypresp_allfn = incallback->foreach;
9724415cd19SGarrett Wollman ypresp_data = (void *)incallback->data;
9734415cd19SGarrett Wollman
9742694f9b9SBill Paul if (clnt_call(clnt, YPPROC_ALL,
975f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypreq_nokey, &yprnk,
976f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypresp_all_seq, &status, tv) != RPC_SUCCESS) {
977c1dfca84SMarcelo Araujo clnt_perror(clnt, "yp_all: clnt_call");
9782694f9b9SBill Paul clnt_destroy(clnt);
9792694f9b9SBill Paul _yp_unbind(ysd);
980c1dfca84SMarcelo Araujo retries++;
9812694f9b9SBill Paul goto again;
9822694f9b9SBill Paul }
9832694f9b9SBill Paul
9844415cd19SGarrett Wollman clnt_destroy(clnt);
98508aff01bSBill Paul savstat = status;
986f249dbccSDag-Erling Smørgrav xdr_free((xdrproc_t)xdr_ypresp_all_seq, &status); /* not really needed... */
987d21de89aSHajimu UMEMOTO YPUNLOCK();
98808aff01bSBill Paul if (savstat != YP_NOMORE)
989ed4d1c46SDag-Erling Smørgrav return (ypprot_err(savstat));
990ed4d1c46SDag-Erling Smørgrav return (0);
9914415cd19SGarrett Wollman }
9924415cd19SGarrett Wollman
9934415cd19SGarrett Wollman int
yp_order(char * indomain,char * inmap,int * outorder)994dc584ddbSDag-Erling Smørgrav yp_order(char *indomain, char *inmap, int *outorder)
9954415cd19SGarrett Wollman {
9964415cd19SGarrett Wollman struct dom_binding *ysd;
9974415cd19SGarrett Wollman struct ypresp_order ypro;
9984415cd19SGarrett Wollman struct ypreq_nokey yprnk;
9994415cd19SGarrett Wollman struct timeval tv;
10004415cd19SGarrett Wollman int r;
10014415cd19SGarrett Wollman
100206643071SBill Paul /* Sanity check */
100306643071SBill Paul
100406643071SBill Paul if (indomain == NULL || !strlen(indomain) ||
100506643071SBill Paul inmap == NULL || !strlen(inmap))
1006ed4d1c46SDag-Erling Smørgrav return (YPERR_BADARGS);
100706643071SBill Paul
1008d21de89aSHajimu UMEMOTO YPLOCK();
10094415cd19SGarrett Wollman again:
1010d21de89aSHajimu UMEMOTO if (_yp_dobind(indomain, &ysd) != 0) {
1011d21de89aSHajimu UMEMOTO YPUNLOCK();
1012ed4d1c46SDag-Erling Smørgrav return (YPERR_DOMAIN);
1013d21de89aSHajimu UMEMOTO }
10144415cd19SGarrett Wollman
10154415cd19SGarrett Wollman tv.tv_sec = _yplib_timeout;
10164415cd19SGarrett Wollman tv.tv_usec = 0;
10174415cd19SGarrett Wollman
10184415cd19SGarrett Wollman yprnk.domain = indomain;
10194415cd19SGarrett Wollman yprnk.map = inmap;
10204415cd19SGarrett Wollman
10214415cd19SGarrett Wollman bzero((char *)(char *)&ypro, sizeof ypro);
10224415cd19SGarrett Wollman
10234415cd19SGarrett Wollman r = clnt_call(ysd->dom_client, YPPROC_ORDER,
1024f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypreq_nokey, &yprnk,
1025f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypresp_order, &ypro, tv);
10269fa75c15SBill Paul
10279fa75c15SBill Paul /*
10289fa75c15SBill Paul * NIS+ in YP compat mode doesn't support the YPPROC_ORDER
10299fa75c15SBill Paul * procedure.
10309fa75c15SBill Paul */
10319fa75c15SBill Paul if (r == RPC_PROCUNAVAIL) {
1032d21de89aSHajimu UMEMOTO YPUNLOCK();
10339fa75c15SBill Paul return(YPERR_YPERR);
10349fa75c15SBill Paul }
10359fa75c15SBill Paul
10364415cd19SGarrett Wollman if (r != RPC_SUCCESS) {
10374415cd19SGarrett Wollman clnt_perror(ysd->dom_client, "yp_order: clnt_call");
10382694f9b9SBill Paul _yp_unbind(ysd);
10394415cd19SGarrett Wollman goto again;
10404415cd19SGarrett Wollman }
10414415cd19SGarrett Wollman
1042a169c9b1SBill Paul if (!(r = ypprot_err(ypro.stat))) {
10434415cd19SGarrett Wollman *outorder = ypro.ordernum;
10442694f9b9SBill Paul }
1045a169c9b1SBill Paul
1046f249dbccSDag-Erling Smørgrav xdr_free((xdrproc_t)xdr_ypresp_order, &ypro);
1047d21de89aSHajimu UMEMOTO YPUNLOCK();
10482694f9b9SBill Paul return (r);
10494415cd19SGarrett Wollman }
10504415cd19SGarrett Wollman
10514415cd19SGarrett Wollman int
yp_master(char * indomain,char * inmap,char ** outname)1052dc584ddbSDag-Erling Smørgrav yp_master(char *indomain, char *inmap, char **outname)
10534415cd19SGarrett Wollman {
10544415cd19SGarrett Wollman struct dom_binding *ysd;
10554415cd19SGarrett Wollman struct ypresp_master yprm;
10564415cd19SGarrett Wollman struct ypreq_nokey yprnk;
10574415cd19SGarrett Wollman struct timeval tv;
10584415cd19SGarrett Wollman int r;
10594415cd19SGarrett Wollman
106006643071SBill Paul /* Sanity check */
106106643071SBill Paul
106206643071SBill Paul if (indomain == NULL || !strlen(indomain) ||
106306643071SBill Paul inmap == NULL || !strlen(inmap))
1064ed4d1c46SDag-Erling Smørgrav return (YPERR_BADARGS);
1065d21de89aSHajimu UMEMOTO YPLOCK();
10664415cd19SGarrett Wollman again:
1067d21de89aSHajimu UMEMOTO if (_yp_dobind(indomain, &ysd) != 0) {
1068d21de89aSHajimu UMEMOTO YPUNLOCK();
1069ed4d1c46SDag-Erling Smørgrav return (YPERR_DOMAIN);
1070d21de89aSHajimu UMEMOTO }
10714415cd19SGarrett Wollman
10724415cd19SGarrett Wollman tv.tv_sec = _yplib_timeout;
10734415cd19SGarrett Wollman tv.tv_usec = 0;
10744415cd19SGarrett Wollman
10754415cd19SGarrett Wollman yprnk.domain = indomain;
10764415cd19SGarrett Wollman yprnk.map = inmap;
10774415cd19SGarrett Wollman
10784415cd19SGarrett Wollman bzero((char *)&yprm, sizeof yprm);
10794415cd19SGarrett Wollman
10804415cd19SGarrett Wollman r = clnt_call(ysd->dom_client, YPPROC_MASTER,
1081f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypreq_nokey, &yprnk,
1082f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypresp_master, &yprm, tv);
10834415cd19SGarrett Wollman if (r != RPC_SUCCESS) {
10844415cd19SGarrett Wollman clnt_perror(ysd->dom_client, "yp_master: clnt_call");
10852694f9b9SBill Paul _yp_unbind(ysd);
10864415cd19SGarrett Wollman goto again;
10874415cd19SGarrett Wollman }
10882694f9b9SBill Paul
10890e276383SBill Paul if (!(r = ypprot_err(yprm.stat))) {
10900e276383SBill Paul *outname = (char *)strdup(yprm.peer);
10912694f9b9SBill Paul }
1092a169c9b1SBill Paul
1093f249dbccSDag-Erling Smørgrav xdr_free((xdrproc_t)xdr_ypresp_master, &yprm);
1094d21de89aSHajimu UMEMOTO YPUNLOCK();
10952694f9b9SBill Paul return (r);
10964415cd19SGarrett Wollman }
1097dc584ddbSDag-Erling Smørgrav
1098b9729ac2SBill Paul int
yp_maplist(char * indomain,struct ypmaplist ** outmaplist)1099dc584ddbSDag-Erling Smørgrav yp_maplist(char *indomain, struct ypmaplist **outmaplist)
11004415cd19SGarrett Wollman {
11014415cd19SGarrett Wollman struct dom_binding *ysd;
11024415cd19SGarrett Wollman struct ypresp_maplist ypml;
11034415cd19SGarrett Wollman struct timeval tv;
11044415cd19SGarrett Wollman int r;
11054415cd19SGarrett Wollman
110606643071SBill Paul /* Sanity check */
110706643071SBill Paul
110806643071SBill Paul if (indomain == NULL || !strlen(indomain))
1109ed4d1c46SDag-Erling Smørgrav return (YPERR_BADARGS);
111006643071SBill Paul
1111d21de89aSHajimu UMEMOTO YPLOCK();
11124415cd19SGarrett Wollman again:
1113d21de89aSHajimu UMEMOTO if (_yp_dobind(indomain, &ysd) != 0) {
1114d21de89aSHajimu UMEMOTO YPUNLOCK();
1115ed4d1c46SDag-Erling Smørgrav return (YPERR_DOMAIN);
1116d21de89aSHajimu UMEMOTO }
11174415cd19SGarrett Wollman
11184415cd19SGarrett Wollman tv.tv_sec = _yplib_timeout;
11194415cd19SGarrett Wollman tv.tv_usec = 0;
11204415cd19SGarrett Wollman
11214415cd19SGarrett Wollman bzero((char *)&ypml, sizeof ypml);
11224415cd19SGarrett Wollman
11234415cd19SGarrett Wollman r = clnt_call(ysd->dom_client, YPPROC_MAPLIST,
1124f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_domainname, &indomain,
1125f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_ypresp_maplist, &ypml,tv);
11264415cd19SGarrett Wollman if (r != RPC_SUCCESS) {
11274415cd19SGarrett Wollman clnt_perror(ysd->dom_client, "yp_maplist: clnt_call");
11282694f9b9SBill Paul _yp_unbind(ysd);
11294415cd19SGarrett Wollman goto again;
11304415cd19SGarrett Wollman }
1131a169c9b1SBill Paul if (!(r = ypprot_err(ypml.stat))) {
11320e276383SBill Paul *outmaplist = ypml.maps;
11332694f9b9SBill Paul }
11342694f9b9SBill Paul
1135f249dbccSDag-Erling Smørgrav /* NO: xdr_free((xdrproc_t)xdr_ypresp_maplist, &ypml);*/
1136d21de89aSHajimu UMEMOTO YPUNLOCK();
11372694f9b9SBill Paul return (r);
11384415cd19SGarrett Wollman }
11394415cd19SGarrett Wollman
1140f249dbccSDag-Erling Smørgrav const char *
yperr_string(int incode)1141dc584ddbSDag-Erling Smørgrav yperr_string(int incode)
11424415cd19SGarrett Wollman {
11434415cd19SGarrett Wollman static char err[80];
11444415cd19SGarrett Wollman
11454415cd19SGarrett Wollman switch (incode) {
11464415cd19SGarrett Wollman case 0:
1147ed4d1c46SDag-Erling Smørgrav return ("Success");
11484415cd19SGarrett Wollman case YPERR_BADARGS:
1149ed4d1c46SDag-Erling Smørgrav return ("Request arguments bad");
11504415cd19SGarrett Wollman case YPERR_RPC:
1151ed4d1c46SDag-Erling Smørgrav return ("RPC failure");
11524415cd19SGarrett Wollman case YPERR_DOMAIN:
1153ed4d1c46SDag-Erling Smørgrav return ("Can't bind to server which serves this domain");
11544415cd19SGarrett Wollman case YPERR_MAP:
1155ed4d1c46SDag-Erling Smørgrav return ("No such map in server's domain");
11564415cd19SGarrett Wollman case YPERR_KEY:
1157ed4d1c46SDag-Erling Smørgrav return ("No such key in map");
11584415cd19SGarrett Wollman case YPERR_YPERR:
1159ed4d1c46SDag-Erling Smørgrav return ("YP server error");
11604415cd19SGarrett Wollman case YPERR_RESRC:
1161ed4d1c46SDag-Erling Smørgrav return ("Local resource allocation failure");
11624415cd19SGarrett Wollman case YPERR_NOMORE:
1163ed4d1c46SDag-Erling Smørgrav return ("No more records in map database");
11644415cd19SGarrett Wollman case YPERR_PMAP:
1165ed4d1c46SDag-Erling Smørgrav return ("Can't communicate with portmapper");
11664415cd19SGarrett Wollman case YPERR_YPBIND:
1167ed4d1c46SDag-Erling Smørgrav return ("Can't communicate with ypbind");
11684415cd19SGarrett Wollman case YPERR_YPSERV:
1169ed4d1c46SDag-Erling Smørgrav return ("Can't communicate with ypserv");
11704415cd19SGarrett Wollman case YPERR_NODOM:
1171ed4d1c46SDag-Erling Smørgrav return ("Local domain name not set");
11724415cd19SGarrett Wollman case YPERR_BADDB:
1173ed4d1c46SDag-Erling Smørgrav return ("Server data base is bad");
11744415cd19SGarrett Wollman case YPERR_VERS:
1175ed4d1c46SDag-Erling Smørgrav return ("YP server version mismatch - server can't supply service.");
11764415cd19SGarrett Wollman case YPERR_ACCESS:
1177ed4d1c46SDag-Erling Smørgrav return ("Access violation");
11784415cd19SGarrett Wollman case YPERR_BUSY:
1179ed4d1c46SDag-Erling Smørgrav return ("Database is busy");
11804415cd19SGarrett Wollman }
11814415cd19SGarrett Wollman sprintf(err, "YP unknown error %d\n", incode);
1182ed4d1c46SDag-Erling Smørgrav return (err);
11834415cd19SGarrett Wollman }
11844415cd19SGarrett Wollman
11854415cd19SGarrett Wollman int
ypprot_err(unsigned int incode)1186dc584ddbSDag-Erling Smørgrav ypprot_err(unsigned int incode)
11874415cd19SGarrett Wollman {
11884415cd19SGarrett Wollman switch (incode) {
11894415cd19SGarrett Wollman case YP_TRUE:
1190ed4d1c46SDag-Erling Smørgrav return (0);
11914415cd19SGarrett Wollman case YP_FALSE:
1192ed4d1c46SDag-Erling Smørgrav return (YPERR_YPBIND);
11934415cd19SGarrett Wollman case YP_NOMORE:
1194ed4d1c46SDag-Erling Smørgrav return (YPERR_NOMORE);
11954415cd19SGarrett Wollman case YP_NOMAP:
1196ed4d1c46SDag-Erling Smørgrav return (YPERR_MAP);
11974415cd19SGarrett Wollman case YP_NODOM:
1198ed4d1c46SDag-Erling Smørgrav return (YPERR_DOMAIN);
11994415cd19SGarrett Wollman case YP_NOKEY:
1200ed4d1c46SDag-Erling Smørgrav return (YPERR_KEY);
12014415cd19SGarrett Wollman case YP_BADOP:
1202ed4d1c46SDag-Erling Smørgrav return (YPERR_YPERR);
12034415cd19SGarrett Wollman case YP_BADDB:
1204ed4d1c46SDag-Erling Smørgrav return (YPERR_BADDB);
12054415cd19SGarrett Wollman case YP_YPERR:
1206ed4d1c46SDag-Erling Smørgrav return (YPERR_YPERR);
12074415cd19SGarrett Wollman case YP_BADARGS:
1208ed4d1c46SDag-Erling Smørgrav return (YPERR_BADARGS);
12094415cd19SGarrett Wollman case YP_VERS:
1210ed4d1c46SDag-Erling Smørgrav return (YPERR_VERS);
12114415cd19SGarrett Wollman }
1212ed4d1c46SDag-Erling Smørgrav return (YPERR_YPERR);
12134415cd19SGarrett Wollman }
12144415cd19SGarrett Wollman
12154415cd19SGarrett Wollman int
_yp_check(char ** dom)1216dc584ddbSDag-Erling Smørgrav _yp_check(char **dom)
12174415cd19SGarrett Wollman {
12184415cd19SGarrett Wollman char *unused;
12194415cd19SGarrett Wollman
1220069eb2caSHajimu UMEMOTO YPLOCK();
12214415cd19SGarrett Wollman if (_yp_domain[0]=='\0')
1222069eb2caSHajimu UMEMOTO if (yp_get_default_domain_locked(&unused)) {
1223069eb2caSHajimu UMEMOTO YPUNLOCK();
1224ed4d1c46SDag-Erling Smørgrav return (0);
1225069eb2caSHajimu UMEMOTO }
12264415cd19SGarrett Wollman
12274415cd19SGarrett Wollman if (dom)
12284415cd19SGarrett Wollman *dom = _yp_domain;
12294415cd19SGarrett Wollman
1230d21de89aSHajimu UMEMOTO if (yp_bind_locked(_yp_domain) == 0) {
1231d21de89aSHajimu UMEMOTO yp_unbind_locked(_yp_domain);
1232069eb2caSHajimu UMEMOTO YPUNLOCK();
1233ed4d1c46SDag-Erling Smørgrav return (1);
12340f98415eSBill Paul }
1235069eb2caSHajimu UMEMOTO YPUNLOCK();
1236ed4d1c46SDag-Erling Smørgrav return (0);
12374415cd19SGarrett Wollman }
1238