yp_access.c revision 12891
1/* 2 * Copyright (c) 1995 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 */ 33 34#include <rpc/rpc.h> 35#include <sys/types.h> 36#include <sys/socket.h> 37#include <netinet/in.h> 38#include <arpa/inet.h> 39#include <sys/stat.h> 40#include <paths.h> 41#include <sys/param.h> 42#include "yp_extern.h" 43#ifdef TCP_WRAPPER 44#include "tcpd.h" 45#endif 46 47extern int debug; 48 49char *yp_procs[] = { "ypproc_null" , 50 "ypproc_domain", 51 "ypproc_domain_nonack", 52 "ypproc_match", 53 "ypproc_first", 54 "ypproc_next", 55 "ypproc_xfr", 56 "ypproc_clear", 57 "ypproc_all", 58 "ypproc_master", 59 "ypproc_order", 60 "ypproc_maplist" 61 }; 62 63/* 64 * Access control functions. 65 * 66 * yp_access() checks the mapname and client host address and watches for 67 * the following things: 68 * 69 * - If the client is referencing one of the master.passwd.* maps, it must 70 * be using a privileged port to make its RPC to us. If it is, then we can 71 * assume that the caller is root and allow the RPC to succeed. If it 72 * isn't access is denied. 73 * 74 * - If we are compiled with the tcpwrapper package, we also check to see 75 * if the host makes it past the libwrap checks and deny access if it 76 * doesn't. Host address checks are disabled if not compiled with the 77 * tcp_wrapper package. 78 * 79 * The yp_validdomain() functions checks the domain specified by the caller 80 * to make sure it's actually served by this server. This is more a sanity 81 * check than an a security check, but this seems to be the best place for 82 * it. 83 */ 84 85int yp_access(map, rqstp) 86 const char *map; 87 const struct svc_req *rqstp; 88{ 89 struct sockaddr_in *rqhost; 90#ifdef TCP_WRAPPER 91 int status = 0; 92 unsigned long oldaddr; 93#endif 94 95 rqhost = svc_getcaller(rqstp->rq_xprt); 96 97 if (debug) { 98 yp_error("Procedure %s called from %s:%d", 99 yp_procs[rqstp->rq_proc], inet_ntoa(rqhost->sin_addr), 100 ntohs(rqhost->sin_port)); 101 if (map != NULL) 102 yp_error("Client is referencing map \"%s\".", map); 103 } 104 105 /* Check the map name if one was supplied. */ 106 if (map != NULL) { 107 if (strstr(map, "master.passwd.") && ntohs(rqhost->sin_port) > 1023) { 108 yp_error("Access to %s denied -- client not privileged", map); 109 return(1); 110 } 111 } 112 113#ifdef TCP_WRAPPER 114 /* Check client address if TCP_WRAPPER is enalbled. */ 115 status = hosts_ctl(progname, STRING_UNKNOWN, 116 inet_ntoa(rqhost->sin_addr, ""); 117 118 if (!status && rqhost->sin_addr.s_addr != oldaddr) { 119 yp_error("connect from %s:%d refused", 120 inet_ntoa(rqhost->sin_addr, ntohs(rqhost->sin_port)); 121 oldaddr = rqhost->sin_addr.s_addr; 122 return(1); 123 } 124#endif 125 return(0); 126 127} 128 129int yp_validdomain(domain) 130 const char *domain; 131{ 132 struct stat statbuf; 133 char dompath[MAXPATHLEN + 2]; 134 135 if (domain == NULL || strstr(domain, "binding") || 136 !strcmp(domain, ".") || !strcmp(domain, "..") || 137 strchr(domain, '/')) 138 return(1); 139 140 snprintf(dompath, sizeof(dompath), "%s/%s", yp_dir, domain); 141 142 if (stat(dompath, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode)) 143 return(1); 144 145 return(0); 146} 147