ypupdated_server.c revision 114601
198944Sobrien/*
2130803Smarcel * Copyright (c) 1995, 1996
398944Sobrien *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
498944Sobrien *
598944Sobrien * Redistribution and use in source and binary forms, with or without
698944Sobrien * modification, are permitted provided that the following conditions
798944Sobrien * are met:
898944Sobrien * 1. Redistributions of source code must retain the above copyright
998944Sobrien *    notice, this list of conditions and the following disclaimer.
1098944Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1198944Sobrien *    notice, this list of conditions and the following disclaimer in the
1298944Sobrien *    documentation and/or other materials provided with the distribution.
1398944Sobrien * 3. All advertising materials mentioning features or use of this software
1498944Sobrien *    must display the following acknowledgement:
1598944Sobrien *      This product includes software developed by Bill Paul.
1698944Sobrien * 4. Neither the name of the author nor the names of any co-contributors
1798944Sobrien *    may be used to endorse or promote products derived from this software
1898944Sobrien *    without specific prior written permission.
1998944Sobrien *
2098944Sobrien * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2198944Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2298944Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2398944Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2498944Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2598944Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2698944Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2798944Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28130803Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29130803Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30130803Smarcel * SUCH DAMAGE.
31130803Smarcel *
32130803Smarcel * ypupdate server implementation
33130803Smarcel *
34130803Smarcel * Written by Bill Paul <wpaul@ctr.columbia.edu>
35130803Smarcel * Center for Telecommunications Research
36130803Smarcel * Columbia University, New York City
37130803Smarcel */
38130803Smarcel
39130803Smarcel#include <sys/cdefs.h>
40130803Smarcel__FBSDID("$FreeBSD: head/usr.sbin/rpc.ypupdated/ypupdated_server.c 114601 2003-05-03 21:06:42Z obrien $");
41130803Smarcel
42130803Smarcel#include <stdio.h>
43130803Smarcel#include <rpc/rpc.h>
44130803Smarcel#include <rpc/key_prot.h>
45130803Smarcel#include <sys/param.h>
46130803Smarcel#include <sys/cdefs.h>
4798944Sobrien#include <rpcsvc/yp.h>
4898944Sobrien#include "ypupdate_prot.h"
49130803Smarcel#include "ypupdated_extern.h"
5098944Sobrien#include "yp_extern.h"
5198944Sobrien#include "ypxfr_extern.h"
5298944Sobrien
5398944Sobrienint children = 0;
54130803Smarcelint forked = 0;
5598944Sobrien
5698944Sobrien/*
5798944Sobrien * Try to avoid spoofing: if a client chooses to use a very large
5898944Sobrien * window and then tries a bunch of randomly chosen encrypted timestamps,
5998944Sobrien * there's a chance he might stumble onto a valid combination.
6098944Sobrien * We therefore reject any RPCs with a window size larger than a preset
6198944Sobrien * value.
6298944Sobrien */
6398944Sobrien#ifndef WINDOW
6498944Sobrien#define WINDOW (60*60)
6598944Sobrien#endif
6698944Sobrien
6798944Sobrienstatic enum auth_stat
6898944Sobrienyp_checkauth(struct svc_req *svcreq)
6998944Sobrien{
7098944Sobrien	struct authdes_cred *des_cred;
7198944Sobrien
7298944Sobrien	switch (svcreq->rq_cred.oa_flavor) {
7398944Sobrien	case AUTH_DES:
7498944Sobrien		des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
7598944Sobrien		if (des_cred->adc_fullname.window > WINDOW) {
7698944Sobrien			yp_error("warning: client-specified window size \
7798944Sobrienwas too large -- possible spoof attempt");
7898944Sobrien			return(AUTH_BADCRED);
7998944Sobrien		}
8098944Sobrien		return(AUTH_OK);
8198944Sobrien		break;
8298944Sobrien	case AUTH_UNIX:
8398944Sobrien	case AUTH_NONE:
8498944Sobrien		yp_error("warning: client didn't use DES authentication");
8598944Sobrien		return(AUTH_TOOWEAK);
8698944Sobrien		break;
8798944Sobrien	default:
8898944Sobrien		yp_error("client used unknown auth flavor");
8998944Sobrien		return(AUTH_REJECTEDCRED);
9098944Sobrien		break;
9198944Sobrien	}
9298944Sobrien}
9398944Sobrien
9498944Sobrienunsigned int *
9598944Sobrienypu_change_1_svc(struct ypupdate_args *args, struct svc_req *svcreq)
9698944Sobrien{
9798944Sobrien	struct authdes_cred *des_cred;
9898944Sobrien	static int res;
9998944Sobrien	char *netname;
10098944Sobrien	enum auth_stat astat;
101130803Smarcel
10298944Sobrien	res = 0;
103130803Smarcel
104130803Smarcel	astat = yp_checkauth(svcreq);
105130803Smarcel
10698944Sobrien	if (astat != AUTH_OK) {
10798944Sobrien		svcerr_auth(svcreq->rq_xprt, astat);
108130803Smarcel		return(&res);
109130803Smarcel	}
110130803Smarcel
111130803Smarcel	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
112130803Smarcel	netname = des_cred->adc_fullname.name;
113130803Smarcel
11498944Sobrien	res = localupdate(netname, "/etc/publickey", YPOP_CHANGE,
11598944Sobrien		args->key.yp_buf_len, args->key.yp_buf_val,
116130803Smarcel		args->datum.yp_buf_len, args->datum.yp_buf_val);
117130803Smarcel
118130803Smarcel	if (res)
11998944Sobrien		return (&res);
12098944Sobrien
12198944Sobrien	res = ypmap_update(netname, args->mapname, YPOP_CHANGE,
12298944Sobrien		args->key.yp_buf_len, args->key.yp_buf_val,
12398944Sobrien		args->datum.yp_buf_len, args->datum.yp_buf_val);
12498944Sobrien
12598944Sobrien	return (&res);
12698944Sobrien}
12798944Sobrien
12898944Sobrienunsigned int *
12998944Sobrienypu_insert_1_svc(struct ypupdate_args *args, struct svc_req *svcreq)
13098944Sobrien{
13198944Sobrien	struct authdes_cred *des_cred;
13298944Sobrien	static int res;
13398944Sobrien	char *netname;
13498944Sobrien	enum auth_stat astat;
13598944Sobrien
13698944Sobrien	res = 0;
13798944Sobrien
13898944Sobrien	astat = yp_checkauth(svcreq);
13998944Sobrien
14098944Sobrien	if (astat != AUTH_OK) {
14198944Sobrien		svcerr_auth(svcreq->rq_xprt, astat);
14298944Sobrien		return(&res);
14398944Sobrien	}
14498944Sobrien
14598944Sobrien	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
14698944Sobrien	netname = des_cred->adc_fullname.name;
14798944Sobrien
14898944Sobrien	res = localupdate(netname, "/etc/publickey", YPOP_INSERT,
14998944Sobrien		args->key.yp_buf_len, args->key.yp_buf_val,
150		args->datum.yp_buf_len, args->datum.yp_buf_val);
151
152	if (res)
153		return (&res);
154
155	res = ypmap_update(netname, args->mapname, YPOP_INSERT,
156		args->key.yp_buf_len, args->key.yp_buf_val,
157		args->datum.yp_buf_len, args->datum.yp_buf_val);
158
159	return (&res);
160}
161
162unsigned int *
163ypu_delete_1_svc(struct ypdelete_args *args, struct svc_req *svcreq)
164{
165	struct authdes_cred *des_cred;
166	static int res;
167	char *netname;
168	enum auth_stat astat;
169
170	res = 0;
171
172	astat = yp_checkauth(svcreq);
173
174	if (astat != AUTH_OK) {
175		svcerr_auth(svcreq->rq_xprt, astat);
176		return(&res);
177	}
178
179	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
180	netname = des_cred->adc_fullname.name;
181
182	res = localupdate(netname, "/etc/publickey", YPOP_DELETE,
183		args->key.yp_buf_len, args->key.yp_buf_val,
184		0,			NULL);
185
186	if (res)
187		return (&res);
188
189	res = ypmap_update(netname, args->mapname, YPOP_DELETE,
190		args->key.yp_buf_len, args->key.yp_buf_val,
191		0,			NULL);
192
193	return (&res);
194}
195
196unsigned int *
197ypu_store_1_svc(struct ypupdate_args *args, struct svc_req *svcreq)
198{
199	struct authdes_cred *des_cred;
200	static int res;
201	char *netname;
202	enum auth_stat astat;
203
204	res = 0;
205
206	astat = yp_checkauth(svcreq);
207
208	if (astat != AUTH_OK) {
209		svcerr_auth(svcreq->rq_xprt, astat);
210		return(&res);
211	}
212
213	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
214	netname = des_cred->adc_fullname.name;
215
216	res = localupdate(netname, "/etc/publickey", YPOP_STORE,
217		args->key.yp_buf_len, args->key.yp_buf_val,
218		args->datum.yp_buf_len, args->datum.yp_buf_val);
219
220	if (res)
221		return (&res);
222
223	res = ypmap_update(netname, args->mapname, YPOP_STORE,
224		args->key.yp_buf_len, args->key.yp_buf_val,
225		args->datum.yp_buf_len, args->datum.yp_buf_val);
226
227	return (&res);
228}
229