1df57947fSPedro F. Giffuni /*-
2df57947fSPedro F. Giffuni  * SPDX-License-Identifier: BSD-4-Clause
3df57947fSPedro F. Giffuni  *
440a5f74dSBill Paul  * Copyright (c) 1995, 1996
540a5f74dSBill Paul  *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
640a5f74dSBill Paul  *
740a5f74dSBill Paul  * Redistribution and use in source and binary forms, with or without
840a5f74dSBill Paul  * modification, are permitted provided that the following conditions
940a5f74dSBill Paul  * are met:
1040a5f74dSBill Paul  * 1. Redistributions of source code must retain the above copyright
1140a5f74dSBill Paul  *    notice, this list of conditions and the following disclaimer.
1240a5f74dSBill Paul  * 2. Redistributions in binary form must reproduce the above copyright
1340a5f74dSBill Paul  *    notice, this list of conditions and the following disclaimer in the
1440a5f74dSBill Paul  *    documentation and/or other materials provided with the distribution.
1540a5f74dSBill Paul  * 3. All advertising materials mentioning features or use of this software
1640a5f74dSBill Paul  *    must display the following acknowledgement:
1740a5f74dSBill Paul  *      This product includes software developed by Bill Paul.
1840a5f74dSBill Paul  * 4. Neither the name of the author nor the names of any co-contributors
1940a5f74dSBill Paul  *    may be used to endorse or promote products derived from this software
2040a5f74dSBill Paul  *    without specific prior written permission.
2140a5f74dSBill Paul  *
2240a5f74dSBill Paul  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2340a5f74dSBill Paul  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2440a5f74dSBill Paul  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2540a5f74dSBill Paul  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2640a5f74dSBill Paul  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2740a5f74dSBill Paul  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2840a5f74dSBill Paul  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2940a5f74dSBill Paul  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3040a5f74dSBill Paul  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3140a5f74dSBill Paul  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3240a5f74dSBill Paul  * SUCH DAMAGE.
3340a5f74dSBill Paul  *
3440a5f74dSBill Paul  * ypupdate server implementation
3540a5f74dSBill Paul  *
3640a5f74dSBill Paul  * Written by Bill Paul <wpaul@ctr.columbia.edu>
3740a5f74dSBill Paul  * Center for Telecommunications Research
3840a5f74dSBill Paul  * Columbia University, New York City
3940a5f74dSBill Paul  */
4040a5f74dSBill Paul 
41b728350eSDavid E. O'Brien #include <sys/cdefs.h>
4240a5f74dSBill Paul #include <stdio.h>
4340a5f74dSBill Paul #include <rpc/rpc.h>
4440a5f74dSBill Paul #include <rpc/key_prot.h>
4540a5f74dSBill Paul #include <sys/param.h>
4640a5f74dSBill Paul #include <rpcsvc/yp.h>
4740a5f74dSBill Paul #include "ypupdate_prot.h"
4840a5f74dSBill Paul #include "ypupdated_extern.h"
4940a5f74dSBill Paul #include "yp_extern.h"
5040a5f74dSBill Paul #include "ypxfr_extern.h"
5140a5f74dSBill Paul 
5240a5f74dSBill Paul int children = 0;
5340a5f74dSBill Paul int forked = 0;
5440a5f74dSBill Paul 
5540a5f74dSBill Paul /*
5640a5f74dSBill Paul  * Try to avoid spoofing: if a client chooses to use a very large
5740a5f74dSBill Paul  * window and then tries a bunch of randomly chosen encrypted timestamps,
5840a5f74dSBill Paul  * there's a chance he might stumble onto a valid combination.
5940a5f74dSBill Paul  * We therefore reject any RPCs with a window size larger than a preset
6040a5f74dSBill Paul  * value.
6140a5f74dSBill Paul  */
6240a5f74dSBill Paul #ifndef WINDOW
6340a5f74dSBill Paul #define WINDOW (60*60)
6440a5f74dSBill Paul #endif
6540a5f74dSBill Paul 
66dc584ddbSDag-Erling Smørgrav static enum auth_stat
yp_checkauth(struct svc_req * svcreq)67dc584ddbSDag-Erling Smørgrav yp_checkauth(struct svc_req *svcreq)
6840a5f74dSBill Paul {
6940a5f74dSBill Paul 	struct authdes_cred *des_cred;
7040a5f74dSBill Paul 
7140a5f74dSBill Paul 	switch (svcreq->rq_cred.oa_flavor) {
7240a5f74dSBill Paul 	case AUTH_DES:
7340a5f74dSBill Paul 		des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
7440a5f74dSBill Paul 		if (des_cred->adc_fullname.window > WINDOW) {
7540a5f74dSBill Paul 			yp_error("warning: client-specified window size \
7640a5f74dSBill Paul was too large -- possible spoof attempt");
7740a5f74dSBill Paul 			return(AUTH_BADCRED);
7840a5f74dSBill Paul 		}
7940a5f74dSBill Paul 		return(AUTH_OK);
8040a5f74dSBill Paul 		break;
8140a5f74dSBill Paul 	case AUTH_UNIX:
8240a5f74dSBill Paul 	case AUTH_NONE:
8340a5f74dSBill Paul 		yp_error("warning: client didn't use DES authentication");
8440a5f74dSBill Paul 		return(AUTH_TOOWEAK);
8540a5f74dSBill Paul 		break;
8640a5f74dSBill Paul 	default:
8740a5f74dSBill Paul 		yp_error("client used unknown auth flavor");
8840a5f74dSBill Paul 		return(AUTH_REJECTEDCRED);
8940a5f74dSBill Paul 		break;
9040a5f74dSBill Paul 	}
9140a5f74dSBill Paul }
9240a5f74dSBill Paul 
93dc584ddbSDag-Erling Smørgrav unsigned int *
ypu_change_1_svc(struct ypupdate_args * args,struct svc_req * svcreq)94dc584ddbSDag-Erling Smørgrav ypu_change_1_svc(struct ypupdate_args *args, struct svc_req *svcreq)
9540a5f74dSBill Paul {
9640a5f74dSBill Paul 	struct authdes_cred *des_cred;
9740a5f74dSBill Paul 	static int res;
9840a5f74dSBill Paul 	char *netname;
9940a5f74dSBill Paul 	enum auth_stat astat;
10040a5f74dSBill Paul 
10140a5f74dSBill Paul 	res = 0;
10240a5f74dSBill Paul 
10340a5f74dSBill Paul 	astat = yp_checkauth(svcreq);
10440a5f74dSBill Paul 
10540a5f74dSBill Paul 	if (astat != AUTH_OK) {
10640a5f74dSBill Paul 		svcerr_auth(svcreq->rq_xprt, astat);
10740a5f74dSBill Paul 		return(&res);
10840a5f74dSBill Paul 	}
10940a5f74dSBill Paul 
11040a5f74dSBill Paul 	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
11140a5f74dSBill Paul 	netname = des_cred->adc_fullname.name;
11240a5f74dSBill Paul 
11340a5f74dSBill Paul 	res = localupdate(netname, "/etc/publickey", YPOP_CHANGE,
11440a5f74dSBill Paul 		args->key.yp_buf_len, args->key.yp_buf_val,
11540a5f74dSBill Paul 		args->datum.yp_buf_len, args->datum.yp_buf_val);
11640a5f74dSBill Paul 
11740a5f74dSBill Paul 	if (res)
11840a5f74dSBill Paul 		return (&res);
11940a5f74dSBill Paul 
12040a5f74dSBill Paul 	res = ypmap_update(netname, args->mapname, YPOP_CHANGE,
12140a5f74dSBill Paul 		args->key.yp_buf_len, args->key.yp_buf_val,
12240a5f74dSBill Paul 		args->datum.yp_buf_len, args->datum.yp_buf_val);
12340a5f74dSBill Paul 
12440a5f74dSBill Paul 	return (&res);
12540a5f74dSBill Paul }
12640a5f74dSBill Paul 
127dc584ddbSDag-Erling Smørgrav unsigned int *
ypu_insert_1_svc(struct ypupdate_args * args,struct svc_req * svcreq)128dc584ddbSDag-Erling Smørgrav ypu_insert_1_svc(struct ypupdate_args *args, struct svc_req *svcreq)
12940a5f74dSBill Paul {
13040a5f74dSBill Paul 	struct authdes_cred *des_cred;
13140a5f74dSBill Paul 	static int res;
13240a5f74dSBill Paul 	char *netname;
13340a5f74dSBill Paul 	enum auth_stat astat;
13440a5f74dSBill Paul 
13540a5f74dSBill Paul 	res = 0;
13640a5f74dSBill Paul 
13740a5f74dSBill Paul 	astat = yp_checkauth(svcreq);
13840a5f74dSBill Paul 
13940a5f74dSBill Paul 	if (astat != AUTH_OK) {
14040a5f74dSBill Paul 		svcerr_auth(svcreq->rq_xprt, astat);
14140a5f74dSBill Paul 		return(&res);
14240a5f74dSBill Paul 	}
14340a5f74dSBill Paul 
14440a5f74dSBill Paul 	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
14540a5f74dSBill Paul 	netname = des_cred->adc_fullname.name;
14640a5f74dSBill Paul 
14740a5f74dSBill Paul 	res = localupdate(netname, "/etc/publickey", YPOP_INSERT,
14840a5f74dSBill Paul 		args->key.yp_buf_len, args->key.yp_buf_val,
14940a5f74dSBill Paul 		args->datum.yp_buf_len, args->datum.yp_buf_val);
15040a5f74dSBill Paul 
15140a5f74dSBill Paul 	if (res)
15240a5f74dSBill Paul 		return (&res);
15340a5f74dSBill Paul 
15440a5f74dSBill Paul 	res = ypmap_update(netname, args->mapname, YPOP_INSERT,
15540a5f74dSBill Paul 		args->key.yp_buf_len, args->key.yp_buf_val,
15640a5f74dSBill Paul 		args->datum.yp_buf_len, args->datum.yp_buf_val);
15740a5f74dSBill Paul 
15840a5f74dSBill Paul 	return (&res);
15940a5f74dSBill Paul }
16040a5f74dSBill Paul 
161dc584ddbSDag-Erling Smørgrav unsigned int *
ypu_delete_1_svc(struct ypdelete_args * args,struct svc_req * svcreq)162dc584ddbSDag-Erling Smørgrav ypu_delete_1_svc(struct ypdelete_args *args, struct svc_req *svcreq)
16340a5f74dSBill Paul {
16440a5f74dSBill Paul 	struct authdes_cred *des_cred;
16540a5f74dSBill Paul 	static int res;
16640a5f74dSBill Paul 	char *netname;
16740a5f74dSBill Paul 	enum auth_stat astat;
16840a5f74dSBill Paul 
16940a5f74dSBill Paul 	res = 0;
17040a5f74dSBill Paul 
17140a5f74dSBill Paul 	astat = yp_checkauth(svcreq);
17240a5f74dSBill Paul 
17340a5f74dSBill Paul 	if (astat != AUTH_OK) {
17440a5f74dSBill Paul 		svcerr_auth(svcreq->rq_xprt, astat);
17540a5f74dSBill Paul 		return(&res);
17640a5f74dSBill Paul 	}
17740a5f74dSBill Paul 
17840a5f74dSBill Paul 	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
17940a5f74dSBill Paul 	netname = des_cred->adc_fullname.name;
18040a5f74dSBill Paul 
18140a5f74dSBill Paul 	res = localupdate(netname, "/etc/publickey", YPOP_DELETE,
18240a5f74dSBill Paul 		args->key.yp_buf_len, args->key.yp_buf_val,
18340a5f74dSBill Paul 		0,			NULL);
18440a5f74dSBill Paul 
18540a5f74dSBill Paul 	if (res)
18640a5f74dSBill Paul 		return (&res);
18740a5f74dSBill Paul 
18840a5f74dSBill Paul 	res = ypmap_update(netname, args->mapname, YPOP_DELETE,
18940a5f74dSBill Paul 		args->key.yp_buf_len, args->key.yp_buf_val,
19040a5f74dSBill Paul 		0,			NULL);
19140a5f74dSBill Paul 
19240a5f74dSBill Paul 	return (&res);
19340a5f74dSBill Paul }
19440a5f74dSBill Paul 
195dc584ddbSDag-Erling Smørgrav unsigned int *
ypu_store_1_svc(struct ypupdate_args * args,struct svc_req * svcreq)196dc584ddbSDag-Erling Smørgrav ypu_store_1_svc(struct ypupdate_args *args, struct svc_req *svcreq)
19740a5f74dSBill Paul {
19840a5f74dSBill Paul 	struct authdes_cred *des_cred;
19940a5f74dSBill Paul 	static int res;
20040a5f74dSBill Paul 	char *netname;
20140a5f74dSBill Paul 	enum auth_stat astat;
20240a5f74dSBill Paul 
20340a5f74dSBill Paul 	res = 0;
20440a5f74dSBill Paul 
20540a5f74dSBill Paul 	astat = yp_checkauth(svcreq);
20640a5f74dSBill Paul 
20740a5f74dSBill Paul 	if (astat != AUTH_OK) {
20840a5f74dSBill Paul 		svcerr_auth(svcreq->rq_xprt, astat);
20940a5f74dSBill Paul 		return(&res);
21040a5f74dSBill Paul 	}
21140a5f74dSBill Paul 
21240a5f74dSBill Paul 	des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
21340a5f74dSBill Paul 	netname = des_cred->adc_fullname.name;
21440a5f74dSBill Paul 
21540a5f74dSBill Paul 	res = localupdate(netname, "/etc/publickey", YPOP_STORE,
21640a5f74dSBill Paul 		args->key.yp_buf_len, args->key.yp_buf_val,
21740a5f74dSBill Paul 		args->datum.yp_buf_len, args->datum.yp_buf_val);
21840a5f74dSBill Paul 
21940a5f74dSBill Paul 	if (res)
22040a5f74dSBill Paul 		return (&res);
22140a5f74dSBill Paul 
22240a5f74dSBill Paul 	res = ypmap_update(netname, args->mapname, YPOP_STORE,
22340a5f74dSBill Paul 		args->key.yp_buf_len, args->key.yp_buf_val,
22440a5f74dSBill Paul 		args->datum.yp_buf_len, args->datum.yp_buf_val);
22540a5f74dSBill Paul 
22640a5f74dSBill Paul 	return (&res);
22740a5f74dSBill Paul }
228