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