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