Home | History | Annotate | Line # | Download | only in yp
yplib.c revision 1.4.2.1
      1      1.3  deraadt /*
      2      1.3  deraadt  * Copyright (c) 1992/3 Theo de Raadt <deraadt (at) fsa.ca>
      3      1.3  deraadt  * All rights reserved.
      4      1.3  deraadt  *
      5      1.3  deraadt  * Redistribution and use in source and binary forms, with or without
      6      1.3  deraadt  * modification, are permitted provided that the following conditions
      7      1.3  deraadt  * are met:
      8      1.3  deraadt  * 1. Redistributions of source code must retain the above copyright
      9      1.3  deraadt  *    notice, this list of conditions and the following disclaimer.
     10      1.3  deraadt  * 2. Redistributions in binary form must reproduce the above copyright
     11      1.3  deraadt  *    notice, this list of conditions and the following disclaimer in the
     12      1.3  deraadt  *    documentation and/or other materials provided with the distribution.
     13      1.3  deraadt  * 3. The name of the author may not be used to endorse or promote
     14      1.3  deraadt  *    products derived from this software without specific prior written
     15      1.3  deraadt  *    permission.
     16      1.3  deraadt  *
     17      1.3  deraadt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     18      1.3  deraadt  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19      1.3  deraadt  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20      1.3  deraadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     21      1.3  deraadt  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22      1.3  deraadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23      1.3  deraadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24      1.3  deraadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25      1.3  deraadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26      1.3  deraadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27      1.3  deraadt  * SUCH DAMAGE.
     28      1.3  deraadt  */
     29      1.3  deraadt 
     30      1.3  deraadt #ifndef LINT
     31  1.4.2.1      cgd static char rcsid[] = "$Id: yplib.c,v 1.4.2.1 1993/07/27 23:55:48 cgd Exp $";
     32      1.3  deraadt #endif
     33      1.3  deraadt 
     34      1.1  deraadt #include <sys/param.h>
     35      1.1  deraadt #include <sys/types.h>
     36      1.1  deraadt #include <sys/socket.h>
     37      1.1  deraadt #include <sys/file.h>
     38      1.1  deraadt #include <errno.h>
     39      1.1  deraadt #include <stdio.h>
     40      1.1  deraadt #include <string.h>
     41      1.1  deraadt #include <rpc/rpc.h>
     42      1.1  deraadt #include <rpc/xdr.h>
     43      1.1  deraadt #include <rpcsvc/yp_prot.h>
     44      1.1  deraadt #include <rpcsvc/ypclnt.h>
     45      1.1  deraadt 
     46      1.1  deraadt #ifndef BINDINGDIR
     47      1.1  deraadt #define BINDINGDIR "/var/yp/binding"
     48      1.1  deraadt #endif
     49      1.1  deraadt #define YPMATCHCACHE
     50      1.1  deraadt 
     51      1.1  deraadt extern bool_t xdr_domainname(), xdr_ypbind_resp();
     52      1.1  deraadt extern bool_t xdr_ypreq_key(), xdr_ypresp_val();
     53      1.1  deraadt extern bool_t xdr_ypreq_nokey(), xdr_ypresp_key_val();
     54      1.1  deraadt extern bool_t xdr_ypresp_all(), xdr_ypresp_all_seq();
     55      1.1  deraadt extern bool_t xdr_ypresp_master();
     56      1.1  deraadt 
     57      1.1  deraadt int (*ypresp_allfn)();
     58      1.1  deraadt void *ypresp_data;
     59      1.1  deraadt 
     60      1.1  deraadt struct dom_binding *_ypbindlist;
     61      1.1  deraadt static char _yp_domain[MAXHOSTNAMELEN];
     62      1.1  deraadt int _yplib_timeout = 10;
     63      1.1  deraadt 
     64      1.1  deraadt #ifdef YPMATCHCACHE
     65      1.1  deraadt int _yplib_cache = 5;
     66      1.1  deraadt 
     67      1.1  deraadt static struct ypmatch_ent {
     68      1.1  deraadt 	struct ypmatch_ent *next;
     69      1.1  deraadt 	char *map, *key, *val;
     70      1.1  deraadt 	int keylen, vallen;
     71      1.1  deraadt 	time_t expire_t;
     72      1.1  deraadt } *ypmc;
     73      1.1  deraadt 
     74      1.1  deraadt static void
     75      1.1  deraadt ypmatch_add(map, key, keylen, val, vallen)
     76  1.4.2.1      cgd char *map;
     77  1.4.2.1      cgd char *key;
     78  1.4.2.1      cgd int keylen;
     79  1.4.2.1      cgd char *val;
     80  1.4.2.1      cgd int vallen;
     81      1.1  deraadt {
     82      1.1  deraadt 	struct ypmatch_ent *ep;
     83      1.1  deraadt 	time_t t;
     84      1.1  deraadt 
     85      1.1  deraadt 	time(&t);
     86      1.1  deraadt 
     87      1.1  deraadt 	for(ep=ypmc; ep; ep=ep->next)
     88      1.1  deraadt 		if(ep->expire_t < t)
     89      1.1  deraadt 			break;
     90      1.1  deraadt 	if(ep==NULL) {
     91      1.1  deraadt 		ep = (struct ypmatch_ent *)malloc(sizeof *ep);
     92      1.1  deraadt 		bzero((char *)ep, sizeof *ep);
     93      1.1  deraadt 		if(ypmc)
     94      1.1  deraadt 			ep->next = ypmc;
     95      1.1  deraadt 		ypmc = ep;
     96      1.1  deraadt 	}
     97      1.1  deraadt 
     98      1.1  deraadt 	if(ep->key)
     99      1.1  deraadt 		free(ep->key);
    100      1.1  deraadt 	if(ep->val)
    101      1.1  deraadt 		free(ep->val);
    102      1.1  deraadt 
    103      1.1  deraadt 	ep->key = NULL;
    104      1.1  deraadt 	ep->val = NULL;
    105      1.1  deraadt 
    106      1.1  deraadt 	ep->key = (char *)malloc(keylen);
    107      1.1  deraadt 	if(ep->key==NULL)
    108      1.1  deraadt 		return;
    109      1.1  deraadt 
    110      1.1  deraadt 	ep->val = (char *)malloc(vallen);
    111      1.1  deraadt 	if(ep->key==NULL) {
    112      1.1  deraadt 		free(ep->key);
    113      1.1  deraadt 		ep->key = NULL;
    114      1.1  deraadt 		return;
    115      1.1  deraadt 	}
    116      1.1  deraadt 	ep->keylen = keylen;
    117      1.1  deraadt 	ep->vallen = vallen;
    118      1.1  deraadt 
    119      1.1  deraadt 	bcopy(key, ep->key, ep->keylen);
    120      1.1  deraadt 	bcopy(val, ep->val, ep->vallen);
    121      1.1  deraadt 
    122      1.1  deraadt 	if(ep->map) {
    123      1.1  deraadt 		if( strcmp(ep->map, map) ) {
    124      1.1  deraadt 			free(ep->map);
    125      1.1  deraadt 			ep->map = strdup(map);
    126      1.1  deraadt 		}
    127      1.1  deraadt 	} else {
    128      1.1  deraadt 		ep->map = strdup(map);
    129      1.1  deraadt 	}
    130      1.1  deraadt 
    131      1.1  deraadt 	ep->expire_t = t + _yplib_cache;
    132      1.1  deraadt }
    133      1.1  deraadt 
    134      1.1  deraadt static bool_t
    135      1.1  deraadt ypmatch_find(map, key, keylen, val, vallen)
    136  1.4.2.1      cgd char *map;
    137  1.4.2.1      cgd char *key;
    138      1.1  deraadt int keylen;
    139      1.1  deraadt char **val;
    140      1.1  deraadt int *vallen;
    141      1.1  deraadt {
    142      1.1  deraadt 	struct ypmatch_ent *ep;
    143      1.1  deraadt 	time_t t;
    144      1.1  deraadt 
    145      1.1  deraadt 	if(ypmc==NULL)
    146      1.1  deraadt 		return 0;
    147      1.1  deraadt 
    148      1.1  deraadt 	time(&t);
    149      1.1  deraadt 
    150      1.1  deraadt 	for(ep=ypmc; ep; ep=ep->next) {
    151      1.1  deraadt 		if(ep->keylen != keylen)
    152      1.1  deraadt 			continue;
    153      1.1  deraadt 		if(strcmp(ep->map, map))
    154      1.1  deraadt 			continue;
    155      1.1  deraadt 		if(bcmp(ep->key, key, keylen))
    156      1.1  deraadt 			continue;
    157      1.1  deraadt 		if(t > ep->expire_t)
    158      1.1  deraadt 			continue;
    159      1.1  deraadt 
    160      1.1  deraadt 		*val = ep->val;
    161      1.1  deraadt 		*vallen = ep->vallen;
    162      1.1  deraadt 		return 1;
    163      1.1  deraadt 	}
    164      1.1  deraadt 	return 0;
    165      1.1  deraadt }
    166      1.1  deraadt #endif
    167      1.1  deraadt 
    168      1.1  deraadt int
    169      1.1  deraadt _yp_dobind(dom, ypdb)
    170      1.1  deraadt char *dom;
    171      1.1  deraadt struct dom_binding **ypdb;
    172      1.1  deraadt {
    173      1.1  deraadt 	static int pid = -1;
    174      1.1  deraadt 	char path[MAXPATHLEN];
    175      1.1  deraadt 	struct dom_binding *ysd, *ysd2;
    176      1.1  deraadt 	struct ypbind_resp ypbr;
    177      1.1  deraadt 	struct timeval tv;
    178      1.1  deraadt 	struct sockaddr_in clnt_sin;
    179      1.1  deraadt 	int clnt_sock, fd, gpid;
    180      1.1  deraadt 	CLIENT *client;
    181      1.1  deraadt 	int new=0, r;
    182      1.1  deraadt 
    183      1.1  deraadt 	gpid = getpid();
    184      1.1  deraadt 	if( !(pid==-1 || pid==gpid) ) {
    185      1.1  deraadt 		ysd = _ypbindlist;
    186      1.1  deraadt 		while(ysd) {
    187      1.1  deraadt 			if(ysd->dom_client)
    188      1.1  deraadt 				clnt_destroy(ysd->dom_client);
    189      1.1  deraadt 			ysd2 = ysd->dom_pnext;
    190      1.1  deraadt 			free(ysd);
    191      1.1  deraadt 			ysd = ysd2;
    192      1.1  deraadt 		}
    193      1.1  deraadt 		_ypbindlist = NULL;
    194      1.1  deraadt 	}
    195      1.1  deraadt 	pid = gpid;
    196      1.1  deraadt 
    197      1.1  deraadt 	if(ypdb!=NULL)
    198      1.1  deraadt 		*ypdb = NULL;
    199      1.1  deraadt 
    200      1.1  deraadt 	if(dom==NULL || strlen(dom)==0)
    201      1.1  deraadt 		return YPERR_BADARGS;
    202      1.1  deraadt 
    203      1.1  deraadt 	for(ysd = _ypbindlist; ysd; ysd = ysd->dom_pnext)
    204      1.1  deraadt 		if( strcmp(dom, ysd->dom_domain) == 0)
    205      1.1  deraadt 			break;
    206      1.1  deraadt 	if(ysd==NULL) {
    207      1.1  deraadt 		ysd = (struct dom_binding *)malloc(sizeof *ysd);
    208      1.1  deraadt 		bzero((char *)ysd, sizeof *ysd);
    209      1.1  deraadt 		ysd->dom_socket = -1;
    210      1.1  deraadt 		ysd->dom_vers = 0;
    211      1.1  deraadt 		new = 1;
    212      1.1  deraadt 	}
    213      1.1  deraadt again:
    214      1.1  deraadt #ifdef BINDINGDIR
    215      1.1  deraadt 	if(ysd->dom_vers==0) {
    216      1.1  deraadt 		sprintf(path, "%s/%s.%d", BINDINGDIR, dom, 2);
    217      1.1  deraadt 		if( (fd=open(path, O_RDONLY)) == -1) {
    218      1.1  deraadt 			/* no binding file, YP is dead. */
    219      1.1  deraadt 			if(new)
    220      1.1  deraadt 				free(ysd);
    221      1.1  deraadt 			return YPERR_YPBIND;
    222      1.1  deraadt 		}
    223      1.1  deraadt 		if( flock(fd, LOCK_EX|LOCK_NB) == -1 && errno==EWOULDBLOCK) {
    224      1.1  deraadt 			r = read(fd, &ysd->dom_server_addr, sizeof ysd->dom_server_addr);
    225      1.1  deraadt 			if(r != sizeof ysd->dom_server_addr) {
    226      1.1  deraadt 				close(fd);
    227      1.1  deraadt 				ysd->dom_vers = -1;
    228      1.1  deraadt 				goto again;
    229      1.1  deraadt 			}
    230      1.1  deraadt 			ysd->dom_server_port = ysd->dom_server_addr.sin_port;
    231      1.1  deraadt 			close(fd);
    232      1.1  deraadt 			goto gotit;
    233      1.1  deraadt 		} else {
    234      1.1  deraadt 			/* no lock on binding file, YP is dead. */
    235      1.1  deraadt 			close(fd);
    236      1.1  deraadt 			if(new)
    237      1.1  deraadt 				free(ysd);
    238      1.1  deraadt 			return YPERR_YPBIND;
    239      1.1  deraadt 		}
    240      1.1  deraadt 	}
    241      1.1  deraadt #endif
    242      1.1  deraadt 	if(ysd->dom_vers==-1 || ysd->dom_vers==0) {
    243      1.1  deraadt 		bzero((char *)&clnt_sin, sizeof clnt_sin);
    244      1.1  deraadt 		clnt_sin.sin_family = AF_INET;
    245      1.1  deraadt 		clnt_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    246      1.1  deraadt 
    247      1.1  deraadt 		clnt_sock = RPC_ANYSOCK;
    248      1.1  deraadt 		client = clnttcp_create(&clnt_sin, YPBINDPROG, YPBINDVERS, &clnt_sock,
    249      1.1  deraadt 			0, 0);
    250      1.1  deraadt 		if(client==NULL) {
    251      1.1  deraadt 			clnt_pcreateerror("clnttcp_create");
    252      1.1  deraadt 			if(new)
    253      1.1  deraadt 				free(ysd);
    254      1.1  deraadt 			return YPERR_YPBIND;
    255      1.1  deraadt 		}
    256      1.1  deraadt 
    257      1.1  deraadt 		tv.tv_sec = _yplib_timeout;
    258      1.1  deraadt 		tv.tv_usec = 0;
    259      1.1  deraadt 		r = clnt_call(client, YPBINDPROC_DOMAIN,
    260      1.1  deraadt 			xdr_domainname, dom, xdr_ypbind_resp, &ypbr, tv);
    261      1.1  deraadt 		if(r != RPC_SUCCESS) {
    262      1.1  deraadt 			fprintf(stderr,
    263      1.1  deraadt 			"YP: server for domain %s not responding, still trying\n", dom);
    264      1.1  deraadt 			clnt_destroy(client);
    265      1.1  deraadt 			ysd->dom_vers = -1;
    266      1.1  deraadt 			goto again;
    267      1.1  deraadt 		}
    268      1.1  deraadt 		clnt_destroy(client);
    269      1.1  deraadt 
    270      1.1  deraadt 		bzero((char *)&ysd->dom_server_addr, sizeof ysd->dom_server_addr);
    271      1.1  deraadt 		ysd->dom_server_addr.sin_family = AF_INET;
    272      1.1  deraadt 		ysd->dom_server_addr.sin_port =
    273      1.1  deraadt 			ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port;
    274      1.1  deraadt 		ysd->dom_server_addr.sin_addr.s_addr =
    275      1.1  deraadt 			ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr.s_addr;
    276      1.1  deraadt 		ysd->dom_server_port =
    277      1.1  deraadt 			ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port;
    278      1.1  deraadt gotit:
    279      1.1  deraadt 		ysd->dom_vers = YPVERS;
    280      1.1  deraadt 		strcpy(ysd->dom_domain, dom);
    281      1.1  deraadt 	}
    282      1.1  deraadt 
    283      1.1  deraadt 	tv.tv_sec = _yplib_timeout/2;
    284      1.1  deraadt 	tv.tv_usec = 0;
    285      1.1  deraadt 	if(ysd->dom_client)
    286      1.1  deraadt 		clnt_destroy(ysd->dom_client);
    287      1.1  deraadt 	ysd->dom_socket = RPC_ANYSOCK;
    288      1.1  deraadt 	ysd->dom_client = clntudp_create(&ysd->dom_server_addr,
    289      1.1  deraadt 		YPPROG, YPVERS, tv, &ysd->dom_socket);
    290      1.1  deraadt 	if(ysd->dom_client==NULL) {
    291      1.1  deraadt 		clnt_pcreateerror("clntudp_create");
    292      1.1  deraadt 		ysd->dom_vers = -1;
    293      1.1  deraadt 		goto again;
    294      1.1  deraadt 	}
    295      1.1  deraadt 	if( fcntl(ysd->dom_socket, F_SETFD, 1) == -1)
    296      1.1  deraadt 		perror("fcntl: F_SETFD");
    297      1.1  deraadt 
    298      1.1  deraadt 	if(new) {
    299      1.1  deraadt 		ysd->dom_pnext = _ypbindlist;
    300      1.1  deraadt 		_ypbindlist = ysd;
    301      1.1  deraadt 	}
    302      1.1  deraadt 
    303      1.1  deraadt 	if(ypdb!=NULL)
    304      1.1  deraadt 		*ypdb = ysd;
    305      1.1  deraadt 	return 0;
    306      1.1  deraadt }
    307      1.1  deraadt 
    308      1.1  deraadt static void
    309      1.1  deraadt _yp_unbind(ypb)
    310      1.1  deraadt struct dom_binding *ypb;
    311      1.1  deraadt {
    312      1.1  deraadt 	clnt_destroy(ypb->dom_client);
    313      1.1  deraadt 	ypb->dom_client = NULL;
    314      1.1  deraadt 	ypb->dom_socket = -1;
    315      1.1  deraadt }
    316      1.1  deraadt 
    317      1.1  deraadt int
    318      1.1  deraadt yp_bind(dom)
    319      1.1  deraadt char *dom;
    320      1.1  deraadt {
    321      1.1  deraadt 	return _yp_dobind(dom, NULL);
    322      1.1  deraadt }
    323      1.1  deraadt 
    324      1.1  deraadt void
    325      1.1  deraadt yp_unbind(dom)
    326      1.1  deraadt char *dom;
    327      1.1  deraadt {
    328      1.1  deraadt 	struct dom_binding *ypb, *ypbp;
    329      1.1  deraadt 
    330      1.1  deraadt 	ypbp = NULL;
    331      1.1  deraadt 	for(ypb=_ypbindlist; ypb; ypb=ypb->dom_pnext) {
    332      1.1  deraadt 		if( strcmp(dom, ypb->dom_domain) == 0) {
    333      1.1  deraadt 			clnt_destroy(ypb->dom_client);
    334      1.1  deraadt 			if(ypbp)
    335      1.1  deraadt 				ypbp->dom_pnext = ypb->dom_pnext;
    336      1.1  deraadt 			else
    337      1.1  deraadt 				_ypbindlist = ypb->dom_pnext;
    338      1.1  deraadt 			free(ypb);
    339      1.1  deraadt 			return;
    340      1.1  deraadt 		}
    341      1.1  deraadt 		ypbp = ypb;
    342      1.1  deraadt 	}
    343      1.1  deraadt 	return;
    344      1.1  deraadt }
    345      1.1  deraadt 
    346      1.1  deraadt int
    347      1.1  deraadt yp_match(indomain, inmap, inkey, inkeylen, outval, outvallen)
    348      1.1  deraadt char *indomain;
    349      1.1  deraadt char *inmap;
    350  1.4.2.1      cgd const char *inkey;
    351      1.1  deraadt int inkeylen;
    352      1.1  deraadt char **outval;
    353      1.1  deraadt int *outvallen;
    354      1.1  deraadt {
    355      1.1  deraadt 	struct dom_binding *ysd;
    356      1.1  deraadt 	struct ypresp_val yprv;
    357      1.1  deraadt 	struct timeval tv;
    358      1.1  deraadt 	struct ypreq_key yprk;
    359      1.1  deraadt 	int r;
    360      1.1  deraadt 
    361      1.1  deraadt 	*outval = NULL;
    362      1.1  deraadt 	*outvallen = 0;
    363      1.1  deraadt 
    364      1.1  deraadt again:
    365      1.1  deraadt 	if( _yp_dobind(indomain, &ysd) != 0)
    366      1.1  deraadt 		return YPERR_DOMAIN;
    367      1.1  deraadt 
    368      1.1  deraadt #ifdef YPMATCHCACHE
    369      1.1  deraadt 	if( !strcmp(_yp_domain, indomain) && ypmatch_find(inmap, inkey,
    370      1.1  deraadt 	    inkeylen, &yprv.valdat.dptr, &yprv.valdat.dsize)) {
    371      1.1  deraadt 		*outvallen = yprv.valdat.dsize;
    372      1.1  deraadt 		*outval = (char *)malloc(*outvallen+1);
    373      1.1  deraadt 		bcopy(yprv.valdat.dptr, *outval, *outvallen);
    374      1.1  deraadt 		(*outval)[*outvallen] = '\0';
    375      1.1  deraadt 		return 0;
    376      1.1  deraadt 	}
    377      1.1  deraadt #endif
    378      1.1  deraadt 
    379      1.1  deraadt 	tv.tv_sec = _yplib_timeout;
    380      1.1  deraadt 	tv.tv_usec = 0;
    381      1.1  deraadt 
    382      1.1  deraadt 	yprk.domain = indomain;
    383      1.1  deraadt 	yprk.map = inmap;
    384      1.1  deraadt 	yprk.keydat.dptr = inkey;
    385      1.1  deraadt 	yprk.keydat.dsize = inkeylen;
    386      1.1  deraadt 
    387      1.1  deraadt 	bzero((char *)&yprv, sizeof yprv);
    388      1.1  deraadt 
    389      1.1  deraadt 	r = clnt_call(ysd->dom_client, YPPROC_MATCH,
    390      1.1  deraadt 		xdr_ypreq_key, &yprk, xdr_ypresp_val, &yprv, tv);
    391      1.1  deraadt 	if(r != RPC_SUCCESS) {
    392      1.1  deraadt 		clnt_perror(ysd->dom_client, "yp_match: clnt_call");
    393      1.1  deraadt 		ysd->dom_vers = -1;
    394      1.1  deraadt 		goto again;
    395      1.1  deraadt 	}
    396      1.1  deraadt 	if( !(r=ypprot_err(yprv.status)) ) {
    397      1.1  deraadt 		*outvallen = yprv.valdat.dsize;
    398      1.1  deraadt 		*outval = (char *)malloc(*outvallen+1);
    399      1.1  deraadt 		bcopy(yprv.valdat.dptr, *outval, *outvallen);
    400      1.1  deraadt 		(*outval)[*outvallen] = '\0';
    401      1.1  deraadt #ifdef YPMATCHCACHE
    402      1.1  deraadt 		if( strcmp(_yp_domain, indomain)==0 )
    403      1.1  deraadt 			 ypmatch_add(inmap, inkey, inkeylen, *outval, *outvallen);
    404      1.1  deraadt #endif
    405      1.1  deraadt 	}
    406      1.4  deraadt 	xdr_free(xdr_ypresp_val, (char *)&yprv);
    407      1.1  deraadt 	_yp_unbind(ysd);
    408      1.1  deraadt 	return r;
    409      1.1  deraadt }
    410      1.1  deraadt 
    411      1.1  deraadt int
    412      1.1  deraadt yp_get_default_domain(domp)
    413      1.1  deraadt char **domp;
    414      1.1  deraadt {
    415      1.1  deraadt 	*domp = NULL;
    416      1.1  deraadt 	if(_yp_domain[0] == '\0')
    417      1.1  deraadt 		if( getdomainname(_yp_domain, sizeof _yp_domain))
    418      1.1  deraadt 			return YPERR_NODOM;
    419      1.1  deraadt 	*domp = _yp_domain;
    420      1.1  deraadt 	return 0;
    421      1.1  deraadt }
    422      1.1  deraadt 
    423      1.1  deraadt int
    424      1.1  deraadt yp_first(indomain, inmap, outkey, outkeylen, outval, outvallen)
    425      1.1  deraadt char *indomain;
    426      1.1  deraadt char *inmap;
    427      1.1  deraadt char **outkey;
    428      1.1  deraadt int *outkeylen;
    429      1.1  deraadt char **outval;
    430      1.1  deraadt int *outvallen;
    431      1.1  deraadt {
    432      1.1  deraadt 	struct ypresp_key_val yprkv;
    433      1.1  deraadt 	struct ypreq_nokey yprnk;
    434      1.1  deraadt 	struct dom_binding *ysd;
    435      1.1  deraadt 	struct timeval tv;
    436      1.1  deraadt 	int r;
    437      1.1  deraadt 
    438      1.1  deraadt 	*outkey = *outval = NULL;
    439      1.1  deraadt 	*outkeylen = *outvallen = 0;
    440      1.1  deraadt 
    441      1.1  deraadt again:
    442      1.1  deraadt 	if( _yp_dobind(indomain, &ysd) != 0)
    443      1.1  deraadt 		return YPERR_DOMAIN;
    444      1.1  deraadt 
    445      1.1  deraadt 	tv.tv_sec = _yplib_timeout;
    446      1.1  deraadt 	tv.tv_usec = 0;
    447      1.1  deraadt 
    448      1.1  deraadt 	yprnk.domain = indomain;
    449      1.1  deraadt 	yprnk.map = inmap;
    450      1.1  deraadt 	bzero((char *)&yprkv, sizeof yprkv);
    451      1.1  deraadt 
    452      1.1  deraadt 	r = clnt_call(ysd->dom_client, YPPROC_FIRST,
    453      1.1  deraadt 		xdr_ypreq_nokey, &yprnk, xdr_ypresp_key_val, &yprkv, tv);
    454      1.1  deraadt 	if(r != RPC_SUCCESS) {
    455      1.1  deraadt 		clnt_perror(ysd->dom_client, "yp_first: clnt_call");
    456      1.1  deraadt 		ysd->dom_vers = -1;
    457      1.1  deraadt 		goto again;
    458      1.1  deraadt 	}
    459      1.1  deraadt 	if( !(r=ypprot_err(yprkv.status)) ) {
    460      1.1  deraadt 		*outkeylen = yprkv.keydat.dsize;
    461      1.1  deraadt 		*outkey = (char *)malloc(*outkeylen+1);
    462      1.1  deraadt 		bcopy(yprkv.keydat.dptr, *outkey, *outkeylen);
    463      1.1  deraadt 		(*outkey)[*outkeylen] = '\0';
    464      1.1  deraadt 		*outvallen = yprkv.valdat.dsize;
    465      1.1  deraadt 		*outval = (char *)malloc(*outvallen+1);
    466      1.1  deraadt 		bcopy(yprkv.valdat.dptr, *outval, *outvallen);
    467      1.1  deraadt 		(*outval)[*outvallen] = '\0';
    468      1.1  deraadt 	}
    469      1.4  deraadt 	xdr_free(xdr_ypresp_key_val, (char *)&yprkv);
    470      1.1  deraadt 	_yp_unbind(ysd);
    471      1.1  deraadt 	return r;
    472      1.1  deraadt }
    473      1.1  deraadt 
    474      1.1  deraadt int
    475      1.1  deraadt yp_next(indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen)
    476      1.1  deraadt char *indomain;
    477      1.1  deraadt char *inmap;
    478      1.1  deraadt char *inkey;
    479      1.1  deraadt int inkeylen;
    480      1.1  deraadt char **outkey;
    481      1.1  deraadt int *outkeylen;
    482      1.1  deraadt char **outval;
    483      1.1  deraadt int *outvallen;
    484      1.1  deraadt {
    485      1.1  deraadt 	struct ypresp_key_val yprkv;
    486      1.1  deraadt 	struct ypreq_key yprk;
    487      1.1  deraadt 	struct dom_binding *ysd;
    488      1.1  deraadt 	struct timeval tv;
    489      1.1  deraadt 	int r;
    490      1.1  deraadt 
    491      1.1  deraadt 	*outkey = *outval = NULL;
    492      1.1  deraadt 	*outkeylen = *outvallen = 0;
    493      1.1  deraadt 
    494      1.1  deraadt again:
    495      1.1  deraadt 	if( _yp_dobind(indomain, &ysd) != 0)
    496      1.1  deraadt 		return YPERR_DOMAIN;
    497      1.1  deraadt 
    498      1.1  deraadt 	tv.tv_sec = _yplib_timeout;
    499      1.1  deraadt 	tv.tv_usec = 0;
    500      1.1  deraadt 
    501      1.1  deraadt 	yprk.domain = indomain;
    502      1.1  deraadt 	yprk.map = inmap;
    503      1.1  deraadt 	yprk.keydat.dptr = inkey;
    504      1.1  deraadt 	yprk.keydat.dsize = inkeylen;
    505      1.1  deraadt 	bzero((char *)&yprkv, sizeof yprkv);
    506      1.1  deraadt 
    507      1.1  deraadt 	r = clnt_call(ysd->dom_client, YPPROC_NEXT,
    508      1.1  deraadt 		xdr_ypreq_key, &yprk, xdr_ypresp_key_val, &yprkv, tv);
    509      1.1  deraadt 	if(r != RPC_SUCCESS) {
    510      1.1  deraadt 		clnt_perror(ysd->dom_client, "yp_next: clnt_call");
    511      1.1  deraadt 		ysd->dom_vers = -1;
    512      1.1  deraadt 		goto again;
    513      1.1  deraadt 	}
    514      1.1  deraadt 	if( !(r=ypprot_err(yprkv.status)) ) {
    515      1.1  deraadt 		*outkeylen = yprkv.keydat.dsize;
    516      1.1  deraadt 		*outkey = (char *)malloc(*outkeylen+1);
    517      1.1  deraadt 		bcopy(yprkv.keydat.dptr, *outkey, *outkeylen);
    518      1.1  deraadt 		(*outkey)[*outkeylen] = '\0';
    519      1.1  deraadt 		*outvallen = yprkv.valdat.dsize;
    520      1.1  deraadt 		*outval = (char *)malloc(*outvallen+1);
    521      1.1  deraadt 		bcopy(yprkv.valdat.dptr, *outval, *outvallen);
    522      1.1  deraadt 		(*outval)[*outvallen] = '\0';
    523      1.1  deraadt 	}
    524      1.4  deraadt 	xdr_free(xdr_ypresp_key_val, (char *)&yprkv);
    525      1.1  deraadt 	_yp_unbind(ysd);
    526      1.1  deraadt 	return r;
    527      1.1  deraadt }
    528      1.1  deraadt 
    529      1.1  deraadt int
    530      1.1  deraadt yp_all(indomain, inmap, incallback)
    531      1.1  deraadt char *indomain;
    532      1.1  deraadt char *inmap;
    533      1.1  deraadt struct ypall_callback *incallback;
    534      1.1  deraadt {
    535      1.1  deraadt 	struct ypreq_nokey yprnk;
    536      1.1  deraadt 	struct dom_binding *ysd;
    537      1.1  deraadt 	struct timeval tv;
    538      1.1  deraadt 	struct sockaddr_in clnt_sin;
    539      1.1  deraadt 	CLIENT *clnt;
    540      1.1  deraadt 	u_long status;
    541      1.1  deraadt 	int clnt_sock;
    542      1.1  deraadt 
    543      1.1  deraadt 	if( _yp_dobind(indomain, &ysd) != 0)
    544      1.1  deraadt 		return YPERR_DOMAIN;
    545      1.1  deraadt 
    546      1.1  deraadt 	tv.tv_sec = _yplib_timeout;
    547      1.1  deraadt 	tv.tv_usec = 0;
    548      1.1  deraadt 	clnt_sock = RPC_ANYSOCK;
    549      1.1  deraadt 	clnt_sin = ysd->dom_server_addr;
    550      1.1  deraadt 	clnt_sin.sin_port = 0;
    551      1.1  deraadt 	clnt = clnttcp_create(&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
    552      1.1  deraadt 	if(clnt==NULL) {
    553      1.1  deraadt 		printf("clnttcp_create failed\n");
    554      1.1  deraadt 		return YPERR_PMAP;
    555      1.1  deraadt 	}
    556      1.1  deraadt 
    557      1.1  deraadt 	yprnk.domain = indomain;
    558      1.1  deraadt 	yprnk.map = inmap;
    559      1.1  deraadt 	ypresp_allfn = incallback->foreach;
    560      1.1  deraadt 	ypresp_data = (void *)incallback->data;
    561      1.1  deraadt 
    562      1.1  deraadt 	(void) clnt_call(clnt, YPPROC_ALL,
    563      1.1  deraadt 		xdr_ypreq_nokey, &yprnk, xdr_ypresp_all_seq, &status, tv);
    564      1.1  deraadt 	clnt_destroy(clnt);
    565      1.4  deraadt 	xdr_free(xdr_ypresp_all_seq, (char *)&status);	/* not really needed... */
    566      1.1  deraadt 	_yp_unbind(ysd);
    567      1.1  deraadt 
    568      1.1  deraadt 	if(status != YP_FALSE)
    569      1.1  deraadt 		return ypprot_err(status);
    570      1.1  deraadt 	return 0;
    571      1.1  deraadt }
    572      1.1  deraadt 
    573      1.1  deraadt int
    574      1.1  deraadt yp_order(indomain, inmap, outorder)
    575      1.1  deraadt char *indomain;
    576      1.1  deraadt char *inmap;
    577      1.1  deraadt int *outorder;
    578      1.1  deraadt {
    579      1.1  deraadt  	struct dom_binding *ysd;
    580      1.1  deraadt 	struct ypresp_order ypro;
    581      1.1  deraadt 	struct ypreq_nokey yprnk;
    582      1.1  deraadt 	struct timeval tv;
    583      1.1  deraadt 	int r;
    584      1.1  deraadt 
    585      1.1  deraadt again:
    586      1.1  deraadt 	if( _yp_dobind(indomain, &ysd) != 0)
    587      1.1  deraadt 		return YPERR_DOMAIN;
    588      1.1  deraadt 
    589      1.1  deraadt 	tv.tv_sec = _yplib_timeout;
    590      1.1  deraadt 	tv.tv_usec = 0;
    591      1.1  deraadt 
    592      1.1  deraadt 	yprnk.domain = indomain;
    593      1.1  deraadt 	yprnk.map = inmap;
    594      1.1  deraadt 
    595      1.1  deraadt 	bzero((char *)(char *)&ypro, sizeof ypro);
    596      1.1  deraadt 
    597      1.1  deraadt 	r = clnt_call(ysd->dom_client, YPPROC_ORDER,
    598      1.1  deraadt 		xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv);
    599      1.1  deraadt 	if(r != RPC_SUCCESS) {
    600      1.1  deraadt 		clnt_perror(ysd->dom_client, "yp_order: clnt_call");
    601      1.1  deraadt 		ysd->dom_vers = -1;
    602      1.1  deraadt 		goto again;
    603      1.1  deraadt 	}
    604      1.1  deraadt 
    605      1.1  deraadt 	*outorder = ypro.ordernum;
    606      1.4  deraadt 	xdr_free(xdr_ypresp_order, (char *)&ypro);
    607      1.1  deraadt 	_yp_unbind(ysd);
    608      1.1  deraadt 	return ypprot_err(ypro.status);
    609      1.1  deraadt }
    610      1.1  deraadt 
    611  1.4.2.1      cgd int
    612      1.1  deraadt yp_master(indomain, inmap, outname)
    613      1.1  deraadt char *indomain;
    614      1.1  deraadt char *inmap;
    615      1.1  deraadt char **outname;
    616      1.1  deraadt {
    617      1.1  deraadt 	struct dom_binding *ysd;
    618      1.1  deraadt 	struct ypresp_master yprm;
    619      1.1  deraadt 	struct ypreq_nokey yprnk;
    620      1.1  deraadt 	struct timeval tv;
    621      1.1  deraadt 	int r;
    622      1.1  deraadt 
    623      1.1  deraadt again:
    624      1.1  deraadt 	if( _yp_dobind(indomain, &ysd) != 0)
    625      1.1  deraadt 		return YPERR_DOMAIN;
    626      1.1  deraadt 
    627      1.1  deraadt 	tv.tv_sec = _yplib_timeout;
    628      1.1  deraadt 	tv.tv_usec = 0;
    629      1.1  deraadt 
    630      1.1  deraadt 	yprnk.domain = indomain;
    631      1.1  deraadt 	yprnk.map = inmap;
    632      1.1  deraadt 
    633      1.1  deraadt 	bzero((char *)&yprm, sizeof yprm);
    634      1.1  deraadt 
    635      1.1  deraadt 	r = clnt_call(ysd->dom_client, YPPROC_MASTER,
    636      1.1  deraadt 		xdr_ypreq_nokey, &yprnk, xdr_ypresp_master, &yprm, tv);
    637      1.1  deraadt 	if(r != RPC_SUCCESS) {
    638      1.1  deraadt 		clnt_perror(ysd->dom_client, "yp_master: clnt_call");
    639      1.1  deraadt 		ysd->dom_vers = -1;
    640      1.1  deraadt 		goto again;
    641      1.1  deraadt 	}
    642      1.1  deraadt 	if( !(r=ypprot_err(yprm.status)) ) {
    643      1.1  deraadt 		*outname = (char *)strdup(yprm.master);
    644      1.1  deraadt 	}
    645      1.4  deraadt 	xdr_free(xdr_ypresp_master, (char *)&yprm);
    646      1.1  deraadt 	_yp_unbind(ysd);
    647      1.1  deraadt 	return r;
    648      1.1  deraadt }
    649      1.1  deraadt 
    650      1.1  deraadt yp_maplist(indomain, outmaplist)
    651      1.1  deraadt char *indomain;
    652      1.1  deraadt struct ypmaplist **outmaplist;
    653      1.1  deraadt {
    654      1.1  deraadt 	struct dom_binding *ysd;
    655      1.1  deraadt 	struct ypresp_maplist ypml;
    656      1.1  deraadt 	struct timeval tv;
    657      1.1  deraadt 	int r;
    658      1.1  deraadt 
    659      1.1  deraadt again:
    660      1.1  deraadt 	if( _yp_dobind(indomain, &ysd) != 0)
    661      1.1  deraadt 		return YPERR_DOMAIN;
    662      1.1  deraadt 
    663      1.1  deraadt 	tv.tv_sec = _yplib_timeout;
    664      1.1  deraadt 	tv.tv_usec = 0;
    665      1.1  deraadt 
    666      1.1  deraadt 	bzero((char *)&ypml, sizeof ypml);
    667      1.1  deraadt 
    668      1.1  deraadt 	r = clnt_call(ysd->dom_client, YPPROC_MAPLIST,
    669      1.1  deraadt 		xdr_domainname, indomain, xdr_ypresp_maplist, &ypml, tv);
    670      1.1  deraadt 	if (r != RPC_SUCCESS) {
    671      1.1  deraadt 		clnt_perror(ysd->dom_client, "yp_maplist: clnt_call");
    672      1.1  deraadt 		ysd->dom_vers = -1;
    673      1.1  deraadt 		goto again;
    674      1.1  deraadt 	}
    675      1.1  deraadt 	*outmaplist = ypml.list;
    676      1.1  deraadt 	/* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/
    677      1.1  deraadt 	_yp_unbind(ysd);
    678      1.1  deraadt 	return ypprot_err(ypml.status);
    679      1.1  deraadt }
    680      1.1  deraadt 
    681      1.1  deraadt char *
    682      1.1  deraadt yperr_string(incode)
    683      1.1  deraadt int incode;
    684      1.1  deraadt {
    685      1.1  deraadt 	static char err[80];
    686      1.1  deraadt 
    687      1.1  deraadt 	switch(incode) {
    688      1.1  deraadt 	case 0:
    689      1.1  deraadt 		return "Success";
    690      1.1  deraadt 	case YPERR_BADARGS:
    691      1.1  deraadt 		return "Request arguments bad";
    692      1.1  deraadt 	case YPERR_RPC:
    693      1.1  deraadt 		return "RPC failure";
    694      1.1  deraadt 	case YPERR_DOMAIN:
    695      1.1  deraadt 		return "Can't bind to server which serves this domain";
    696      1.1  deraadt 	case YPERR_MAP:
    697      1.1  deraadt 		return "No such map in server's domain";
    698      1.1  deraadt 	case YPERR_KEY:
    699      1.1  deraadt 		return "No such key in map";
    700      1.1  deraadt 	case YPERR_YPERR:
    701      1.1  deraadt 		return "YP server error";
    702      1.1  deraadt 	case YPERR_RESRC:
    703      1.1  deraadt 		return "Local resource allocation failure";
    704      1.1  deraadt 	case YPERR_NOMORE:
    705      1.1  deraadt 		return "No more records in map database";
    706      1.1  deraadt 	case YPERR_PMAP:
    707      1.1  deraadt 		return "Can't communicate with portmapper";
    708      1.1  deraadt 	case YPERR_YPBIND:
    709      1.1  deraadt 		return "Can't communicate with ypbind";
    710      1.1  deraadt 	case YPERR_YPSERV:
    711      1.1  deraadt 		return "Can't communicate with ypserv";
    712      1.1  deraadt 	case YPERR_NODOM:
    713      1.1  deraadt 		return "Local domain name not set";
    714      1.1  deraadt 	case YPERR_BADDB:
    715      1.1  deraadt 		return "Server data base is bad";
    716      1.1  deraadt 	case YPERR_VERS:
    717      1.1  deraadt 		return "YP server version mismatch - server can't supply service.";
    718      1.1  deraadt 	case YPERR_ACCESS:
    719      1.1  deraadt 		return "Access violation";
    720      1.1  deraadt 	case YPERR_BUSY:
    721      1.1  deraadt 		return "Database is busy";
    722      1.1  deraadt 	}
    723      1.1  deraadt 	sprintf(err, "YP unknown error %d\n", incode);
    724      1.1  deraadt 	return err;
    725      1.1  deraadt }
    726      1.1  deraadt 
    727      1.1  deraadt int
    728      1.1  deraadt ypprot_err(incode)
    729      1.1  deraadt unsigned int incode;
    730      1.1  deraadt {
    731      1.1  deraadt 	switch(incode) {
    732      1.1  deraadt 	case YP_TRUE:
    733      1.1  deraadt 		return 0;
    734      1.1  deraadt 	case YP_FALSE:
    735      1.1  deraadt 		return YPERR_YPBIND;
    736      1.1  deraadt 	case YP_NOMORE:
    737      1.1  deraadt 		return YPERR_NOMORE;
    738      1.1  deraadt 	case YP_NOMAP:
    739      1.1  deraadt 		return YPERR_MAP;
    740      1.1  deraadt 	case YP_NODOM:
    741      1.1  deraadt 		return YPERR_NODOM;
    742      1.1  deraadt 	case YP_NOKEY:
    743      1.1  deraadt 		return YPERR_KEY;
    744      1.1  deraadt 	case YP_BADOP:
    745      1.1  deraadt 		return YPERR_YPERR;
    746      1.1  deraadt 	case YP_BADDB:
    747      1.1  deraadt 		return YPERR_BADDB;
    748      1.1  deraadt 	case YP_YPERR:
    749      1.1  deraadt 		return YPERR_YPERR;
    750      1.1  deraadt 	case YP_BADARGS:
    751      1.1  deraadt 		return YPERR_BADARGS;
    752      1.1  deraadt 	case YP_VERS:
    753      1.1  deraadt 		return YPERR_VERS;
    754      1.1  deraadt 	}
    755      1.1  deraadt 	return YPERR_YPERR;
    756      1.1  deraadt }
    757      1.1  deraadt 
    758      1.1  deraadt int
    759      1.1  deraadt _yp_check(dom)
    760      1.1  deraadt char **dom;
    761      1.1  deraadt {
    762      1.1  deraadt 	int use_yp = 0;
    763      1.1  deraadt 	char *unused;
    764      1.1  deraadt 
    765      1.1  deraadt 	if( _yp_domain[0]=='\0' )
    766      1.1  deraadt 		if( yp_get_default_domain(&unused) )
    767      1.1  deraadt 			return 0;
    768      1.1  deraadt 
    769      1.1  deraadt 	if(dom)
    770      1.1  deraadt 		*dom = _yp_domain;
    771      1.1  deraadt 
    772      1.1  deraadt 	if( yp_bind(_yp_domain)==0 )
    773      1.1  deraadt 		return 1;
    774      1.1  deraadt 	return 0;
    775      1.1  deraadt }
    776