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