126213Swpaul/*
226213Swpaul * Copyright (c) 1995, 1996
326213Swpaul *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
426213Swpaul *
526213Swpaul * Redistribution and use in source and binary forms, with or without
626213Swpaul * modification, are permitted provided that the following conditions
726213Swpaul * are met:
826213Swpaul * 1. Redistributions of source code must retain the above copyright
926213Swpaul *    notice, this list of conditions and the following disclaimer.
1026213Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1126213Swpaul *    notice, this list of conditions and the following disclaimer in the
1226213Swpaul *    documentation and/or other materials provided with the distribution.
1326213Swpaul * 3. All advertising materials mentioning features or use of this software
1426213Swpaul *    must display the following acknowledgement:
1526213Swpaul *	This product includes software developed by Bill Paul.
1626213Swpaul * 4. Neither the name of the author nor the names of any co-contributors
1726213Swpaul *    may be used to endorse or promote products derived from this software
1826213Swpaul *    without specific prior written permission.
1926213Swpaul *
2026213Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2126213Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2226213Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2326213Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2426213Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2526213Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2626213Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2726213Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2826213Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2926213Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3026213Swpaul * SUCH DAMAGE.
3126213Swpaul *
3226213Swpaul * ypupdate client-side library function.
3326213Swpaul *
3426213Swpaul * Written by Bill Paul <wpaul@ctr.columbia.edu>
3526213Swpaul * Center for Telecommunications Research
3626213Swpaul * Columbia University, New York City
3726213Swpaul */
3826213Swpaul
3984220Sdillon#include <sys/cdefs.h>
4084220Sdillon__FBSDID("$FreeBSD$");
4184220Sdillon
4226213Swpaul#include <stdlib.h>
4326213Swpaul#include <rpc/rpc.h>
4426213Swpaul#include <rpcsvc/yp_prot.h>
4526213Swpaul#include <rpcsvc/ypclnt.h>
4626213Swpaul#include <rpcsvc/ypupdate_prot.h>
4726213Swpaul#include <rpc/key_prot.h>
4826213Swpaul
4926213Swpaul#ifndef WINDOW
5026213Swpaul#define WINDOW (60*60)
5126213Swpaul#endif
5226213Swpaul
5326213Swpaul#ifndef TIMEOUT
5426213Swpaul#define TIMEOUT 300
5526213Swpaul#endif
5626213Swpaul
5726213Swpaulint
5890298Sdesyp_update(char *domain, char *map, unsigned int ypop, char *key, int keylen,
5990298Sdes    char *data, int datalen)
6026213Swpaul{
6126213Swpaul	char *master;
6226213Swpaul	int rval;
6326213Swpaul	unsigned int res;
6426213Swpaul	struct ypupdate_args upargs;
6526213Swpaul	struct ypdelete_args delargs;
6626213Swpaul	CLIENT *clnt;
6726213Swpaul	char netname[MAXNETNAMELEN+1];
6826213Swpaul	des_block des_key;
6926213Swpaul	struct timeval timeout;
7026213Swpaul
7126213Swpaul	/* Get the master server name for 'domain.' */
7226213Swpaul	if ((rval = yp_master(domain, map, &master)))
7326213Swpaul		return(rval);
7426213Swpaul
7526213Swpaul	/* Check that ypupdated is running there. */
7626213Swpaul	if (getrpcport(master, YPU_PROG, YPU_VERS, ypop))
7726213Swpaul		return(YPERR_DOMAIN);
7826213Swpaul
7926213Swpaul	/* Get a handle. */
8026213Swpaul	if ((clnt = clnt_create(master, YPU_PROG, YPU_VERS, "tcp")) == NULL)
8126213Swpaul		return(YPERR_RPC);
8226213Swpaul
8326213Swpaul	/*
8490297Sdes	 * Assemble netname of server.
8526213Swpaul	 * NOTE: It's difficult to discern from the documentation, but
8626213Swpaul	 * when you make a Secure RPC call, the netname you pass should
8726213Swpaul	 * be the netname of the guy on the other side, not your own
8826213Swpaul	 * netname. This is how the client side knows what public key
8926213Swpaul	 * to use for the initial exchange. Passing your own netname
9026213Swpaul	 * only works if the server on the other side is running under
9126213Swpaul	 * your UID.
9226213Swpaul	 */
9326213Swpaul	if (!host2netname(netname, master, domain)) {
9426213Swpaul		clnt_destroy(clnt);
9526213Swpaul		return(YPERR_BADARGS);
9626213Swpaul	}
9726213Swpaul
9826213Swpaul	/* Make up a DES session key. */
9926213Swpaul	key_gendes(&des_key);
10026213Swpaul
10126213Swpaul	/* Set up DES authentication. */
10226213Swpaul	if ((clnt->cl_auth = (AUTH *)authdes_create(netname, WINDOW, NULL,
10326213Swpaul			&des_key)) == NULL) {
10426213Swpaul		clnt_destroy(clnt);
10526213Swpaul		return(YPERR_RESRC);
10626213Swpaul	}
10726213Swpaul
10826213Swpaul	/* Set a timeout for clnt_call(). */
10926213Swpaul	timeout.tv_usec = 0;
11026213Swpaul	timeout.tv_sec = TIMEOUT;
11126213Swpaul
11226213Swpaul	/*
11326213Swpaul	 * Make the call. Note that we use clnt_call() here rather than
11426213Swpaul	 * the rpcgen-erated client stubs. We could use those stubs, but
11526213Swpaul	 * then we'd have to do some gymnastics to get at the error
11626213Swpaul	 * information to figure out what error code to send back to the
11726213Swpaul	 * caller. With clnt_call(), we get the error status returned to
11826213Swpaul	 * us right away, and we only have to exert a small amount of
11926213Swpaul	 * extra effort.
12026213Swpaul	 */
12190297Sdes	switch (ypop) {
12226213Swpaul	case YPOP_CHANGE:
12326213Swpaul		upargs.mapname = map;
12426213Swpaul		upargs.key.yp_buf_len = keylen;
12526213Swpaul		upargs.key.yp_buf_val = key;
12626213Swpaul		upargs.datum.yp_buf_len = datalen;
12726213Swpaul		upargs.datum.yp_buf_val = data;
12826213Swpaul
129121529Speter		if ((rval = clnt_call(clnt, YPU_CHANGE,
130121529Speter			(xdrproc_t)xdr_ypupdate_args, &upargs,
131121529Speter			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
13226213Swpaul			if (rval == RPC_AUTHERROR)
13326213Swpaul				res = YPERR_ACCESS;
13426213Swpaul			else
13526213Swpaul				res = YPERR_RPC;
13626213Swpaul		}
13726213Swpaul
13826213Swpaul		break;
13926213Swpaul	case YPOP_INSERT:
14026213Swpaul		upargs.mapname = map;
14126213Swpaul		upargs.key.yp_buf_len = keylen;
14226213Swpaul		upargs.key.yp_buf_val = key;
14326213Swpaul		upargs.datum.yp_buf_len = datalen;
14426213Swpaul		upargs.datum.yp_buf_val = data;
14526213Swpaul
146121529Speter		if ((rval = clnt_call(clnt, YPU_INSERT,
147121529Speter			(xdrproc_t)xdr_ypupdate_args, &upargs,
148121529Speter			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
14926213Swpaul			if (rval == RPC_AUTHERROR)
15026213Swpaul				res = YPERR_ACCESS;
15126213Swpaul			else
15226213Swpaul				res = YPERR_RPC;
15326213Swpaul		}
15426213Swpaul
15526213Swpaul		break;
15626213Swpaul	case YPOP_DELETE:
15726213Swpaul		delargs.mapname = map;
15826213Swpaul		delargs.key.yp_buf_len = keylen;
15926213Swpaul		delargs.key.yp_buf_val = key;
16026213Swpaul
161121529Speter		if ((rval = clnt_call(clnt, YPU_DELETE,
162121529Speter			(xdrproc_t)xdr_ypdelete_args, &delargs,
163121529Speter			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
16426213Swpaul			if (rval == RPC_AUTHERROR)
16526213Swpaul				res = YPERR_ACCESS;
16626213Swpaul			else
16726213Swpaul				res = YPERR_RPC;
16826213Swpaul		}
16926213Swpaul
17026213Swpaul		break;
17126213Swpaul	case YPOP_STORE:
17226213Swpaul		upargs.mapname = map;
17326213Swpaul		upargs.key.yp_buf_len = keylen;
17426213Swpaul		upargs.key.yp_buf_val = key;
17526213Swpaul		upargs.datum.yp_buf_len = datalen;
17626213Swpaul		upargs.datum.yp_buf_val = data;
17726213Swpaul
178121529Speter		if ((rval = clnt_call(clnt, YPU_STORE,
179121529Speter			(xdrproc_t)xdr_ypupdate_args, &upargs,
180121529Speter			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
18126213Swpaul			if (rval == RPC_AUTHERROR)
18226213Swpaul				res = YPERR_ACCESS;
18326213Swpaul			else
18426213Swpaul				res = YPERR_RPC;
18526213Swpaul		}
18626213Swpaul
18726213Swpaul		break;
18826213Swpaul	default:
18926213Swpaul		res = YPERR_BADARGS;
19026213Swpaul		break;
19126213Swpaul	}
19226213Swpaul
19326213Swpaul	/* All done: tear down the connection. */
19426213Swpaul	auth_destroy(clnt->cl_auth);
19526213Swpaul	clnt_destroy(clnt);
19626213Swpaul	free(master);
19726213Swpaul
19826213Swpaul	return(res);
19926213Swpaul}
200