summaryrefslogtreecommitdiffstats
path: root/source/lib/access.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/lib/access.c')
-rw-r--r--source/lib/access.c133
1 files changed, 68 insertions, 65 deletions
diff --git a/source/lib/access.c b/source/lib/access.c
index 4e524735e49..8bf3ba19337 100644
--- a/source/lib/access.c
+++ b/source/lib/access.c
@@ -10,6 +10,9 @@
#include "includes.h"
+/* Delimiters for lists of daemons or clients. */
+static char *sep = ", \t";
+
#define FAIL (-1)
#define ALLONES ((uint32)0xFFFFFFFF)
@@ -60,8 +63,7 @@ static int string_match(char *tok,char *s, char *invalid_char)
* return True if the string is a (host) member of the
* netgroup. Return True if the token fully matches the
* string. If the token is a netnumber/netmask pair, return
- * True if the address is a member of the specified subnet.
- */
+ * True if the address is a member of the specified subnet. */
if (tok[0] == '.') { /* domain: match last fields */
if ((str_len = strlen(s)) > (tok_len = strlen(tok))
@@ -104,19 +106,19 @@ static int string_match(char *tok,char *s, char *invalid_char)
} else if (strcasecmp(tok, "FAIL") == 0) { /* fail: match any */
return (FAIL);
} else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
- if (strchr_m(s, '.') == 0 && strcasecmp(s, "unknown") != 0)
+ if (strchr(s, '.') == 0 && strcasecmp(s, "unknown") != 0)
return (True);
} else if (!strcasecmp(tok, s)) { /* match host name or address */
return (True);
} else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* network */
if (strncmp(tok, s, tok_len) == 0)
return (True);
- } else if ((cut = strchr_m(tok, '/')) != 0) { /* netnumber/netmask */
+ } else if ((cut = strchr(tok, '/')) != 0) { /* netnumber/netmask */
if (isdigit((int)s[0]) && masked_match(tok, cut, s))
return (True);
- } else if (strchr_m(tok, '*') != 0) {
+ } else if (strchr(tok, '*') != 0) {
*invalid_char = '*';
- } else if (strchr_m(tok, '?') != 0) {
+ } else if (strchr(tok, '?') != 0) {
*invalid_char = '?';
}
return (False);
@@ -152,11 +154,20 @@ token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
}
/* list_match - match an item against a list of tokens with exceptions */
-static int list_match(char **list,char *item, int (*match_fn)(char *, char *))
+/* (All modifications are marked with the initials "jkf") */
+static int list_match(char *list,char *item, int (*match_fn)(char *, char *))
{
+ char *tok;
+ char *listcopy; /* jkf */
int match = False;
- if (!list) return False;
+ /*
+ * jkf@soton.ac.uk -- 31 August 1994 -- Stop list_match()
+ * overwriting the list given as its first parameter.
+ */
+
+ /* jkf -- can get called recursively with NULL list */
+ listcopy = (list == 0) ? (char *)0 : strdup(list);
/*
* Process tokens one at a time. We have exhausted all possible matches
@@ -165,30 +176,30 @@ static int list_match(char **list,char *item, int (*match_fn)(char *, char *))
* the match is affected by any exceptions.
*/
- for (; *list ; list++) {
- if (strcasecmp(*list, "EXCEPT") == 0) /* EXCEPT: give up */
+ for (tok = strtok(listcopy, sep); tok ; tok = strtok(NULL, sep)) {
+ if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
break;
- if ((match = (*match_fn) (*list, item))) /* True or FAIL */
+ if ((match = (*match_fn) (tok, item))) /* True or FAIL */
break;
}
/* Process exceptions to True or FAIL matches. */
if (match != False) {
- while (*list && strcasecmp(*list, "EXCEPT"))
- list++;
-
- for (; *list; list++) {
- if ((*match_fn) (*list, item)) /* Exception Found */
- return False;
+ while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
+ /* VOID */ ;
+ if (tok == 0 || list_match((char *) 0, item, match_fn) == False) {
+ SAFE_FREE(listcopy); /* jkf */
+ return (match);
}
}
- return (match);
+ SAFE_FREE(listcopy); /* jkf */
+ return (False);
}
/* return true if access should be allowed */
-static BOOL allow_access_internal(char **deny_list,char **allow_list,
+BOOL allow_access(char *deny_list,char *allow_list,
char *cname,char *caddr)
{
char *client[2];
@@ -227,12 +238,12 @@ static BOOL allow_access_internal(char **deny_list,char **allow_list,
if (!allow_list || *allow_list == 0)
return(!list_match(deny_list,(char *)client,client_match));
- /* if there are both types of list then allow all hosts on the
+ /* if there are both type of list then allow all hosts on the
allow list */
if (list_match(allow_list,(char *)client,client_match))
return (True);
- /* if there are both types of list and it's not on the allow then
+ /* if there are both type of list and it's not on the allow then
allow it if its not on the deny */
if (list_match(deny_list,(char *)client,client_match))
return (False);
@@ -240,99 +251,91 @@ static BOOL allow_access_internal(char **deny_list,char **allow_list,
return (True);
}
-/* return true if access should be allowed */
-BOOL allow_access(char **deny_list,char **allow_list,
- const char *cname, const char *caddr)
-{
- BOOL ret;
-
- char *nc_cname = smb_xstrdup(cname);
- char *nc_caddr = smb_xstrdup(caddr);
-
- ret = allow_access_internal(deny_list, allow_list, nc_cname, nc_caddr);
-
- SAFE_FREE(nc_cname);
- SAFE_FREE(nc_caddr);
- return ret;
-}
-
/* return true if the char* contains ip addrs only. Used to avoid
gethostbyaddr() calls */
-static BOOL only_ipaddrs_in_list(char** list)
+static BOOL only_ipaddrs_in_list(const char* list)
{
BOOL only_ip = True;
-
- if (!list) return True;
+ char *listcopy,
+ *tok;
- for (; *list ; list++)
+ listcopy = strdup(list);
+
+ for (tok = strtok(listcopy, sep); tok ; tok = strtok(NULL, sep))
{
/* factor out the special strings */
- if (!strcasecmp(*list, "ALL") || !strcasecmp(*list, "FAIL") ||
- !strcasecmp(*list, "EXCEPT"))
+ if (!strcasecmp(tok, "ALL") || !strcasecmp(tok, "FAIL") ||
+ !strcasecmp(tok, "EXCEPT"))
{
continue;
}
- if (!is_ipaddress(*list))
+ if (!is_ipaddress(tok))
{
- char *p;
/*
* if we failed, make sure that it was not because the token
* was a network/netmask pair. Only network/netmask pairs
* have a '/' in them
*/
- if ((p=strchr_m(*list, '/')) == NULL)
+ if (strchr(tok, '/') == NULL)
{
only_ip = False;
- DEBUG(3,("only_ipaddrs_in_list: list has non-ip address (%s)\n", *list));
+ DEBUG(3,("only_ipaddrs_in_list: list [%s] has non-ip address %s\n", list, tok));
break;
}
}
}
+ SAFE_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 check_access(int sock, char *allow_list, char *deny_list)
{
BOOL ret = False;
BOOL only_ip = False;
+ char *deny = NULL;
+ char *allow = NULL;
- if ((!deny_list || *deny_list==0) && (!allow_list || *allow_list==0))
- {
+ DEBUG(10,("check_access: allow = %s, deny = %s\n",
+ allow_list ? allow_list : "NULL",
+ deny_list ? deny_list : "NULL"));
+
+ if (deny_list)
+ deny = strdup(deny_list);
+ if (allow_list)
+ allow = strdup(allow_list);
+
+ if ((!deny || *deny==0) && (!allow || *allow==0))
ret = True;
- }
- if (!ret)
- {
+ 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))
- {
+ if (only_ipaddrs_in_list(allow) && only_ipaddrs_in_list(deny)) {
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
- {
+ ret = allow_access(deny,allow, "", 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),
+ ret = allow_access(deny,allow, get_socket_name(sock),
get_socket_addr(sock));
}
- if (ret)
- {
+ if (ret) {
DEBUG(2,("Allowed connection from %s (%s)\n",
only_ip ? "" : get_socket_name(sock),
get_socket_addr(sock)));
- }
- else
- {
+ } else {
DEBUG(0,("Denied connection from %s (%s)\n",
only_ip ? "" : get_socket_name(sock),
get_socket_addr(sock)));
}
}
+ SAFE_FREE(deny);
+ SAFE_FREE(allow);
+
return(ret);
}