yp_access.c (13375) | yp_access.c (14240) |
---|---|
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 --- 18 unchanged lines hidden (view full) --- 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> | 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 --- 18 unchanged lines hidden (view full) --- 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 <rpcsvc/yp.h> 36#include <rpcsvc/yppasswd.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> | 37#include <sys/types.h> 38#include <sys/socket.h> 39#include <netinet/in.h> 40#include <arpa/inet.h> 41#include <sys/stat.h> 42#include <paths.h> |
43#include <errno.h> |
|
41#include <sys/param.h> 42#include "yp_extern.h" 43#ifdef TCP_WRAPPER 44#include "tcpd.h" 45#endif 46 | 44#include <sys/param.h> 45#include "yp_extern.h" 46#ifdef TCP_WRAPPER 47#include "tcpd.h" 48#endif 49 |
50#ifndef lint 51static const char rcsid[] = "$Id$"; 52#endif 53 |
|
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 | 54extern int debug; 55 56char *yp_procs[] = { "ypproc_null" , 57 "ypproc_domain", 58 "ypproc_domain_nonack", 59 "ypproc_match", 60 "ypproc_first", 61 "ypproc_next", 62 "ypproc_xfr", 63 "ypproc_clear", 64 "ypproc_all", 65 "ypproc_master", 66 "ypproc_order", 67 "ypproc_maplist" 68 }; 69 |
70#ifdef TCP_WRAPPER 71void load_securenets() 72{ 73} 74#else 75struct securenet { 76 struct in_addr net; 77 struct in_addr mask; 78 struct securenet *next; 79}; 80 81struct securenet *securenets; 82 83#define LINEBUFSZ 1024 84 |
|
63/* | 85/* |
86 * Read /var/yp/securenets file and initialize the securenets 87 * list. If the file doesn't exist, we set up a dummy entry that 88 * allows all hosts to connect. 89 */ 90void load_securenets() 91{ 92 FILE *fp; 93 char path[MAXPATHLEN + 2]; 94 char linebuf[1024 + 2]; 95 struct securenet *tmp; 96 97 /* 98 * If securenets is not NULL, we are being called to reload 99 * the list; free the existing list before re-reading the 100 * securenets file. 101 */ 102 if (securenets != NULL) { 103 while(securenets) { 104 tmp = securenets->next; 105 free(securenets->net); 106 free(securenets->mask); 107 free(securenets); 108 securenets = tmp; 109 } 110 } 111 112 snprintf(path, MAXPATHLEN, "%s/securenets", yp_dir); 113 114 if ((fp = fopen(path, "r")) == NULL) { 115 if (errno == ENOENT) { 116 securenets = (struct securenet *)malloc(sizeof(struct securenet)); 117 securenets->net.s_addr = INADDR_ANY; 118 securenets->mask.s_addr = INADDR_BROADCAST; 119 securenets->next = NULL; 120 return; 121 } else { 122 yp_error("fopen(%s) failed: %s", path, strerror(errno)); 123 exit(1); 124 } 125 } 126 127 securenets = NULL; 128 129 while(fgets(linebuf, LINEBUFSZ, fp)) { 130 char addr1[20], addr2[20]; 131 132 if (linebuf[0] == '#') 133 continue; 134 if (sscanf(linebuf, "%s %s", addr1, addr2) < 2) { 135 yp_error("badly formatted securenets entry: %s", 136 linebuf); 137 continue; 138 } 139 140 tmp = (struct securenet *)malloc(sizeof(struct securenet)); 141 142 if (!inet_aton((char *)&addr1, (struct in_addr *)&tmp->net)) { 143 yp_error("badly formatted securenets entry: %s", addr1); 144 free(tmp); 145 continue; 146 } 147 148 if (!inet_aton((char *)&addr2, (struct in_addr *)&tmp->mask)) { 149 yp_error("badly formatted securenets entry: %s", addr2); 150 free(tmp); 151 continue; 152 } 153 154 tmp->next = securenets; 155 securenets = tmp; 156 } 157 158 fclose(fp); 159 160} 161#endif 162 163/* |
|
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 * | 164 * Access control functions. 165 * 166 * yp_access() checks the mapname and client host address and watches for 167 * the following things: 168 * 169 * - If the client is referencing one of the master.passwd.* maps, it must 170 * be using a privileged port to make its RPC to us. If it is, then we can 171 * assume that the caller is root and allow the RPC to succeed. If it 172 * isn't access is denied. 173 * |
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. | 174 * - The client's IP address is checked against the securenets rules. 175 * There are two kinds of securenets support: the built-in support, 176 * which is very simple and depends on the presense of a 177 * /var/yp/securenets file, and tcp-wrapper support, which requires 178 * Wietse Venema's libwrap.a and tcpd.h. (Since the tcp-wrapper 179 * package does not ship with FreeBSD, we use the built-in support 180 * by default. Users can recompile the server the tcp-wrapper library 181 * if they already have it installed and want to use hosts.allow and 182 * hosts.deny to control access instead od having a seperate securenets 183 * file.) |
78 * | 184 * |
185 * If no /var/yp/securenets file is present, the host access checks 186 * are bypassed and all hosts are allowed to connect. 187 * |
|
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; | 188 * The yp_validdomain() functions checks the domain specified by the caller 189 * to make sure it's actually served by this server. This is more a sanity 190 * check than an a security check, but this seems to be the best place for 191 * it. 192 */ 193 194int yp_access(map, rqstp) 195 const char *map; 196 const struct svc_req *rqstp; 197{ 198 struct sockaddr_in *rqhost; |
90#ifdef TCP_WRAPPER | |
91 int status = 0; 92 unsigned long oldaddr; | 199 int status = 0; 200 unsigned long oldaddr; |
201#ifndef TCP_WRAPPER 202 struct securenet *tmp; |
|
93#endif 94 95 rqhost = svc_getcaller(rqstp->rq_xprt); 96 97 if (debug) { 98 yp_error("Procedure %s called from %s:%d", | 203#endif 204 205 rqhost = svc_getcaller(rqstp->rq_xprt); 206 207 if (debug) { 208 yp_error("Procedure %s called from %s:%d", |
209 /* Hack to allow rpc.yppasswdd to use this routine */ 210 rqstp->rq_prog == YPPASSWDPROG ? 211 "yppasswdproc_update" : |
|
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) { | 212 yp_procs[rqstp->rq_proc], inet_ntoa(rqhost->sin_addr), 213 ntohs(rqhost->sin_port)); 214 if (map != NULL) 215 yp_error("Client is referencing map \"%s\".", map); 216 } 217 218 /* Check the map name if one was supplied. */ 219 if (map != NULL) { |
107 if (strstr(map, "master.passwd.") && ntohs(rqhost->sin_port) > 1023) { | 220 if ((strstr(map, "master.passwd.") || 221 rqstp->rq_proc == YPPROC_XFR) && 222 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 | 223 yp_error("Access to %s denied -- client not privileged", map); 224 return(1); 225 } 226 } 227 228#ifdef TCP_WRAPPER |
114 /* Check client address if TCP_WRAPPER is enalbled. */ | |
115 status = hosts_ctl(progname, STRING_UNKNOWN, | 229 status = hosts_ctl(progname, STRING_UNKNOWN, |
116 inet_ntoa(rqhost->sin_addr, ""); | 230 inet_ntoa(rqhost->sin_addr), ""); 231#else 232 tmp = securenets; 233 while(tmp) { 234 if (((rqhost->sin_addr.s_addr & ~tmp->mask.s_addr) 235 | tmp->net.s_addr) == rqhost->sin_addr.s_addr) { 236 status = 1; 237 break; 238 } 239 tmp = tmp->next; 240 } 241#endif |
117 | 242 |
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; | 243 if (!status) { 244 if (rqhost->sin_addr.s_addr != oldaddr) { 245 yp_error("connect from %s:%d to procedure %s refused", 246 inet_ntoa(rqhost->sin_addr), 247 ntohs(rqhost->sin_port), 248 rqstp->rq_prog == YPPASSWDPROG ? 249 "yppasswdproc_update" : 250 yp_procs[rqstp->rq_proc]); 251 oldaddr = rqhost->sin_addr.s_addr; 252 } |
122 return(1); 123 } | 253 return(1); 254 } |
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, "..") || | 255 return(0); 256 257} 258 259int yp_validdomain(domain) 260 const char *domain; 261{ 262 struct stat statbuf; 263 char dompath[MAXPATHLEN + 2]; 264 265 if (domain == NULL || strstr(domain, "binding") || 266 !strcmp(domain, ".") || !strcmp(domain, "..") || |
137 strchr(domain, '/')) | 267 strchr(domain, '/') || strlen(domain) > YPMAXDOMAIN) |
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} | 268 return(1); 269 270 snprintf(dompath, sizeof(dompath), "%s/%s", yp_dir, domain); 271 272 if (stat(dompath, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode)) 273 return(1); 274 275 return(0); 276} |