yp_access.c revision 12891
112891Swpaul/* 212891Swpaul * Copyright (c) 1995 312891Swpaul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 412891Swpaul * 512891Swpaul * Redistribution and use in source and binary forms, with or without 612891Swpaul * modification, are permitted provided that the following conditions 712891Swpaul * are met: 812891Swpaul * 1. Redistributions of source code must retain the above copyright 912891Swpaul * notice, this list of conditions and the following disclaimer. 1012891Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1112891Swpaul * notice, this list of conditions and the following disclaimer in the 1212891Swpaul * documentation and/or other materials provided with the distribution. 1312891Swpaul * 3. All advertising materials mentioning features or use of this software 1412891Swpaul * must display the following acknowledgement: 1512891Swpaul * This product includes software developed by Bill Paul. 1612891Swpaul * 4. Neither the name of the author nor the names of any co-contributors 1712891Swpaul * may be used to endorse or promote products derived from this software 1812891Swpaul * without specific prior written permission. 1912891Swpaul * 2012891Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 2112891Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2212891Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2312891Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE 2412891Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2512891Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2612891Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2712891Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2812891Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2912891Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3012891Swpaul * SUCH DAMAGE. 3112891Swpaul * 3212891Swpaul */ 3312891Swpaul 3412891Swpaul#include <rpc/rpc.h> 3512891Swpaul#include <sys/types.h> 3612891Swpaul#include <sys/socket.h> 3712891Swpaul#include <netinet/in.h> 3812891Swpaul#include <arpa/inet.h> 3912891Swpaul#include <sys/stat.h> 4012891Swpaul#include <paths.h> 4112891Swpaul#include <sys/param.h> 4212891Swpaul#include "yp_extern.h" 4312891Swpaul#ifdef TCP_WRAPPER 4412891Swpaul#include "tcpd.h" 4512891Swpaul#endif 4612891Swpaul 4712891Swpaulextern int debug; 4812891Swpaul 4912891Swpaulchar *yp_procs[] = { "ypproc_null" , 5012891Swpaul "ypproc_domain", 5112891Swpaul "ypproc_domain_nonack", 5212891Swpaul "ypproc_match", 5312891Swpaul "ypproc_first", 5412891Swpaul "ypproc_next", 5512891Swpaul "ypproc_xfr", 5612891Swpaul "ypproc_clear", 5712891Swpaul "ypproc_all", 5812891Swpaul "ypproc_master", 5912891Swpaul "ypproc_order", 6012891Swpaul "ypproc_maplist" 6112891Swpaul }; 6212891Swpaul 6312891Swpaul/* 6412891Swpaul * Access control functions. 6512891Swpaul * 6612891Swpaul * yp_access() checks the mapname and client host address and watches for 6712891Swpaul * the following things: 6812891Swpaul * 6912891Swpaul * - If the client is referencing one of the master.passwd.* maps, it must 7012891Swpaul * be using a privileged port to make its RPC to us. If it is, then we can 7112891Swpaul * assume that the caller is root and allow the RPC to succeed. If it 7212891Swpaul * isn't access is denied. 7312891Swpaul * 7412891Swpaul * - If we are compiled with the tcpwrapper package, we also check to see 7512891Swpaul * if the host makes it past the libwrap checks and deny access if it 7612891Swpaul * doesn't. Host address checks are disabled if not compiled with the 7712891Swpaul * tcp_wrapper package. 7812891Swpaul * 7912891Swpaul * The yp_validdomain() functions checks the domain specified by the caller 8012891Swpaul * to make sure it's actually served by this server. This is more a sanity 8112891Swpaul * check than an a security check, but this seems to be the best place for 8212891Swpaul * it. 8312891Swpaul */ 8412891Swpaul 8512891Swpaulint yp_access(map, rqstp) 8612891Swpaul const char *map; 8712891Swpaul const struct svc_req *rqstp; 8812891Swpaul{ 8912891Swpaul struct sockaddr_in *rqhost; 9012891Swpaul#ifdef TCP_WRAPPER 9112891Swpaul int status = 0; 9212891Swpaul unsigned long oldaddr; 9312891Swpaul#endif 9412891Swpaul 9512891Swpaul rqhost = svc_getcaller(rqstp->rq_xprt); 9612891Swpaul 9712891Swpaul if (debug) { 9812891Swpaul yp_error("Procedure %s called from %s:%d", 9912891Swpaul yp_procs[rqstp->rq_proc], inet_ntoa(rqhost->sin_addr), 10012891Swpaul ntohs(rqhost->sin_port)); 10112891Swpaul if (map != NULL) 10212891Swpaul yp_error("Client is referencing map \"%s\".", map); 10312891Swpaul } 10412891Swpaul 10512891Swpaul /* Check the map name if one was supplied. */ 10612891Swpaul if (map != NULL) { 10712891Swpaul if (strstr(map, "master.passwd.") && ntohs(rqhost->sin_port) > 1023) { 10812891Swpaul yp_error("Access to %s denied -- client not privileged", map); 10912891Swpaul return(1); 11012891Swpaul } 11112891Swpaul } 11212891Swpaul 11312891Swpaul#ifdef TCP_WRAPPER 11412891Swpaul /* Check client address if TCP_WRAPPER is enalbled. */ 11512891Swpaul status = hosts_ctl(progname, STRING_UNKNOWN, 11612891Swpaul inet_ntoa(rqhost->sin_addr, ""); 11712891Swpaul 11812891Swpaul if (!status && rqhost->sin_addr.s_addr != oldaddr) { 11912891Swpaul yp_error("connect from %s:%d refused", 12012891Swpaul inet_ntoa(rqhost->sin_addr, ntohs(rqhost->sin_port)); 12112891Swpaul oldaddr = rqhost->sin_addr.s_addr; 12212891Swpaul return(1); 12312891Swpaul } 12412891Swpaul#endif 12512891Swpaul return(0); 12612891Swpaul 12712891Swpaul} 12812891Swpaul 12912891Swpaulint yp_validdomain(domain) 13012891Swpaul const char *domain; 13112891Swpaul{ 13212891Swpaul struct stat statbuf; 13312891Swpaul char dompath[MAXPATHLEN + 2]; 13412891Swpaul 13512891Swpaul if (domain == NULL || strstr(domain, "binding") || 13612891Swpaul !strcmp(domain, ".") || !strcmp(domain, "..") || 13712891Swpaul strchr(domain, '/')) 13812891Swpaul return(1); 13912891Swpaul 14012891Swpaul snprintf(dompath, sizeof(dompath), "%s/%s", yp_dir, domain); 14112891Swpaul 14212891Swpaul if (stat(dompath, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode)) 14312891Swpaul return(1); 14412891Swpaul 14512891Swpaul return(0); 14612891Swpaul} 147