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