summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/lib/access.c79
1 files changed, 71 insertions, 8 deletions
diff --git a/source3/lib/access.c b/source3/lib/access.c
index d646c0823b..8fd64b9c04 100644
--- a/source3/lib/access.c
+++ b/source3/lib/access.c
@@ -239,31 +239,94 @@ BOOL allow_access(char *deny_list,char *allow_list,
return (True);
}
+/* return true if the char* contains ip addrs only. Used to avoid
+gethostbyaddr() calls */
+static BOOL only_ipaddrs_in_list(const char* list)
+{
+ BOOL only_ip = True;
+ char *listcopy,
+ *tok;
+
+ listcopy = strdup(list);
+
+ for (tok = strtok(listcopy, sep); tok ; tok = strtok(NULL, sep))
+ {
+ /* factor out the special strings */
+ if (!strcasecmp(tok, "ALL") || !strcasecmp(tok, "FAIL") ||
+ !strcasecmp(tok, "EXCEPT"))
+ {
+ continue;
+ }
+
+ if (!is_ipaddress(tok))
+ {
+ char *p;
+ /*
+ * if we failed, make surethat it was not because the token
+ * was a network/netmask pair. Only network/netmask pairs
+ * have a '/' in them
+ */
+ if ((p=strtok(tok, "/")) == NULL)
+ {
+ only_ip = False;
+ DEBUG(3,("only_ipaddrs_in_list: list [%s] has non-ip address %s\n", list, p));
+ break;
+ }
+ }
+ }
+
+ if (listcopy)
+ free (listcopy);
+
+ return only_ip;
+}
+
/* return true if access should be allowed to a service for a socket */
BOOL check_access(int sock, char *allow_list, char *deny_list)
{
BOOL ret = False;
+ BOOL only_ip = False;
if (deny_list) deny_list = strdup(deny_list);
if (allow_list) allow_list = strdup(allow_list);
- if ((!deny_list || *deny_list==0) && (!allow_list || *allow_list==0)) {
+ if ((!deny_list || *deny_list==0) && (!allow_list || *allow_list==0))
+ {
ret = True;
}
- if (!ret) {
- if (allow_access(deny_list,allow_list,
- get_socket_name(sock),get_socket_addr(sock))) {
+ if (!ret)
+ {
+ /* bypass gethostbyaddr() calls if the lists only contain IP addrs */
+ if (only_ipaddrs_in_list(allow_list) && only_ipaddrs_in_list(deny_list))
+ {
+ only_ip = True;
+ DEBUG (3, ("check_access: no hostnames in host allow/deny list.\n"));
+ ret = allow_access(deny_list,allow_list, "", get_socket_addr(sock));
+ }
+ else
+ {
+ DEBUG (3, ("check_access: hostnames in host allow/deny list.\n"));
+ ret = allow_access(deny_list,allow_list, get_socket_name(sock),
+ get_socket_addr(sock));
+ }
+
+ if (ret)
+ {
DEBUG(2,("Allowed connection from %s (%s)\n",
- get_socket_name(sock),get_socket_addr(sock)));
- ret = True;
- } else {
+ only_ip ? "" : get_socket_name(sock),
+ get_socket_addr(sock)));
+ }
+ else
+ {
DEBUG(0,("Denied connection from %s (%s)\n",
- get_socket_name(sock),get_socket_addr(sock)));
+ only_ip ? "" : get_socket_name(sock),
+ get_socket_addr(sock)));
}
}
if (deny_list) free(deny_list);
if (allow_list) free(allow_list);
+
return(ret);
}