18256fad9SBill Paul /* 28256fad9SBill Paul * Copyright (c) 1995, 1996 38256fad9SBill Paul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 48256fad9SBill Paul * 58256fad9SBill Paul * Redistribution and use in source and binary forms, with or without 68256fad9SBill Paul * modification, are permitted provided that the following conditions 78256fad9SBill Paul * are met: 88256fad9SBill Paul * 1. Redistributions of source code must retain the above copyright 98256fad9SBill Paul * notice, this list of conditions and the following disclaimer. 108256fad9SBill Paul * 2. Redistributions in binary form must reproduce the above copyright 118256fad9SBill Paul * notice, this list of conditions and the following disclaimer in the 128256fad9SBill Paul * documentation and/or other materials provided with the distribution. 138256fad9SBill Paul * 3. All advertising materials mentioning features or use of this software 148256fad9SBill Paul * must display the following acknowledgement: 158256fad9SBill Paul * This product includes software developed by Bill Paul. 168256fad9SBill Paul * 4. Neither the name of the author nor the names of any co-contributors 178256fad9SBill Paul * may be used to endorse or promote products derived from this software 188256fad9SBill Paul * without specific prior written permission. 198256fad9SBill Paul * 208256fad9SBill Paul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 218256fad9SBill Paul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 228256fad9SBill Paul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 238256fad9SBill Paul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE 248256fad9SBill Paul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 258256fad9SBill Paul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 268256fad9SBill Paul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 278256fad9SBill Paul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 288256fad9SBill Paul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 298256fad9SBill Paul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 308256fad9SBill Paul * SUCH DAMAGE. 318256fad9SBill Paul * 32df4ddde7SBill Paul * $Id: yppasswdd_main.c,v 1.4 1996/06/23 22:44:04 wpaul Exp $ 338256fad9SBill Paul */ 348256fad9SBill Paul 358256fad9SBill Paul #include "yppasswd.h" 368256fad9SBill Paul #include <stdio.h> 378256fad9SBill Paul #include <sys/types.h> 388256fad9SBill Paul #include <stdlib.h> /* getenv, exit */ 398256fad9SBill Paul #include <unistd.h> 408256fad9SBill Paul #include <string.h> 418256fad9SBill Paul #include <sys/param.h> 428256fad9SBill Paul #include <rpc/pmap_clnt.h> /* for pmap_unset */ 438256fad9SBill Paul #include <string.h> /* strcmp */ 448256fad9SBill Paul #include <signal.h> 458256fad9SBill Paul #include <fcntl.h> 468256fad9SBill Paul #include <sys/ioctl.h> 478256fad9SBill Paul #include <sys/stat.h> 488256fad9SBill Paul #include <sys/ttycom.h> /* TIOCNOTTY */ 498256fad9SBill Paul #ifdef __cplusplus 508256fad9SBill Paul #include <sysent.h> /* getdtablesize, open */ 518256fad9SBill Paul #endif /* __cplusplus */ 528256fad9SBill Paul #include <memory.h> 538256fad9SBill Paul #include <sys/socket.h> 548256fad9SBill Paul #include <netinet/in.h> 558256fad9SBill Paul #include <syslog.h> 568256fad9SBill Paul #include <err.h> 578256fad9SBill Paul #include <errno.h> 588256fad9SBill Paul #include <rpcsvc/yp.h> 598256fad9SBill Paul struct dom_binding {}; 608256fad9SBill Paul #include <rpcsvc/ypclnt.h> 618256fad9SBill Paul #include "yppasswdd_extern.h" 628256fad9SBill Paul #include "yppasswd_comm.h" 638256fad9SBill Paul #include "ypxfr_extern.h" 648256fad9SBill Paul 658256fad9SBill Paul #ifndef SIG_PF 668256fad9SBill Paul #define SIG_PF void(*)(int) 678256fad9SBill Paul #endif 688256fad9SBill Paul 698256fad9SBill Paul #ifdef DEBUG 708256fad9SBill Paul #define RPC_SVC_FG 718256fad9SBill Paul #endif 728256fad9SBill Paul 738256fad9SBill Paul #define _RPCSVC_CLOSEDOWN 120 748256fad9SBill Paul #ifndef lint 75df4ddde7SBill Paul static const char rcsid[] = "$Id: yppasswdd_main.c,v 1.4 1996/06/23 22:44:04 wpaul Exp $"; 768256fad9SBill Paul #endif /* not lint */ 778256fad9SBill Paul int _rpcpmstart = 0; /* Started by a port monitor ? */ 788256fad9SBill Paul static int _rpcfdtype; 798256fad9SBill Paul /* Whether Stream or Datagram ? */ 808256fad9SBill Paul /* States a server can be in wrt request */ 818256fad9SBill Paul 828256fad9SBill Paul #define _IDLE 0 838256fad9SBill Paul #define _SERVED 1 848256fad9SBill Paul #define _SERVING 2 858256fad9SBill Paul 868256fad9SBill Paul extern int _rpcsvcstate; /* Set when a request is serviced */ 878256fad9SBill Paul char *progname = "rpc.yppasswdd"; 88ba21c862SBill Paul char *yp_dir = _PATH_YP; 89ba21c862SBill Paul char *passfile_default = _PATH_YP "master.passwd"; 908256fad9SBill Paul char *passfile; 918256fad9SBill Paul char *yppasswd_domain = NULL; 928256fad9SBill Paul int no_chsh = 0; 938256fad9SBill Paul int no_chfn = 0; 948256fad9SBill Paul int allow_additions = 0; 958256fad9SBill Paul int multidomain = 0; 968256fad9SBill Paul int verbose = 0; 97589b8bfcSBill Paul int resvport = 1; 988b6a78c2SBill Paul int inplace = 0; 998256fad9SBill Paul int yp_sock; 1008256fad9SBill Paul 1018256fad9SBill Paul 1028256fad9SBill Paul static void 1038256fad9SBill Paul my_svc_run() 1048256fad9SBill Paul { 1058256fad9SBill Paul #ifdef FD_SETSIZE 1068256fad9SBill Paul fd_set readfds; 1078256fad9SBill Paul #else 1088256fad9SBill Paul int readfds; 1098256fad9SBill Paul #endif /* def FD_SETSIZE */ 1108256fad9SBill Paul extern int errno; 1118256fad9SBill Paul 1128256fad9SBill Paul for (;;) { 1138256fad9SBill Paul 1148256fad9SBill Paul 1158256fad9SBill Paul #ifdef FD_SETSIZE 1168256fad9SBill Paul readfds = svc_fdset; 1178256fad9SBill Paul #else 1188256fad9SBill Paul readfds = svc_fds; 1198256fad9SBill Paul #endif /* def FD_SETSIZE */ 1208256fad9SBill Paul FD_SET(yp_sock, &readfds); 1218256fad9SBill Paul 1228256fad9SBill Paul switch (select(_rpc_dtablesize(), &readfds, (fd_set *)0, (fd_set *)0, 1238256fad9SBill Paul (struct timeval *)0)) { 1248256fad9SBill Paul case -1: 1258256fad9SBill Paul if (errno == EINTR) { 1268256fad9SBill Paul continue; 1278256fad9SBill Paul } 1288256fad9SBill Paul perror("svc_run: - select failed"); 1298256fad9SBill Paul return; 1308256fad9SBill Paul case 0: 1318256fad9SBill Paul continue; 1328256fad9SBill Paul default: 1338256fad9SBill Paul if (FD_ISSET(yp_sock, &readfds)) { 1348256fad9SBill Paul do_master(); 1358256fad9SBill Paul FD_CLR(yp_sock, &readfds); 1368256fad9SBill Paul } 1378256fad9SBill Paul svc_getreqset(&readfds); 1388256fad9SBill Paul } 1398256fad9SBill Paul } 1408256fad9SBill Paul } 1418256fad9SBill Paul 1428256fad9SBill Paul static void terminate(sig) 1438256fad9SBill Paul int sig; 1448256fad9SBill Paul { 1458256fad9SBill Paul svc_unregister(YPPASSWDPROG, YPPASSWDVERS); 1468256fad9SBill Paul close(yp_sock); 1478256fad9SBill Paul unlink(sockname); 1488256fad9SBill Paul exit(0); 1498256fad9SBill Paul } 1508256fad9SBill Paul 151589b8bfcSBill Paul static void reload(sig) 152589b8bfcSBill Paul int sig; 153589b8bfcSBill Paul { 154589b8bfcSBill Paul load_securenets(); 155589b8bfcSBill Paul } 156589b8bfcSBill Paul 1578256fad9SBill Paul static void 1588256fad9SBill Paul closedown(int sig) 1598256fad9SBill Paul { 1608256fad9SBill Paul if (_rpcsvcstate == _IDLE) { 1618256fad9SBill Paul extern fd_set svc_fdset; 1628256fad9SBill Paul static int size; 1638256fad9SBill Paul int i, openfd; 1648256fad9SBill Paul 1658256fad9SBill Paul if (_rpcfdtype == SOCK_DGRAM) { 1668256fad9SBill Paul close(yp_sock); 1678256fad9SBill Paul unlink(sockname); 1688256fad9SBill Paul exit(0); 1698256fad9SBill Paul } 1708256fad9SBill Paul if (size == 0) { 1718256fad9SBill Paul size = getdtablesize(); 1728256fad9SBill Paul } 1738256fad9SBill Paul for (i = 0, openfd = 0; i < size && openfd < 2; i++) 1748256fad9SBill Paul if (FD_ISSET(i, &svc_fdset)) 1758256fad9SBill Paul openfd++; 1768256fad9SBill Paul if (openfd <= 1) { 1778256fad9SBill Paul close(yp_sock); 1788256fad9SBill Paul unlink(sockname); 1798256fad9SBill Paul exit(0); 1808256fad9SBill Paul } 1818256fad9SBill Paul } 1828256fad9SBill Paul if (_rpcsvcstate == _SERVED) 1838256fad9SBill Paul _rpcsvcstate = _IDLE; 1848256fad9SBill Paul 1858256fad9SBill Paul (void) signal(SIGALRM, (SIG_PF) closedown); 1868256fad9SBill Paul (void) alarm(_RPCSVC_CLOSEDOWN/2); 1878256fad9SBill Paul } 1888256fad9SBill Paul 1898256fad9SBill Paul static void usage() 1908256fad9SBill Paul { 1918256fad9SBill Paul fprintf(stderr, "Usage: %s [-t master.passwd file] [-d domain] \ 1928b6a78c2SBill Paul [-p path] [-s] [-f] [-m] [-i] [-a] [-v] [-u] [-h]\n", 1938256fad9SBill Paul progname); 1948256fad9SBill Paul exit(1); 1958256fad9SBill Paul } 1968256fad9SBill Paul 1978256fad9SBill Paul main(argc, argv) 1988256fad9SBill Paul int argc; 1998256fad9SBill Paul char *argv[]; 2008256fad9SBill Paul { 2018256fad9SBill Paul register SVCXPRT *transp = NULL; 2028256fad9SBill Paul int sock; 2038256fad9SBill Paul int proto = 0; 2048256fad9SBill Paul struct sockaddr_in saddr; 2058256fad9SBill Paul int asize = sizeof (saddr); 2068256fad9SBill Paul int ch; 2078256fad9SBill Paul int rval; 2088256fad9SBill Paul char *mastername; 2098256fad9SBill Paul char myname[MAXHOSTNAMELEN + 2]; 2108256fad9SBill Paul extern int errno; 2118256fad9SBill Paul extern int debug; 2128256fad9SBill Paul 2138256fad9SBill Paul debug = 1; 2148256fad9SBill Paul 215df4ddde7SBill Paul while ((ch = getopt(argc, argv, "t:d:p:sfamuivh")) != EOF) { 2168256fad9SBill Paul switch(ch) { 2178256fad9SBill Paul case 't': 2188256fad9SBill Paul passfile_default = optarg; 2198256fad9SBill Paul break; 2208256fad9SBill Paul case 'd': 2218256fad9SBill Paul yppasswd_domain = optarg; 2228256fad9SBill Paul break; 2238256fad9SBill Paul case 's': 2248256fad9SBill Paul no_chsh++; 2258256fad9SBill Paul break; 2268256fad9SBill Paul case 'f': 2278256fad9SBill Paul no_chfn++; 2288256fad9SBill Paul break; 2298256fad9SBill Paul case 'p': 2308256fad9SBill Paul yp_dir = optarg; 2318256fad9SBill Paul break; 2328256fad9SBill Paul case 'a': 2338256fad9SBill Paul allow_additions++; 2348256fad9SBill Paul break; 2358256fad9SBill Paul case 'm': 2368256fad9SBill Paul multidomain++; 2378256fad9SBill Paul break; 2388b6a78c2SBill Paul case 'i': 2398b6a78c2SBill Paul inplace++; 2408b6a78c2SBill Paul break; 2418256fad9SBill Paul case 'v': 2428256fad9SBill Paul verbose++; 2438256fad9SBill Paul break; 244589b8bfcSBill Paul case 'u': 245589b8bfcSBill Paul resvport = 0; 246589b8bfcSBill Paul break; 2478256fad9SBill Paul default: 2488256fad9SBill Paul case 'h': 2498256fad9SBill Paul usage(); 2508256fad9SBill Paul break; 2518256fad9SBill Paul } 2528256fad9SBill Paul } 2538256fad9SBill Paul 2548256fad9SBill Paul if (yppasswd_domain == NULL) { 2558256fad9SBill Paul if (yp_get_default_domain(&yppasswd_domain)) { 2568256fad9SBill Paul yp_error("no domain specified and system domain \ 2578256fad9SBill Paul name isn't set -- aborting"); 2588256fad9SBill Paul usage(); 2598256fad9SBill Paul } 2608256fad9SBill Paul } 2618256fad9SBill Paul 262589b8bfcSBill Paul load_securenets(); 263589b8bfcSBill Paul 2648256fad9SBill Paul if (getrpcport("localhost", YPPROG, YPVERS, IPPROTO_UDP) <= 0) { 2658256fad9SBill Paul yp_error("this host is not an NIS server -- aborting"); 2668256fad9SBill Paul exit(1); 2678256fad9SBill Paul } 2688256fad9SBill Paul 2698256fad9SBill Paul if ((mastername = ypxfr_get_master(yppasswd_domain, "passwd.byname", 2708256fad9SBill Paul "localhost",0)) == NULL) { 2718256fad9SBill Paul yp_error("can't get name of NIS master server"); 2728256fad9SBill Paul exit(1); 2738256fad9SBill Paul } 2748256fad9SBill Paul 2758256fad9SBill Paul if (gethostname((char *)&myname, sizeof(myname)) == -1) { 2768256fad9SBill Paul yp_error("can't get local hostname: %s", strerror(errno)); 2778256fad9SBill Paul exit(1); 2788256fad9SBill Paul } 2798256fad9SBill Paul 2808256fad9SBill Paul if (strncmp(mastername, (char *)&myname, sizeof(myname))) { 2818256fad9SBill Paul yp_error("this host is not an NIS master server -- aborting"); 2828256fad9SBill Paul exit(1); 2838256fad9SBill Paul } 2848256fad9SBill Paul 285589b8bfcSBill Paul debug = 0; 286589b8bfcSBill Paul 2878256fad9SBill Paul if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) { 2888256fad9SBill Paul int ssize = sizeof (int); 2898256fad9SBill Paul 2908256fad9SBill Paul if (saddr.sin_family != AF_INET) 2918256fad9SBill Paul exit(1); 2928256fad9SBill Paul if (getsockopt(0, SOL_SOCKET, SO_TYPE, 2938256fad9SBill Paul (char *)&_rpcfdtype, &ssize) == -1) 2948256fad9SBill Paul exit(1); 2958256fad9SBill Paul sock = 0; 2968256fad9SBill Paul _rpcpmstart = 1; 2978256fad9SBill Paul proto = 0; 2988256fad9SBill Paul openlog(progname, LOG_PID, LOG_DAEMON); 2998256fad9SBill Paul } else { 300df4ddde7SBill Paul if (!debug) { 301df4ddde7SBill Paul if (daemon(0,0)) { 302df4ddde7SBill Paul err(1,"cannot fork"); 3038256fad9SBill Paul } 3048256fad9SBill Paul } 3058256fad9SBill Paul openlog(progname, LOG_PID, LOG_DAEMON); 3068256fad9SBill Paul sock = RPC_ANYSOCK; 3078256fad9SBill Paul (void) pmap_unset(YPPASSWDPROG, YPPASSWDVERS); 3088256fad9SBill Paul } 3098256fad9SBill Paul 3108256fad9SBill Paul if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) { 3118256fad9SBill Paul transp = svcudp_create(sock); 3128256fad9SBill Paul if (transp == NULL) { 3138256fad9SBill Paul yp_error("cannot create udp service."); 3148256fad9SBill Paul exit(1); 3158256fad9SBill Paul } 3168256fad9SBill Paul if (!_rpcpmstart) 3178256fad9SBill Paul proto = IPPROTO_UDP; 3188256fad9SBill Paul if (!svc_register(transp, YPPASSWDPROG, YPPASSWDVERS, yppasswdprog_1, proto)) { 3198256fad9SBill Paul yp_error("unable to register (YPPASSWDPROG, YPPASSWDVERS, udp)."); 3208256fad9SBill Paul exit(1); 3218256fad9SBill Paul } 3228256fad9SBill Paul } 3238256fad9SBill Paul 3248256fad9SBill Paul if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) { 3258256fad9SBill Paul transp = svctcp_create(sock, 0, 0); 3268256fad9SBill Paul if (transp == NULL) { 3278256fad9SBill Paul yp_error("cannot create tcp service."); 3288256fad9SBill Paul exit(1); 3298256fad9SBill Paul } 3308256fad9SBill Paul if (!_rpcpmstart) 3318256fad9SBill Paul proto = IPPROTO_TCP; 3328256fad9SBill Paul if (!svc_register(transp, YPPASSWDPROG, YPPASSWDVERS, yppasswdprog_1, proto)) { 3338256fad9SBill Paul yp_error("unable to register (YPPASSWDPROG, YPPASSWDVERS, tcp)."); 3348256fad9SBill Paul exit(1); 3358256fad9SBill Paul } 3368256fad9SBill Paul } 3378256fad9SBill Paul 3388256fad9SBill Paul if (transp == (SVCXPRT *)NULL) { 3398256fad9SBill Paul yp_error("could not create a handle"); 3408256fad9SBill Paul exit(1); 3418256fad9SBill Paul } 3428256fad9SBill Paul if (_rpcpmstart) { 3438256fad9SBill Paul (void) signal(SIGALRM, (SIG_PF) closedown); 3448256fad9SBill Paul (void) alarm(_RPCSVC_CLOSEDOWN/2); 3458256fad9SBill Paul } 346589b8bfcSBill Paul /* set up resource limits and block signals */ 3478256fad9SBill Paul pw_init(); 3488256fad9SBill Paul 3498256fad9SBill Paul /* except SIGCHLD, which we need to catch */ 3508256fad9SBill Paul install_reaper(1); 3518256fad9SBill Paul signal(SIGTERM, (SIG_PF) terminate); 3528256fad9SBill Paul 353589b8bfcSBill Paul signal(SIGHUP, (SIG_PF) reload); 354589b8bfcSBill Paul 3558256fad9SBill Paul unlink(sockname); 3568256fad9SBill Paul yp_sock = makeservsock(); 3578256fad9SBill Paul if (chmod(sockname, 0)) 3588256fad9SBill Paul err(1, "chmod of %s failed", sockname); 3598256fad9SBill Paul 3608256fad9SBill Paul my_svc_run(); 3618256fad9SBill Paul yp_error("svc_run returned"); 3628256fad9SBill Paul exit(1); 3638256fad9SBill Paul /* NOTREACHED */ 3648256fad9SBill Paul } 365