yp_update.c revision 121529
118334Speter/*
218334Speter * Copyright (c) 1995, 1996
318334Speter *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
490075Sobrien *
590075Sobrien * Redistribution and use in source and binary forms, with or without
618334Speter * modification, are permitted provided that the following conditions
718334Speter * are met:
890075Sobrien * 1. Redistributions of source code must retain the above copyright
918334Speter *    notice, this list of conditions and the following disclaimer.
1090075Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1190075Sobrien *    notice, this list of conditions and the following disclaimer in the
1290075Sobrien *    documentation and/or other materials provided with the distribution.
1390075Sobrien * 3. All advertising materials mentioning features or use of this software
1418334Speter *    must display the following acknowledgement:
1590075Sobrien *	This product includes software developed by Bill Paul.
1690075Sobrien * 4. Neither the name of the author nor the names of any co-contributors
1790075Sobrien *    may be used to endorse or promote products derived from this software
1890075Sobrien *    without specific prior written permission.
1918334Speter *
2018334Speter * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2190075Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2290075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2390075Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2418334Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2518334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2650397Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2752284Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2818334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2918334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3018334Speter * SUCH DAMAGE.
3118334Speter *
3218334Speter * ypupdate client-side library function.
3318334Speter *
3418334Speter * Written by Bill Paul <wpaul@ctr.columbia.edu>
3518334Speter * Center for Telecommunications Research
3618334Speter * Columbia University, New York City
3718334Speter */
3818334Speter
3918334Speter#include <sys/cdefs.h>
4052284Sobrien__FBSDID("$FreeBSD: head/lib/librpcsvc/yp_update.c 121529 2003-10-26 03:43:35Z peter $");
4118334Speter
4290075Sobrien#include <stdlib.h>
4390075Sobrien#include <rpc/rpc.h>
4490075Sobrien#include <rpcsvc/yp_prot.h>
4590075Sobrien#include <rpcsvc/ypclnt.h>
4690075Sobrien#include <rpcsvc/ypupdate_prot.h>
4790075Sobrien#include <rpc/key_prot.h>
4818334Speter
4918334Speter#ifndef WINDOW
5018334Speter#define WINDOW (60*60)
5118334Speter#endif
5218334Speter
5318334Speter#ifndef TIMEOUT
5418334Speter#define TIMEOUT 300
5518334Speter#endif
5618334Speter
5718334Speterint
5818334Speteryp_update(char *domain, char *map, unsigned int ypop, char *key, int keylen,
5918334Speter    char *data, int datalen)
6018334Speter{
6118334Speter	char *master;
6218334Speter	int rval;
6350397Sobrien	unsigned int res;
6452284Sobrien	struct ypupdate_args upargs;
6552284Sobrien	struct ypdelete_args delargs;
6618334Speter	CLIENT *clnt;
6790075Sobrien	char netname[MAXNETNAMELEN+1];
6818334Speter	des_block des_key;
6918334Speter	struct timeval timeout;
7018334Speter
7118334Speter	/* Get the master server name for 'domain.' */
7218334Speter	if ((rval = yp_master(domain, map, &master)))
7318334Speter		return(rval);
7418334Speter
7518334Speter	/* Check that ypupdated is running there. */
7618334Speter	if (getrpcport(master, YPU_PROG, YPU_VERS, ypop))
7718334Speter		return(YPERR_DOMAIN);
7818334Speter
7918334Speter	/* Get a handle. */
8018334Speter	if ((clnt = clnt_create(master, YPU_PROG, YPU_VERS, "tcp")) == NULL)
8118334Speter		return(YPERR_RPC);
8218334Speter
8318334Speter	/*
8418334Speter	 * Assemble netname of server.
8518334Speter	 * NOTE: It's difficult to discern from the documentation, but
8618334Speter	 * when you make a Secure RPC call, the netname you pass should
8718334Speter	 * be the netname of the guy on the other side, not your own
8818334Speter	 * netname. This is how the client side knows what public key
8918334Speter	 * to use for the initial exchange. Passing your own netname
9018334Speter	 * only works if the server on the other side is running under
9118334Speter	 * your UID.
9218334Speter	 */
9390075Sobrien	if (!host2netname(netname, master, domain)) {
9418334Speter		clnt_destroy(clnt);
9518334Speter		return(YPERR_BADARGS);
9618334Speter	}
9790075Sobrien
9818334Speter	/* Make up a DES session key. */
9990075Sobrien	key_gendes(&des_key);
10090075Sobrien
10118334Speter	/* Set up DES authentication. */
10218334Speter	if ((clnt->cl_auth = (AUTH *)authdes_create(netname, WINDOW, NULL,
10318334Speter			&des_key)) == NULL) {
10418334Speter		clnt_destroy(clnt);
10518334Speter		return(YPERR_RESRC);
10618334Speter	}
10718334Speter
10850397Sobrien	/* Set a timeout for clnt_call(). */
10918334Speter	timeout.tv_usec = 0;
11052284Sobrien	timeout.tv_sec = TIMEOUT;
11118334Speter
11218334Speter	/*
11318334Speter	 * Make the call. Note that we use clnt_call() here rather than
11418334Speter	 * the rpcgen-erated client stubs. We could use those stubs, but
11552284Sobrien	 * then we'd have to do some gymnastics to get at the error
11618334Speter	 * information to figure out what error code to send back to the
11718334Speter	 * caller. With clnt_call(), we get the error status returned to
11818334Speter	 * us right away, and we only have to exert a small amount of
11918334Speter	 * extra effort.
12018334Speter	 */
12118334Speter	switch (ypop) {
12218334Speter	case YPOP_CHANGE:
12318334Speter		upargs.mapname = map;
12452284Sobrien		upargs.key.yp_buf_len = keylen;
12518334Speter		upargs.key.yp_buf_val = key;
12618334Speter		upargs.datum.yp_buf_len = datalen;
12790075Sobrien		upargs.datum.yp_buf_val = data;
12818334Speter
12918334Speter		if ((rval = clnt_call(clnt, YPU_CHANGE,
13050397Sobrien			(xdrproc_t)xdr_ypupdate_args, &upargs,
13150397Sobrien			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
13290075Sobrien			if (rval == RPC_AUTHERROR)
13390075Sobrien				res = YPERR_ACCESS;
13418334Speter			else
13518334Speter				res = YPERR_RPC;
13618334Speter		}
13718334Speter
13818334Speter		break;
13918334Speter	case YPOP_INSERT:
14018334Speter		upargs.mapname = map;
14118334Speter		upargs.key.yp_buf_len = keylen;
14218334Speter		upargs.key.yp_buf_val = key;
14318334Speter		upargs.datum.yp_buf_len = datalen;
14418334Speter		upargs.datum.yp_buf_val = data;
14518334Speter
14618334Speter		if ((rval = clnt_call(clnt, YPU_INSERT,
14718334Speter			(xdrproc_t)xdr_ypupdate_args, &upargs,
14818334Speter			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
14918334Speter			if (rval == RPC_AUTHERROR)
15018334Speter				res = YPERR_ACCESS;
15118334Speter			else
15218334Speter				res = YPERR_RPC;
15318334Speter		}
15418334Speter
15518334Speter		break;
15618334Speter	case YPOP_DELETE:
15718334Speter		delargs.mapname = map;
15818334Speter		delargs.key.yp_buf_len = keylen;
15918334Speter		delargs.key.yp_buf_val = key;
16018334Speter
16118334Speter		if ((rval = clnt_call(clnt, YPU_DELETE,
16218334Speter			(xdrproc_t)xdr_ypdelete_args, &delargs,
16318334Speter			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
16418334Speter			if (rval == RPC_AUTHERROR)
16518334Speter				res = YPERR_ACCESS;
16618334Speter			else
16718334Speter				res = YPERR_RPC;
16818334Speter		}
16918334Speter
17018334Speter		break;
17118334Speter	case YPOP_STORE:
17218334Speter		upargs.mapname = map;
17318334Speter		upargs.key.yp_buf_len = keylen;
17418334Speter		upargs.key.yp_buf_val = key;
17518334Speter		upargs.datum.yp_buf_len = datalen;
17618334Speter		upargs.datum.yp_buf_val = data;
17718334Speter
17818334Speter		if ((rval = clnt_call(clnt, YPU_STORE,
17918334Speter			(xdrproc_t)xdr_ypupdate_args, &upargs,
18018334Speter			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
18118334Speter			if (rval == RPC_AUTHERROR)
18290075Sobrien				res = YPERR_ACCESS;
18318334Speter			else
18418334Speter				res = YPERR_RPC;
18590075Sobrien		}
18618334Speter
18718334Speter		break;
18818334Speter	default:
18918334Speter		res = YPERR_BADARGS;
19018334Speter		break;
19118334Speter	}
19218334Speter
19318334Speter	/* All done: tear down the connection. */
19418334Speter	auth_destroy(clnt->cl_auth);
19518334Speter	clnt_destroy(clnt);
19618334Speter	free(master);
19718334Speter
19818334Speter	return(res);
19918334Speter}
20018334Speter