1 /* $NetBSD: scaffold.c,v 1.8 2002/06/06 21:28:50 itojun Exp $ */ 2 3 /* 4 * Routines for testing only. Not really industrial strength. 5 * 6 * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. 7 */ 8 9 #include <sys/cdefs.h> 10 #ifndef lint 11 #if 0 12 static char sccs_id[] = "@(#) scaffold.c 1.6 97/03/21 19:27:24"; 13 #else 14 __RCSID("$NetBSD: scaffold.c,v 1.8 2002/06/06 21:28:50 itojun Exp $"); 15 #endif 16 #endif 17 18 /* System libraries. */ 19 20 #include <sys/types.h> 21 #include <sys/stat.h> 22 #include <sys/socket.h> 23 #include <netinet/in.h> 24 #include <arpa/inet.h> 25 #include <netdb.h> 26 #include <stdio.h> 27 #include <syslog.h> 28 #include <setjmp.h> 29 #include <string.h> 30 #include <stdlib.h> 31 32 #ifndef INADDR_NONE 33 #define INADDR_NONE (-1) /* XXX should be 0xffffffff */ 34 #endif 35 36 /* Application-specific. */ 37 38 #include "tcpd.h" 39 #include "scaffold.h" 40 41 /* 42 * These are referenced by the options module and by rfc931.c. 43 */ 44 int allow_severity = SEVERITY; 45 int deny_severity = LOG_WARNING; 46 extern int rfc931_timeout; /* = RFC931_TIMEOUT; */ 47 48 /* find_inet_addr - find all addresses for this host, result to free() */ 49 50 struct addrinfo *find_inet_addr(host, flags) 51 char *host; 52 int flags; 53 { 54 struct addrinfo hints, *res; 55 int error; 56 57 memset(&hints, 0, sizeof(hints)); 58 hints.ai_socktype = SOCK_DGRAM; 59 hints.ai_flags = AI_CANONNAME | flags; 60 error = getaddrinfo(host, "0", &hints, &res); 61 if (error) { 62 tcpd_warn("%s: %s", host, gai_strerror(error)); 63 return (0); 64 } 65 66 if (res->ai_canonname && STR_NE(host, res->ai_canonname)) { 67 tcpd_warn("%s: hostname alias", host); 68 tcpd_warn("(official name: %.*s)", STRING_LENGTH, res->ai_canonname); 69 } 70 return (res); 71 } 72 73 /* check_dns - give each address thorough workout, return address count */ 74 75 int check_dns(host) 76 char *host; 77 { 78 struct request_info request; 79 struct sockaddr_storage ss; 80 struct addrinfo *res0, *res; 81 int count; 82 83 if ((res0 = find_inet_addr(host, 0)) == NULL) 84 return (0); 85 memset(&ss, 0, sizeof(ss)); 86 request_init(&request, RQ_CLIENT_SIN, &ss, 0); 87 sock_methods(&request); 88 89 count = 0; 90 for (res = res0; res; res = res->ai_next) { 91 count++; 92 if (res->ai_addrlen > sizeof(ss)) 93 continue; 94 memcpy(&ss, res->ai_addr, res->ai_addrlen); 95 96 /* 97 * Force host name and address conversions. Use the request structure 98 * as a cache. Detect hostname lookup problems. Any name/name or 99 * name/address conflicts will be reported while eval_hostname() does 100 * its job. 101 */ 102 request_set(&request, RQ_CLIENT_ADDR, "", RQ_CLIENT_NAME, "", 0); 103 if (STR_EQ(eval_hostname(request.client), unknown)) 104 tcpd_warn("host address %s->name lookup failed", 105 eval_hostaddr(request.client)); 106 tcpd_warn("%s %s", eval_hostname(request.client), unknown); 107 } 108 freeaddrinfo(res0); 109 return (count); 110 } 111 112 /* dummy function to intercept the real shell_cmd() */ 113 114 /* ARGSUSED */ 115 116 void shell_cmd(command) 117 char *command; 118 { 119 if (hosts_access_verbose) 120 printf("command: %s", command); 121 } 122 123 /* dummy function to intercept the real clean_exit() */ 124 125 /* ARGSUSED */ 126 127 void clean_exit(request) 128 struct request_info *request; 129 { 130 exit(0); 131 } 132 133 #if 0 134 /* dummy function to intercept the real rfc931() */ 135 136 /* ARGSUSED */ 137 138 void rfc931(request) 139 struct request_info *request; 140 { 141 strcpy(request->user, unknown); 142 } 143 #endif 144 145 /* check_path - examine accessibility */ 146 147 int check_path(path, st) 148 char *path; 149 struct stat *st; 150 { 151 struct stat stbuf; 152 char buf[BUFSIZ]; 153 154 if (stat(path, st) < 0) 155 return (-1); 156 #ifdef notdef 157 if (st->st_uid != 0) 158 tcpd_warn("%s: not owned by root", path); 159 if (st->st_mode & 020) 160 tcpd_warn("%s: group writable", path); 161 #endif 162 if (st->st_mode & 002) 163 tcpd_warn("%s: world writable", path); 164 if (path[0] == '/' && path[1] != 0) { 165 strrchr(strcpy(buf, path), '/')[0] = 0; 166 (void) check_path(buf[0] ? buf : "/", &stbuf); 167 } 168 return (0); 169 } 170