1/*
2 * Copyright (c) 1995, 1996
3 *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *      This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * ypupdate server implementation
33 *
34 * Written by Bill Paul <wpaul@ctr.columbia.edu>
35 * Center for Telecommunications Research
36 * Columbia University, New York City
37 */
38
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD$");
41
42#include <stdio.h>
43#include <rpc/rpc.h>
44#include <rpc/key_prot.h>
45#include <sys/param.h>
46#include <rpcsvc/yp.h>
47#include "ypupdate_prot.h"
48#include "ypupdated_extern.h"
49#include "yp_extern.h"
50#include "ypxfr_extern.h"
51
52int children = 0;
53int forked = 0;
54
55/*
56 * Try to avoid spoofing: if a client chooses to use a very large
57 * window and then tries a bunch of randomly chosen encrypted timestamps,
58 * there's a chance he might stumble onto a valid combination.
59 * We therefore reject any RPCs with a window size larger than a preset
60 * value.
61 */
62#ifndef WINDOW
63#define WINDOW (60*60)
64#endif
65
66static enum auth_stat
67yp_checkauth(struct svc_req *svcreq)
68{
69	struct authdes_cred *des_cred;
70
71	switch (svcreq->rq_cred.oa_flavor) {
72	case AUTH_DES:
73		des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
74		if (des_cred->adc_fullname.window > WINDOW) {
75			yp_error("warning: client-specified window size \
76was too large -- possible spoof attempt");
77			return(AUTH_BADCRED);
78		}
79		return(AUTH_OK);
80		break;
81	case AUTH_UNIX:
82	case AUTH_NONE:
83		yp_error("warning: client didn't use DES authentication");
84		return(AUTH_TOOWEAK);
85		break;
86	default:
87		yp_error("client used unknown auth flavor");
88		return(AUTH_REJECTEDCRED);
89		break;
90	}
91}
92
93unsigned int *
94ypu_change_1_svc(struct ypupdate_args *args, struct svc_req *svcreq)
95{
96	struct authdes_cred *des_cred;
97	static int res;
98	char *netname;
99	enum auth_stat astat;
100
101	res = 0;
102
103	astat = yp_checkauth(svcreq);
104
105	if (astat != AUTH_OK) {
106		svcerr_auth(svcreq->rq_xprt, astat);
107		return(&res);
108	}
109
110	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
111	netname = des_cred->adc_fullname.name;
112
113	res = localupdate(netname, "/etc/publickey", YPOP_CHANGE,
114		args->key.yp_buf_len, args->key.yp_buf_val,
115		args->datum.yp_buf_len, args->datum.yp_buf_val);
116
117	if (res)
118		return (&res);
119
120	res = ypmap_update(netname, args->mapname, YPOP_CHANGE,
121		args->key.yp_buf_len, args->key.yp_buf_val,
122		args->datum.yp_buf_len, args->datum.yp_buf_val);
123
124	return (&res);
125}
126
127unsigned int *
128ypu_insert_1_svc(struct ypupdate_args *args, struct svc_req *svcreq)
129{
130	struct authdes_cred *des_cred;
131	static int res;
132	char *netname;
133	enum auth_stat astat;
134
135	res = 0;
136
137	astat = yp_checkauth(svcreq);
138
139	if (astat != AUTH_OK) {
140		svcerr_auth(svcreq->rq_xprt, astat);
141		return(&res);
142	}
143
144	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
145	netname = des_cred->adc_fullname.name;
146
147	res = localupdate(netname, "/etc/publickey", YPOP_INSERT,
148		args->key.yp_buf_len, args->key.yp_buf_val,
149		args->datum.yp_buf_len, args->datum.yp_buf_val);
150
151	if (res)
152		return (&res);
153
154	res = ypmap_update(netname, args->mapname, YPOP_INSERT,
155		args->key.yp_buf_len, args->key.yp_buf_val,
156		args->datum.yp_buf_len, args->datum.yp_buf_val);
157
158	return (&res);
159}
160
161unsigned int *
162ypu_delete_1_svc(struct ypdelete_args *args, struct svc_req *svcreq)
163{
164	struct authdes_cred *des_cred;
165	static int res;
166	char *netname;
167	enum auth_stat astat;
168
169	res = 0;
170
171	astat = yp_checkauth(svcreq);
172
173	if (astat != AUTH_OK) {
174		svcerr_auth(svcreq->rq_xprt, astat);
175		return(&res);
176	}
177
178	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
179	netname = des_cred->adc_fullname.name;
180
181	res = localupdate(netname, "/etc/publickey", YPOP_DELETE,
182		args->key.yp_buf_len, args->key.yp_buf_val,
183		0,			NULL);
184
185	if (res)
186		return (&res);
187
188	res = ypmap_update(netname, args->mapname, YPOP_DELETE,
189		args->key.yp_buf_len, args->key.yp_buf_val,
190		0,			NULL);
191
192	return (&res);
193}
194
195unsigned int *
196ypu_store_1_svc(struct ypupdate_args *args, struct svc_req *svcreq)
197{
198	struct authdes_cred *des_cred;
199	static int res;
200	char *netname;
201	enum auth_stat astat;
202
203	res = 0;
204
205	astat = yp_checkauth(svcreq);
206
207	if (astat != AUTH_OK) {
208		svcerr_auth(svcreq->rq_xprt, astat);
209		return(&res);
210	}
211
212	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
213	netname = des_cred->adc_fullname.name;
214
215	res = localupdate(netname, "/etc/publickey", YPOP_STORE,
216		args->key.yp_buf_len, args->key.yp_buf_val,
217		args->datum.yp_buf_len, args->datum.yp_buf_val);
218
219	if (res)
220		return (&res);
221
222	res = ypmap_update(netname, args->mapname, YPOP_STORE,
223		args->key.yp_buf_len, args->key.yp_buf_val,
224		args->datum.yp_buf_len, args->datum.yp_buf_val);
225
226	return (&res);
227}
228