xref: /netbsd-src/libexec/rpc.rwalld/rwalld.c (revision 2b8aaed8cd498f784adff8b449eee3eb8e00c2a3)
1*2b8aaed8Splunky /* $NetBSD: rwalld.c,v 1.23 2011/09/16 16:13:17 plunky Exp $ */
2176865a0Sthorpej 
3e7153151Sbrezak /*
4e7153151Sbrezak  * Copyright (c) 1993 Christopher G. Demetriou
5e7153151Sbrezak  * All rights reserved.
6e7153151Sbrezak  *
7e7153151Sbrezak  * Redistribution and use in source and binary forms, with or without
8e7153151Sbrezak  * modification, are permitted provided that the following conditions
9e7153151Sbrezak  * are met:
10e7153151Sbrezak  * 1. Redistributions of source code must retain the above copyright
11e7153151Sbrezak  *    notice, this list of conditions and the following disclaimer.
12e7153151Sbrezak  * 2. Redistributions in binary form must reproduce the above copyright
13e7153151Sbrezak  *    notice, this list of conditions and the following disclaimer in the
14e7153151Sbrezak  *    documentation and/or other materials provided with the distribution.
15db755e7cScgd  * 3. All advertising materials mentioning features or use of this software
16db755e7cScgd  *    must display the following acknowledgement:
17db755e7cScgd  *          This product includes software developed for the
1899410184Ssalo  *          NetBSD Project.  See http://www.NetBSD.org/ for
19db755e7cScgd  *          information about NetBSD.
20db755e7cScgd  * 4. The name of the author may not be used to endorse or promote products
21db755e7cScgd  *    derived from this software without specific prior written permission.
22e7153151Sbrezak  *
23db755e7cScgd  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24db755e7cScgd  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25db755e7cScgd  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26db755e7cScgd  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27db755e7cScgd  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28db755e7cScgd  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29db755e7cScgd  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30db755e7cScgd  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31db755e7cScgd  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32db755e7cScgd  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33db755e7cScgd  *
34db755e7cScgd  * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
35e7153151Sbrezak  */
36e7153151Sbrezak 
3773f3225dSchristos #include <sys/cdefs.h>
38e7153151Sbrezak #ifndef lint
39*2b8aaed8Splunky __RCSID("$NetBSD: rwalld.c,v 1.23 2011/09/16 16:13:17 plunky Exp $");
40aee4b07bSmycroft #endif /* not lint */
41e7153151Sbrezak 
42e7153151Sbrezak #include <unistd.h>
4373f3225dSchristos #include <stdlib.h>
44e7153151Sbrezak #include <sys/types.h>
45e7153151Sbrezak #include <pwd.h>
46e7153151Sbrezak #include <stdio.h>
47e7153151Sbrezak #include <string.h>
488ee607a6Smycroft #include <syslog.h>
49e7153151Sbrezak #include <errno.h>
50e7153151Sbrezak #include <sys/socket.h>
51e7153151Sbrezak #include <signal.h>
52e7153151Sbrezak #include <sys/wait.h>
53e7153151Sbrezak #include <rpc/rpc.h>
54e7153151Sbrezak #include <rpcsvc/rwall.h>
55e7153151Sbrezak 
56e7153151Sbrezak #ifdef OSF
57e7153151Sbrezak #define WALL_CMD "/usr/sbin/wall"
58e7153151Sbrezak #else
59e7153151Sbrezak #define WALL_CMD "/usr/bin/wall -n"
60e7153151Sbrezak #endif
61e7153151Sbrezak 
6273f3225dSchristos static int from_inetd = 1;
63e7153151Sbrezak 
646185360fSfvdl static void cleanup(int);
656185360fSfvdl static void wallprog_1(struct svc_req *, SVCXPRT *);
66e7153151Sbrezak 
679eba1e42Sjoerg __dead static void
cleanup(int n)686185360fSfvdl cleanup(int n)
69e3cbb4b4Smycroft {
7036407a95Smrg 
716185360fSfvdl 	(void)rpcb_unset(WALLPROG, WALLVERS, NULL);
72e3cbb4b4Smycroft 	exit(0);
73e3cbb4b4Smycroft }
74e3cbb4b4Smycroft 
7573f3225dSchristos int
main(int argc,char * argv[])766185360fSfvdl main(int argc, char *argv[])
77e7153151Sbrezak {
78e7153151Sbrezak 	SVCXPRT *transp;
79b3032cafSfvdl 	struct sockaddr_storage from;
800c37c63eSmrg 	socklen_t fromlen;
81e7153151Sbrezak 
82e7153151Sbrezak 	if (geteuid() == 0) {
83e7153151Sbrezak 		struct passwd *pep = getpwnam("nobody");
84e7153151Sbrezak 		if (pep)
85e7153151Sbrezak 			setuid(pep->pw_uid);
86e7153151Sbrezak 		else
87e7153151Sbrezak 			setuid(getuid());
88e7153151Sbrezak 	}
89e7153151Sbrezak 
90e7153151Sbrezak 	/*
91e7153151Sbrezak 	 * See if inetd started us
92e7153151Sbrezak 	 */
93002aa598Smycroft 	fromlen = sizeof(from);
946185360fSfvdl 	if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0)
95e7153151Sbrezak 		from_inetd = 0;
96e7153151Sbrezak 
97e7153151Sbrezak 	if (!from_inetd) {
98e3cbb4b4Smycroft 		daemon(0, 0);
99e7153151Sbrezak 
1006185360fSfvdl 		(void) rpcb_unset(WALLPROG, WALLVERS, NULL);
101e3cbb4b4Smycroft 
102e3cbb4b4Smycroft 		(void) signal(SIGINT, cleanup);
103e3cbb4b4Smycroft 		(void) signal(SIGTERM, cleanup);
104e3cbb4b4Smycroft 		(void) signal(SIGHUP, cleanup);
105e7153151Sbrezak 	}
106e7153151Sbrezak 
107f2130fd9Smrg 	openlog("rpc.rwalld", LOG_PID, LOG_DAEMON);
108e7153151Sbrezak 
1096185360fSfvdl 	if (from_inetd) {
1106185360fSfvdl 		transp = svc_dg_create(0, 0, 0);
111e7153151Sbrezak 		if (transp == NULL) {
112e3cbb4b4Smycroft 			syslog(LOG_ERR, "cannot create udp service.");
113e7153151Sbrezak 			exit(1);
114e7153151Sbrezak 		}
1156185360fSfvdl 		if (!svc_reg(transp, WALLPROG, WALLVERS, wallprog_1, NULL)) {
1166185360fSfvdl 			syslog(LOG_ERR, "unable to register "
1176185360fSfvdl 			    "(WALLPROG, WALLVERS).");
118e7153151Sbrezak 			exit(1);
119e7153151Sbrezak 		}
1206185360fSfvdl 	} else {
1216185360fSfvdl 		if (!svc_create(wallprog_1, WALLPROG, WALLVERS, "udp")) {
1226185360fSfvdl 			syslog(LOG_ERR, "unable to create "
1236185360fSfvdl 			    "(WALLPROG, WALLVERS.)");
1246185360fSfvdl 			exit(1);
1256185360fSfvdl 		}
1266185360fSfvdl 	}
127e3cbb4b4Smycroft 
128e7153151Sbrezak 	svc_run();
129e3cbb4b4Smycroft 	syslog(LOG_ERR, "svc_run returned");
130e7153151Sbrezak 	exit(1);
131e7153151Sbrezak 
132e7153151Sbrezak }
133e7153151Sbrezak 
134e3cbb4b4Smycroft void *
wallproc_wall_1_svc(char ** s,struct svc_req * rqstp)1356185360fSfvdl wallproc_wall_1_svc(char **s, struct svc_req *rqstp)
136e7153151Sbrezak {
137e7153151Sbrezak 	FILE *pfp;
138e7153151Sbrezak 
139e7153151Sbrezak 	pfp = popen(WALL_CMD, "w");
140e7153151Sbrezak 	if (pfp != NULL) {
141e7153151Sbrezak 		fprintf(pfp, "\007\007%s", *s);
142e7153151Sbrezak 		pclose(pfp);
143e7153151Sbrezak 	}
144e3cbb4b4Smycroft 
145516fa506Smycroft 	return (*s);
146e7153151Sbrezak }
147e7153151Sbrezak 
14873f3225dSchristos static void
wallprog_1(struct svc_req * rqstp,SVCXPRT * transp)1496185360fSfvdl wallprog_1(struct svc_req *rqstp, SVCXPRT *transp)
150e7153151Sbrezak {
151e7153151Sbrezak 	union {
152e7153151Sbrezak 		char *wallproc_wall_1_arg;
153e7153151Sbrezak 	} argument;
154e7153151Sbrezak 	char *result;
1554a5c9a20Spk 	xdrproc_t xdr_argument, xdr_result;
156fed935ebSpk 	char *(*local) __P((char **, struct svc_req *));
157e7153151Sbrezak 
158e7153151Sbrezak 	switch (rqstp->rq_proc) {
159e7153151Sbrezak 	case NULLPROC:
160*2b8aaed8Splunky 		(void)svc_sendreply(transp, (xdrproc_t)xdr_void, NULL);
161e7153151Sbrezak 		goto leave;
162e7153151Sbrezak 
163e7153151Sbrezak 	case WALLPROC_WALL:
1644a5c9a20Spk 		xdr_argument = (xdrproc_t)xdr_wrapstring;
1654a5c9a20Spk 		xdr_result = (xdrproc_t)xdr_void;
166fed935ebSpk 		local = (char *(*) __P((char **, struct svc_req *)))
167fed935ebSpk 			wallproc_wall_1_svc;
168e7153151Sbrezak 		break;
169e7153151Sbrezak 
170e7153151Sbrezak 	default:
171e7153151Sbrezak 		svcerr_noproc(transp);
172e7153151Sbrezak 		goto leave;
173e7153151Sbrezak 	}
174bfd52621Sperry 	memset((char *)&argument, 0, sizeof(argument));
175b54e7589Scgd 	if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) {
176e7153151Sbrezak 		svcerr_decode(transp);
177e7153151Sbrezak 		goto leave;
178e7153151Sbrezak 	}
179fed935ebSpk 	result = (*local)((char **)&argument, rqstp);
180e7153151Sbrezak 	if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
181e7153151Sbrezak 		svcerr_systemerr(transp);
182e7153151Sbrezak 	}
183b54e7589Scgd 	if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) {
1848ee607a6Smycroft 		syslog(LOG_ERR, "unable to free arguments");
185e7153151Sbrezak 		exit(1);
186e7153151Sbrezak 	}
187e7153151Sbrezak leave:
188e7153151Sbrezak 	if (from_inetd)
189e7153151Sbrezak 		exit(0);
190e7153151Sbrezak }
191