X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fmisc%2Ftcpwrapper.c;h=6f65c1375c4b1cfa5e2b18654604f20af649ce9f;hp=0ba856f9819d6af0593a0e47fe267120df33fd16;hb=90c944c9cc1fde845caa29b98c2864eb32660403;hpb=ae8e7dbe9641dbc69c34bcede416f0d91612d3f1 diff --git a/support/misc/tcpwrapper.c b/support/misc/tcpwrapper.c index 0ba856f..6f65c13 100644 --- a/support/misc/tcpwrapper.c +++ b/support/misc/tcpwrapper.c @@ -34,12 +34,12 @@ #ifdef HAVE_CONFIG_H #include #endif -#include + +#ifdef HAVE_LIBWRAP #include #include #include #include -#include #include #include #include @@ -48,6 +48,7 @@ #include #include +#include "tcpwrapper.h" #include "xlog.h" #ifdef SYSV40 @@ -55,45 +56,8 @@ #include #endif -static void logit(int severity, struct sockaddr_in *addr, - u_long procnum, u_long prognum, char *text); -static void toggle_verboselog(int sig); static int check_files(void); -int verboselog = 0; -int allow_severity = LOG_INFO; -int deny_severity = LOG_WARNING; - -/* A handful of macros for "readability". */ - -#ifdef HAVE_LIBWRAP -/* coming from libwrap.a (tcp_wrappers) */ -extern int hosts_ctl(char *daemon, char *name, char *addr, char *user); -#else -int hosts_ctl(char *daemon, char *name, char *addr, char *user) -{ - return 0; -} -#endif - -#define legal_port(a,p) \ - (ntohs((a)->sin_port) < IPPORT_RESERVED || (p) >= IPPORT_RESERVED) - -#define log_bad_port(addr, proc, prog) \ - logit(deny_severity, addr, proc, prog, ": request from unprivileged port") - -#define log_bad_host(addr, proc, prog) \ - logit(deny_severity, addr, proc, prog, ": request from unauthorized host") - -#define log_bad_owner(addr, proc, prog) \ - logit(deny_severity, addr, proc, prog, ": request from non-local host") - -#define log_no_forward(addr, proc, prog) \ - logit(deny_severity, addr, proc, prog, ": request not forwarded") - -#define log_client(addr, proc, prog) \ - logit(allow_severity, addr, proc, prog, "") - #define ALLOW 1 #define DENY 0 @@ -111,29 +75,35 @@ hash_head haccess_tbl[HASH_TABLE_SIZE]; static haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long); static void haccess_add(struct sockaddr_in *addr, u_long, int); -inline unsigned int strtoint(char *str) +static unsigned long +strtoint(const char *str) { - unsigned int n = 0; - int len = strlen(str); - int i; + unsigned long i, n = 0; + size_t len = strlen(str); - for (i=0; i < len; i++) - n+=((int)str[i])*i; + for (i = 0; i < len; i++) + n += (unsigned char)str[i] * i; return n; } -static inline int hashint(unsigned int num) + +static unsigned int +hashint(const unsigned long num) +{ + return (unsigned int)(num % HASH_TABLE_SIZE); +} + +static unsigned int +HASH(const char *addr, const unsigned long program) { - return num % HASH_TABLE_SIZE; + return hashint(strtoint(addr) + program); } -#define HASH(_addr, _prog) \ - hashint((strtoint((_addr))+(_prog))) void haccess_add(struct sockaddr_in *addr, u_long prog, int access) { hash_head *head; - haccess_t *hptr; - int hash; + haccess_t *hptr; + unsigned int hash; hptr = (haccess_t *)malloc(sizeof(haccess_t)); if (hptr == NULL) @@ -153,8 +123,8 @@ void haccess_add(struct sockaddr_in *addr, u_long prog, int access) haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long prog) { hash_head *head; - haccess_t *hptr; - int hash; + haccess_t *hptr; + unsigned int hash; hash = HASH(inet_ntoa(addr->sin_addr), prog); head = &(haccess_tbl[hash]); @@ -166,6 +136,16 @@ haccess_t *haccess_lookup(struct sockaddr_in *addr, u_long prog) return NULL; } +static void +logit(const struct sockaddr_in *sin) +{ + char buf[INET_ADDRSTRLEN]; + + xlog_warn("connect from %s denied: request from unauthorized host", + inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf))); + +} + int good_client(daemon, addr) char *daemon; @@ -182,43 +162,6 @@ struct sockaddr_in *addr; return DENY; } -/* check_startup - additional startup code */ - -void check_startup(void) -{ - - /* - * Give up root privileges so that we can never allocate a privileged - * port when forwarding an rpc request. - * - * Fix 8/3/00 Philipp Knirsch: First lookup our rpc user. If we find it, - * switch to that uid, otherwise simply resue the old bin user and print - * out a warning in syslog. - */ - - struct passwd *pwent; - - pwent = getpwnam("rpc"); - if (pwent == NULL) { - syslog(LOG_WARNING, "user rpc not found, reverting to user bin"); - if (setuid(1) == -1) { - syslog(LOG_ERR, "setuid(1) failed: %m"); - exit(1); - } - } - else { - if (setuid(pwent->pw_uid) == -1) { - syslog(LOG_WARNING, "setuid() to rpc user failed: %m"); - if (setuid(1) == -1) { - syslog(LOG_ERR, "setuid(1) failed: %m"); - exit(1); - } - } - } - - (void) signal(SIGINT, toggle_verboselog); -} - /* check_files - check to see if either access files have changed */ static int check_files() @@ -246,14 +189,17 @@ static int check_files() return changed; } -/* check_default - additional checks for NULL, DUMP, GETPORT and unknown */ - +/** + * check_default - additional checks for NULL, DUMP, GETPORT and unknown + * @daemon: pointer to '\0'-terminated ASCII string containing name of the + * daemon requesting the access check + * @addr: pointer to socket address containing address of caller + * @prog: RPC program number caller is attempting to access + * + * Returns TRUE if the caller is allowed access; otherwise FALSE is returned. + */ int -check_default(daemon, addr, proc, prog) -char *daemon; -struct sockaddr_in *addr; -u_long proc; -u_long prog; +check_default(char *daemon, struct sockaddr_in *addr, u_long prog) { haccess_t *acc = NULL; int changed = check_files(); @@ -262,86 +208,21 @@ u_long prog; if (acc && changed == 0) return (acc->access); - if (!(from_local(addr) || good_client(daemon, addr))) { - log_bad_host(addr, proc, prog); + if (!(from_local((struct sockaddr *)addr) || good_client(daemon, addr))) { + logit(addr); if (acc) acc->access = FALSE; else haccess_add(addr, prog, FALSE); return (FALSE); } - if (verboselog) - log_client(addr, proc, prog); if (acc) acc->access = TRUE; else haccess_add(addr, prog, TRUE); - return (TRUE); -} -/* check_privileged_port - additional checks for privileged-port updates */ -int -check_privileged_port(struct sockaddr_in *addr, - u_long proc, u_long prog, u_long port) -{ -#ifdef CHECK_PORT - if (!legal_port(addr, port)) { - log_bad_port(addr, proc, prog); - return (FALSE); - } -#endif return (TRUE); } -/* toggle_verboselog - toggle verbose logging flag */ - -static void toggle_verboselog(int sig) -{ - (void) signal(sig, toggle_verboselog); - verboselog = !verboselog; -} - -/* logit - report events of interest via the syslog daemon */ - -static void logit(int severity, struct sockaddr_in *addr, - u_long procnum, u_long prognum, char *text) -{ - char *procname; - char procbuf[16 + 4 * sizeof(u_long)]; - char *progname; - char progbuf[16 + 4 * sizeof(u_long)]; - struct rpcent *rpc; - - /* - * Fork off a process or the portmap daemon might hang while - * getrpcbynumber() or syslog() does its thing. - * - * Don't forget to wait for the children, too... - */ - - if (fork() == 0) { - - /* Try to map program number to name. */ - - if (prognum == 0) { - progname = ""; - } else if ((rpc = getrpcbynumber((int) prognum))) { - progname = rpc->r_name; - } else { - snprintf(progname = progbuf, sizeof (progbuf), - "prog (%lu)", prognum); - } - - /* Try to map procedure number to name. */ - - snprintf(procname = procbuf, sizeof (procbuf), - "proc (%lu)", (u_long) procnum); - - /* Write syslog record. */ - - syslog(severity, "connect from %s to %s in %s%s", - inet_ntoa(addr->sin_addr), procname, progname, text); - exit(0); - } -} +#endif /* HAVE_LIBWRAP */