ldap/servers
by Noriko Hosoi
ldap/servers/plugins/acl/acl.c | 77 +++++++++++++++++++++++-------------
ldap/servers/plugins/acl/acl.h | 5 +-
ldap/servers/plugins/acl/aclgroup.c | 2
ldap/servers/plugins/acl/acllist.c | 48 +++++++++++++---------
ldap/servers/slapd/dn.c | 2
ldap/servers/slapd/plugin_acl.c | 30 ++++++++++----
6 files changed, 106 insertions(+), 58 deletions(-)
New commits:
commit 5beb93d42efb807838c09c5fab898876876f8d09
Author: Noriko Hosoi <nhosoi(a)totoro.usersys.redhat.com>
Date: Fri Sep 21 12:35:18 2012 -0700
Trac Ticket #340 - Change on SLAPI_MODRDN_NEWSUPERIOR is not
evaluated in acl
https://fedorahosted.org/389/ticket/340
Bug Description: When modrdn operation was executed, only newrdn
change was passed to the acl plugin. Also, the change was used
only for the acl search, but not for the acl target in the items
in the acl cache.
Fix Description: This patch also passes the newsuperior update
to the acl plugin. And the modrdn updates are applied to the
acl target in the acl cache.
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index 15e474e..3389404 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -170,9 +170,9 @@ acl_access_allowed_modrdn(
* Test if have access to make the first rdn of dn in entry e.
*/
-static int check_rdn_access( Slapi_PBlock *pb, Slapi_Entry *e, const char *dn,
- int access) {
-
+static int
+check_rdn_access( Slapi_PBlock *pb, Slapi_Entry *e, const char *dn, int access)
+{
char **dns;
char **rdns;
int retCode = LDAP_INSUFFICIENT_ACCESS;
@@ -655,7 +655,8 @@ cleanup_and_ret:
}
-static void print_access_control_summary( char *source, int ret_val, char *clientDn,
+static void
+print_access_control_summary( char *source, int ret_val, char *clientDn,
struct acl_pblock *aclpb,
char *right,
char *attr,
@@ -1524,11 +1525,12 @@ acl_check_mods(
*
**************************************************************************/
extern void
-acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
+acl_modified (Slapi_PBlock *pb, int optype, Slapi_DN *e_sdn, void *change)
{
struct berval **bvalue;
char **value;
int rv=0; /* returned value */
+ const char* n_dn;
char* new_RDN;
char* parent_DN;
char* new_DN;
@@ -1537,10 +1539,12 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
int j;
Slapi_Attr *attr = NULL;
Slapi_Entry *e = NULL;
- Slapi_DN *e_sdn;
aclUserGroup *ugroup = NULL;
- e_sdn = slapi_sdn_new_normdn_byval ( n_dn );
+ if (NULL == e_sdn) {
+ return;
+ }
+ n_dn = slapi_sdn_get_dn(e_sdn);
/* Before we proceed, Let's first check if we are changing any groups.
** If we are, then we need to change the signature
*/
@@ -1768,45 +1772,64 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
}
break;
- }/* case op is modify*/
+ }/* case op is modify*/
- case SLAPI_OPERATION_MODRDN:
-
- new_RDN = (char*) change;
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acl_modified (MODRDN %s => \"%s\"\n",
- n_dn, new_RDN);
+ case SLAPI_OPERATION_MODRDN:
+ {
+ char **rdn_parent;
+ rdn_parent = (char **)change;
+ new_RDN = rdn_parent[0];
+ parent_DN = rdn_parent[1];
/* compute new_DN: */
- parent_DN = slapi_dn_parent (n_dn);
- if (parent_DN == NULL) {
- new_DN = new_RDN;
+ if (NULL == parent_DN) {
+ parent_DN = slapi_dn_parent(n_dn);
+ }
+ if (NULL == parent_DN) {
+ if (NULL == new_RDN) {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acl_modified (MODRDN %s => \"no change\"\n",
+ n_dn);
+ break;
+ } else {
+ new_DN = new_RDN;
+ }
} else {
- new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
+ if (NULL == new_RDN) {
+ Slapi_RDN *rdn= slapi_rdn_new();
+ slapi_sdn_get_rdn(e_sdn, rdn);
+ new_DN = slapi_create_dn_string("%s,%s", slapi_rdn_get_rdn(rdn),
+ parent_DN);
+ slapi_rdn_free(&rdn);
+ } else {
+ new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
+ }
}
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acl_modified (MODRDN %s => \"%s\"\n", n_dn, new_RDN);
/* Change the acls */
- acllist_acicache_WRITE_LOCK();
+ acllist_acicache_WRITE_LOCK();
/* acllist_moddn_aci_needsLock expects normalized new_DN,
* which is no need to be case-ignored */
acllist_moddn_aci_needsLock ( e_sdn, new_DN );
acllist_acicache_WRITE_UNLOCK();
/* deallocat the parent_DN */
- if (parent_DN != NULL) {
- slapi_ch_free ( (void **) &new_DN );
- slapi_ch_free ( (void **) &parent_DN );
+ if (parent_DN != NULL) {
+ slapi_ch_free_string(&new_DN);
+ if (parent_DN != rdn_parent[1]) {
+ slapi_ch_free_string(&parent_DN);
+ }
}
break;
-
- default:
+ } /* case op is modrdn */
+ default:
/* print ERROR */
break;
} /*optype switch */
-
- slapi_sdn_free ( &e_sdn );
-
}
+
/***************************************************************************
*
* acl__scan_for_acis
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index 4fa3e3f..28c38e7 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -796,7 +796,8 @@ int acl_read_access_allowed_on_attr ( Slapi_PBlock *pb, Slapi_Entry *e, char
struct berval *val, int access);
void acl_set_acllist (Slapi_PBlock *pb, int scope, char *base);
void acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf);
-void acl_modified ( Slapi_PBlock *pb, int optype, char *dn, void *change);
+void acl_modified (Slapi_PBlock *pb, int optype, Slapi_DN *e_sdn, void *change);
+
int acl_access_allowed_disjoint_resource( Slapi_PBlock *pb, Slapi_Entry *e,
char *attr, struct berval *val, int access );
int acl_access_allowed_main ( Slapi_PBlock *pb, Slapi_Entry *e, char **attrs,
@@ -866,7 +867,7 @@ void acllist_print_tree ( Avlnode *root, int *depth, char *start, char *side);
AciContainer *acllist_get_aciContainer_new ( );
void acllist_done_aciContainer ( AciContainer *);
-aclUserGroup* aclg_find_userGroup (char *n_dn);
+aclUserGroup* aclg_find_userGroup (const char *n_dn);
void aclg_regen_ugroup_signature( aclUserGroup *ugroup);
void aclg_markUgroupForRemoval ( aclUserGroup *u_group );
void aclg_reader_incr_ugroup_refcnt(aclUserGroup* u_group);
diff --git a/ldap/servers/plugins/acl/aclgroup.c b/ldap/servers/plugins/acl/aclgroup.c
index c694293..2231304 100644
--- a/ldap/servers/plugins/acl/aclgroup.c
+++ b/ldap/servers/plugins/acl/aclgroup.c
@@ -213,7 +213,7 @@ aclg_reset_userGroup ( struct acl_pblock *aclpb )
*/
aclUserGroup*
-aclg_find_userGroup(char *n_dn)
+aclg_find_userGroup(const char *n_dn)
{
aclUserGroup *u_group = NULL;
int i;
diff --git a/ldap/servers/plugins/acl/acllist.c b/ldap/servers/plugins/acl/acllist.c
index 9b5363a..e8198af 100644
--- a/ldap/servers/plugins/acl/acllist.c
+++ b/ldap/servers/plugins/acl/acllist.c
@@ -600,7 +600,6 @@ void
acllist_init_scan (Slapi_PBlock *pb, int scope, const char *base)
{
Acl_PBlock *aclpb;
- int i;
AciContainer *root;
char *basedn = NULL;
int index;
@@ -671,11 +670,6 @@ acllist_init_scan (Slapi_PBlock *pb, int scope, const char *base)
aclpb->aclpb_state &= ~ACLPB_SEARCH_BASED_ON_LIST ;
acllist_acicache_READ_UNLOCK();
-
- i = 0;
- while ( i < aclpb_max_selected_acls && aclpb->aclpb_base_handles_index[i] != -1 ) {
- i++;
- }
}
/*
@@ -893,34 +887,50 @@ acllist_acicache_WRITE_LOCK( )
int
acllist_moddn_aci_needsLock ( Slapi_DN *oldsdn, char *newdn )
{
-
-
AciContainer *aciListHead;
AciContainer *head;
+ aci_t *acip;
+ const char *oldndn;
/* first get the container */
aciListHead = acllist_get_aciContainer_new ( );
slapi_sdn_free(&aciListHead->acic_sdn);
- aciListHead->acic_sdn = oldsdn;
-
+ aciListHead->acic_sdn = oldsdn;
if ( NULL == (head = (AciContainer *) avl_find( acllistRoot, aciListHead,
- (IFP) __acllist_aciContainer_node_cmp ) ) ) {
+ (IFP) __acllist_aciContainer_node_cmp ) ) ) {
slapi_log_error ( SLAPI_PLUGIN_ACL, plugin_name,
- "Can't find the acl in the tree for moddn operation:olddn%s\n",
- slapi_sdn_get_ndn ( oldsdn ));
+ "Can't find the acl in the tree for moddn operation:olddn%s\n",
+ slapi_sdn_get_ndn ( oldsdn ));
aciListHead->acic_sdn = NULL;
__acllist_free_aciContainer ( &aciListHead );
- return 1;
+ return 1;
}
-
- /* Now set the new DN */
- slapi_sdn_done ( head->acic_sdn );
- slapi_sdn_set_normdn_byval ( head->acic_sdn, newdn );
-
+ /* Now set the new DN */
+ slapi_sdn_set_normdn_byval(head->acic_sdn, newdn);
+
+ /* If necessary, reset the target DNs, as well. */
+ oldndn = slapi_sdn_get_ndn(oldsdn);
+ for (acip = head->acic_list; acip; acip = acip->aci_next) {
+ const char *ndn = slapi_sdn_get_ndn(acip->aci_sdn);
+ char *p = PL_strstr(ndn, oldndn);
+ if (p) {
+ if (p == ndn) {
+ /* target dn is identical, replace it with new DN*/
+ slapi_sdn_set_normdn_byval(acip->aci_sdn, newdn);
+ } else {
+ /* target dn is a descendent of olddn, merge it with new DN*/
+ char *mynewdn;
+ *p = '\0';
+ mynewdn = slapi_ch_smprintf("%s%s", ndn, newdn);
+ slapi_sdn_set_normdn_passin(acip->aci_sdn, mynewdn);
+ }
+ }
+ }
+
aciListHead->acic_sdn = NULL;
__acllist_free_aciContainer ( &aciListHead );
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 11e56a9..b79d0f2 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -2097,7 +2097,7 @@ slapi_sdn_set_normdn_byval(Slapi_DN *sdn, const char *normdn)
slapi_sdn_done(sdn);
sdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
if(normdn == NULL) {
- sdn->dn = slapi_ch_strdup(normdn);
+ sdn->dn = NULL;
sdn->ndn_len = 0;
} else {
sdn->dn = slapi_ch_strdup(normdn);
diff --git a/ldap/servers/slapd/plugin_acl.c b/ldap/servers/slapd/plugin_acl.c
index b878156..3bc3f21 100644
--- a/ldap/servers/slapd/plugin_acl.c
+++ b/ldap/servers/slapd/plugin_acl.c
@@ -134,11 +134,10 @@ int
plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
{
struct slapdplugin *p;
- char *dn;
int rc = 0;
- void *change = NULL;
- Slapi_Entry *te = NULL;
- Slapi_DN *sdn = NULL;
+ void *change = NULL;
+ Slapi_Entry *te = NULL;
+ Slapi_DN *sdn = NULL;
Operation *operation;
slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
@@ -146,7 +145,7 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
(void)slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
switch ( optype ) {
- case SLAPI_OPERATION_MODIFY:
+ case SLAPI_OPERATION_MODIFY:
(void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
break;
case SLAPI_OPERATION_ADD:
@@ -158,11 +157,27 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
}
break;
case SLAPI_OPERATION_MODRDN:
+ {
+ void *mychange[2];
+ char *newrdn = NULL;
+ Slapi_DN *psdn = NULL;
+ char *pdn = NULL;
+
/* newrdn: "change" is normalized but not case-ignored */
/* The acl plugin expects normalized newrdn, but no need to be case-
* ignored. */
- (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &change );
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn );
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &psdn );
+ if (psdn) {
+ pdn = (char *)slapi_sdn_get_dn(psdn);
+ } else {
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR, &pdn );
+ }
+ mychange[0] = newrdn;
+ mychange[1] = pdn;
+ change = mychange;
break;
+ }
}
if (NULL == sdn) {
@@ -172,10 +187,9 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
}
/* call the global plugins first and then the backend specific */
- dn = (char*)slapi_sdn_get_ndn(sdn); /* jcm - Had to cast away const */
for ( p = get_plugin_list(PLUGIN_LIST_ACL); p != NULL; p = p->plg_next ) {
if (plugin_invoke_plugin_sdn(p, SLAPI_PLUGIN_ACL_MODS_UPDATE, pb, sdn)){
- rc = (*p->plg_acl_mods_update)(pb, optype, dn, change );
+ rc = (*p->plg_acl_mods_update)(pb, optype, sdn, change );
if ( rc != LDAP_SUCCESS ) break;
}
}
11 years
Branch '389-ds-base-1.2.11' - ldap/servers
by Mark Reynolds
ldap/servers/plugins/rootdn_access/rootdn_access.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
New commits:
commit 2689bcbcaf4ea4b91c5b5f1c03af3dc676bb93a4
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Sep 21 16:05:55 2012 -0400
Ticket 474 - Root DN Access Control - days allowed not working correctly
Bug Description: If you set more than one day in the rootdn-days-allowed config
attribute the plugin can reject all rootDN binds.
Fix Description: Correct the order of the char strings in strstr().
https://fedorahosted.org/389/ticket/474
Reviewed by: richm(Thanks!)
diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c
index 19e578c..bae2703 100644
--- a/ldap/servers/plugins/rootdn_access/rootdn_access.c
+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c
@@ -440,8 +440,9 @@ rootdn_check_access(Slapi_PBlock *pb){
memmove(day, timestr, 3); // we only want the day
today = strToLower(today);
- if(!strstr(today, daysAllowed)){
- slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: bind not allowed for today\n");
+ if(!strstr(daysAllowed, today)){
+ slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: bind not allowed for today(%s), "
+ "only allowed on days: %s\n", today, daysAllowed);
return -1;
}
}
11 years
ldap/servers
by Mark Reynolds
ldap/servers/plugins/rootdn_access/rootdn_access.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
New commits:
commit 940ac98613957b69c3b32e47ed50cd25d5a80542
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Sep 21 15:33:45 2012 -0400
Ticket 747 - Root DN Access Control - days allowed not working correctly
Bug Description: If you set more than one day in the rootdn-days-allowed config
attribute the plugin can reject all rootDN binds.
Fix Description: Correct the order of the char strings in strstr().
https://fedorahosted.org/389/ticket/474
Reviewed by: richm(Thanks!)
diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c
index 19e578c..bae2703 100644
--- a/ldap/servers/plugins/rootdn_access/rootdn_access.c
+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c
@@ -440,8 +440,9 @@ rootdn_check_access(Slapi_PBlock *pb){
memmove(day, timestr, 3); // we only want the day
today = strToLower(today);
- if(!strstr(today, daysAllowed)){
- slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: bind not allowed for today\n");
+ if(!strstr(daysAllowed, today)){
+ slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: bind not allowed for today(%s), "
+ "only allowed on days: %s\n", today, daysAllowed);
return -1;
}
}
11 years
Branch '389-ds-base-1.2.11' - ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/repl5.h | 1
ldap/servers/plugins/replication/repl5_replica.c | 4
ldap/servers/plugins/replication/repl5_replica_config.c | 68 +++++++++++-----
ldap/servers/plugins/replication/repl_extop.c | 5 +
4 files changed, 60 insertions(+), 18 deletions(-)
New commits:
commit 822199e809b6100dfd908eb308eacf81956b3f34
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Sep 21 12:49:09 2012 -0400
Ticket 467 - CLEANALLRUV abort task should be able to ignore down replicas
Bug Description: The abort task previously would wait for all the replicas to be online,
and receive the extended op task. This made it impossible to abort the
cleanallruv task, if you wanted to abort because a server was down.
Fix Description: Changed the default behavior to ignore down replicas, and added a new attribute
to the abort task entry: replica-certify-all: (yes,no). Default is "no". If
set to "yes", then it will wait until all the replicas have received the abort task.
Also fixed a crash caused by running the abort task agsint a server that does not have
replication setup. The crashed was caused by freeing uninitialized pointers.
https://fedorahosted.org/389/ticket/467
Reviewed by: richm(Thanks!)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 7b6cb8c..61b51b0 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -642,6 +642,7 @@ typedef struct _cleanruv_data
CSN *maxcsn;
char *repl_root;
Slapi_DN *sdn;
+ char *certify;
} cleanruv_data;
/* replutil.c */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 9e0fb24..2b1d958 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1914,6 +1914,7 @@ done:
char *ridstr = NULL;
char *repl_root;
char *token = NULL;
+ char *certify = NULL;
ReplicaId rid;
int i;
@@ -1935,6 +1936,7 @@ done:
}
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
+ certify = ldap_utf8strtok_r(iter, ":", &iter);
stop_ruv_cleaning();
maxcsn = replica_get_cleanruv_maxcsn(r, rid);
delete_cleaned_rid(r, rid, maxcsn);
@@ -1966,6 +1968,7 @@ done:
data->payload = payload;
data->repl_root = slapi_ch_strdup(repl_root);
data->sdn = slapi_sdn_dup(r->repl_root);
+ data->certify = slapi_ch_strdup(certify);
thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
@@ -1976,6 +1979,7 @@ done:
slapi_sdn_free(&data->sdn);
ber_bvfree(data->payload);
slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free_string(&data->certify);
slapi_ch_free((void **)&data);
}
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index f22d2de..9d47100 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1262,7 +1262,8 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id (%d) for task - (%s)",
rid, slapi_sdn_get_dn(task_dn));
cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
- rc = LDAP_OPERATIONS_ERROR;
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
/*
@@ -1270,7 +1271,9 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
*/
dn = slapi_sdn_new_dn_byval(base_dn);
if((r = replica_get_replica_from_dn(dn)) == NULL){
- *returncode = LDAP_OPERATIONS_ERROR ;
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Could not find replica from dn(%s)",slapi_sdn_get_dn(dn));
+ cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
+ *returncode = LDAP_OPERATIONS_ERROR;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
@@ -1281,9 +1284,7 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
out:
if(rc){
cleanruv_log(task, CLEANALLRUV_ID, "Task failed...(%d)", rc);
- *returncode = rc;
slapi_task_finish(task, *returncode);
- rc = SLAPI_DSE_CALLBACK_ERROR;
} else {
rc = SLAPI_DSE_CALLBACK_OK;
}
@@ -2182,18 +2183,19 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
Replica *replica;
ReplicaId rid;
cleanruv_data *data = NULL;
- Slapi_DN *sdn;
+ Slapi_DN *sdn = NULL;
Object *r;
- CSN *maxcsn;
+ CSN *maxcsn = NULL;
const char *base_dn;
const char *rid_str;
- char *ridstr;
+ const char *certify_all;
+ char *ridstr = NULL;
int rc = SLAPI_DSE_CALLBACK_OK;
if(get_abort_cleanruv_task_count() >= CLEANRIDSIZ){
/* we are already running the maximum number of tasks */
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,
- "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OPERATIONS_ERROR;
return SLAPI_DSE_CALLBACK_ERROR;
}
@@ -2204,17 +2206,20 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
* Get our task settings
*/
if ((rid_str = fetch_attr(e, "replica-id", 0)) == NULL){
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Missing required attr \"replica-id\"");
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Missing required attr \"replica-id\"");
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
if ((base_dn = fetch_attr(e, "replica-base-dn", 0)) == NULL){
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Missing required attr \"replica-base-dn\"");
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Missing required attr \"replica-base-dn\"");
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
+ certify_all = fetch_attr(e, "replica-certify-all", 0);
/*
* Check the rid
*/
@@ -2232,15 +2237,31 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
*/
sdn = slapi_sdn_new_dn_byval(base_dn);
if((r = replica_get_replica_from_dn(sdn)) == NULL){
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Failed to find replica from dn(%s)", base_dn);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Failed to find replica from dn(%s)", base_dn);
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OPERATIONS_ERROR;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
/*
+ * Check verify value
+ */
+ if(certify_all){
+ if(strcasecmp(certify_all,"yes") && strcasecmp(certify_all,"no")){
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid value for \"replica-certify-all\", the value "
+ "must be \"yes\" or \"no\".");
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ } else {
+ certify_all = "no";
+ }
+ /*
* Create payload
*/
- ridstr = slapi_ch_smprintf("%d:%s", rid, base_dn);
+ ridstr = slapi_ch_smprintf("%d:%s:%s", rid, base_dn, certify_all);
payload = create_ruv_payload(ridstr);
if(payload == NULL){
@@ -2274,6 +2295,7 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
data->rid = rid;
data->repl_root = slapi_ch_strdup(base_dn);
data->sdn = NULL;
+ data->certify = slapi_ch_strdup(certify_all);
thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
@@ -2286,7 +2308,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
}
out:
-
csn_free(&maxcsn);
slapi_ch_free_string(&ridstr);
slapi_sdn_free(&sdn);
@@ -2321,7 +2342,7 @@ replica_abort_task_thread(void *arg)
* to timing issues, we need to wait to grab the replica obj until we get here.
*/
if((data->repl_obj = replica_get_replica_from_dn(data->sdn)) == NULL){
- cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Failed to get replica from dn (%s).", slapi_sdn_get_dn(data->sdn));
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Failed to get replica object from dn (%s).", slapi_sdn_get_dn(data->sdn));
goto done;
}
if(data->replica == NULL && data->repl_obj){
@@ -2335,6 +2356,10 @@ replica_abort_task_thread(void *arg)
*/
while(agmt_not_notified && !slapi_is_shutting_down()){
agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica);
+ if(agmt_obj == NULL){
+ agmt_not_notified = 0;
+ break;
+ }
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
@@ -2342,8 +2367,14 @@ replica_abort_task_thread(void *arg)
continue;
}
if(replica_cleanallruv_send_abort_extop(agmt, data->task, data->payload)){
- agmt_not_notified = 1;
- break;
+ if(strcasecmp(data->certify,"yes") == 0){
+ /* we are verifying all the replicas receive the abort task */
+ agmt_not_notified = 1;
+ break;
+ } else {
+ /* we do not care if we could not reach a replica, just continue as if we did */
+ agmt_not_notified = 0;
+ }
} else {
/* success */
agmt_not_notified = 0;
@@ -2373,7 +2404,7 @@ replica_abort_task_thread(void *arg)
done:
if(agmt_not_notified){
/* failure */
- cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup.");
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup.");
} else {
/*
* Clean up the config
@@ -2390,6 +2421,7 @@ done:
ber_bvfree(data->payload);
}
slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free_string(&data->certify);
slapi_sdn_free(&data->sdn);
slapi_ch_free((void **)&data);
}
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 645e749..1b72dfb 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1455,6 +1455,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
char *extop_oid;
char *repl_root;
char *payload = NULL;
+ char *certify_all;
char *iter;
int rc = 0;
@@ -1475,6 +1476,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
+ certify_all = ldap_utf8strtok_r(iter, ":", &iter);
if(!is_cleaned_rid(rid) || is_task_aborted(rid)){
/* This replica has already been aborted, or was never cleaned, or already finished cleaning */
@@ -1521,6 +1523,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
data->payload = slapi_ch_bvdup(extop_payload);
data->rid = rid;
data->repl_root = slapi_ch_strdup(repl_root);
+ data->certify = slapi_ch_strdup(certify_all);
/*
* Stop the cleaning, and delete the rid
*/
@@ -1541,6 +1544,8 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
}
slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort cleanAllRUV task: unable to create abort "
"thread. Aborting task.\n");
+ slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free_string(&data->certify);
rc = LDAP_OPERATIONS_ERROR;
}
11 years
ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/repl5.h | 1
ldap/servers/plugins/replication/repl5_replica.c | 4
ldap/servers/plugins/replication/repl5_replica_config.c | 68 +++++++++++-----
ldap/servers/plugins/replication/repl_extop.c | 5 +
4 files changed, 60 insertions(+), 18 deletions(-)
New commits:
commit ce408229bc135aa89754861eaae58de379fd45c0
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Sep 21 12:38:32 2012 -0400
Ticket 467 - CLEANALLRUV abort task should be able to ignore down replicas
Bug Description: The abort task previously would wait for all the replicas to be online,
and receive the extended op task. This made it impossible to abort the
cleanallruv task, if you wanted to abort because a server was down.
Fix Description: Changed the default behavior to ignore down replicas, and added a new attribute
to the abort task entry: replica-certify-all: (yes,no). Default is "no". If
set to "yes", then it will wait until all the replicas have received the abort task.
Also fixed a crash caused by running the abort task agsint a server that does not have
replication setup. The crashed was caused by freeing uninitialized pointers.
https://fedorahosted.org/389/ticket/467
Reviewed by: richm(Thanks!)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 7b6cb8c..61b51b0 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -642,6 +642,7 @@ typedef struct _cleanruv_data
CSN *maxcsn;
char *repl_root;
Slapi_DN *sdn;
+ char *certify;
} cleanruv_data;
/* replutil.c */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 9e0fb24..2b1d958 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1914,6 +1914,7 @@ done:
char *ridstr = NULL;
char *repl_root;
char *token = NULL;
+ char *certify = NULL;
ReplicaId rid;
int i;
@@ -1935,6 +1936,7 @@ done:
}
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
+ certify = ldap_utf8strtok_r(iter, ":", &iter);
stop_ruv_cleaning();
maxcsn = replica_get_cleanruv_maxcsn(r, rid);
delete_cleaned_rid(r, rid, maxcsn);
@@ -1966,6 +1968,7 @@ done:
data->payload = payload;
data->repl_root = slapi_ch_strdup(repl_root);
data->sdn = slapi_sdn_dup(r->repl_root);
+ data->certify = slapi_ch_strdup(certify);
thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
@@ -1976,6 +1979,7 @@ done:
slapi_sdn_free(&data->sdn);
ber_bvfree(data->payload);
slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free_string(&data->certify);
slapi_ch_free((void **)&data);
}
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 38fce99..21f63d2 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1262,7 +1262,8 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id (%d) for task - (%s)",
rid, slapi_sdn_get_dn(task_dn));
cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
- rc = LDAP_OPERATIONS_ERROR;
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
/*
@@ -1270,7 +1271,9 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
*/
dn = slapi_sdn_new_dn_byval(base_dn);
if((r = replica_get_replica_from_dn(dn)) == NULL){
- *returncode = LDAP_OPERATIONS_ERROR ;
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Could not find replica from dn(%s)",slapi_sdn_get_dn(dn));
+ cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
+ *returncode = LDAP_OPERATIONS_ERROR;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
@@ -1281,9 +1284,7 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
out:
if(rc){
cleanruv_log(task, CLEANALLRUV_ID, "Task failed...(%d)", rc);
- *returncode = rc;
slapi_task_finish(task, *returncode);
- rc = SLAPI_DSE_CALLBACK_ERROR;
} else {
rc = SLAPI_DSE_CALLBACK_OK;
}
@@ -2182,18 +2183,19 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
Replica *replica;
ReplicaId rid;
cleanruv_data *data = NULL;
- Slapi_DN *sdn;
+ Slapi_DN *sdn = NULL;
Object *r;
- CSN *maxcsn;
+ CSN *maxcsn = NULL;
const char *base_dn;
const char *rid_str;
- char *ridstr;
+ const char *certify_all;
+ char *ridstr = NULL;
int rc = SLAPI_DSE_CALLBACK_OK;
if(get_abort_cleanruv_task_count() >= CLEANRIDSIZ){
/* we are already running the maximum number of tasks */
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,
- "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OPERATIONS_ERROR;
return SLAPI_DSE_CALLBACK_ERROR;
}
@@ -2204,17 +2206,20 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
* Get our task settings
*/
if ((rid_str = fetch_attr(e, "replica-id", 0)) == NULL){
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Missing required attr \"replica-id\"");
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Missing required attr \"replica-id\"");
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
if ((base_dn = fetch_attr(e, "replica-base-dn", 0)) == NULL){
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Missing required attr \"replica-base-dn\"");
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Missing required attr \"replica-base-dn\"");
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
+ certify_all = fetch_attr(e, "replica-certify-all", 0);
/*
* Check the rid
*/
@@ -2232,15 +2237,31 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
*/
sdn = slapi_sdn_new_dn_byval(base_dn);
if((r = replica_get_replica_from_dn(sdn)) == NULL){
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Failed to find replica from dn(%s)", base_dn);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Failed to find replica from dn(%s)", base_dn);
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OPERATIONS_ERROR;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
/*
+ * Check verify value
+ */
+ if(certify_all){
+ if(strcasecmp(certify_all,"yes") && strcasecmp(certify_all,"no")){
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid value for \"replica-certify-all\", the value "
+ "must be \"yes\" or \"no\".");
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ } else {
+ certify_all = "no";
+ }
+ /*
* Create payload
*/
- ridstr = slapi_ch_smprintf("%d:%s", rid, base_dn);
+ ridstr = slapi_ch_smprintf("%d:%s:%s", rid, base_dn, certify_all);
payload = create_ruv_payload(ridstr);
if(payload == NULL){
@@ -2274,6 +2295,7 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
data->rid = rid;
data->repl_root = slapi_ch_strdup(base_dn);
data->sdn = NULL;
+ data->certify = slapi_ch_strdup(certify_all);
thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
@@ -2286,7 +2308,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
}
out:
-
csn_free(&maxcsn);
slapi_ch_free_string(&ridstr);
slapi_sdn_free(&sdn);
@@ -2321,7 +2342,7 @@ replica_abort_task_thread(void *arg)
* to timing issues, we need to wait to grab the replica obj until we get here.
*/
if((data->repl_obj = replica_get_replica_from_dn(data->sdn)) == NULL){
- cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Failed to get replica from dn (%s).", slapi_sdn_get_dn(data->sdn));
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Failed to get replica object from dn (%s).", slapi_sdn_get_dn(data->sdn));
goto done;
}
if(data->replica == NULL && data->repl_obj){
@@ -2335,6 +2356,10 @@ replica_abort_task_thread(void *arg)
*/
while(agmt_not_notified && !slapi_is_shutting_down()){
agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica);
+ if(agmt_obj == NULL){
+ agmt_not_notified = 0;
+ break;
+ }
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
@@ -2342,8 +2367,14 @@ replica_abort_task_thread(void *arg)
continue;
}
if(replica_cleanallruv_send_abort_extop(agmt, data->task, data->payload)){
- agmt_not_notified = 1;
- break;
+ if(strcasecmp(data->certify,"yes") == 0){
+ /* we are verifying all the replicas receive the abort task */
+ agmt_not_notified = 1;
+ break;
+ } else {
+ /* we do not care if we could not reach a replica, just continue as if we did */
+ agmt_not_notified = 0;
+ }
} else {
/* success */
agmt_not_notified = 0;
@@ -2373,7 +2404,7 @@ replica_abort_task_thread(void *arg)
done:
if(agmt_not_notified){
/* failure */
- cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup.");
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup.");
} else {
/*
* Clean up the config
@@ -2390,6 +2421,7 @@ done:
ber_bvfree(data->payload);
}
slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free_string(&data->certify);
slapi_sdn_free(&data->sdn);
slapi_ch_free((void **)&data);
}
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 645e749..1b72dfb 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1455,6 +1455,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
char *extop_oid;
char *repl_root;
char *payload = NULL;
+ char *certify_all;
char *iter;
int rc = 0;
@@ -1475,6 +1476,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
+ certify_all = ldap_utf8strtok_r(iter, ":", &iter);
if(!is_cleaned_rid(rid) || is_task_aborted(rid)){
/* This replica has already been aborted, or was never cleaned, or already finished cleaning */
@@ -1521,6 +1523,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
data->payload = slapi_ch_bvdup(extop_payload);
data->rid = rid;
data->repl_root = slapi_ch_strdup(repl_root);
+ data->certify = slapi_ch_strdup(certify_all);
/*
* Stop the cleaning, and delete the rid
*/
@@ -1541,6 +1544,8 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
}
slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort cleanAllRUV task: unable to create abort "
"thread. Aborting task.\n");
+ slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free_string(&data->certify);
rc = LDAP_OPERATIONS_ERROR;
}
11 years
ldap/ldif ldap/servers
by Mark Reynolds
ldap/ldif/template-dse.ldif.in | 3
ldap/servers/slapd/attrsyntax.c | 23 --
ldap/servers/slapd/back-ldbm/monitor.c | 26 ++
ldap/servers/slapd/dn.c | 347 +++++++++++++++++++++++++++++++++
ldap/servers/slapd/libglobs.c | 71 ++++++
ldap/servers/slapd/main.c | 3
ldap/servers/slapd/proto-slap.h | 7
ldap/servers/slapd/schema.c | 17 -
ldap/servers/slapd/slap.h | 6
ldap/servers/slapd/slapi-private.h | 6
10 files changed, 462 insertions(+), 47 deletions(-)
New commits:
commit 1d6dd39fb8b0ef8eb42ec9ef8c3d325e27a3d3c1
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Thu Sep 13 10:00:56 2012 -0400
Ticket 408 - create a normalized dn cache
Description: When we call slapi_dn_normalize_ext, first check if the dn is
in the cache. If it is, return the normalized dn(ndn), otherwise
make a copy of the raw/unnormalized dn so we can use it as the hash
key. We need to copy it because the normalize process consumes/modifys
the string. Then at the end of the slapi_dn_normalize_ext, we add the
ndn to the hash using the rawdn as the key.
This feature is configurable, and the max size can also be set. The
default is 20mb for max size. You can also monitor the cache searching
on the ldbm monitor(cn=monitor,cn=userRoot,cn=ldbm database,cn=plugins,cn=config).
https://fedorahosted.org/389/ticket/408
Reviewed by: richm & noriko (Thanks!)
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in
index ddf2b35..c626726 100644
--- a/ldap/ldif/template-dse.ldif.in
+++ b/ldap/ldif/template-dse.ldif.in
@@ -53,9 +53,10 @@ nsslapd-auditlog-maxlogsize: 100
nsslapd-auditlog-logrotationtime: 1
nsslapd-auditlog-logrotationtimeunit: day
nsslapd-rootdn: %rootdn%
+nsslapd-rootpw: %ds_passwd%
nsslapd-maxdescriptors: 1024
nsslapd-max-filter-nest-level: 40
-nsslapd-rootpw: %ds_passwd%
+nsslapd-ndn-cache-enabled: off
dn: cn=features,cn=config
objectclass: top
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
index 62dfea1..36ed768 100644
--- a/ldap/servers/slapd/attrsyntax.c
+++ b/ldap/servers/slapd/attrsyntax.c
@@ -202,29 +202,6 @@ attr_syntax_new()
}
/*
- * hashNocaseString - used for case insensitive hash lookups
- */
-static PLHashNumber
-hashNocaseString(const void *key)
-{
- PLHashNumber h = 0;
- const unsigned char *s;
-
- for (s = key; *s; s++)
- h = (h >> 28) ^ (h << 4) ^ (tolower(*s));
- return h;
-}
-
-/*
- * hashNocaseCompare - used for case insensitive hash key comparisons
- */
-static PRIntn
-hashNocaseCompare(const void *v1, const void *v2)
-{
- return (strcasecmp((char *)v1, (char *)v2) == 0);
-}
-
-/*
* Given an OID, return the syntax info. If there is more than one
* attribute syntax with the same OID (i.e. aliases), the first one
* will be returned. This is usually the "canonical" one, but it may
diff --git a/ldap/servers/slapd/back-ldbm/monitor.c b/ldap/servers/slapd/back-ldbm/monitor.c
index 075a48f..ee4f01a 100644
--- a/ldap/servers/slapd/back-ldbm/monitor.c
+++ b/ldap/servers/slapd/back-ldbm/monitor.c
@@ -70,8 +70,8 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e,
struct berval *vals[2];
char buf[BUFSIZ];
PRUint64 hits, tries;
- long nentries,maxentries;
- size_t size,maxsize;
+ long nentries, maxentries, count;
+ size_t size, maxsize;
/* NPCTE fix for bugid 544365, esc 0. <P.R> <04-Jul-2001> */
struct stat astat;
/* end of NPCTE fix for bugid 544365 */
@@ -145,6 +145,28 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e,
sprintf(buf, "%ld", maxentries);
MSET("maxDnCacheCount");
}
+ /* normalized dn cache stats */
+ if(config_get_ndn_cache_enabled()){
+ ndn_cache_get_stats(&hits, &tries, &size, &maxsize, &count);
+ sprintf(buf, "%" NSPRIu64, tries);
+ MSET("normalizedDnCacheTries");
+ sprintf(buf, "%" NSPRIu64, hits);
+ MSET("normalizedDnCacheHits");
+ sprintf(buf, "%" NSPRIu64, tries - hits);
+ MSET("normalizedDnCacheMisses");
+ sprintf(buf, "%lu", (unsigned long)(100.0*(double)hits / (double)(tries > 0 ? tries : 1)));
+ MSET("normalizedDnCacheHitRatio");
+ sprintf(buf, "%lu", size);
+ MSET("currentNormalizedDnCacheSize");
+ if(maxsize == 0){
+ sprintf(buf, "%d", -1);
+ } else {
+ sprintf(buf, "%lu", maxsize);
+ }
+ MSET("maxNormalizedDnCacheSize");
+ sprintf(buf, "%ld", count);
+ MSET("currentNormalizedDnCacheCount");
+ }
#ifdef DEBUG
{
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 568871f..11e56a9 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -51,6 +51,7 @@
#include <sys/socket.h>
#endif
#include "slap.h"
+#include <plhash.h>
#undef SDN_DEBUG
@@ -61,6 +62,52 @@ static void sort_rdn_avs( struct berval *avs, int count, int escape );
static int rdn_av_cmp( struct berval *av1, struct berval *av2 );
static void rdn_av_swap( struct berval *av1, struct berval *av2, int escape );
+/* normalized dn cache related definitions*/
+struct
+ndn_cache_lru
+{
+ struct ndn_cache_lru *prev;
+ struct ndn_cache_lru *next;
+ char *key;
+};
+
+struct
+ndn_cache_ctx
+{
+ struct ndn_cache_lru *head;
+ struct ndn_cache_lru *tail;
+ Slapi_Counter *cache_hits;
+ Slapi_Counter *cache_tries;
+ Slapi_Counter *cache_misses;
+ size_t cache_size;
+ size_t cache_max_size;
+ long cache_count;
+};
+
+struct
+ndn_hash_val
+{
+ char *ndn;
+ size_t len;
+ int size;
+ struct ndn_cache_lru *lru_node; /* used to speed up lru shuffling */
+};
+
+#define NDN_FLUSH_COUNT 10000 /* number of DN's to remove when cache fills up */
+#define NDN_MIN_COUNT 1000 /* the minimum number of DN's to keep in the cache */
+#define NDN_CACHE_BUCKETS 2053 /* prime number */
+
+static PLHashNumber ndn_hash_string(const void *key);
+static int ndn_cache_lookup(char *dn, size_t dn_len, char **result, char **udn, int *rc);
+static void ndn_cache_update_lru(struct ndn_cache_lru **node);
+static void ndn_cache_add(char *dn, size_t dn_len, char *ndn, size_t ndn_len);
+static void ndn_cache_delete(char *dn);
+static void ndn_cache_flush();
+static int ndn_started = 0;
+static PRLock *lru_lock = NULL;
+static Slapi_RWLock *ndn_cache_lock = NULL;
+static struct ndn_cache_ctx *ndn_cache = NULL;
+static PLHashTable *ndn_cache_hashtable = NULL;
#define ISBLANK(c) ((c) == ' ')
#define ISBLANKSTR(s) (((*(s)) == '2') && (*((s)+1) == '0'))
@@ -487,6 +534,7 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
char *ends = NULL;
char *endd = NULL;
char *lastesc = NULL;
+ char *udn;
/* rdn avs for the main DN */
char *typestart = NULL;
int rdn_av_count = 0;
@@ -511,6 +559,14 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
if (0 == src_len) {
src_len = strlen(src);
}
+ /*
+ * Check the normalized dn cache
+ */
+ if(ndn_cache_lookup(src, src_len, dest, &udn, &rc)){
+ *dest_len = strlen(*dest);
+ return rc;
+ }
+
s = PL_strnchr(src, '\\', src_len);
if (s) {
*dest_len = src_len * 3;
@@ -1072,6 +1128,10 @@ bail:
/* We terminate the str with NULL only when we allocate the str */
*d = '\0';
}
+ /* add this dn to the normalized dn cache */
+ if(*dest)
+ ndn_cache_add(udn, src_len, *dest, *dest_len);
+
return rc;
}
@@ -2567,3 +2627,290 @@ slapi_sdn_get_size(const Slapi_DN *sdn)
sz += strlen(sdn->dn) + 1;
return sz;
}
+
+/*
+ *
+ * Normalized DN Cache
+ *
+ */
+
+/*
+ * Hashing function using Bernstein's method
+ */
+static PLHashNumber
+ndn_hash_string(const void *key)
+{
+ PLHashNumber hash = 5381;
+ unsigned char *x = (unsigned char *)key;
+ int c;
+
+ while ((c = *x++)){
+ hash = ((hash << 5) + hash) ^ c;
+ }
+ return hash;
+}
+
+void
+ndn_cache_init()
+{
+ if(!config_get_ndn_cache_enabled()){
+ return;
+ }
+ ndn_cache_hashtable = PL_NewHashTable( NDN_CACHE_BUCKETS, ndn_hash_string, PL_CompareStrings, PL_CompareValues, 0, 0);
+ ndn_cache = (struct ndn_cache_ctx *)slapi_ch_malloc(sizeof(struct ndn_cache_ctx));
+ ndn_cache->cache_max_size = config_get_ndn_cache_size();
+ ndn_cache->cache_hits = slapi_counter_new();
+ ndn_cache->cache_tries = slapi_counter_new();
+ ndn_cache->cache_misses = slapi_counter_new();
+ ndn_cache->cache_count = 0;
+ ndn_cache->cache_size = sizeof(struct ndn_cache_ctx) + sizeof(PLHashTable) + sizeof(PLHashTable);
+ ndn_cache->head = NULL;
+ ndn_cache->tail = NULL;
+
+ if ( NULL == ( lru_lock = PR_NewLock()) || NULL == ( ndn_cache_lock = slapi_new_rwlock())) {
+ char *errorbuf = NULL;
+ if(ndn_cache_hashtable){
+ PL_HashTableDestroy(ndn_cache_hashtable);
+ }
+ ndn_cache_hashtable = NULL;
+ config_set_ndn_cache_enabled(CONFIG_NDN_CACHE, "off", errorbuf, 1 );
+ slapi_counter_destroy(&ndn_cache->cache_hits);
+ slapi_counter_destroy(&ndn_cache->cache_tries);
+ slapi_counter_destroy(&ndn_cache->cache_misses);
+ slapi_ch_free((void **)&ndn_cache);
+ slapi_log_error( SLAPI_LOG_FATAL, "ndn_cache_init", "Failed to create locks. Disabling cache.\n" );
+ } else {
+ ndn_started = 1;
+ }
+}
+
+/*
+ * Look up this dn in the ndn cache
+ */
+static int
+ndn_cache_lookup(char *dn, size_t dn_len, char **result, char **udn, int *rc)
+{
+ struct ndn_hash_val *ndn_ht_val = NULL;
+ char *ndn, *key;
+ int rv = 0;
+
+ if(ndn_started == 0){
+ return rv;
+ }
+ if(dn_len == 0){
+ *result = dn;
+ *rc = 0;
+ return 1;
+ }
+ slapi_counter_increment(ndn_cache->cache_tries);
+ slapi_rwlock_rdlock(ndn_cache_lock);
+ ndn_ht_val = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn);
+ if(ndn_ht_val){
+ ndn_cache_update_lru(&ndn_ht_val->lru_node);
+ slapi_counter_increment(ndn_cache->cache_hits);
+ if(ndn_ht_val->len == dn_len ){
+ /* the dn was already normalized, just return the dn as the result */
+ *result = dn;
+ *rc = 0;
+ } else {
+ *rc = 1; /* free result */
+ ndn = slapi_ch_malloc(ndn_ht_val->len + 1);
+ memcpy(ndn, ndn_ht_val->ndn, ndn_ht_val->len);
+ ndn[ndn_ht_val->len] = '\0';
+ *result = ndn;
+ }
+ rv = 1;
+ } else {
+ /* copy/preserve the udn, so we can use it as the key when we add dn's to the hashtable */
+ key = slapi_ch_malloc(dn_len + 1);
+ memcpy(key, dn, dn_len);
+ key[dn_len] = '\0';
+ *udn = key;
+ }
+ slapi_rwlock_unlock(ndn_cache_lock);
+
+ return rv;
+}
+
+/*
+ * Move this lru node to the top of the list
+ */
+static void
+ndn_cache_update_lru(struct ndn_cache_lru **node)
+{
+ struct ndn_cache_lru *prev, *next, *curr_node = *node;
+
+ if(curr_node == NULL){
+ return;
+ }
+ PR_Lock(lru_lock);
+ if(curr_node->prev == NULL){
+ /* already the top node */
+ PR_Unlock(lru_lock);
+ return;
+ }
+ prev = curr_node->prev;
+ next = curr_node->next;
+ if(next){
+ next->prev = prev;
+ prev->next = next;
+ } else {
+ /* this was the tail, so reset the tail */
+ ndn_cache->tail = prev;
+ prev->next = NULL;
+ }
+ curr_node->prev = NULL;
+ curr_node->next = ndn_cache->head;
+ ndn_cache->head->prev = curr_node;
+ ndn_cache->head = curr_node;
+ PR_Unlock(lru_lock);
+}
+
+/*
+ * Add a ndn to the cache. Try and do as much as possible before taking the write lock.
+ */
+static void
+ndn_cache_add(char *dn, size_t dn_len, char *ndn, size_t ndn_len)
+{
+ struct ndn_hash_val *ht_entry;
+ struct ndn_cache_lru *new_node = NULL;
+ PLHashEntry *he;
+ int size;
+
+ if(ndn_started == 0 || dn_len == 0){
+ return;
+ }
+ if(strlen(ndn) > ndn_len){
+ /* we need to null terminate the ndn */
+ *(ndn + ndn_len) = '\0';
+ }
+ /*
+ * Calculate the approximate memory footprint of the hash entry, key, and lru entry.
+ */
+ size = (dn_len * 2) + ndn_len + sizeof(PLHashEntry) + sizeof(struct ndn_hash_val) + sizeof(struct ndn_cache_lru);
+ /*
+ * Create our LRU node
+ */
+ new_node = (struct ndn_cache_lru *)slapi_ch_malloc(sizeof(struct ndn_cache_lru));
+ if(new_node == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, "ndn_cache_add", "Failed to allocate new lru node.\n");
+ return;
+ }
+ new_node->prev = NULL;
+ new_node->key = dn; /* dn has already been allocated */
+ /*
+ * Its possible this dn was added to the hash by another thread.
+ */
+ slapi_rwlock_wrlock(ndn_cache_lock);
+ ht_entry = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn);
+ if(ht_entry){
+ /* already exists, free the node and return */
+ slapi_rwlock_unlock(ndn_cache_lock);
+ slapi_ch_free_string(&new_node->key);
+ slapi_ch_free((void **)&new_node);
+ return;
+ }
+ /*
+ * Create the hash entry
+ */
+ ht_entry = (struct ndn_hash_val *)slapi_ch_malloc(sizeof(struct ndn_hash_val));
+ if(ht_entry == NULL){
+ slapi_rwlock_unlock(ndn_cache_lock);
+ slapi_log_error( SLAPI_LOG_FATAL, "ndn_cache_add", "Failed to allocate new hash entry.\n");
+ slapi_ch_free_string(&new_node->key);
+ slapi_ch_free((void **)&new_node);
+ return;
+ }
+ ht_entry->ndn = slapi_ch_malloc(ndn_len + 1);
+ memcpy(ht_entry->ndn, ndn, ndn_len);
+ ht_entry->ndn[ndn_len] = '\0';
+ ht_entry->len = ndn_len;
+ ht_entry->size = size;
+ ht_entry->lru_node = new_node;
+ /*
+ * Check if our cache is full
+ */
+ PR_Lock(lru_lock); /* grab the lru lock now, as ndn_cache_flush needs it */
+ if(ndn_cache->cache_max_size != 0 && ((ndn_cache->cache_size + size) > ndn_cache->cache_max_size)){
+ ndn_cache_flush();
+ }
+ /*
+ * Set the ndn cache lru nodes
+ */
+ if(ndn_cache->head == NULL && ndn_cache->tail == NULL){
+ /* this is the first node */
+ ndn_cache->head = new_node;
+ ndn_cache->tail = new_node;
+ new_node->next = NULL;
+ } else {
+ new_node->next = ndn_cache->head;
+ ndn_cache->head->prev = new_node;
+ }
+ ndn_cache->head = new_node;
+ PR_Unlock(lru_lock);
+ /*
+ * Add the new object to the hashtable, and update our stats
+ */
+ he = PL_HashTableAdd(ndn_cache_hashtable, new_node->key, (void *)ht_entry);
+ if(he == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, "ndn_cache_add", "Failed to add new entry to hash(%s)\n",dn);
+ } else {
+ ndn_cache->cache_count++;
+ ndn_cache->cache_size += size;
+ }
+ slapi_rwlock_unlock(ndn_cache_lock);
+}
+
+/*
+ * cache is full, remove the least used dn's. lru_lock/ndn_cache write lock are already taken
+ */
+static void
+ndn_cache_flush()
+{
+ struct ndn_cache_lru *node, *next, *flush_node;
+ int i;
+
+ node = ndn_cache->tail;
+ for(i = 0; i < NDN_FLUSH_COUNT && ndn_cache->cache_count > NDN_MIN_COUNT; i++){
+ flush_node = node;
+ /* update the lru */
+ next = node->prev;
+ next->next = NULL;
+ ndn_cache->tail = next;
+ node = next;
+ /* now update the hash */
+ ndn_cache->cache_count--;
+ ndn_cache_delete(flush_node->key);
+ slapi_ch_free_string(&flush_node->key);
+ slapi_ch_free((void **)&flush_node);
+ }
+
+ slapi_log_error( SLAPI_LOG_CACHE, "ndn_cache_flush","Flushed cache.\n");
+}
+
+/* this is already "write" locked from ndn_cache_add */
+static void
+ndn_cache_delete(char *dn)
+{
+ struct ndn_hash_val *ht_val;
+
+ ht_val = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn);
+ if(ht_val){
+ ndn_cache->cache_size -= ht_val->size;
+ slapi_ch_free_string(&ht_val->ndn);
+ PL_HashTableRemove(ndn_cache_hashtable, dn);
+ }
+}
+/* stats for monitor */
+void
+ndn_cache_get_stats(PRUint64 *hits, PRUint64 *tries, size_t *size, size_t *max_size, long *count)
+{
+ slapi_rwlock_rdlock(ndn_cache_lock);
+ *hits = slapi_counter_get_value(ndn_cache->cache_hits);
+ *tries = slapi_counter_get_value(ndn_cache->cache_tries);
+ *size = ndn_cache->cache_size;
+ *max_size = ndn_cache->cache_max_size;
+ *count = ndn_cache->cache_count;
+ slapi_rwlock_unlock(ndn_cache_lock);
+}
+
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 3226ede..dc8452a 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -691,6 +691,14 @@ static struct config_get_and_set {
NULL, 0,
(void**)&global_slapdFrontendConfig.disk_preserve_logging,
CONFIG_ON_OFF, (ConfigGetFunc)config_get_disk_preserve_logging},
+ {CONFIG_NDN_CACHE, config_set_ndn_cache_enabled,
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.ndn_cache_enabled, CONFIG_INT,
+ (ConfigGetFunc)config_get_ndn_cache_enabled},
+ {CONFIG_NDN_CACHE_SIZE, config_set_ndn_cache_max_size,
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.ndn_cache_max_size,
+ CONFIG_INT, (ConfigGetFunc)config_get_ndn_cache_size},
#ifdef MEMPOOL_EXPERIMENTAL
,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch,
NULL, 0,
@@ -704,7 +712,7 @@ static struct config_get_and_set {
/*
* hashNocaseString - used for case insensitive hash lookups
*/
-static PLHashNumber
+PLHashNumber
hashNocaseString(const void *key)
{
PLHashNumber h = 0;
@@ -718,7 +726,7 @@ hashNocaseString(const void *key)
/*
* hashNocaseCompare - used for case insensitive hash key comparisons
*/
-static PRIntn
+PRIntn
hashNocaseCompare(const void *v1, const void *v2)
{
return (strcasecmp((char *)v1, (char *)v2) == 0);
@@ -1092,6 +1100,8 @@ FrontendConfig_init () {
cfg->disk_grace_period = 60; /* 1 hour */
cfg->disk_preserve_logging = LDAP_OFF;
cfg->disk_logging_critical = LDAP_OFF;
+ cfg->ndn_cache_enabled = LDAP_OFF;
+ cfg->ndn_cache_max_size = NDN_DEFAULT_SIZE;
#ifdef MEMPOOL_EXPERIMENTAL
cfg->mempool_switch = LDAP_ON;
@@ -1310,6 +1320,42 @@ config_set_disk_grace_period( const char *attrname, char *value, char *errorbuf,
return retVal;
}
+int
+config_set_ndn_cache_enabled(const char *attrname, char *value, char *errorbuf, int apply )
+{
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ int retVal;
+
+ retVal = config_set_onoff ( attrname, value, &(slapdFrontendConfig->ndn_cache_enabled), errorbuf, apply);
+
+ return retVal;
+}
+
+int
+config_set_ndn_cache_max_size(const char *attrname, char *value, char *errorbuf, int apply )
+{
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ long size;
+ int retVal = LDAP_SUCCESS;
+
+ size = atol(value);
+ if(size < 0){
+ size = 0; /* same as -1 */
+ }
+ if(size > 0 && size < 1024000){
+ PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "ndn_cache_max_size too low(%d), changing to "
+ "%d bytes.\n",(int)size, NDN_DEFAULT_SIZE);
+ size = NDN_DEFAULT_SIZE;
+ }
+ if(apply){
+ CFG_LOCK_WRITE(slapdFrontendConfig);
+ slapdFrontendConfig->ndn_cache_max_size = size;
+ CFG_UNLOCK_WRITE(slapdFrontendConfig);
+ }
+
+ return retVal;
+}
+
int
config_set_port( const char *attrname, char *port, char *errorbuf, int apply ) {
long nPort;
@@ -5213,6 +5259,27 @@ config_get_max_filter_nest_level()
return retVal;
}
+size_t
+config_get_ndn_cache_size(){
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ size_t retVal;
+
+ CFG_LOCK_READ(slapdFrontendConfig);
+ retVal = slapdFrontendConfig->ndn_cache_max_size;
+ CFG_UNLOCK_READ(slapdFrontendConfig);
+ return retVal;
+}
+
+int
+config_get_ndn_cache_enabled(){
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ int retVal;
+
+ CFG_LOCK_READ(slapdFrontendConfig);
+ retVal = slapdFrontendConfig->ndn_cache_enabled;
+ CFG_UNLOCK_READ(slapdFrontendConfig);
+ return retVal;
+}
char *
config_get_basedn() {
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index 69314cc..03d7086 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -1042,6 +1042,9 @@ main( int argc, char **argv)
}
}
+ /* initialize the normalized DN cache */
+ ndn_cache_init();
+
/*
* Detach ourselves from the terminal (unless running in debug mode).
* We must detach before we start any threads since detach forks() on
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index cdd5eec..55c3a78 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -388,6 +388,8 @@ int config_set_disk_grace_period( const char *attrname, char *value, char *error
int config_set_disk_preserve_logging( const char *attrname, char *value, char *errorbuf, int apply );
int config_set_disk_logging_critical( const char *attrname, char *value, char *errorbuf, int apply );
int config_set_auditlog_unhashed_pw(const char *attrname, char *value, char *errorbuf, int apply);
+int config_set_ndn_cache_enabled(const char *attrname, char *value, char *errorbuf, int apply);
+int config_set_ndn_cache_max_size(const char *attrname, char *value, char *errorbuf, int apply);
#if !defined(_WIN32) && !defined(AIX)
int config_set_maxdescriptors( const char *attrname, char *value, char *errorbuf, int apply );
@@ -543,6 +545,11 @@ long config_get_disk_threshold();
int config_get_disk_grace_period();
int config_get_disk_preserve_logging();
int config_get_disk_logging_critical();
+int config_get_ndn_cache_count();
+size_t config_get_ndn_cache_size();
+int config_get_ndn_cache_enabled();
+PLHashNumber hashNocaseString(const void *key);
+PRIntn hashNocaseCompare(const void *v1, const void *v2);
int is_abspath(const char *);
char* rel2abspath( char * );
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
index ba76b65..c66c320 100644
--- a/ldap/servers/slapd/schema.c
+++ b/ldap/servers/slapd/schema.c
@@ -250,22 +250,6 @@ dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int
return SLAPI_DSE_CALLBACK_ERROR;
}
-#if 0
-/*
- * hashNocaseString - used for case insensitive hash lookups
- */
-static PLHashNumber
-hashNocaseString(const void *key)
-{
- PLHashNumber h = 0;
- const unsigned char *s;
-
- for (s = key; *s; s++)
- h = (h >> 28) ^ (h << 4) ^ (tolower(*s));
- return h;
-}
-#endif
-
static const char *
skipWS(const char *s)
{
@@ -278,7 +262,6 @@ skipWS(const char *s)
return s;
}
-
/*
* like strchr() but strings within single quotes are skipped.
*/
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index ca1cb87..33607cb 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -2012,6 +2012,8 @@ typedef struct _slapdEntryPoints {
#define CONFIG_DISK_GRACE_PERIOD "nsslapd-disk-monitoring-grace-period"
#define CONFIG_DISK_PRESERVE_LOGGING "nsslapd-disk-monitoring-preserve-logging"
#define CONFIG_DISK_LOGGING_CRITICAL "nsslapd-disk-monitoring-logging-critical"
+#define CONFIG_NDN_CACHE "nsslapd-ndn-cache-enabled"
+#define CONFIG_NDN_CACHE_SIZE "nsslapd-ndn-cache-max-size"
#ifdef MEMPOOL_EXPERIMENTAL
#define CONFIG_MEMPOOL_SWITCH_ATTRIBUTE "nsslapd-mempool"
@@ -2247,6 +2249,10 @@ typedef struct _slapdFrontendConfig {
int disk_grace_period;
int disk_preserve_logging;
int disk_logging_critical;
+
+ /* normalized dn cache */
+ int ndn_cache_enabled;
+ size_t ndn_cache_max_size;
} slapdFrontendConfig_t;
/* possible values for slapdFrontendConfig_t.schemareplace */
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index a57b453..6c2781c 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -384,12 +384,14 @@ Slapi_DN *slapi_sdn_init_normdn_ndn_passin(Slapi_DN *sdn, const char *dn);
Slapi_DN *slapi_sdn_init_normdn_passin(Slapi_DN *sdn, const char *dn);
char *slapi_dn_normalize_original( char *dn );
char *slapi_dn_normalize_case_original( char *dn );
+void ndn_cache_init();
+void ndn_cache_get_stats(PRUint64 *hits, PRUint64 *tries, size_t *size, size_t *max_size, long *count);
+#define NDN_DEFAULT_SIZE 20971520 /* 20mb - size of normalized dn cache */
/* filter.c */
int filter_flag_is_set(const Slapi_Filter *f,unsigned char flag);
char *slapi_filter_to_string(const Slapi_Filter *f, char *buffer, size_t bufsize);
-char *
-slapi_filter_to_string_internal( const struct slapi_filter *f, char *buf, size_t *bufsize );
+char *slapi_filter_to_string_internal( const struct slapi_filter *f, char *buf, size_t *bufsize );
/* operation.c */
11 years
389-ds-console.spec build.properties fedora-ds-console.spec
by Mark Reynolds
389-ds-console.spec | 4 ++++
build.properties | 2 +-
fedora-ds-console.spec | 4 ++++
3 files changed, 9 insertions(+), 1 deletion(-)
New commits:
commit c8286d770b2427c9e19a4d081498547e1bbfc978
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Sep 17 16:03:56 2012 -0400
Bumped version to 1.2.7
diff --git a/389-ds-console.spec b/389-ds-console.spec
index 7e4f308..3f9cb2d 100644
--- a/389-ds-console.spec
+++ b/389-ds-console.spec
@@ -83,6 +83,10 @@ rm -rf $RPM_BUILD_ROOT
%doc %{_datadir}/%{pkgname}/manual/en/slapd/help/*.html
%changelog
+* Mon Sep 17, 2012 Mark Reynolds <mareynol(a)redhat.com> 1.2.7-1
+- added/enhancement for 806566
+- bumped version to 1.2.7
+
* Tue Jul 14 2009 Rich Megginson <rmeggins(a)redhat.com> 1.2.0-3
- added doc subpackage
diff --git a/build.properties b/build.properties
index 006a854..f8f12aa 100755
--- a/build.properties
+++ b/build.properties
@@ -21,7 +21,7 @@
lang=en
ldapconsole.root=..
-ldapconsole.version=1.2.6
+ldapconsole.version=1.2.7
ldapconsole.gen.version=1.2
brand=389
ldapconsole.name=${brand}-ds-${ldapconsole.version}
diff --git a/fedora-ds-console.spec b/fedora-ds-console.spec
index a1553c7..d14307f 100755
--- a/fedora-ds-console.spec
+++ b/fedora-ds-console.spec
@@ -69,6 +69,10 @@ rm -rf $RPM_BUILD_ROOT
%doc %{_datadir}/%{pkgname}/manual/en/slapd/help/*.html
%changelog
+* Mon Sep 17, 2012 Mark Reynolds <mareynol(a)redhat.com> 1.2.7-1
+- added/enhancement for 806566
+- bumped version to 1.2.7
+
* Tue Mar 31 2009 Rich Megginson <rmeggins(a)redhat.com> 1.2.0-1
- this is the 1.2.0 release
11 years
src/com
by Mark Reynolds
src/com/netscape/admin/dirserv/cosedit/ResEditorCosAttributes.java | 45 ++++++++--
src/com/netscape/admin/dirserv/dirserv.properties | 4
2 files changed, 44 insertions(+), 5 deletions(-)
New commits:
commit c83af3bbf6602e3d548e817e73db2a3272bf6bbc
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Sep 14 17:09:16 2012 -0400
Ticket 370 - Opening merge qualifier CoS entry using RHDS console changes the entry
Bug Description: Opening a cos entry that uses a cosAttrbiute with "merge-schemes",
gets rewritten with only the qualifier in the cosAttribute.
Fix Description: The value is changed because the console doesn't know about "merge-schemes".
Added "merge-schemes" to the cos editor(for each qualifer). So it can be
set correctly in the console, and the value is also not over written.
https://fedorahosted.org/389/ticket/370
Reviewed by: richm & noriko (Thanks!)
diff --git a/src/com/netscape/admin/dirserv/cosedit/ResEditorCosAttributes.java b/src/com/netscape/admin/dirserv/cosedit/ResEditorCosAttributes.java
index e8dbfdf..5a85c04 100644
--- a/src/com/netscape/admin/dirserv/cosedit/ResEditorCosAttributes.java
+++ b/src/com/netscape/admin/dirserv/cosedit/ResEditorCosAttributes.java
@@ -56,11 +56,15 @@ public class ResEditorCosAttributes extends DefaultResEditorPage
// Fetch the labels for attribute qualifier.
// Note: array indices match the values DEFAULT, OVERRIDE...
- _qualifierLabels = new Vector(3);
+ _qualifierLabels = new Vector(8);
_qualifierLabels.addElement(_resource.getString(_section, "qualifier-default"));
+ _qualifierLabels.addElement(_resource.getString(_section, "qualifier-default-merge-schemes"));
_qualifierLabels.addElement(_resource.getString(_section, "qualifier-override"));
+ _qualifierLabels.addElement(_resource.getString(_section, "qualifier-override-merge-schemes"));
_qualifierLabels.addElement(_resource.getString(_section, "qualifier-operational"));
+ _qualifierLabels.addElement(_resource.getString(_section, "qualifier-operational-merge-schemes"));
_qualifierLabels.addElement(_resource.getString(_section, "qualifier-operational-default"));
+ _qualifierLabels.addElement(_resource.getString(_section, "qualifier-operational-default-merge-schemes"));
}
@@ -451,9 +455,13 @@ public class ResEditorCosAttributes extends DefaultResEditorPage
*/
class CosAttributeRec {
public static final int DEFAULT = 0;
- public static final int OVERRIDE = 1;
- public static final int OPERATIONAL = 2;
- public static final int OPERATIONAL_DEFAULT = 3;
+ public static final int DEFAULT_MERGE_SCHEMES = 1;
+ public static final int OVERRIDE = 2;
+ public static final int OVERRIDE_MERGE_SCHEMES = 3;
+ public static final int OPERATIONAL = 4;
+ public static final int OPERATIONAL_MERGE_SCHEMES = 5;
+ public static final int OPERATIONAL_DEFAULT = 6;
+ public static final int OPERATIONAL_DEFAULT_MERGE_SCHEMES = 7;
String name;
int qualifier;
@@ -472,7 +480,18 @@ class CosAttributeRec {
qualifier = OPERATIONAL;
else if (token.equalsIgnoreCase("operational-default"))
qualifier = OPERATIONAL_DEFAULT;
- else {
+ else if (token.equalsIgnoreCase("merge-schemes")){
+ // Now check if we already have a qualifier set, and modify it if necessary
+ if(qualifier == DEFAULT){
+ qualifier = DEFAULT_MERGE_SCHEMES;
+ } else if(qualifier == OVERRIDE){
+ qualifier = OVERRIDE_MERGE_SCHEMES;
+ } else if(qualifier == OPERATIONAL){
+ qualifier = OPERATIONAL_MERGE_SCHEMES;
+ } else if(qualifier == OPERATIONAL_DEFAULT){
+ qualifier = OPERATIONAL_DEFAULT_MERGE_SCHEMES;
+ }
+ } else {
Debug.println(0, "ResEditorCosAttributes.CosAttributeRec: " +
"ignored invalid cosAttribute qualifier (" + token + ")");
}
@@ -482,14 +501,30 @@ class CosAttributeRec {
public String toString() {
StringBuffer sb = new StringBuffer(name);
switch(qualifier) {
+ case DEFAULT_MERGE_SCHEMES:
+ sb.append(" merge-schemes");
+ break;
case OVERRIDE:
sb.append(" override");
break;
+ case OVERRIDE_MERGE_SCHEMES:
+ sb.append(" override merge-schemes");
+ break;
case OPERATIONAL:
sb.append(" operational");
break;
+ case OPERATIONAL_MERGE_SCHEMES:
+ sb.append(" operational merge-schemes");
+ break;
+ case OPERATIONAL_DEFAULT:
+ sb.append(" operational-default");
+ break;
+ case OPERATIONAL_DEFAULT_MERGE_SCHEMES:
+ sb.append(" operational-default merge-schemes");
+ break;
// case DEFAULT: nothing needed
}
+
return sb.toString();
}
};
diff --git a/src/com/netscape/admin/dirserv/dirserv.properties b/src/com/netscape/admin/dirserv/dirserv.properties
index d79ef5b..2cfcdf1 100644
--- a/src/com/netscape/admin/dirserv/dirserv.properties
+++ b/src/com/netscape/admin/dirserv/dirserv.properties
@@ -2772,9 +2772,13 @@ cosAttributesPage-browseButton=Browse...
cosAttributesPage-header-name=Attribute Name
cosAttributesPage-header-qualifier=Class of Service Behavior
cosAttributesPage-qualifier-default=Does not override target entry attribute
+cosAttributesPage-qualifier-default-merge-schemes=Does not override target entry attribute (merge-schemes)
cosAttributesPage-qualifier-override=Overrides target entry attribute
+cosAttributesPage-qualifier-override-merge-schemes=Overrides target entry attribute (merge-schemes)
cosAttributesPage-qualifier-operational=Overrides target entry attribute and is operational
+cosAttributesPage-qualifier-operational-merge-schemes=Overrides target entry attribute and is operational (merge-schemes)
cosAttributesPage-qualifier-operational-default=Does not override target entry attribute and is operational
+cosAttributesPage-qualifier-operational-default-merge-schemes=Does not override target entry attribute and is operational (merge-schemes)
cosTemplatePage-id=Template
cosTemplatePage-label=Choose how the template entry is identified:
cosTemplatePage-pointerRadioButton=By its DN
11 years
2 commits - .gitignore ldap/servers
by Richard Allen Megginson
.gitignore | 4 ++++
ldap/servers/plugins/replication/repl_extop.c | 10 ++++++----
2 files changed, 10 insertions(+), 4 deletions(-)
New commits:
commit 1f775d7339cdabde70e73ce0be2e4432b16ba1a3
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri Sep 14 13:57:22 2012 -0600
fix compiler warnings in ticket 374 code
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index ca8fc55..645e749 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -46,7 +46,10 @@
#include "repl5.h"
#include "repl5_prot_private.h"
#include "cl5_api.h"
-
+#define ENABLE_TEST_TICKET_374
+#ifdef ENABLE_TEST_TICKET_374
+#include <unistd.h> /* for usleep */
+#endif
/*
* repl_extop.c - there are two types of functions in this file:
@@ -902,13 +905,12 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb)
}
/* remove this code once ticket 374 is fixed */
-#define ENABLE_TEST_TICKET_374
#ifdef ENABLE_TEST_TICKET_374
if (getenv("SLAPD_TEST_TICKET_374") && (opid > 20)) {
int i = 0;
int max = 480 * 5;
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
- "conn=%d op=%d repl=\"%s\": "
+ "conn=%" NSPRIu64 " op=%d repl=\"%s\": "
"374 - Starting sleep: connext->repl_protocol_version == %d\n",
connid, opid, repl_root, connext->repl_protocol_version);
@@ -917,7 +919,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb)
}
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
- "conn=%d op=%d repl=\"%s\": "
+ "conn=%" NSPRIu64 " op=%d repl=\"%s\": "
"374 - Finished sleep: connext->repl_protocol_version == %d\n",
connid, opid, repl_root, connext->repl_protocol_version);
}
commit f7cd60c0f54fcef0723fd6785aa7e808dedbb365
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Thu Sep 6 14:36:29 2012 -0600
add eclipse generated files to the ignore list
diff --git a/.gitignore b/.gitignore
index c1ba6bd..ea1af3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
autom4te.cache
*~
*.patch
+.autotools
+.cproject
+.project
+.settings
11 years
Branch '389-ds-base-1.2.11' - ldap/servers
by Richard Allen Megginson
ldap/servers/plugins/replication/repl_extop.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
New commits:
commit 0b79915854da26aae0d17f509f168290926cf14f
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri Sep 14 13:57:22 2012 -0600
fix compiler warnings in ticket 374 code
(cherry picked from commit 1f775d7339cdabde70e73ce0be2e4432b16ba1a3)
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index ca8fc55..645e749 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -46,7 +46,10 @@
#include "repl5.h"
#include "repl5_prot_private.h"
#include "cl5_api.h"
-
+#define ENABLE_TEST_TICKET_374
+#ifdef ENABLE_TEST_TICKET_374
+#include <unistd.h> /* for usleep */
+#endif
/*
* repl_extop.c - there are two types of functions in this file:
@@ -902,13 +905,12 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb)
}
/* remove this code once ticket 374 is fixed */
-#define ENABLE_TEST_TICKET_374
#ifdef ENABLE_TEST_TICKET_374
if (getenv("SLAPD_TEST_TICKET_374") && (opid > 20)) {
int i = 0;
int max = 480 * 5;
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
- "conn=%d op=%d repl=\"%s\": "
+ "conn=%" NSPRIu64 " op=%d repl=\"%s\": "
"374 - Starting sleep: connext->repl_protocol_version == %d\n",
connid, opid, repl_root, connext->repl_protocol_version);
@@ -917,7 +919,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb)
}
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
- "conn=%d op=%d repl=\"%s\": "
+ "conn=%" NSPRIu64 " op=%d repl=\"%s\": "
"374 - Finished sleep: connext->repl_protocol_version == %d\n",
connid, opid, repl_root, connext->repl_protocol_version);
}
11 years