xref: /openbsd/libexec/rpc.rwalld/rwalld.c (revision c72b5b24)
1*c72b5b24Smillert /*	$OpenBSD: rwalld.c,v 1.6 2002/02/16 21:27:31 millert Exp $	*/
25d36dfa4Sniklas 
3df930be7Sderaadt /*
4df930be7Sderaadt  * Copyright (c) 1993 Christopher G. Demetriou
5df930be7Sderaadt  * All rights reserved.
6df930be7Sderaadt  *
7df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
8df930be7Sderaadt  * modification, are permitted provided that the following conditions
9df930be7Sderaadt  * are met:
10df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
11df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
12df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
13df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
14df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
15df930be7Sderaadt  * 3. The name of the author may not be used to endorse or promote
16df930be7Sderaadt  *    products derived from this software without specific prior written
17df930be7Sderaadt  *    permission.
18df930be7Sderaadt  *
19df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20df930be7Sderaadt  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21df930be7Sderaadt  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23df930be7Sderaadt  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29df930be7Sderaadt  * SUCH DAMAGE.
30df930be7Sderaadt  */
31df930be7Sderaadt 
32df930be7Sderaadt #ifndef lint
33*c72b5b24Smillert static char rcsid[] = "$OpenBSD: rwalld.c,v 1.6 2002/02/16 21:27:31 millert Exp $";
34df930be7Sderaadt #endif /* not lint */
35df930be7Sderaadt 
36df930be7Sderaadt #include <sys/types.h>
37a5553e71Sderaadt #include <sys/socket.h>
38a5553e71Sderaadt #include <sys/wait.h>
39df930be7Sderaadt #include <pwd.h>
40a5553e71Sderaadt #include <stdlib.h>
41df930be7Sderaadt #include <stdio.h>
42df930be7Sderaadt #include <string.h>
43df930be7Sderaadt #include <syslog.h>
44df930be7Sderaadt #include <errno.h>
45a5553e71Sderaadt #include <unistd.h>
46df930be7Sderaadt #include <signal.h>
47df930be7Sderaadt #include <rpc/rpc.h>
48df930be7Sderaadt #include <rpcsvc/rwall.h>
49df930be7Sderaadt 
50df930be7Sderaadt #ifdef OSF
51df930be7Sderaadt #define WALL_CMD "/usr/sbin/wall"
52df930be7Sderaadt #else
53df930be7Sderaadt #define WALL_CMD "/usr/bin/wall -n"
54df930be7Sderaadt #endif
55df930be7Sderaadt 
56df930be7Sderaadt void wallprog_1();
57df930be7Sderaadt 
58df930be7Sderaadt int from_inetd = 1;
59df930be7Sderaadt 
60df930be7Sderaadt void
61df930be7Sderaadt cleanup()
62df930be7Sderaadt {
637884a5c6Sderaadt 	(void) pmap_unset(WALLPROG, WALLVERS);		/* XXX signal race */
647884a5c6Sderaadt 	_exit(0);
65df930be7Sderaadt }
66df930be7Sderaadt 
67a5553e71Sderaadt int
68df930be7Sderaadt main(argc, argv)
69df930be7Sderaadt 	int argc;
70df930be7Sderaadt 	char *argv[];
71df930be7Sderaadt {
72df930be7Sderaadt 	SVCXPRT *transp;
73df930be7Sderaadt 	int sock = 0;
74df930be7Sderaadt 	int proto = 0;
75df930be7Sderaadt 	struct sockaddr_in from;
76df930be7Sderaadt 	int fromlen;
77df930be7Sderaadt 
78df930be7Sderaadt 	if (geteuid() == 0) {
79df930be7Sderaadt 		struct passwd *pep = getpwnam("nobody");
80e054f005Stholo 		if (pep) {
81e054f005Stholo 			seteuid(pep->pw_uid);
82df930be7Sderaadt 			setuid(pep->pw_uid);
83e054f005Stholo 		}
84e054f005Stholo 		else {
85e054f005Stholo 			seteuid(getuid());
86df930be7Sderaadt 			setuid(getuid());
87df930be7Sderaadt 		}
88e054f005Stholo 	}
89df930be7Sderaadt 
90df930be7Sderaadt 	/*
91df930be7Sderaadt 	 * See if inetd started us
92df930be7Sderaadt 	 */
93df930be7Sderaadt 	fromlen = sizeof(from);
94df930be7Sderaadt 	if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) {
95df930be7Sderaadt 		from_inetd = 0;
96df930be7Sderaadt 		sock = RPC_ANYSOCK;
97df930be7Sderaadt 		proto = IPPROTO_UDP;
98df930be7Sderaadt 	}
99df930be7Sderaadt 
100df930be7Sderaadt 	if (!from_inetd) {
101df930be7Sderaadt 		daemon(0, 0);
102df930be7Sderaadt 
103df930be7Sderaadt 		(void) pmap_unset(WALLPROG, WALLVERS);
104df930be7Sderaadt 
105df930be7Sderaadt 		(void) signal(SIGINT, cleanup);
106df930be7Sderaadt 		(void) signal(SIGTERM, cleanup);
107df930be7Sderaadt 		(void) signal(SIGHUP, cleanup);
108df930be7Sderaadt 	}
109df930be7Sderaadt 
110df930be7Sderaadt 	openlog("rpc.rwalld", LOG_CONS|LOG_PID, LOG_DAEMON);
111df930be7Sderaadt 
112df930be7Sderaadt 	transp = svcudp_create(sock);
113df930be7Sderaadt 	if (transp == NULL) {
114df930be7Sderaadt 		syslog(LOG_ERR, "cannot create udp service.");
115df930be7Sderaadt 		exit(1);
116df930be7Sderaadt 	}
117df930be7Sderaadt 	if (!svc_register(transp, WALLPROG, WALLVERS, wallprog_1, proto)) {
118df930be7Sderaadt 		syslog(LOG_ERR, "unable to register (WALLPROG, WALLVERS, %s).", proto?"udp":"(inetd)");
119df930be7Sderaadt 		exit(1);
120df930be7Sderaadt 	}
121df930be7Sderaadt 
122df930be7Sderaadt 	svc_run();
123df930be7Sderaadt 	syslog(LOG_ERR, "svc_run returned");
124df930be7Sderaadt 	exit(1);
125df930be7Sderaadt 
126df930be7Sderaadt }
127df930be7Sderaadt 
128df930be7Sderaadt void *
129df930be7Sderaadt wallproc_wall_1_svc(s, rqstp )
130df930be7Sderaadt 	char **s;
131df930be7Sderaadt 	struct svc_req *rqstp;
132df930be7Sderaadt {
133df930be7Sderaadt 	FILE *pfp;
134df930be7Sderaadt 
135df930be7Sderaadt 	pfp = popen(WALL_CMD, "w");
136df930be7Sderaadt 	if (pfp != NULL) {
137df930be7Sderaadt 		fprintf(pfp, "\007\007%s", *s);
138df930be7Sderaadt 		pclose(pfp);
139df930be7Sderaadt 	}
140df930be7Sderaadt 
141df930be7Sderaadt 	return (*s);
142df930be7Sderaadt }
143df930be7Sderaadt 
144df930be7Sderaadt void
145df930be7Sderaadt wallprog_1(rqstp, transp)
146df930be7Sderaadt 	struct svc_req *rqstp;
147df930be7Sderaadt 	SVCXPRT *transp;
148df930be7Sderaadt {
149df930be7Sderaadt 	union {
150df930be7Sderaadt 		char *wallproc_wall_1_arg;
151df930be7Sderaadt 	} argument;
152df930be7Sderaadt 	char *result;
153df930be7Sderaadt 	xdrproc_t xdr_argument, xdr_result;
154*c72b5b24Smillert 	char *(*local)(char **, struct svc_req *);
155df930be7Sderaadt 
156df930be7Sderaadt 	switch (rqstp->rq_proc) {
157df930be7Sderaadt 	case NULLPROC:
158df930be7Sderaadt 		(void)svc_sendreply(transp, xdr_void, (char *)NULL);
159df930be7Sderaadt 		goto leave;
160df930be7Sderaadt 
161df930be7Sderaadt 	case WALLPROC_WALL:
162df930be7Sderaadt 		xdr_argument = (xdrproc_t)xdr_wrapstring;
163df930be7Sderaadt 		xdr_result = (xdrproc_t)xdr_void;
164*c72b5b24Smillert 		local = (char *(*)(char **, struct svc_req *))
165df930be7Sderaadt 			wallproc_wall_1_svc;
166df930be7Sderaadt 		break;
167df930be7Sderaadt 
168df930be7Sderaadt 	default:
169df930be7Sderaadt 		svcerr_noproc(transp);
170df930be7Sderaadt 		goto leave;
171df930be7Sderaadt 	}
172df930be7Sderaadt 	bzero((char *)&argument, sizeof(argument));
173df930be7Sderaadt 	if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) {
174df930be7Sderaadt 		svcerr_decode(transp);
175df930be7Sderaadt 		goto leave;
176df930be7Sderaadt 	}
177df930be7Sderaadt 	result = (*local)((char **)&argument, rqstp);
178df930be7Sderaadt 	if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
179df930be7Sderaadt 		svcerr_systemerr(transp);
180df930be7Sderaadt 	}
181df930be7Sderaadt 	if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) {
182df930be7Sderaadt 		syslog(LOG_ERR, "unable to free arguments");
183df930be7Sderaadt 		exit(1);
184df930be7Sderaadt 	}
185df930be7Sderaadt leave:
186df930be7Sderaadt 	if (from_inetd)
187df930be7Sderaadt 		exit(0);
188df930be7Sderaadt }
189