|
|
dc8c34 |
From b791dc9fbd1b88d033d848e3cb0db8f93e2dbff5 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Mark Reynolds <mareynol@redhat.com>
|
|
|
dc8c34 |
Date: Wed, 9 May 2012 16:03:59 -0400
|
|
|
dc8c34 |
Subject: [PATCH 374/375] Ticket #196 - RFE: Interpret IPV6 addresses for ACIs,
|
|
|
dc8c34 |
replication, and chaining
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Bug Description: replication, chaining, and access control do not hanbdle IPv6 addresses
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Fix Description: For replication and chaining, we just needed to put brackets "[]" around
|
|
|
dc8c34 |
the IP address in the ldap urls. We also need to update
|
|
|
dc8c34 |
convert_to_openldap_uri(), which is called by slapi_ldap_init_ext().
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Access control needed to remove the IPv6 restriction check, and update
|
|
|
dc8c34 |
libaccess to be IPv6 aware.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/196
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by: Norkio!
|
|
|
dc8c34 |
|
|
|
dc8c34 |
(cherry picked from commit 4d7d59e756d5dc2dbc04c7ee95759f211795a093)
|
|
|
dc8c34 |
(cherry picked from commit 44413ce12710f310d377727399abc8f9a870c5eb)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/plugins/acl/acllas.c | 53 +--
|
|
|
dc8c34 |
ldap/servers/plugins/replication/repl5_plugins.c | 7 +-
|
|
|
dc8c34 |
ldap/servers/plugins/replication/windows_private.c | 7 +-
|
|
|
dc8c34 |
ldap/servers/slapd/ldaputil.c | 90 +++--
|
|
|
dc8c34 |
ldap/servers/slapd/slapi-plugin.h | 9 +
|
|
|
dc8c34 |
lib/libaccess/lasip.cpp | 397 ++++++++++++++++-----
|
|
|
dc8c34 |
lib/libaccess/lasip.h | 3 +-
|
|
|
dc8c34 |
7 files changed, 407 insertions(+), 159 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
|
|
|
dc8c34 |
index fc7f185..a0cc53d 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/acl/acllas.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/acl/acllas.c
|
|
|
dc8c34 |
@@ -281,16 +281,12 @@ int
|
|
|
dc8c34 |
DS_LASIpGetter(NSErr_t *errp, PList_t subject, PList_t resource, PList_t
|
|
|
dc8c34 |
auth_info, PList_t global_auth, void *arg)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
+ struct acl_pblock *aclpb = NULL;
|
|
|
dc8c34 |
+ PRNetAddr *client_praddr = NULL;
|
|
|
dc8c34 |
+ char ip_str[256];
|
|
|
dc8c34 |
+ int rv = LAS_EVAL_TRUE;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- struct acl_pblock *aclpb = NULL;
|
|
|
dc8c34 |
- IPAddr_t ip=0;
|
|
|
dc8c34 |
- PRNetAddr client_praddr;
|
|
|
dc8c34 |
- struct in_addr client_addr;
|
|
|
dc8c34 |
- int rv;
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- rv = ACL_GetAttribute(errp, DS_PROP_ACLPB, (void **)&aclpb,
|
|
|
dc8c34 |
- subject, resource, auth_info, global_auth);
|
|
|
dc8c34 |
+ rv = ACL_GetAttribute(errp, DS_PROP_ACLPB, (void **)&aclpb, subject, resource, auth_info, global_auth);
|
|
|
dc8c34 |
if ( rv != LAS_EVAL_TRUE || ( NULL == aclpb )) {
|
|
|
dc8c34 |
acl_print_acllib_err(errp, NULL);
|
|
|
dc8c34 |
slapi_log_error( SLAPI_LOG_ACL, plugin_name,
|
|
|
dc8c34 |
@@ -298,29 +294,34 @@ DS_LASIpGetter(NSErr_t *errp, PList_t subject, PList_t resource, PList_t
|
|
|
dc8c34 |
return LAS_EVAL_FAIL;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if ( slapi_pblock_get( aclpb->aclpb_pblock, SLAPI_CONN_CLIENTNETADDR,
|
|
|
dc8c34 |
- &client_praddr ) != 0 ) {
|
|
|
dc8c34 |
- slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "Could not get client IP.\n" );
|
|
|
dc8c34 |
- return( LAS_EVAL_FAIL );
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- if ( !PR_IsNetAddrType(&client_praddr, PR_IpAddrV4Mapped) ) {
|
|
|
dc8c34 |
- slapi_log_error( SLAPI_LOG_ACL, plugin_name,
|
|
|
dc8c34 |
- "Client address is IPv6. ACLs only support IPv4 addresses so far.\n");
|
|
|
dc8c34 |
+ client_praddr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr));
|
|
|
dc8c34 |
+ if(client_praddr == NULL){
|
|
|
dc8c34 |
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "DS_LASIpGetter: failed to allocate client_praddr\n");
|
|
|
dc8c34 |
return( LAS_EVAL_FAIL );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- client_addr.s_addr = client_praddr.ipv6.ip.pr_s6_addr32[3];
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- ip = (IPAddr_t) ntohl( client_addr.s_addr );
|
|
|
dc8c34 |
- rv = PListInitProp(subject, 0, ACL_ATTR_IP, (void *)ip, NULL);
|
|
|
dc8c34 |
+ if ( slapi_pblock_get( aclpb->aclpb_pblock, SLAPI_CONN_CLIENTNETADDR, client_praddr ) != 0 ) {
|
|
|
dc8c34 |
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "DS_LASIpGetter: Could not get client IP.\n" );
|
|
|
dc8c34 |
+ slapi_ch_free((void **)&client_praddr);
|
|
|
dc8c34 |
+ return( LAS_EVAL_FAIL );
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- slapi_log_error( SLAPI_LOG_ACL, plugin_name,
|
|
|
dc8c34 |
- "Returning client ip address '%s'\n",
|
|
|
dc8c34 |
- (slapi_is_loglevel_set(SLAPI_LOG_ACL) ? inet_ntoa(client_addr) : ""));
|
|
|
dc8c34 |
+ rv = PListInitProp(subject, 0, ACL_ATTR_IP, (void *)client_praddr, NULL);
|
|
|
dc8c34 |
+ if (rv < 0) {
|
|
|
dc8c34 |
+ slapi_log_error ( SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter: "
|
|
|
dc8c34 |
+ "Couldn't set the client addr property(%d)\n", rv );
|
|
|
dc8c34 |
+ slapi_ch_free((void **)&client_praddr);
|
|
|
dc8c34 |
+ return LAS_EVAL_FAIL;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if( PR_NetAddrToString(client_praddr, ip_str, sizeof(ip_str)) == PR_SUCCESS){
|
|
|
dc8c34 |
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter: "
|
|
|
dc8c34 |
+ "Returning client ip address '%s'\n", ip_str);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter: "
|
|
|
dc8c34 |
+ "Returning client ip address 'unknown'\n");
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
|
|
|
dc8c34 |
return LAS_EVAL_TRUE;
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
|
|
|
dc8c34 |
index afb0364..dddbf15 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/replication/repl5_plugins.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
|
|
|
dc8c34 |
@@ -133,7 +133,12 @@ multimaster_set_local_purl()
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
else
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- local_purl = slapi_ch_smprintf("ldap://%s:%s", host, port);
|
|
|
dc8c34 |
+ if(slapi_is_ipv6_addr(host)){
|
|
|
dc8c34 |
+ /* need to put brackets around the ipv6 address */
|
|
|
dc8c34 |
+ local_purl = slapi_ch_smprintf("ldap://[%s]:%s", host, port);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ local_purl = slapi_ch_smprintf("ldap://%s:%s", host, port);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* slapi_ch_free acceptS NULL pointer */
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/replication/windows_private.c b/ldap/servers/plugins/replication/windows_private.c
|
|
|
dc8c34 |
index a103cad..4381943 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/replication/windows_private.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/replication/windows_private.c
|
|
|
dc8c34 |
@@ -321,7 +321,12 @@ const char* windows_private_get_purl(const Repl_Agmt *ra)
|
|
|
dc8c34 |
char *hostname;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
hostname = agmt_get_hostname(ra);
|
|
|
dc8c34 |
- windows_purl = slapi_ch_smprintf("ldap://%s:%d", hostname, agmt_get_port(ra));
|
|
|
dc8c34 |
+ if(slapi_is_ipv6_addr(hostname)){
|
|
|
dc8c34 |
+ /* need to put brackets around the ipv6 address */
|
|
|
dc8c34 |
+ windows_purl = slapi_ch_smprintf("ldap://[%s]:%d", hostname, agmt_get_port(ra));
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ windows_purl = slapi_ch_smprintf("ldap://%s:%d", hostname, agmt_get_port(ra));
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
slapi_ch_free_string(&hostname);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
return windows_purl;
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c
|
|
|
dc8c34 |
index 331dd71..4b8c16d 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/ldaputil.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/ldaputil.c
|
|
|
dc8c34 |
@@ -165,55 +165,59 @@ convert_to_openldap_uri(const char *hostname_or_uri, int port, const char *proto
|
|
|
dc8c34 |
char *my_copy = NULL;
|
|
|
dc8c34 |
char *start = NULL;
|
|
|
dc8c34 |
char *iter = NULL;
|
|
|
dc8c34 |
+ char *ptr = NULL;
|
|
|
dc8c34 |
char *s = NULL;
|
|
|
dc8c34 |
const char *brkstr = " ";
|
|
|
dc8c34 |
+ int done = 0;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if (!hostname_or_uri) {
|
|
|
dc8c34 |
- return NULL;
|
|
|
dc8c34 |
+ return NULL;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if(slapi_is_ipv6_addr(hostname_or_uri)){
|
|
|
dc8c34 |
+ /* We need to encapsulate the ipv6 addr with brackets */
|
|
|
dc8c34 |
+ my_copy = slapi_ch_smprintf("[%s]",hostname_or_uri);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ my_copy = slapi_ch_strdup(hostname_or_uri);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- my_copy = slapi_ch_strdup(hostname_or_uri);
|
|
|
dc8c34 |
/* see if hostname_or_uri is an ldap uri */
|
|
|
dc8c34 |
if (!proto && !PL_strncasecmp(my_copy, "ldap", 4)) {
|
|
|
dc8c34 |
- start = my_copy + 4;
|
|
|
dc8c34 |
- if ((*start == 's') || (*start == 'i')) {
|
|
|
dc8c34 |
- start++;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
- if (!PL_strncmp(start, "://", 3)) {
|
|
|
dc8c34 |
- *start = '\0';
|
|
|
dc8c34 |
- proto = my_copy;
|
|
|
dc8c34 |
- start += 3;
|
|
|
dc8c34 |
- } else {
|
|
|
dc8c34 |
- slapi_log_error(SLAPI_LOG_FATAL, "convert_to_openldap_uri",
|
|
|
dc8c34 |
- "The given LDAP URI [%s] is not valid\n", hostname_or_uri);
|
|
|
dc8c34 |
- goto end;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
+ start = my_copy + 4;
|
|
|
dc8c34 |
+ if ((*start == 's') || (*start == 'i')) {
|
|
|
dc8c34 |
+ start++;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (!PL_strncmp(start, "://", 3)) {
|
|
|
dc8c34 |
+ *start = '\0';
|
|
|
dc8c34 |
+ proto = my_copy;
|
|
|
dc8c34 |
+ start += 3;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_FATAL, "convert_to_openldap_uri",
|
|
|
dc8c34 |
+ "The given LDAP URI [%s] is not valid\n", hostname_or_uri);
|
|
|
dc8c34 |
+ goto end;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
} else if (!proto) {
|
|
|
dc8c34 |
- slapi_log_error(SLAPI_LOG_FATAL, "convert_to_openldap_uri",
|
|
|
dc8c34 |
- "The given LDAP URI [%s] is not valid\n", hostname_or_uri);
|
|
|
dc8c34 |
- goto end;
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_FATAL, "convert_to_openldap_uri",
|
|
|
dc8c34 |
+ "The given LDAP URI [%s] is not valid\n", hostname_or_uri);
|
|
|
dc8c34 |
+ goto end;
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
- start = my_copy; /* just assume it's not a uri */
|
|
|
dc8c34 |
+ start = my_copy; /* just assume it's not a uri */
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- for (s = ldap_utf8strtok_r(my_copy, brkstr, &iter); s != NULL;
|
|
|
dc8c34 |
- s = ldap_utf8strtok_r(NULL, brkstr, &iter)) {
|
|
|
dc8c34 |
- char *ptr;
|
|
|
dc8c34 |
- int last = 0;
|
|
|
dc8c34 |
- /* strtok will grab the '/' at the end of the uri, if any,
|
|
|
dc8c34 |
- so terminate parsing there */
|
|
|
dc8c34 |
- if ((ptr = strchr(s, '/'))) {
|
|
|
dc8c34 |
- *ptr = '\0';
|
|
|
dc8c34 |
- last = 1;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
- if (retstr) {
|
|
|
dc8c34 |
- retstr = PR_sprintf_append(retstr, "/ %s://%s", proto, s);
|
|
|
dc8c34 |
- } else {
|
|
|
dc8c34 |
- retstr = PR_smprintf("%s://%s", proto, s);
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
- if (last) {
|
|
|
dc8c34 |
- break;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
+ for (s = ldap_utf8strtok_r(my_copy, brkstr, &iter); s != NULL; s = ldap_utf8strtok_r(NULL, brkstr, &iter)) {
|
|
|
dc8c34 |
+ /* strtok will grab the '/' at the end of the uri, if any, so terminate parsing there */
|
|
|
dc8c34 |
+ if ((ptr = strchr(s, '/'))) {
|
|
|
dc8c34 |
+ *ptr = '\0';
|
|
|
dc8c34 |
+ done = 1;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (retstr) {
|
|
|
dc8c34 |
+ retstr = PR_sprintf_append(retstr, "/ %s://%s", proto, s);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ retstr = PR_smprintf("%s://%s", proto, s);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (done) {
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* add the port on the last one */
|
|
|
dc8c34 |
@@ -2271,3 +2275,15 @@ mozldap_ldap_explode_rdn( const char *rdn, const int notypes )
|
|
|
dc8c34 |
return( mozldap_ldap_explode( rdn, notypes, LDAP_RDN ) );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+int
|
|
|
dc8c34 |
+slapi_is_ipv6_addr( const char *hostname ){
|
|
|
dc8c34 |
+ PRNetAddr addr;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if(PR_StringToNetAddr(hostname, &addr) == PR_SUCCESS &&
|
|
|
dc8c34 |
+ !PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) &&
|
|
|
dc8c34 |
+ addr.raw.family == PR_AF_INET6)
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
+ return 1;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ return 0;
|
|
|
dc8c34 |
+}
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
|
|
dc8c34 |
index 75d5aa9..cb15a25 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/slapi-plugin.h
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/slapi-plugin.h
|
|
|
dc8c34 |
@@ -3015,6 +3015,15 @@ void slapi_rdn_set_rdn(Slapi_RDN *rdn,const Slapi_RDN *fromrdn);
|
|
|
dc8c34 |
void slapi_rdn_free(Slapi_RDN **rdn);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/**
|
|
|
dc8c34 |
+ * Checks if the value of ipAddress is a IPv6 address
|
|
|
dc8c34 |
+ *
|
|
|
dc8c34 |
+ * \param ipAddress is a string that is either an IPv4 or IPv6 address
|
|
|
dc8c34 |
+ * \return 1 if address is an IPv6 address
|
|
|
dc8c34 |
+ * \return 0 if address is an IPv4 address
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+int slapi_is_ipv6_addr( const char *ipAddress);
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+/**
|
|
|
dc8c34 |
* Frees and clears the contents of a \c Slapi_RDN structure from memory.
|
|
|
dc8c34 |
*
|
|
|
dc8c34 |
* Both the RDN value and the array of split RDNs are freed. Those pointers
|
|
|
dc8c34 |
diff --git a/lib/libaccess/lasip.cpp b/lib/libaccess/lasip.cpp
|
|
|
dc8c34 |
index 7f5c01e..e66f48a 100644
|
|
|
dc8c34 |
--- a/lib/libaccess/lasip.cpp
|
|
|
dc8c34 |
+++ b/lib/libaccess/lasip.cpp
|
|
|
dc8c34 |
@@ -60,6 +60,8 @@
|
|
|
dc8c34 |
#include "aclcache.h"
|
|
|
dc8c34 |
#include <libaccess/dbtlibaccess.h>
|
|
|
dc8c34 |
#include <libaccess/aclerror.h>
|
|
|
dc8c34 |
+#include <prio.h>
|
|
|
dc8c34 |
+#include "nspr.h"
|
|
|
dc8c34 |
|
|
|
dc8c34 |
#define LAS_IP_IS_CONSTANT(x) (((x) == (LASIpTree_t *)LAS_EVAL_TRUE) || ((x) == (LASIpTree_t *)LAS_EVAL_FALSE))
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -67,8 +69,9 @@
|
|
|
dc8c34 |
extern int LASIpGetIp();
|
|
|
dc8c34 |
#endif
|
|
|
dc8c34 |
|
|
|
dc8c34 |
-static int
|
|
|
dc8c34 |
-LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop);
|
|
|
dc8c34 |
+static int colonhex_ipv6(char *ipstr, char *netmaskstr, PRIPv6Addr *ipv6, int *netmask);
|
|
|
dc8c34 |
+static int LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop);
|
|
|
dc8c34 |
+static int LASIpAddPatternIPv6(NSErr_t *errp, int netmask, PRIPv6Addr *ipv6, LASIpTree_t **treetop);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* dotdecimal
|
|
|
dc8c34 |
* Takes netmask and ip strings and returns the numeric values,
|
|
|
dc8c34 |
@@ -259,68 +262,108 @@ LASIpTreeDealloc(LASIpTree_t *startnode)
|
|
|
dc8c34 |
* ret code The usual LAS return codes.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
static int
|
|
|
dc8c34 |
-LASIpBuild(NSErr_t *errp, char *attr_name, CmpOp_t comparator, char *attr_pattern, LASIpTree_t **treetop)
|
|
|
dc8c34 |
+LASIpBuild(NSErr_t *errp, char *attr_name, CmpOp_t comparator, char *attr_pattern, LASIpContext_t *context)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
unsigned int delimiter; /* length of valid token */
|
|
|
dc8c34 |
char token[64], token2[64]; /* a single ip[+netmask] */
|
|
|
dc8c34 |
char *curptr; /* current place in attr_pattern */
|
|
|
dc8c34 |
- int netmask, ip;
|
|
|
dc8c34 |
+ int netmask = 0;
|
|
|
dc8c34 |
+ int ip = 0;
|
|
|
dc8c34 |
char *plusptr;
|
|
|
dc8c34 |
- int retcode;
|
|
|
dc8c34 |
+ int retcode;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if (NULL == treetop) {
|
|
|
dc8c34 |
+ if (NULL == context) {
|
|
|
dc8c34 |
return ACL_RES_ERROR;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- /* ip address can be delimited by space, tab, comma, or carriage return
|
|
|
dc8c34 |
- * only.
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * IP address can be delimited by space, tab, comma, or carriage return only.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
curptr = attr_pattern;
|
|
|
dc8c34 |
do {
|
|
|
dc8c34 |
delimiter = strcspn(curptr, ", \t");
|
|
|
dc8c34 |
delimiter = (delimiter <= strlen(curptr)) ? delimiter : strlen(curptr);
|
|
|
dc8c34 |
strncpy(token, curptr, delimiter);
|
|
|
dc8c34 |
- if (delimiter >= sizeof(token)) {
|
|
|
dc8c34 |
+ if (delimiter >= sizeof(token)) {
|
|
|
dc8c34 |
return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
|
|
|
dc8c34 |
token[delimiter] = '\0';
|
|
|
dc8c34 |
/* skip all the white space after the token */
|
|
|
dc8c34 |
- curptr = strpbrk((curptr+delimiter), "1234567890+.*");
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- /* Is there a netmask? */
|
|
|
dc8c34 |
- plusptr = strchr(token, '+');
|
|
|
dc8c34 |
- if (plusptr == NULL) {
|
|
|
dc8c34 |
- if (curptr && (*curptr == '+')) {
|
|
|
dc8c34 |
- /* There was a space before (and possibly after) the plus sign*/
|
|
|
dc8c34 |
- curptr = strpbrk((++curptr), "1234567890.*");
|
|
|
dc8c34 |
- delimiter = strcspn(curptr, ", \t");
|
|
|
dc8c34 |
- delimiter = (delimiter <= strlen(curptr)) ? delimiter : strlen(curptr);
|
|
|
dc8c34 |
- if (delimiter >= sizeof(token2)) {
|
|
|
dc8c34 |
- return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
- strncpy(token2, curptr, delimiter);
|
|
|
dc8c34 |
- token2[delimiter] = '\0';
|
|
|
dc8c34 |
- retcode = dotdecimal(token, token2, &ip, &netmask);
|
|
|
dc8c34 |
+ curptr = strpbrk((curptr+delimiter), "1234567890+.*ABCDEFabcdef:/");
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * IPv4 addresses do not have ":"
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ if( strstr(token,":") == NULL ){
|
|
|
dc8c34 |
+ /* Is there a netmask? */
|
|
|
dc8c34 |
+ plusptr = strchr(token, '+');
|
|
|
dc8c34 |
+ if (plusptr == NULL) {
|
|
|
dc8c34 |
+ if (curptr && (*curptr == '+')) {
|
|
|
dc8c34 |
+ /* There was a space before (and possibly after) the plus sign*/
|
|
|
dc8c34 |
+ curptr = strpbrk((++curptr), "1234567890.*");
|
|
|
dc8c34 |
+ delimiter = strcspn(curptr, ", \t");
|
|
|
dc8c34 |
+ delimiter = (delimiter <= strlen(curptr)) ? delimiter : strlen(curptr);
|
|
|
dc8c34 |
+ if (delimiter >= sizeof(token2)) {
|
|
|
dc8c34 |
+ return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ strncpy(token2, curptr, delimiter);
|
|
|
dc8c34 |
+ token2[delimiter] = '\0';
|
|
|
dc8c34 |
+ retcode = dotdecimal(token, token2, &ip, &netmask);
|
|
|
dc8c34 |
+ if (retcode)
|
|
|
dc8c34 |
+ return (retcode);
|
|
|
dc8c34 |
+ curptr = strpbrk((++curptr), "1234567890+.*");
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ retcode = dotdecimal(token, "255.255.255.255", &ip, &netmask);
|
|
|
dc8c34 |
+ if (retcode)
|
|
|
dc8c34 |
+ return (retcode);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ /* token is the IP addr string in both cases */
|
|
|
dc8c34 |
+ *plusptr ='\0'; /* truncate the string */
|
|
|
dc8c34 |
+ retcode =dotdecimal(token, ++plusptr, &ip, &netmask);
|
|
|
dc8c34 |
if (retcode)
|
|
|
dc8c34 |
return (retcode);
|
|
|
dc8c34 |
- curptr = strpbrk((++curptr), "1234567890+.*");
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if (LASIpAddPattern(errp, netmask, ip, &context->treetop) != 0)
|
|
|
dc8c34 |
+ return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * IPv6
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ PRIPv6Addr ipv6;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ plusptr = strchr(token, '/');
|
|
|
dc8c34 |
+ if (plusptr == NULL) {
|
|
|
dc8c34 |
+ if (curptr && (*curptr == '/')) {
|
|
|
dc8c34 |
+ /* There was a space before (and possibly after) the plus sign */
|
|
|
dc8c34 |
+ curptr = strpbrk((++curptr), "1234567890.*:ABCDEFabcdef");
|
|
|
dc8c34 |
+ delimiter = strcspn(curptr, ", \t");
|
|
|
dc8c34 |
+ delimiter = (delimiter <= strlen(curptr)) ? delimiter : strlen(curptr);
|
|
|
dc8c34 |
+ strncpy(token2, curptr, delimiter);
|
|
|
dc8c34 |
+ token2[delimiter] = '\0';
|
|
|
dc8c34 |
+ retcode = colonhex_ipv6(token, token2, &ipv6, &netmask);
|
|
|
dc8c34 |
+ if (retcode)
|
|
|
dc8c34 |
+ return (retcode);
|
|
|
dc8c34 |
+ curptr = strpbrk((++curptr), "1234567890+.:ABCDEFabcdef*");
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ retcode = colonhex_ipv6(token, "128", &ipv6, &netmask);
|
|
|
dc8c34 |
+ if (retcode)
|
|
|
dc8c34 |
+ return (retcode);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
- retcode =dotdecimal(token, "255.255.255.255", &ip, &netmask);
|
|
|
dc8c34 |
+ /* token is the IP addr string in both cases */
|
|
|
dc8c34 |
+ *plusptr ='\0'; /* truncate the string */
|
|
|
dc8c34 |
+ retcode = colonhex_ipv6(token, ++plusptr, &ipv6, &netmask);
|
|
|
dc8c34 |
if (retcode)
|
|
|
dc8c34 |
return (retcode);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- } else {
|
|
|
dc8c34 |
- /* token is the IP addr string in both cases */
|
|
|
dc8c34 |
- *plusptr ='\0'; /* truncate the string */
|
|
|
dc8c34 |
- retcode =dotdecimal(token, ++plusptr, &ip, &netmask);
|
|
|
dc8c34 |
- if (retcode)
|
|
|
dc8c34 |
- return (retcode);
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- if (LASIpAddPattern(errp, netmask, ip, treetop) != 0)
|
|
|
dc8c34 |
- return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+ if (LASIpAddPatternIPv6(errp, netmask, &ipv6, &context->treetop_ipv6) != (int)NULL) {
|
|
|
dc8c34 |
+ return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
} while ((curptr != NULL) && (delimiter != 0));
|
|
|
dc8c34 |
|
|
|
dc8c34 |
return 0;
|
|
|
dc8c34 |
@@ -361,13 +404,15 @@ LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop)
|
|
|
dc8c34 |
if (*treetop == (LASIpTree_t *)NULL) { /* No tree at all */
|
|
|
dc8c34 |
curptr = LASIpTreeAllocNode(errp);
|
|
|
dc8c34 |
if (curptr == NULL) {
|
|
|
dc8c34 |
- nserrGenerate(errp, ACLERRFAIL, ACLERR5100, ACL_Program, 1, XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_));
|
|
|
dc8c34 |
+ nserrGenerate(errp, ACLERRFAIL, ACLERR5100, ACL_Program, 1,
|
|
|
dc8c34 |
+ XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_));
|
|
|
dc8c34 |
return ACL_RES_ERROR;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
*treetop = curptr;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- /* Special case if the netmask is 0.
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Special case if the netmask is 0.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
if (stopbit > 31) {
|
|
|
dc8c34 |
(*treetop)->action[0] = (LASIpTree_t *)LAS_EVAL_TRUE;
|
|
|
dc8c34 |
@@ -375,24 +420,18 @@ LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop)
|
|
|
dc8c34 |
return 0;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
/* follow the tree down the pattern path bit by bit until the
|
|
|
dc8c34 |
* end of the tree is reached (i.e. a constant).
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
for (curbit=31,curptr=*treetop; curbit >= 0; curbit--) {
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
/* Is the current bit ON? If so set curval to 1 else 0 */
|
|
|
dc8c34 |
curval = (pattern & (1<
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* Are we done, if so remove the rest of the tree */
|
|
|
dc8c34 |
if (curbit == stopbit) {
|
|
|
dc8c34 |
LASIpTreeDealloc(curptr->action[curval]);
|
|
|
dc8c34 |
- curptr->action[curval] =
|
|
|
dc8c34 |
- (LASIpTree_t *)LAS_EVAL_TRUE;
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- /* This is the normal exit point. Most other
|
|
|
dc8c34 |
- * exits must be due to errors.
|
|
|
dc8c34 |
- */
|
|
|
dc8c34 |
+ curptr->action[curval] = (LASIpTree_t *)LAS_EVAL_TRUE;
|
|
|
dc8c34 |
+ /* This is the normal exit point. Most other exits must be due to errors. */
|
|
|
dc8c34 |
return 0;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -401,7 +440,8 @@ LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop)
|
|
|
dc8c34 |
newptr = LASIpTreeAllocNode(errp);
|
|
|
dc8c34 |
if (newptr == NULL) {
|
|
|
dc8c34 |
LASIpTreeDealloc(*treetop);
|
|
|
dc8c34 |
- nserrGenerate(errp, ACLERRFAIL, ACLERR5110, ACL_Program, 1, XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_1));
|
|
|
dc8c34 |
+ nserrGenerate(errp, ACLERRFAIL, ACLERR5110, ACL_Program, 1,
|
|
|
dc8c34 |
+ XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_1));
|
|
|
dc8c34 |
return ACL_RES_ERROR;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
curptr->action[curval] = newptr;
|
|
|
dc8c34 |
@@ -451,51 +491,57 @@ int LASIpEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
|
|
|
dc8c34 |
PList_t subject, PList_t resource, PList_t auth_info,
|
|
|
dc8c34 |
PList_t global_auth)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- int bit;
|
|
|
dc8c34 |
- int value;
|
|
|
dc8c34 |
- IPAddr_t ip;
|
|
|
dc8c34 |
- int retcode;
|
|
|
dc8c34 |
- LASIpTree_t *node;
|
|
|
dc8c34 |
- LASIpContext_t *context = NULL;
|
|
|
dc8c34 |
- int rv;
|
|
|
dc8c34 |
- char ip_str[124];
|
|
|
dc8c34 |
+ LASIpContext_t *context = NULL;
|
|
|
dc8c34 |
+ LASIpTree_t *node = NULL;
|
|
|
dc8c34 |
+ IPAddr_t ip;
|
|
|
dc8c34 |
+ PRNetAddr *client_addr = NULL;
|
|
|
dc8c34 |
+ struct in_addr client_inaddr;
|
|
|
dc8c34 |
+ char ip_str[124];
|
|
|
dc8c34 |
+ int retcode;
|
|
|
dc8c34 |
+ int value;
|
|
|
dc8c34 |
+ int bit;
|
|
|
dc8c34 |
+ int rc = LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ int rv;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
*cachable = ACL_INDEF_CACHABLE;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if (strcmp(attr_name, "ip") != 0) {
|
|
|
dc8c34 |
- nserrGenerate(errp, ACLERRINVAL, ACLERR5200, ACL_Program, 2, XP_GetAdminStr(DBT_lasIpBuildReceivedRequestForAttr_), attr_name);
|
|
|
dc8c34 |
+ nserrGenerate(errp, ACLERRINVAL, ACLERR5200, ACL_Program, 2,
|
|
|
dc8c34 |
+ XP_GetAdminStr(DBT_lasIpBuildReceivedRequestForAttr_), attr_name);
|
|
|
dc8c34 |
return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ((comparator != CMP_OP_EQ) && (comparator != CMP_OP_NE)) {
|
|
|
dc8c34 |
- nserrGenerate(errp, ACLERRINVAL, ACLERR5210, ACL_Program, 2, XP_GetAdminStr(DBT_lasipevalIllegalComparatorDN_), comparator_string(comparator));
|
|
|
dc8c34 |
+ nserrGenerate(errp, ACLERRINVAL, ACLERR5210, ACL_Program, 2,
|
|
|
dc8c34 |
+ XP_GetAdminStr(DBT_lasipevalIllegalComparatorDN_), comparator_string(comparator));
|
|
|
dc8c34 |
return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- /* GET THE IP ADDR FROM THE SESSION CONTEXT AND STORE IT IN THE
|
|
|
dc8c34 |
- * VARIABLE ip.
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Get the IP addr from the session context, and store it in "client_addr
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
#ifndef UTEST
|
|
|
dc8c34 |
- rv = ACL_GetAttribute(errp, ACL_ATTR_IP, (void **)&ip,
|
|
|
dc8c34 |
- subject, resource, auth_info, global_auth);
|
|
|
dc8c34 |
+ rv = ACL_GetAttribute(errp, ACL_ATTR_IP, (void **)&client_addr, subject, resource, auth_info, global_auth);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if (rv != LAS_EVAL_TRUE) {
|
|
|
dc8c34 |
if (subject || resource) {
|
|
|
dc8c34 |
/* Don't ereport if called from ACL_CachableAclList */
|
|
|
dc8c34 |
- char rv_str[16];
|
|
|
dc8c34 |
- sprintf(rv_str, "%d", rv);
|
|
|
dc8c34 |
- nserrGenerate(errp, ACLERRINVAL, ACLERR5220, ACL_Program, 2, XP_GetAdminStr(DBT_lasipevalUnableToGetSessionAddre_), rv_str);
|
|
|
dc8c34 |
+ char rv_str[16];
|
|
|
dc8c34 |
+ sprintf(rv_str, "%d", rv);
|
|
|
dc8c34 |
+ nserrGenerate(errp, ACLERRINVAL, ACLERR5220, ACL_Program, 2,
|
|
|
dc8c34 |
+ XP_GetAdminStr(DBT_lasipevalUnableToGetSessionAddre_), rv_str);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- return LAS_EVAL_FAIL;
|
|
|
dc8c34 |
+ return LAS_EVAL_FAIL;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
#else
|
|
|
dc8c34 |
ip = (IPAddr_t)LASIpGetIp();
|
|
|
dc8c34 |
#endif
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- /* If this is the first time through, build the pattern tree first.
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * If this is the first time through, build the pattern tree first.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
if (*LAS_cookie == NULL) {
|
|
|
dc8c34 |
- if (strcspn(attr_pattern, "0123456789.*,+ \t")) {
|
|
|
dc8c34 |
+ if (strcspn(attr_pattern, "0123456789.*,+ \tABCDEFabcdef:/")) {
|
|
|
dc8c34 |
return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
ACL_CritEnter();
|
|
|
dc8c34 |
@@ -503,13 +549,14 @@ int LASIpEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
|
|
|
dc8c34 |
*LAS_cookie = context =
|
|
|
dc8c34 |
(LASIpContext_t *)PERM_MALLOC(sizeof(LASIpContext_t));
|
|
|
dc8c34 |
if (context == NULL) {
|
|
|
dc8c34 |
- nserrGenerate(errp, ACLERRNOMEM, ACLERR5230, ACL_Program, 1, XP_GetAdminStr(DBT_lasipevalUnableToAllocateContext_));
|
|
|
dc8c34 |
+ nserrGenerate(errp, ACLERRNOMEM, ACLERR5230, ACL_Program, 1,
|
|
|
dc8c34 |
+ XP_GetAdminStr(DBT_lasipevalUnableToAllocateContext_));
|
|
|
dc8c34 |
ACL_CritExit();
|
|
|
dc8c34 |
return LAS_EVAL_FAIL;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
context->treetop = NULL;
|
|
|
dc8c34 |
- retcode = LASIpBuild(errp, attr_name, comparator, attr_pattern,
|
|
|
dc8c34 |
- &context->treetop);
|
|
|
dc8c34 |
+ context->treetop_ipv6 = NULL;
|
|
|
dc8c34 |
+ retcode = LASIpBuild(errp, attr_name, comparator, attr_pattern, context);
|
|
|
dc8c34 |
if (retcode) {
|
|
|
dc8c34 |
ACL_CritExit();
|
|
|
dc8c34 |
return (retcode);
|
|
|
dc8c34 |
@@ -523,30 +570,194 @@ int LASIpEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
|
|
|
dc8c34 |
context = (LASIpContext *) *LAS_cookie;
|
|
|
dc8c34 |
ACL_CritExit();
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Check if IP is ipv4/ipv6
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ if ( PR_IsNetAddrType( client_addr, PR_IpAddrV4Mapped) || client_addr->raw.family == PR_AF_INET ) {
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * IPv4
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /* Set the appropriate s_addr for ipv4 or ipv4 mapped to ipv6 */
|
|
|
dc8c34 |
+ if (client_addr->raw.family == PR_AF_INET) {
|
|
|
dc8c34 |
+ client_inaddr.s_addr = client_addr->inet.ip;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ client_inaddr.s_addr = client_addr->ipv6.ip._S6_un._S6_u32[3];
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ node = context->treetop;
|
|
|
dc8c34 |
+ ip = (IPAddr_t)PR_ntohl( client_inaddr.s_addr );
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if(node == NULL){
|
|
|
dc8c34 |
+ rc = (comparator == CMP_OP_EQ ? LAS_EVAL_FALSE : LAS_EVAL_TRUE);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ for (bit = 31; bit >= 0; bit--) {
|
|
|
dc8c34 |
+ value = (ip & (IPAddr_t) (1 << bit)) ? 1 : 0;
|
|
|
dc8c34 |
+ if (LAS_IP_IS_CONSTANT(node->action[value])){
|
|
|
dc8c34 |
+ /* Reached a result, so return it */
|
|
|
dc8c34 |
+ if (comparator == CMP_OP_EQ){
|
|
|
dc8c34 |
+ rc = (int)(PRSize)node->action[value];
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ rc = ((int)(PRSize)node->action[value] == LAS_EVAL_TRUE) ? LAS_EVAL_FALSE : LAS_EVAL_TRUE;
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ /* Move on to the next bit */
|
|
|
dc8c34 |
+ node = node->action[value];
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if(rc == LAS_EVAL_INVALID){
|
|
|
dc8c34 |
+ sprintf(ip_str, "%x", (unsigned int)ip);
|
|
|
dc8c34 |
+ nserrGenerate(errp, ACLERRINTERNAL, ACLERR5240, ACL_Program, 2,
|
|
|
dc8c34 |
+ XP_GetAdminStr(DBT_lasipevalReach32BitsWithoutConcl_), ip_str);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * IPv6
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ PRIPv6Addr *ipv6 = &(client_addr->ipv6.ip);
|
|
|
dc8c34 |
+ LASIpTree_t *node;
|
|
|
dc8c34 |
+ int bit_position = 15;
|
|
|
dc8c34 |
+ int field = 0;
|
|
|
dc8c34 |
+ int addr = 0;
|
|
|
dc8c34 |
+ int value;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ node = context->treetop_ipv6;
|
|
|
dc8c34 |
+ if ( node == NULL ) {
|
|
|
dc8c34 |
+ retcode = (comparator == CMP_OP_EQ ? LAS_EVAL_FALSE : LAS_EVAL_TRUE);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ addr = PR_ntohs( ipv6->_S6_un._S6_u16[field]);
|
|
|
dc8c34 |
+ for (bit = 127; bit >= 0 ; bit--, bit_position--) {
|
|
|
dc8c34 |
+ value = (addr & (1 << bit_position)) ? 1 : 0;
|
|
|
dc8c34 |
+ if (LAS_IP_IS_CONSTANT(node->action[value])) {
|
|
|
dc8c34 |
+ /* Reached a result, so return it */
|
|
|
dc8c34 |
+ if (comparator == CMP_OP_EQ){
|
|
|
dc8c34 |
+ return(int)(long)node->action[value];
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ return(((int)(long)node->action[value] == LAS_EVAL_TRUE) ? LAS_EVAL_FALSE : LAS_EVAL_TRUE);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ node = node->action[value];
|
|
|
dc8c34 |
+ if ( bit % 16 == 0) {
|
|
|
dc8c34 |
+ /* Ok, move to the next field in the IPv6 addr: f:f:next:f:f:f:f:f */
|
|
|
dc8c34 |
+ field++;
|
|
|
dc8c34 |
+ addr = PR_ntohs( ipv6->_S6_un._S6_u16[field]);
|
|
|
dc8c34 |
+ bit_position = 15;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ rc = LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ return rc;
|
|
|
dc8c34 |
+}
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+/*
|
|
|
dc8c34 |
+ * The ipv6 version of LASIpAddPattern
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+static int
|
|
|
dc8c34 |
+LASIpAddPatternIPv6(NSErr_t *errp, int netmask, PRIPv6Addr *ipv6, LASIpTree_t **treetop)
|
|
|
dc8c34 |
+{
|
|
|
dc8c34 |
+ LASIpTree_t *curptr;
|
|
|
dc8c34 |
+ LASIpTree_t *newptr;
|
|
|
dc8c34 |
+ int stopbit;
|
|
|
dc8c34 |
+ int curbit;
|
|
|
dc8c34 |
+ int curval;
|
|
|
dc8c34 |
+ int field = 0; /* (8) 16 bit fields in a IPv6 address: x:x:x:x:x:x:x:x */
|
|
|
dc8c34 |
+ int addr = 0;
|
|
|
dc8c34 |
+ int curbit_position = 15; /* 16 bits: 0-15 */
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /* stop at the first 1 in the netmask from low to high */
|
|
|
dc8c34 |
+ stopbit = 128 - netmask;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- node = context->treetop;
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- for (bit=31; bit >=0; bit--) {
|
|
|
dc8c34 |
- value = (ip & (IPAddr_t) (1<
|
|
|
dc8c34 |
- if (LAS_IP_IS_CONSTANT(node->action[value])) {
|
|
|
dc8c34 |
- /* Reached a result, so return it */
|
|
|
dc8c34 |
- if (comparator == CMP_OP_EQ)
|
|
|
dc8c34 |
- return((int)(PRSize)node->action[value]);
|
|
|
dc8c34 |
- else
|
|
|
dc8c34 |
- return(((int)(PRSize)node->action[value] ==
|
|
|
dc8c34 |
- LAS_EVAL_TRUE) ?
|
|
|
dc8c34 |
- LAS_EVAL_FALSE : LAS_EVAL_TRUE);
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- } else
|
|
|
dc8c34 |
- /* Move on to the next bit */
|
|
|
dc8c34 |
- node = node->action[value];
|
|
|
dc8c34 |
+ /* Special case if there's no tree. Allocate the first node */
|
|
|
dc8c34 |
+ if (*treetop == (LASIpTree_t *)NULL) { /* No tree at all */
|
|
|
dc8c34 |
+ curptr = LASIpTreeAllocNode(errp);
|
|
|
dc8c34 |
+ if (curptr == NULL) {
|
|
|
dc8c34 |
+ nserrGenerate(errp, ACLERRFAIL, ACLERR5100, ACL_Program, 1,
|
|
|
dc8c34 |
+ XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_));
|
|
|
dc8c34 |
+ return ACL_RES_ERROR;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ *treetop = curptr;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ addr = PR_ntohs(ipv6->_S6_un._S6_u16[field]);
|
|
|
dc8c34 |
+ for (curbit = 127, curptr = *treetop; curbit >= 0; curbit--, curbit_position--){
|
|
|
dc8c34 |
+ /* Is the current bit ON? If so set curval to 1 else 0 */
|
|
|
dc8c34 |
+ curval = (addr & (1 << curbit_position)) ? 1 : 0;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /* Are we done, if so remove the rest of the tree */
|
|
|
dc8c34 |
+ if (curbit == stopbit) {
|
|
|
dc8c34 |
+ LASIpTreeDealloc(curptr->action[curval]);
|
|
|
dc8c34 |
+ curptr->action[curval] = (LASIpTree_t *)LAS_EVAL_TRUE;
|
|
|
dc8c34 |
+ /* This is the normal exit point. Most other exits must be due to errors. */
|
|
|
dc8c34 |
+ return 0;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /* Oops reached the end - must allocate */
|
|
|
dc8c34 |
+ if (LAS_IP_IS_CONSTANT(curptr->action[curval])) {
|
|
|
dc8c34 |
+ newptr = LASIpTreeAllocNode(errp);
|
|
|
dc8c34 |
+ if (newptr == NULL) {
|
|
|
dc8c34 |
+ LASIpTreeDealloc(*treetop);
|
|
|
dc8c34 |
+ nserrGenerate(errp, ACLERRFAIL, ACLERR5110, ACL_Program, 1,
|
|
|
dc8c34 |
+ XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_1));
|
|
|
dc8c34 |
+ return ACL_RES_ERROR;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ curptr->action[curval] = newptr;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /* Keep going down the tree */
|
|
|
dc8c34 |
+ curptr = curptr->action[curval];
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if ( curbit % 16 == 0) {
|
|
|
dc8c34 |
+ /* Ok, move to the next field in the addr */
|
|
|
dc8c34 |
+ field++;
|
|
|
dc8c34 |
+ addr = PR_ntohs(ipv6->_S6_un._S6_u16[field]);
|
|
|
dc8c34 |
+ curbit_position = 15;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ return ACL_RES_ERROR;
|
|
|
dc8c34 |
+}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- /* Cannot reach here. Even a 32 bit mismatch has a conclusion in
|
|
|
dc8c34 |
- * the pattern tree.
|
|
|
dc8c34 |
+/*
|
|
|
dc8c34 |
+ * This is very similar to dotdecimal(), but for ipv6 addresses
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+static int
|
|
|
dc8c34 |
+colonhex_ipv6(char *ipstr, char *netmaskstr, PRIPv6Addr *ipv6, int *netmask)
|
|
|
dc8c34 |
+{
|
|
|
dc8c34 |
+ PRNetAddr addr;
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Validate netmaskstr - can only be digits
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ if (strcspn(netmaskstr, "0123456789")){
|
|
|
dc8c34 |
+ return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Validate ipstr - can only have digits, colons, hex chars, and dots
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ if(strcspn(ipstr, "0123456789:ABCDEFabcdef.")){
|
|
|
dc8c34 |
+ return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * validate the netmask - must be between 1 and 128
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
- sprintf(ip_str, "%x", (unsigned int)ip);
|
|
|
dc8c34 |
- nserrGenerate(errp, ACLERRINTERNAL, ACLERR5240, ACL_Program, 2, XP_GetAdminStr(DBT_lasipevalReach32BitsWithoutConcl_), ip_str);
|
|
|
dc8c34 |
- return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ *netmask = atoi(netmaskstr);
|
|
|
dc8c34 |
+ if(*netmask < 1 || *netmask > 128){
|
|
|
dc8c34 |
+ return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Get the net addr
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ if (PR_StringToNetAddr(ipstr, &addr) != PR_SUCCESS){
|
|
|
dc8c34 |
+ return LAS_EVAL_INVALID;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Set the ipv6 addr
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ *ipv6 = addr.ipv6.ip;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ return 0;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/lib/libaccess/lasip.h b/lib/libaccess/lasip.h
|
|
|
dc8c34 |
index c353d9d..c1fe0fc 100644
|
|
|
dc8c34 |
--- a/lib/libaccess/lasip.h
|
|
|
dc8c34 |
+++ b/lib/libaccess/lasip.h
|
|
|
dc8c34 |
@@ -46,5 +46,6 @@ typedef struct LASIpTree {
|
|
|
dc8c34 |
} LASIpTree_t;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
typedef struct LASIpContext {
|
|
|
dc8c34 |
- LASIpTree_t *treetop; /* Top of the pattern tree */
|
|
|
dc8c34 |
+ LASIpTree_t *treetop; /* Top of the pattern tree */
|
|
|
dc8c34 |
+ LASIpTree_t *treetop_ipv6; /* Top of the IPv6 pattern tree */
|
|
|
dc8c34 |
} LASIpContext_t;
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
2.4.3
|
|
|
dc8c34 |
|