ldap/schema/01core389.ldif | 3
ldap/servers/slapd/fe.h | 21 ++++
ldap/servers/slapd/fedse.c | 67 ++++++-------
ldap/servers/slapd/sasl_map.c | 208 +++++++++++++++++++++++++++++-------------
ldap/servers/slapd/saslbind.c | 62 +++++++-----
5 files changed, 239 insertions(+), 122 deletions(-)
New commits:
commit 83f292c9b4e3f68482e9773c30ce96d6129fd68f
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Dec 21 17:24:29 2012 -0500
Ticket 534 - RFE: Add SASL mappings fallback
Bug Description: If the mapping fails to find an entry the bind fails without
checking if other mappings would also match.
Fix Description: Added the fallback functionality. Also added the ability to
prioritize
the mapping order, and to be able to modify the mappings while
the server is up.
https://fedorahosted.org/389/ticket/534
Reviewed by: noriko & richm (Thanks!)
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index fb707d3..d22edaa 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -113,6 +113,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.9999999 NAME
'nsds5debugreplicatimeout'
attributeTypes: ( 2.16.840.1.113730.3.1.2064 NAME 'nsSaslMapRegexString' DESC
'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2065 NAME 'nsSaslMapBaseDNTemplate' DESC
'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2066 NAME 'nsSaslMapFilterTemplate' DESC
'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2142 NAME 'nsSaslMapPriority' DESC
'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( nsCertfile-oid NAME 'nsCertfile' DESC 'Netscape defined
attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsKeyfile-oid NAME 'nsKeyfile' DESC 'Netscape defined
attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSL2-oid NAME 'nsSSL2' DESC 'Netscape defined attribute
type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
@@ -152,7 +153,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica'
DESC 'Netscape de
objectClasses: ( 2.16.840.1.113730.3.2.113 NAME 'nsTombstone' DESC 'Netscape
defined objectclass' SUP top MAY ( nsParentUniqueId $ nscpEntryDN ) X-ORIGIN
'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC
'Netscape defined objectclass' SUP top MUST ( cn ) MAY (
nsds5ReplicaCleanRUVNotified $ nsDS5ReplicaHost $ nsDS5ReplicaPort $
nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $
nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $
nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh
$ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $
nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $
nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress
$ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $
nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $
nsds5ReplicaStripAttrs $ nsds5replicaSessionPauseTime ) X-ORIGIN 'Netscape Directory
Server' )
objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape
defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server'
)
-objectClasses: ( 2.16.840.1.113730.3.2.317 NAME 'nsSaslMapping' DESC
'Netscape defined objectclass' SUP top MUST ( cn $ nsSaslMapRegexString $
nsSaslMapBaseDNTemplate $ nsSaslMapFilterTemplate ) X-ORIGIN 'Netscape Directory
Server' )
+objectClasses: ( 2.16.840.1.113730.3.2.317 NAME 'nsSaslMapping' DESC
'Netscape defined objectclass' SUP top MUST ( cn $ nsSaslMapRegexString $
nsSaslMapBaseDNTemplate $ nsSaslMapFilterTemplate ) MAY ( nsSaslMapPriority ) X-ORIGIN
'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.43 NAME 'nsSNMP' DESC 'Netscape
defined objectclass' SUP top MUST ( cn $ nsSNMPEnabled ) MAY ( nsSNMPOrganization $
nsSNMPLocation $ nsSNMPContact $ nsSNMPDescription $ nsSNMPName $ nsSNMPMasterHost $
nsSNMPMasterPort ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( nsEncryptionConfig-oid NAME 'nsEncryptionConfig' DESC
'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsCertfile $ nsKeyfile $
nsSSL2 $ nsSSL3 $ nsTLS1 $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $
nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers) X-ORIGIN 'Netscape' )
objectClasses: ( nsEncryptionModule-oid NAME 'nsEncryptionModule' DESC
'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsSSLToken $
nsSSLPersonalityssl $ nsSSLActivation ) X-ORIGIN 'Netscape' )
diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
index 3a985cb..d21d108 100644
--- a/ldap/servers/slapd/fe.h
+++ b/ldap/servers/slapd/fe.h
@@ -190,10 +190,29 @@ int sasl_io_cleanup(Connection *c, void *data);
/*
* sasl_map.c
*/
+typedef struct sasl_map_data_ sasl_map_data;
+struct sasl_map_data_ {
+ char *name;
+ char *regular_expression;
+ char *template_base_dn;
+ char *template_search_filter;
+ int priority;
+ sasl_map_data *next; /* For linked list */
+ sasl_map_data *prev;
+};
+
+typedef struct _sasl_map_private {
+ Slapi_RWLock *lock;
+ sasl_map_data *map_data_list;
+} sasl_map_private;
+
int sasl_map_config_add(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int
*returncode, char *returntext, void *arg);
int sasl_map_config_delete(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
int *returncode, char *returntext, void *arg);
-int sasl_map_domap(char *sasl_user, char *sasl_realm, char **ldap_search_base, char
**ldap_search_filter);
+int sasl_map_config_modify(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
int *returncode, char *returntext, void *arg);
+int sasl_map_domap(sasl_map_data **map, char *sasl_user, char *sasl_realm, char
**ldap_search_base, char **ldap_search_filter);
int sasl_map_init();
int sasl_map_done();
+void sasl_map_read_lock();
+void sasl_map_read_unlock();
#endif
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index dbfba16..5434c75 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -1767,7 +1767,7 @@ search_snmp(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
e, int *ret
int
setup_internal_backends(char *configdir)
{
- int rc = init_schema_dse(configdir);
+ int rc = init_schema_dse(configdir);
Slapi_DN config;
slapi_sdn_init_ndn_byref(&config,"cn=config");
@@ -1777,15 +1777,15 @@ setup_internal_backends(char *configdir)
rc= init_dse_file(configdir, &config);
}
- if(rc)
- {
+ if(rc)
+ {
Slapi_DN monitor;
Slapi_DN counters;
Slapi_DN snmp;
Slapi_DN root;
- Slapi_Backend *be;
- Slapi_DN encryption;
- Slapi_DN saslmapping;
+ Slapi_Backend *be;
+ Slapi_DN encryption;
+ Slapi_DN saslmapping;
slapi_sdn_init_ndn_byref(&monitor,"cn=monitor");
slapi_sdn_init_ndn_byref(&counters,"cn=counters,cn=monitor");
@@ -1795,50 +1795,51 @@ setup_internal_backends(char *configdir)
slapi_sdn_init_ndn_byref(&encryption,"cn=encryption,cn=config");
slapi_sdn_init_ndn_byref(&saslmapping,"cn=mapping,cn=sasl,cn=config");
- /* Search */
-
dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",read_config_dse,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_BASE,"(objectclass=*)",monitor_info,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",read_root_dse,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_SUBTREE,EGG_FILTER,search_easter_egg,NULL);
/* Egg */
-
dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&counters,LDAP_SCOPE_BASE,"(objectclass=*)",search_counters,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&snmp,LDAP_SCOPE_BASE,"(objectclass=*)",search_snmp,NULL);
+ /* Search */
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",read_config_dse,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_BASE,"(objectclass=*)",monitor_info,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",read_root_dse,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_SUBTREE,EGG_FILTER,search_easter_egg,NULL);
/* Egg */
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&counters,LDAP_SCOPE_BASE,"(objectclass=*)",search_counters,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&snmp,LDAP_SCOPE_BASE,"(objectclass=*)",search_snmp,NULL);
dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&encryption,LDAP_SCOPE_BASE,"(objectclass=*)",search_encryption,NULL);
- /* Modify */
-
dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",modify_config_dse,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_POSTOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",postop_modify_config_dse,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",modify_root_dse,NULL);
+ /* Modify */
+ dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",modify_config_dse,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_POSTOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",postop_modify_config_dse,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",modify_root_dse,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&saslmapping,LDAP_SCOPE_SUBTREE,"(objectclass=nsSaslMapping)",sasl_map_config_modify,NULL);
- /* Delete */
-
dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&counters,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&snmp,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
+ /* Delete */
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&counters,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&snmp,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&encryption,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
-
dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&saslmapping,LDAP_SCOPE_SUBTREE,"(objectclass=nsSaslMapping)",sasl_map_config_delete,NULL);
- /* Write */
-
dse_register_callback(pfedse,DSE_OPERATION_WRITE,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_SUBTREE,EGG_FILTER,dont_allow_that,NULL);
/* Egg */
+ /* Write */
+ dse_register_callback(pfedse,DSE_OPERATION_WRITE,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_SUBTREE,EGG_FILTER,dont_allow_that,NULL);
/* Egg */
+ /* Add */
dse_register_callback(pfedse,SLAPI_OPERATION_ADD,DSE_FLAG_PREOP,&saslmapping,LDAP_SCOPE_SUBTREE,"(objectclass=nsSaslMapping)",sasl_map_config_add,NULL);
- be= be_new_internal(pfedse, "DSE", DSE_BACKEND);
- be_addsuffix(be,&root);
- be_addsuffix(be,&monitor);
- be_addsuffix(be,&config);
+ be = be_new_internal(pfedse, "DSE", DSE_BACKEND);
+ be_addsuffix(be,&root);
+ be_addsuffix(be,&monitor);
+ be_addsuffix(be,&config);
add_internal_entries();
- add_easter_egg_entry();
+ add_easter_egg_entry();
slapi_sdn_done(&monitor);
slapi_sdn_done(&counters);
slapi_sdn_done(&snmp);
slapi_sdn_done(&root);
slapi_sdn_done(&saslmapping);
- } else {
+ } else {
slapi_log_error( SLAPI_LOG_FATAL, "dse",
"Please edit the file to correct the reported problems"
" and then restart the server.\n" );
@@ -1846,7 +1847,7 @@ setup_internal_backends(char *configdir)
}
slapi_sdn_done(&config);
- return rc;
+ return rc;
}
int fedse_create_startOK(char *filename, char *startokfilename, const char *configdir)
diff --git a/ldap/servers/slapd/sasl_map.c b/ldap/servers/slapd/sasl_map.c
index 7e7cfb8..96905ec 100644
--- a/ldap/servers/slapd/sasl_map.c
+++ b/ldap/servers/slapd/sasl_map.c
@@ -48,25 +48,9 @@
* Map SASL identities to LDAP searches
*/
-/*
- * We maintain a list of mappings to consult
- */
-
-typedef struct sasl_map_data_ sasl_map_data;
-struct sasl_map_data_ {
- char *name;
- char *regular_expression;
- char *template_base_dn;
- char *template_search_filter;
- sasl_map_data *next; /* For linked list */
-};
-
-typedef struct _sasl_map_private {
- PRLock *lock;
- sasl_map_data *map_data_list;
-} sasl_map_private;
-
static char * configDN = "cn=mapping,cn=sasl,cn=config";
+#define LOW_PRIORITY 100
+#define LOW_PRIORITY_STR "100"
/*
* DBDB: this is ugly, but right now there is _no_ server-wide
@@ -87,7 +71,7 @@ sasl_map_private *sasl_map_get_global_priv()
static
sasl_map_private *sasl_map_new_private()
{
- PRLock *new_lock = PR_NewLock();
+ Slapi_RWLock *new_lock = slapi_new_rwlock();
sasl_map_private *new_priv = NULL;
if (NULL == new_lock) {
return NULL;
@@ -100,20 +84,23 @@ sasl_map_private *sasl_map_new_private()
static void
sasl_map_free_private(sasl_map_private **priv)
{
- PR_DestroyLock((*priv)->lock);
+ slapi_destroy_rwlock((*priv)->lock);
slapi_ch_free((void**)priv);
*priv = NULL;
}
/* This function does a shallow copy on the payload data supplied, so the caller should
not free it, and it needs to be allocated using slapi_ch_malloc() */
static
-sasl_map_data *sasl_map_new_data(char *name, char *regex, char *dntemplate, char
*filtertemplate)
+sasl_map_data *sasl_map_new_data(char *name, char *regex, char *dntemplate, char
*filtertemplate, int priority)
{
sasl_map_data *new_dp = (sasl_map_data *) slapi_ch_calloc(1,sizeof(sasl_map_data));
new_dp->name = name;
new_dp->regular_expression = regex;
new_dp->template_base_dn = dntemplate;
new_dp->template_search_filter = filtertemplate;
+ new_dp->priority = priority;
+ new_dp->next = NULL;
+ new_dp->prev = NULL;
return new_dp;
}
@@ -139,31 +126,39 @@ sasl_map_remove_list_entry(sasl_map_private *priv, char *removeme)
int ret = 0;
int foundit = 0;
sasl_map_data *current = NULL;
- sasl_map_data *previous = NULL;
- PR_Lock(priv->lock);
+ sasl_map_data *prev = NULL;
+ sasl_map_data *next = NULL;
+
+ slapi_rwlock_wrlock(priv->lock);
current = priv->map_data_list;
while (current) {
+ next = current->next;
if (0 == strcmp(current->name,removeme)) {
foundit = 1;
- if (previous) {
+ prev = current->prev;
+ if (prev) {
/* Unlink it */
- previous->next = current->next;
+ if(next){
+ next->prev = prev;
+ }
+ prev->next = next;
} else {
/* That was the first list entry */
priv->map_data_list = current->next;
+ priv->map_data_list->prev = NULL;
}
/* Payload free */
sasl_map_free_data(¤t);
/* And no need to look further */
break;
}
- previous = current;
- current = current->next;
+ current = next;
}
+ slapi_rwlock_unlock(priv->lock);
if (!foundit) {
ret = -1;
}
- PR_Unlock(priv->lock);
+
return ret;
}
@@ -208,15 +203,21 @@ sasl_map_insert_list_entry(sasl_map_private *priv, sasl_map_data
*dp)
int ret = 0;
int ishere = 0;
sasl_map_data *current = NULL;
+ sasl_map_data *last = NULL;
+ sasl_map_data *prev = NULL;
+
if (NULL == dp) {
return ret;
}
- PR_Lock(priv->lock);
+
+ slapi_rwlock_wrlock(priv->lock);
+
/* Check to see if it's here already */
current = priv->map_data_list;
while (current) {
if (0 == sasl_map_cmp_data(current, dp)) {
ishere = 1;
+ break;
}
if (current->next) {
current = current->next;
@@ -225,15 +226,39 @@ sasl_map_insert_list_entry(sasl_map_private *priv, sasl_map_data
*dp)
}
}
if (ishere) {
+ slapi_rwlock_unlock(priv->lock);
return -1;
}
- /* current now points to the end of the list or NULL */
+
+ /* insert the map in its proper place */
if (NULL == priv->map_data_list) {
priv->map_data_list = dp;
} else {
- current->next = dp;
+ current = priv->map_data_list;
+ while (current) {
+ last = current;
+ if(current->priority > dp->priority){
+ prev = current->prev;
+ if(prev){
+ prev->next = dp;
+ dp->prev = prev;
+ } else {
+ /* this is now the head of the list */
+ priv->map_data_list = dp;
+ }
+ current->prev = dp;
+ dp->next = current;
+ slapi_rwlock_unlock(priv->lock);
+ return ret;
+ }
+ current = current->next;
+ }
+ /* add the map at the end of the list */
+ last->next = dp;
+ dp->prev = last;
}
- PR_Unlock(priv->lock);
+ slapi_rwlock_unlock(priv->lock);
+
return ret;
}
@@ -342,9 +367,11 @@ static int
sasl_map_config_parse_entry(Slapi_Entry *entry, sasl_map_data **new_dp)
{
int ret = 0;
+ int priority;
char *regex = NULL;
char *basedntemplate = NULL;
char *filtertemplate = NULL;
+ char *priority_str = NULL;
char *map_name = NULL;
*new_dp = NULL;
@@ -352,21 +379,43 @@ sasl_map_config_parse_entry(Slapi_Entry *entry, sasl_map_data
**new_dp)
basedntemplate = slapi_entry_attr_get_charptr( entry,
"nsSaslMapBaseDNTemplate" );
filtertemplate = slapi_entry_attr_get_charptr( entry,
"nsSaslMapFilterTemplate" );
map_name = slapi_entry_attr_get_charptr( entry, "cn" );
+ priority_str = slapi_entry_attr_get_charptr( entry, "nsSaslMapPriority" );
+ if(priority_str){
+ priority = atoi(priority_str);
+ } else {
+ priority = LOW_PRIORITY;
+ }
+ if(priority == 0 || priority > LOW_PRIORITY){
+ struct berval desc;
+ struct berval *newval[2] = {0, 0};
+
+ desc.bv_val = LOW_PRIORITY_STR;
+ desc.bv_len = strlen(desc.bv_val);
+ newval[0] = &desc;
+ if (entry_replace_values(entry, "nsSaslMapPriority", newval) != 0){
+ LDAPDebug( LDAP_DEBUG_TRACE, "sasl_map_config_parse_entry: failed to reset
priority to (%d)\n",
+ LOW_PRIORITY,0,0);
+ } else {
+ LDAPDebug( LDAP_DEBUG_ANY, "sasl_map_config_parse_entry: resetting
nsSaslMapPriority to lowest priority(%d)\n",
+ LOW_PRIORITY,0,0);
+ }
+ priority = LOW_PRIORITY;
+ }
if ( (NULL == map_name) || (NULL == regex) ||
(NULL == basedntemplate) || (NULL == filtertemplate) ) {
/* Invalid entry */
ret = -1;
} else {
/* Make the new dp */
- *new_dp = sasl_map_new_data(map_name, regex, basedntemplate, filtertemplate);
+ *new_dp = sasl_map_new_data(map_name, regex, basedntemplate, filtertemplate,
priority);
}
if (ret) {
- slapi_ch_free((void **) &map_name);
- slapi_ch_free((void **) ®ex);
- slapi_ch_free((void **) &basedntemplate);
- slapi_ch_free((void **) &filtertemplate);
+ slapi_ch_free_string(&map_name);
+ slapi_ch_free_string(®ex);
+ slapi_ch_free_string(&basedntemplate);
+ slapi_ch_free_string(&filtertemplate);
}
return ret;
}
@@ -431,6 +480,35 @@ sasl_map_config_add(Slapi_PBlock *pb, Slapi_Entry* entryBefore,
Slapi_Entry* e,
}
int
+sasl_map_config_modify(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int
*returncode, char *returntext, void *arg)
+{
+ sasl_map_private *priv = sasl_map_get_global_priv();
+ sasl_map_data *dp;
+ char *map_name = NULL;
+ int ret = SLAPI_DSE_CALLBACK_ERROR;
+
+ if((map_name = slapi_entry_attr_get_charptr( entryBefore, "cn" )) == NULL){
+ LDAPDebug( LDAP_DEBUG_TRACE, "sasl_map_config_modify: could not find name of
map\n",0,0,0);
+ return ret;
+ }
+ if(sasl_map_remove_list_entry(priv, map_name) == 0){
+ ret = sasl_map_config_parse_entry(e, &dp);
+ if (!ret && dp) {
+ ret = sasl_map_insert_list_entry(priv, dp);
+ if(ret == 0){
+ ret = SLAPI_DSE_CALLBACK_OK;
+ }
+ }
+ }
+ if(ret == SLAPI_DSE_CALLBACK_ERROR){
+ LDAPDebug( LDAP_DEBUG_TRACE, "sasl_map_config_modify: failed to update
map(%s)\n",map_name,0,0);
+ }
+ slapi_ch_free_string(&map_name);
+
+ return ret;
+}
+
+int
sasl_map_config_delete(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int
*returncode, char *returntext, void *arg)
{
int ret = 0;
@@ -485,30 +563,20 @@ int sasl_map_done()
}
/* Free the map list */
- PR_Lock(priv->lock);
+ slapi_rwlock_wrlock(priv->lock);
dp = priv->map_data_list;
while (dp) {
sasl_map_data *dp_next = dp->next;
sasl_map_free_data(&dp);
dp = dp_next;
}
- PR_Unlock(priv->lock);
+ slapi_rwlock_unlock(priv->lock);
/* Free the private structure */
sasl_map_free_private(&priv);
return ret;
}
-static sasl_map_data*
-sasl_map_first(sasl_map_private *priv)
-{
- sasl_map_data *result = NULL;
- PR_Lock(priv->lock);
- result = priv->map_data_list;
- PR_Unlock(priv->lock);
- return result;
-}
-
static int
sasl_map_check(sasl_map_data *dp, char *sasl_user_and_realm, char **ldap_search_base,
char **ldap_search_filter)
{
@@ -610,28 +678,31 @@ sasl_map_str_concat(char *s1, char *s2)
* returns 1 if matched, 0 otherwise
*/
int
-sasl_map_domap(char *sasl_user, char *sasl_realm, char **ldap_search_base, char
**ldap_search_filter)
+sasl_map_domap(sasl_map_data **map, char *sasl_user, char *sasl_realm, char
**ldap_search_base, char **ldap_search_filter)
{
- int ret = 0;
- sasl_map_data *this_map = NULL;
- char *sasl_user_and_realm = NULL;
sasl_map_private *priv = sasl_map_get_global_priv();
+ char *sasl_user_and_realm = NULL;
+ int ret = 0;
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "-> sasl_map_domap\n", 0, 0, 0 );
+ if(map == NULL){
+ LDAPDebug( LDAP_DEBUG_TRACE, "<- sasl_map_domap: Internal error, mapping is
NULL\n",0,0,0);
+ return ret;
+ }
*ldap_search_base = NULL;
*ldap_search_filter = NULL;
- LDAPDebug( LDAP_DEBUG_TRACE, "-> sasl_map_domap\n", 0, 0, 0 );
sasl_user_and_realm = sasl_map_str_concat(sasl_user,sasl_realm);
/* Walk the list of maps */
- this_map = sasl_map_first(priv);
- while (this_map) {
- int matched = 0;
+ if(*map == NULL)
+ *map = priv->map_data_list;
+ while (*map) {
/* If one matches, then make the search params */
- LDAPDebug( LDAP_DEBUG_TRACE, "sasl_map_domap - trying map [%s]\n",
this_map->name, 0, 0 );
- matched = sasl_map_check(this_map, sasl_user_and_realm, ldap_search_base,
ldap_search_filter);
- if (1 == matched) {
- ret = 1;
+ LDAPDebug( LDAP_DEBUG_TRACE, "sasl_map_domap - trying map [%s]\n",
(*map)->name, 0, 0 );
+ if((ret = sasl_map_check(*map, sasl_user_and_realm, ldap_search_base,
ldap_search_filter))){
+ *map = sasl_map_next(*map);
break;
}
- this_map = sasl_map_next(this_map);
+ *map = sasl_map_next(*map);
}
if (sasl_user_and_realm) {
slapi_ch_free((void**)&sasl_user_and_realm);
@@ -640,3 +711,16 @@ sasl_map_domap(char *sasl_user, char *sasl_realm, char
**ldap_search_base, char
return ret;
}
+void
+sasl_map_read_lock()
+{
+ sasl_map_private *priv = sasl_map_get_global_priv();
+ slapi_rwlock_rdlock(priv->lock);
+}
+
+void
+sasl_map_read_unlock()
+{
+ sasl_map_private *priv = sasl_map_get_global_priv();
+ slapi_rwlock_unlock(priv->lock);
+}
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
index f9ddbfc..6181474 100644
--- a/ldap/servers/slapd/saslbind.c
+++ b/ldap/servers/slapd/saslbind.c
@@ -323,14 +323,15 @@ static Slapi_Entry *ids_sasl_user_to_entry(
const char *user_realm
)
{
- int found = 0;
- int attrsonly = 0, scope = LDAP_SCOPE_SUBTREE;
LDAPControl **ctrls = NULL;
+ sasl_map_data *map = NULL;
Slapi_Entry *entry = NULL;
char **attrs = NULL;
- int regexmatch = 0;
char *base = NULL;
char *filter = NULL;
+ int attrsonly = 0, scope = LDAP_SCOPE_SUBTREE;
+ int regexmatch = 0;
+ int found = 0;
/* Check for wildcards in the authid and realm. If we encounter one,
* just fail the mapping without performing a costly internal search. */
@@ -345,31 +346,42 @@ static Slapi_Entry *ids_sasl_user_to_entry(
}
/* New regex-based identity mapping */
- regexmatch = sasl_map_domap((char*)user, (char*)user_realm, &base, &filter);
- if (regexmatch) {
- ids_sasl_user_search(base, scope, filter,
- ctrls, attrs, attrsonly,
- &entry, &found);
-
- if (found == 1) {
- LDAPDebug(LDAP_DEBUG_TRACE, "sasl user search found this entry: dn:%s,
"
- "matching filter=%s\n", entry->e_sdn.dn, filter, 0);
- } else if (found == 0) {
- LDAPDebug(LDAP_DEBUG_TRACE, "sasl user search found no entries matching
"
- "filter=%s\n", filter, 0, 0);
- } else {
- LDAPDebug(LDAP_DEBUG_TRACE, "sasl user search found more than one entry
"
- "matching filter=%s\n", filter, 0, 0);
- if (entry) {
- slapi_entry_free(entry);
- entry = NULL;
+ sasl_map_read_lock();
+ while(1){
+ regexmatch = sasl_map_domap(&map, (char*)user, (char*)user_realm, &base,
&filter);
+ if (regexmatch) {
+ ids_sasl_user_search(base, scope, filter,
+ ctrls, attrs, attrsonly,
+ &entry, &found);
+ if (found == 1) {
+ LDAPDebug(LDAP_DEBUG_TRACE, "sasl user search found this entry:
dn:%s, "
+ "matching filter=%s\n", entry->e_sdn.dn, filter, 0);
+ } else if (found == 0) {
+ LDAPDebug(LDAP_DEBUG_TRACE, "sasl user search found no entries
matching "
+ "filter=%s\n", filter, 0, 0);
+ } else {
+ LDAPDebug(LDAP_DEBUG_TRACE, "sasl user search found more than one
entry "
+ "matching filter=%s\n", filter, 0, 0);
+ if (entry) {
+ slapi_entry_free(entry);
+ entry = NULL;
+ }
}
- }
- /* Free the filter etc */
- slapi_ch_free_string(&base);
- slapi_ch_free_string(&filter);
+ /* Free the filter etc */
+ slapi_ch_free_string(&base);
+ slapi_ch_free_string(&filter);
+
+ /* If we didn't find an entry, look at the other maps */
+ if(found){
+ break;
+ }
+ }
+ if(map == NULL){
+ break;
+ }
}
+ sasl_map_read_unlock();
return entry;
}