ldap/servers
by Richard Allen Megginson
ldap/servers/slapd/auditlog.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
New commits:
commit 97ef3ddcb09a5cf7e17a77282295bf5634c45f3b
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri Jun 1 17:26:34 2012 -0600
Ticket #389 - ADD operations not in audit log
https://fedorahosted.org/389/ticket/389
Resolves: Ticket #389
Bug Description: ADD operations not in audit log
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description: Re-add code that was previously deleted. Also, log the
unnormalized, raw DN for operations.
Platforms tested: RHEL6 x86_64, Fedora 17
Flag Day: no
Doc impact: no
(cherry picked from commit ff11cccbba3f60761ca949a2feacc9d0b35451e7)
diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c
index 16c0f7e..81afe3e 100644
--- a/ldap/servers/slapd/auditlog.c
+++ b/ldap/servers/slapd/auditlog.c
@@ -83,6 +83,9 @@ write_audit_log_entry( Slapi_PBlock *pb )
case SLAPI_OPERATION_MODIFY:
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
break;
+ case SLAPI_OPERATION_ADD:
+ slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &change );
+ break;
case SLAPI_OPERATION_DELETE:
{
char * deleterDN = NULL;
@@ -100,7 +103,8 @@ write_audit_log_entry( Slapi_PBlock *pb )
return; /* Unsupported operation type. */
}
curtime = current_time();
- dn = slapi_sdn_get_dn(sdn);
+ /* log the raw, unnormalized DN */
+ dn = slapi_sdn_get_udn(sdn);
write_audit_file( operation_get_type(op), dn, change, flag, curtime );
}
11 years, 9 months
ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/cl5_clcache.c | 1
ldap/servers/plugins/replication/repl5_replica_config.c | 29 ++++++++++----
ldap/servers/plugins/rootdn_access/rootdn_access.c | 32 +++++++++-------
ldap/servers/slapd/back-ldbm/cache.c | 24 +++++++++---
ldap/servers/slapd/back-ldbm/dblayer.c | 5 +-
ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c | 6 +--
6 files changed, 63 insertions(+), 34 deletions(-)
New commits:
commit c446a6908df750b67604a3cd3821e0420ae00218
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed Jun 13 18:41:47 2012 -0400
COVERITY FIXES
12762
12763
12764
12765
12766
12767
12768
12769
12771
Reviewed by: Noriko & Richm (Thanks!)
diff --git a/ldap/servers/plugins/replication/cl5_clcache.c b/ldap/servers/plugins/replication/cl5_clcache.c
index 5816837..202cb64 100644
--- a/ldap/servers/plugins/replication/cl5_clcache.c
+++ b/ldap/servers/plugins/replication/cl5_clcache.c
@@ -680,6 +680,7 @@ clcache_skip_change ( CLC_Buffer *buf )
*/
skip = 0;
}
+ csn_free(&cons_maxcsn);
break;
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 8d338c0..e5c7035 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1176,7 +1176,7 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
{
PRThread *thread = NULL;
Repl_Connection *conn;
- Replica *replica = (Replica*)object_get_data (r);
+ Replica *replica;
Object *agmt_obj;
Repl_Agmt *agmt;
ConnResult crc;
@@ -1189,7 +1189,16 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
int rc = 0;
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: cleaning rid (%d)...\n",(int)rid);
- set_cleaned_rid(rid);
+
+ /*
+ * Grab the replica
+ */
+ if(r){
+ replica = (Replica*)object_get_data (r);
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is NULL, aborting task\n");
+ return -1;
+ }
/*
* Create payload
*/
@@ -1197,9 +1206,13 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
payload = create_ruv_payload(ridstr);
if(payload == NULL){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to create ext op payload, aborting task\n");
- goto done;
+ slapi_ch_free_string(&ridstr);
+ return -1;
}
+
+ set_cleaned_rid(rid);
+
agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
while (agmt_obj)
{
@@ -1245,11 +1258,12 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
}
-done:
-
- if(payload)
+ /*
+ * We're done with the payload, free it.
+ */
+ if(payload){
ber_bvfree(payload);
-
+ }
slapi_ch_free_string(&ridstr);
/*
@@ -1277,7 +1291,6 @@ done:
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
"monitoring thread. Aborting task.\n");
}
-
} else if(r == 0){ /* success */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully Finished.\n");
} else {
diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c
index 7fb5615..19e578c 100644
--- a/ldap/servers/plugins/rootdn_access/rootdn_access.c
+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c
@@ -217,7 +217,8 @@ static int
rootdn_load_config(Slapi_PBlock *pb)
{
Slapi_Entry *e = NULL;
- char *openTime, *closeTime;
+ char *openTime = NULL;
+ char *closeTime = NULL;
char hour[3], min[3];
int result = 0;
int i;
@@ -243,7 +244,8 @@ rootdn_load_config(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
"invalid rootdn-days-allowed value (%s), must be all letters, and comma separators\n",closeTime);
slapi_ch_free_string(&daysAllowed);
- return -1;
+ result = -1;
+ goto free_and_return;
}
daysAllowed = strToLower(daysAllowed);
}
@@ -251,14 +253,14 @@ rootdn_load_config(Slapi_PBlock *pb)
if (strcspn(openTime, "0123456789")){
slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
"invalid rootdn-open-time value (%s), must be all digits\n",openTime);
- slapi_ch_free_string(&openTime);
- return -1;
+ result = -1;
+ goto free_and_return;
}
if(strlen(openTime) != 4){
slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
"invalid format for rootdn-open-time value (%s). Should be HHMM\n", openTime);
- slapi_ch_free_string(&openTime);
- return -1;
+ result = -1;
+ goto free_and_return;
}
/*
* convert the time to all seconds
@@ -271,14 +273,14 @@ rootdn_load_config(Slapi_PBlock *pb)
if (strcspn(closeTime, "0123456789")){
slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
"invalid rootdn-open-time value (%s), must be all digits, and should be HHMM\n",closeTime);
- slapi_ch_free_string(&closeTime);
- return -1;
+ result = -1;
+ goto free_and_return;
}
if(strlen(closeTime) != 4){
slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
"invalid format for rootdn-open-time value (%s), should be HHMM\n", closeTime);
- slapi_ch_free_string(&closeTime);
- return -1;
+ result = -1;
+ goto free_and_return;
}
/*
* convert the time to all seconds
@@ -294,13 +296,15 @@ rootdn_load_config(Slapi_PBlock *pb)
"there must be a open and a close time\n");
slapi_ch_free_string(&closeTime);
slapi_ch_free_string(&openTime);
- return -1;
+ result = -1;
+ goto free_and_return;
}
if(close_time && open_time && close_time <= open_time){
/* Make sure the closing time is greater than the open time */
slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
"the close time must be greater than the open time\n");
result = -1;
+ goto free_and_return;
}
if(hosts){
for(i = 0; hosts[i] != NULL; i++){
@@ -370,13 +374,15 @@ rootdn_load_config(Slapi_PBlock *pb)
}
}
}
- slapi_ch_free_string(&openTime);
- slapi_ch_free_string(&closeTime);
} else {
/* failed to get the plugin entry */
result = -1;
}
+free_and_return:
+ slapi_ch_free_string(&openTime);
+ slapi_ch_free_string(&closeTime);
+
slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "<-- rootdn_load_config (%d)\n", result);
return result;
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index 045b1eb..1c81a1b 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -1058,7 +1058,9 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
}
if (!add_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID), newe, NULL)) {
LOG("entry cache replace: can't add id\n", 0, 0, 0);
- remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn));
+ if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
+ LOG("entry cache replace: failed to remove dn table\n", 0, 0, 0);
+ }
PR_Unlock(cache->c_mutex);
return 1;
}
@@ -1066,8 +1068,12 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
if (newuuid && !add_hash(cache->c_uuidtable, (void *)newuuid, strlen(newuuid),
newe, NULL)) {
LOG("entry cache replace: can't add uuid\n", 0, 0, 0);
- remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn));
- remove_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID));
+ if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
+ LOG("entry cache replace: failed to remove dn table(uuid cache)\n", 0, 0, 0);
+ }
+ if(remove_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID)) == 0){
+ LOG("entry cache replace: failed to remove id table(uuid cache)\n", 0, 0, 0);
+ }
PR_Unlock(cache->c_mutex);
return 1;
}
@@ -1357,7 +1363,9 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
PR_Unlock(cache->c_mutex);
return 0;
}
- remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn));
+ if(remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn)) == 0){
+ LOG("entrycache_add_int: failed to remove dn table\n", 0, 0, 0);
+ }
e->ep_state |= ENTRY_STATE_NOTINCACHE;
PR_Unlock(cache->c_mutex);
return -1;
@@ -1369,8 +1377,12 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
NULL)) {
LOG("entry %s already in uuid cache!\n", backentry_get_ndn(e),
0, 0);
- remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn));
- remove_hash(cache->c_idtable, &(e->ep_id), sizeof(ID));
+ if(remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn)) == 0){
+ LOG("entrycache_add_int: failed to remove dn table(uuid cache)\n", 0, 0, 0);
+ }
+ if(remove_hash(cache->c_idtable, &(e->ep_id), sizeof(ID)) == 0){
+ LOG("entrycache_add_int: failed to remove id table(uuid cache)\n", 0, 0, 0);
+ }
e->ep_state |= ENTRY_STATE_NOTINCACHE;
PR_Unlock(cache->c_mutex);
return -1;
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 09d10a0..227218f 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -3884,7 +3884,7 @@ static int txn_test_threadmain(void *param)
txn_test_iter **ttilist = NULL;
size_t tticnt = 0;
DB_TXN *txn = NULL;
- txn_test_cfg cfg;
+ txn_test_cfg cfg = {0};
size_t counter = 0;
char keybuf[8192];
char databuf[8192];
@@ -3941,8 +3941,7 @@ wait_for_init:
object_release(inst_obj);
goto wait_for_init;
}
- dblayer_get_index_file(be, ai, &db, 0);
- if (NULL == db) {
+ if((dblayer_get_index_file(be, ai, &db, 0) != 0) || db == NULL){
if (strcasecmp(*idx, TXN_TEST_IDX_OK_IF_NULL)) {
object_release(inst_obj);
goto wait_for_init;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
index 449e02a..9b5b0de 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
@@ -2170,8 +2170,8 @@ _entryrdn_replace_suffix_id(DBC *cursor, DBT *key, DBT *adddata,
char *realkeybuf = NULL;
DBT realkey;
char buffer[RDN_BULK_FETCH_BUFFER_SIZE];
- DBT data;
- DBT moddata;
+ DBT data = {0};
+ DBT moddata = {0};
rdn_elem **childelems = NULL;
rdn_elem **cep = NULL;
rdn_elem *childelem = NULL;
@@ -2216,7 +2216,6 @@ _entryrdn_replace_suffix_id(DBC *cursor, DBT *key, DBT *adddata,
key->flags = DB_DBT_USERMEM;
/* Setting the bulk fetch buffer */
- memset(&data, 0, sizeof(data));
data.ulen = sizeof(buffer);
data.size = sizeof(buffer);
data.data = buffer;
@@ -2227,7 +2226,6 @@ _entryrdn_replace_suffix_id(DBC *cursor, DBT *key, DBT *adddata,
realkey.size = realkey.ulen = strlen(realkeybuf) + 1;
realkey.flags = DB_DBT_USERMEM;
- memset(&moddata, 0, sizeof(moddata));
moddata.flags = DB_DBT_USERMEM;
for (db_retry = 0; db_retry < RETRY_TIMES; db_retry++) {
11 years, 9 months
ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/repl5_agmt.c | 34 +++------------
ldap/servers/slapd/libglobs.c | 58 ++++++++++++++++++++++++++
ldap/servers/slapd/slapi-plugin.h | 9 ++++
3 files changed, 75 insertions(+), 26 deletions(-)
New commits:
commit 8f21ac81cfe8bf70b555ae011c9e7ff953deeb8e
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Jun 12 16:32:32 2012 -0400
Ticket #388 - Improve replication agreement status messages
Bug Description: Result codes that were negative values triggered a generic error
message (System Error). This is because of mozLDAP's ldap_err2string()
which can only handle positive values, but openldap's ldap_err2string
can handle both positive and negative numbers.
Fix Description: Created a wrapper function (slapi_err2string), that can handle both
positive and negative error codes, regardless which ldap library is
being used.
Reviewed by:
https://fedorahosted.org/389/ticket/388
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 4db7e13..4beb13a 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2098,6 +2098,7 @@ agmt_set_last_update_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *
else if (ldaprc != LDAP_SUCCESS)
{
char *replmsg = NULL;
+
if ( replrc ) {
replmsg = protocol_response2string(replrc);
/* Do not mix the unknown replication error with the known ldap one */
@@ -2105,19 +2106,9 @@ agmt_set_last_update_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *
replmsg = NULL;
}
}
- if (ldaprc > 0) {
- PR_snprintf(ra->last_update_status, STATUS_LEN,
- "%d %s%sLDAP error: %s%s%s",
- ldaprc,
- message?message:"",message?"":" - ",
- ldap_err2string(ldaprc),
- replmsg ? " - " : "", replmsg ? replmsg : "");
- } else { /* ldaprc is < 0 */
- PR_snprintf(ra->last_update_status, STATUS_LEN,
- "%d %s%sSystem error%s%s",
- ldaprc,message?message:"",message?"":" - ",
- replmsg ? " - " : "", replmsg ? replmsg : "");
- }
+ PR_snprintf(ra->last_update_status, STATUS_LEN, "%d %s%sLDAP error: %s%s%s",
+ ldaprc, message?message:"",message?"":" - ",
+ slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "");
}
/* ldaprc == LDAP_SUCCESS */
else if (replrc != 0)
@@ -2175,6 +2166,7 @@ agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *me
if (ldaprc != LDAP_SUCCESS)
{
char *replmsg = NULL;
+
if ( replrc ) {
replmsg = protocol_response2string(replrc);
/* Do not mix the unknown replication error with the known ldap one */
@@ -2182,19 +2174,9 @@ agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *me
replmsg = NULL;
}
}
- if (ldaprc > 0) {
- PR_snprintf(ra->last_init_status, STATUS_LEN,
- "%d %s%sLDAP error: %s%s%s",
- ldaprc,
- message?message:"",message?"":" - ",
- ldap_err2string(ldaprc),
- replmsg ? " - " : "", replmsg ? replmsg : "");
- } else { /* ldaprc is < 0 */
- PR_snprintf(ra->last_init_status, STATUS_LEN,
- "%d %s%sSystem error%s%s",
- ldaprc,message?message:"",message?"":" - ",
- replmsg ? " - " : "", replmsg ? replmsg : "");
- }
+ PR_snprintf(ra->last_init_status, STATUS_LEN, "%d %s%sLDAP error: %s%s%s",
+ ldaprc, message?message:"",message?"":" - ",
+ slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "");
}
/* ldaprc == LDAP_SUCCESS */
else if (replrc != 0)
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index c1e4051..282fc0d 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -6546,3 +6546,61 @@ config_set_auditlog_enabled(int value){
}
CFG_UNLOCK_WRITE(slapdFrontendConfig);
}
+
+char *
+slapi_err2string(int result)
+{
+ /*
+ * If we are using openldap, then we can safely use ldap_err2string with
+ * positive and negative result codes. MozLDAP's ldap_err2string can
+ * only handle positive result codes.
+ */
+#if defined (USE_OPENLDAP)
+ return ldap_err2string(result);
+#else
+ if(result >= 0){
+ return ldap_err2string(result);
+ }
+ switch (result)
+ {
+ case -1:
+ return ("Can't contact LDAP server");
+ case -2:
+ return ("Local error");
+ case -3:
+ return ("Encoding error");
+ case -4:
+ return ("Decoding error");
+ case -5:
+ return ("Timed out");
+ case -6:
+ return ("Unknown authentication method");
+ case -7:
+ return ("Bad search filter");
+ case -8:
+ return ("User canceled operation");
+ case -9:
+ return ("Bad parameter to an ldap routine");
+ case -10:
+ return ("Out of memory");
+ case -11:
+ return ("Connect error");
+ case -12:
+ return ("Not Supported");
+ case -13:
+ return ("Control not found");
+ case -14:
+ return ("No results returned");
+ case -15:
+ return ("More results to return");
+ case -16:
+ return ("Client Loop");
+ case -17:
+ return ("Referral Limit Exceeded");
+
+ default:
+ return ("Unknown system error");
+ }
+#endif
+}
+
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index bad97f8..4dbf7db 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5302,6 +5302,15 @@ void slapi_ch_array_add( char ***array, char *string );
int slapi_ch_array_utf8_inlist(char **array, char *string);
/**
+ * Returns the error string of an ldap result code, but it can also handle
+ * library errors(negative result codes)
+ *
+ * \param result The result code
+ * \return The error text string of the result code
+ */
+char *slapi_err2string(int result);
+
+/**
* Check if the server has started shutting down
*
* \return 1 if the server is shutting down
11 years, 9 months
Branch '389-ds-base-1.2.11' - 4 commits - ldap/ldif ldap/servers Makefile.am Makefile.in
by Richard Allen Megginson
Makefile.am | 13
Makefile.in | 50 +
ldap/ldif/template-dse.ldif.in | 11
ldap/servers/plugins/replication/repl5.h | 10
ldap/servers/plugins/replication/repl5_connection.c | 26
ldap/servers/plugins/replication/repl5_replica_config.c | 257 +++++-
ldap/servers/plugins/replication/repl_extop.c | 91 +-
ldap/servers/plugins/rootdn_access/rootdn_access.c | 663 ++++++++++++++++
ldap/servers/plugins/rootdn_access/rootdn_access.h | 57 +
ldap/servers/slapd/auditlog.c | 6
ldap/servers/slapd/back-ldbm/cache.c | 8
ldap/servers/slapd/back-ldbm/dblayer.c | 9
ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c | 1
ldap/servers/slapd/bind.c | 34
ldap/servers/slapd/pblock.c | 14
ldap/servers/slapd/plugin.c | 11
ldap/servers/slapd/slap.h | 2
ldap/servers/slapd/slapi-plugin.h | 3
18 files changed, 1178 insertions(+), 88 deletions(-)
New commits:
commit ff11cccbba3f60761ca949a2feacc9d0b35451e7
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri Jun 1 17:26:34 2012 -0600
Ticket #389 - ADD operations not in audit log
https://fedorahosted.org/389/ticket/389
Resolves: Ticket #389
Bug Description: ADD operations not in audit log
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description: Re-add code that was previously deleted. Also, log the
unnormalized, raw DN for operations.
Platforms tested: RHEL6 x86_64, Fedora 17
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c
index 79cd407..9c5ffad 100644
--- a/ldap/servers/slapd/auditlog.c
+++ b/ldap/servers/slapd/auditlog.c
@@ -82,6 +82,9 @@ write_audit_log_entry( Slapi_PBlock *pb )
case SLAPI_OPERATION_MODIFY:
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
break;
+ case SLAPI_OPERATION_ADD:
+ slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &change );
+ break;
case SLAPI_OPERATION_DELETE:
{
char * deleterDN = NULL;
@@ -99,7 +102,8 @@ write_audit_log_entry( Slapi_PBlock *pb )
return; /* Unsupported operation type. */
}
curtime = current_time();
- dn = slapi_sdn_get_dn(sdn);
+ /* log the raw, unnormalized DN */
+ dn = slapi_sdn_get_udn(sdn);
write_audit_file( operation_get_type(op), dn, change, flag, curtime );
}
commit 44cdc84ddc75b40a2e9b9578468db903b28dfb6b
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri May 25 12:39:09 2012 -0600
fix coverity issues with uninit vals, no return checking
12766 Uninitialized pointer read
In _entryrdn_replace_suffix_id(): Reads an uninitialized pointer or its target
12765 Uninitialized pointer read
In txn_test_threadmain(): Reads an uninitialized pointer or its target
12764 Unchecked return value
In txn_test_threadmain(): Value returned from a function is not checked for errors before being used
12763 Unchecked return value
In entrycache_replace(): Value returned from a function is not checked for errors before being used
12762 Unchecked return value
In entrycache_add_int(): Value returned from a function is not checked for errors before being used
Reviewed by: mreynolds (Thanks!)
(cherry picked from commit 98784ec829061e969c84b3cd5882326a0376ebd6)
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index 045b1eb..de84700 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -1058,7 +1058,9 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
}
if (!add_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID), newe, NULL)) {
LOG("entry cache replace: can't add id\n", 0, 0, 0);
- remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn));
+ if (remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn))) {
+ LOG("entry cache replace: can't remove dn after add id failed\n", 0, 0, 0);
+ }
PR_Unlock(cache->c_mutex);
return 1;
}
@@ -1357,7 +1359,9 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
PR_Unlock(cache->c_mutex);
return 0;
}
- remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn));
+ if (remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn))) {
+ LOG("=>= entrycache_add_int could not remove existing id from dn cache\n", 0, 0, 0);
+ }
e->ep_state |= ENTRY_STATE_NOTINCACHE;
PR_Unlock(cache->c_mutex);
return -1;
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 09d10a0..90e48af 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -3897,12 +3897,12 @@ static int txn_test_threadmain(void *param)
INCR_THREAD_COUNT(priv);
+ txn_test_init_cfg(&cfg);
+
if (!priv->dblayer_enable_transactions) {
goto end;
}
- txn_test_init_cfg(&cfg);
-
wait_for_init:
free_ttilist(&ttilist, &tticnt);
DS_Sleep(PR_MillisecondsToInterval(1000));
@@ -3941,9 +3941,8 @@ wait_for_init:
object_release(inst_obj);
goto wait_for_init;
}
- dblayer_get_index_file(be, ai, &db, 0);
- if (NULL == db) {
- if (strcasecmp(*idx, TXN_TEST_IDX_OK_IF_NULL)) {
+ if (dblayer_get_index_file(be, ai, &db, 0) || (NULL == db)) {
+ if ((NULL == db) && strcasecmp(*idx, TXN_TEST_IDX_OK_IF_NULL)) {
object_release(inst_obj);
goto wait_for_init;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
index 449e02a..0541543 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
@@ -2179,6 +2179,7 @@ _entryrdn_replace_suffix_id(DBC *cursor, DBT *key, DBT *adddata,
size_t curr_childnum = 0;
int db_retry = 0;
+ memset(&moddata, 0, sizeof(moddata));
/* temporary id added for the non exisiting suffix */
/* Let's replace it with the real entry ID */
/* SELF */
commit 1b4b9d53d2cfec92802f6fd4fdbc0101e987c6ee
Author: Mark Reynolds <mareynol(a)redhat.com>
Date: Wed May 16 11:28:01 2012 -0400
Ticket 368 - Make the cleanAllRUV task one step
Bug Description: The first version of this fix required a second releaseRUV step.
Fix Description: Created a new "monitoring" thread that checks all the replicas RUV's
to see if the rid was cleaned. Once they are cleaned, we automatically
release the RID for reuse.
I also refined the logging so it easy to track the status of the task.
https://fedorahosted.org/389/ticket/368
reviewed by: richm (Thanks Rich!)
(cherry picked from commit 507b593fa47efeb8a4fc3c2d6b75428e7a69a480)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index d3feeb0..b04d9c4 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -439,6 +439,9 @@ long conn_get_timeout(Repl_Connection *conn);
void conn_set_agmt_changed(Repl_Connection *conn);
ConnResult conn_read_result(Repl_Connection *conn, int *message_id);
ConnResult conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retdatap, LDAPControl ***returned_controls, int send_msgid, int *resp_msgid, int noblock);
+LDAP * conn_get_ldap(Repl_Connection *conn);
+void conn_lock(Repl_Connection *conn);
+void conn_unlock(Repl_Connection *conn);
/* In repl5_protocol.c */
typedef struct repl_protocol Repl_Protocol;
@@ -598,9 +601,16 @@ void set_released_rid(int rid);
int is_released_rid(int rid);
int is_already_released_rid();
void delete_released_rid();
+void replica_cleanallruv_monitor_thread(void *arg);
#define ALREADY_RELEASED -1
+typedef struct _cleanruv_data
+{
+ Object *repl_obj;
+ ReplicaId rid;
+} cleanruv_data;
+
/* replutil.c */
LDAPControl* create_managedsait_control ();
LDAPControl* create_backend_control(Slapi_DN *sdn);
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index a074a9f..5fdc601 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -1710,6 +1710,16 @@ conn_get_timeout(Repl_Connection *conn)
return retval;
}
+LDAP *
+conn_get_ldap(Repl_Connection *conn)
+{
+ if(conn){
+ return conn->ld;
+ } else {
+ return NULL;
+ }
+}
+
void conn_set_agmt_changed(Repl_Connection *conn)
{
PR_ASSERT(NULL != conn);
@@ -1908,3 +1918,19 @@ repl5_debug_timeout_callback(time_t when, void *arg)
"repl5_debug_timeout_callback: set debug level to %d at %ld\n",
s_debug_level, when);
}
+
+void
+conn_lock(Repl_Connection *conn)
+{
+ if(conn){
+ PR_Lock(conn->lock);
+ }
+}
+
+void
+conn_unlock(Repl_Connection *conn)
+{
+ if(conn){
+ PR_Unlock(conn->lock);
+ }
+}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 5a3ed07..ca646e9 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -81,12 +81,12 @@ static int replica_execute_cl2ldif_task (Object *r, char *returntext);
static int replica_execute_ldif2cl_task (Object *r, char *returntext);
static int replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext);
static int replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext);
-static int replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext);
+static int replica_execute_release_ruv_task(Object *r, ReplicaId rid);
static struct berval *create_ruv_payload(char *value);
static int replica_cleanup_task (Object *r, const char *task_name, char *returntext, int apply_mods);
static int replica_task_done(Replica *replica);
-
static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry *e);
+int g_get_shutdown();
/*
* Note: internal add/modify/delete operations should not be run while
@@ -860,21 +860,6 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
else
return LDAP_SUCCESS;
}
- else if (strncasecmp (task_name, RELEASERUV, RELEASERUVLEN) == 0)
- {
- int temprid = atoi(&(task_name[RELEASERUVLEN]));
- if (temprid <= 0 || temprid >= READ_ONLY_REPLICA_ID){
- PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id for task - %s", task_name);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,"replica_execute_task: %s\n", returntext);
- return LDAP_OPERATIONS_ERROR;
- }
- if (apply_mods)
- {
- return replica_execute_release_ruv_task(r, (ReplicaId)temprid, returntext);
- }
- else
- return LDAP_SUCCESS;
- }
else
{
PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "unsupported replica task - %s", task_name);
@@ -1177,7 +1162,6 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not
* Clean the changelog RUV's, and set the rids
*/
cl5CleanRUV(rid);
- set_cleaned_rid(rid);
delete_released_rid();
if (rc != RUV_SUCCESS){
@@ -1191,19 +1175,22 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not
static int
replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
{
+ PRThread *thread = NULL;
Repl_Connection *conn;
Replica *replica = (Replica*)object_get_data (r);
Object *agmt_obj;
Repl_Agmt *agmt;
ConnResult crc;
+ cleanruv_data *data = NULL;
const Slapi_DN *dn = NULL;
struct berval *payload = NULL;
char *ridstr = NULL;
int send_msgid = 0;
+ int agmt_count = 0;
int rc = 0;
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: cleaning rid (%d)...\n",(int)rid);
-
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: cleaning rid (%d)...\n",(int)rid);
+ set_cleaned_rid(rid);
/*
* Create payload
*/
@@ -1245,8 +1232,9 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to send "
"cleanruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
} else {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: successfully sent "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: successfully sent "
"cleanruv extended op to (%s)\n",slapi_sdn_get_dn(dn));
+ agmt_count++;
}
conn_start_linger(conn);
}
@@ -1270,17 +1258,218 @@ done:
*/
replica_execute_cleanruv_task (r, rid, returntext);
- if(rc == 0){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: operation successful\n");
+ if(rc == 0 && agmt_count > 0){ /* success, but we need to check our replicas */
+ /*
+ * Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid
+ */
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to allocate "
+ "cleanruv_data. Aborting task.\n");
+ return -1;
+ }
+ data->repl_obj = r;
+ data->rid = rid;
+
+ thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_monitor_thread,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
+ "monitoring thread. Aborting task.\n");
+ }
+
+ } else if(r == 0){ /* success */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully Finished.\n");
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: operation failed (%d)\n",rc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Task failed (%d)\n",rc);
}
return rc;
}
+/*
+ * After all the cleanAllRUV extended ops have been sent, we need to monitoring those replicas'
+ * RUVs. Once the rid is cleaned, then we need to release it, and push this "release"
+ * to the other replicas
+ */
+void
+replica_cleanallruv_monitor_thread(void *arg)
+{
+ Object *agmt_obj;
+ LDAP *ld;
+ Repl_Connection *conn;
+ Repl_Agmt *agmt;
+ Replica *replica;;
+ cleanruv_data *data = arg;
+ LDAPMessage *result, *entry;
+ BerElement *ber;
+ time_t start_time;
+ struct berval **vals;
+ char *rid_text;
+ char *attrs[2];
+ char *attr;
+ int replicas_cleaned = 0;
+ int found = 0;
+ int crc;
+ int rc = 0;
+ int i;
+
+ /*
+ * Initialize our settings
+ */
+ attrs[0] = "nsds50ruv";
+ attrs[1] = NULL;
+ rid_text = slapi_ch_smprintf("{replica %d ldap", data->rid);
+ replica = (Replica*)object_get_data (data->repl_obj);
+ start_time = current_time();
+
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Waiting for all the replicas to get cleaned...\n");
+
+ while(!g_get_shutdown())
+ {
+ DS_Sleep(PR_SecondsToInterval(10));
+ found = 0;
+ agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
+ while (agmt_obj){
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ if(!agmt_is_enabled(agmt)){
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ continue;
+ }
+ /*
+ * Get the replication connection
+ */
+ conn = (Repl_Connection *)agmt_get_connection(agmt);
+ crc = conn_connect(conn);
+ if (CONN_OPERATION_FAILED == crc ){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to connect "
+ "to repl agreement connection (%s), error %d\n","", ACQUIRE_TRANSIENT_ERROR);
+ continue;
+ } else if (CONN_SSL_NOT_ENABLED == crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to acquire "
+ "repl agmt connection (%s), error %d\n","", ACQUIRE_FATAL_ERROR);
+ continue;
+ }
+ /*
+ * Get the LDAP connection handle from the conn
+ */
+ ld = conn_get_ldap(conn);
+ if(ld == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to get LDAP "
+ "handle from the replication agmt (%s). Moving on to the next agmt.\n",agmt_get_long_name(agmt));
+ continue;
+ }
+ /*
+ * Search this replica for its tombstone/ruv entry
+ */
+ conn_cancel_linger(conn);
+ conn_lock(conn);
+ rc = ldap_search_ext_s(ld, slapi_sdn_get_dn(agmt_get_replarea(agmt)), LDAP_SCOPE_SUBTREE,
+ "(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))",
+ attrs, 0, NULL, NULL, NULL, 0, &result);
+ if(rc != LDAP_SUCCESS){
+ /*
+ * Couldn't contact ldap server, what should we do?
+ *
+ * Skip it and move on! It's the admin's job to make sure all the replicas are up and running
+ */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to contact "
+ "agmt (%s), moving on to the next agmt.\n", agmt_get_long_name(agmt));
+ conn_unlock(conn);
+ conn_start_linger(conn);
+ continue;
+ }
+ /*
+ * There is only one entry. Check its "nsds50ruv" for our cleaned rid
+ */
+ entry = ldap_first_entry( ld, result );
+ if ( entry != NULL ) {
+ for ( attr = ldap_first_attribute( ld, entry, &ber ); attr != NULL; attr = ldap_next_attribute( ld, entry, ber ) ){
+ /* make sure the attribute is nsds50ruv */
+ if(strcasecmp(attr,"nsds50ruv") != 0){
+ continue;
+ }
+ if ((vals = ldap_get_values_len( ld, entry, attr)) != NULL ) {
+ for ( i = 0; vals[i] && vals[i]->bv_val; i++ ) {
+ /* look for this replica */
+ if(strstr(rid_text, vals[i]->bv_val)){
+ /* rid has not been cleaned yet, start over */
+ found = 1;
+ break;
+ }
+ }
+ ldap_value_free_len(vals);
+ }
+ ldap_memfree( attr );
+ }
+ if ( ber != NULL ) {
+ ber_free( ber, 0 );
+ }
+ }
+ ldap_msgfree( result );
+ /*
+ * Unlock the connection, and start the linger timer
+ */
+ conn_unlock(conn);
+ conn_start_linger(conn);
+
+ if(found){
+ /*
+ * If we've been trying to clean these replicas for over an hour, just quit
+ */
+ if( (current_time() - start_time) > 3600){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: timed out checking if replicas have "
+ "been cleaned. The rid has not been released, you need to rerun the task.\n");
+ goto done;
+ }
+ /*
+ * a rid has not been cleaned yet, go back to sleep and check them again
+ */
+ break;
+ }
+
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ }
+ if(!found){
+ /*
+ * The replicas have been cleaned! Next, release the rid
+ */
+ replicas_cleaned = 1;
+ break;
+ }
+ } /* while */
+
+ /*
+ * If the replicas are cleaned, release the rid
+ */
+ if(replicas_cleaned){
+ rc = replica_execute_release_ruv_task(data->repl_obj, data->rid);
+ if(rc == 0){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully Finished. All active "
+ "replicas have been cleaned.\n");
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Failed: Replica ID was not released (%d) "
+ "You will need to rerun the task.\n", rc);
+ }
+ } else {
+ /*
+ * Shutdown
+ */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: slapd shutting down, you will need to rerun the task.\n");
+ }
+
+done:
+ slapi_ch_free((void **)&rid_text);
+ slapi_ch_free((void **)&data);
+}
+
+/*
+ * This function releases the cleaned rid so that it can be reused.
+ * We send this operation to all the known active replicas.
+ */
static int
-replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext)
+replica_execute_release_ruv_task(Object *r, ReplicaId rid)
{
Repl_Connection *conn;
Replica *replica = (Replica*)object_get_data (r);
@@ -1293,7 +1482,7 @@ replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext)
int send_msgid = 0;
int rc = 0;
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseRUV_task: releasing rid (%d)...\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: releasing rid (%d)...\n", rid);
/*
* Set the released rid, and trigger cl trimmming
@@ -1339,18 +1528,18 @@ replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext)
conn_cancel_linger(conn);
crc = conn_send_extended_operation(conn, REPL_RELEASERUV_OID, payload, NULL, &send_msgid);
if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: failed to send "
- "releaseruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to send "
+ "releaseRUV extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
rc = LDAP_OPERATIONS_ERROR;
} else {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseRUV_task: successfully sent "
- "extended op to (%s)\n",slapi_sdn_get_dn(dn));
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: successfully sent "
+ "releaseRUV extended op to (%s)\n",slapi_sdn_get_dn(dn));
}
conn_start_linger(conn);
}
if(crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: replica (%s) has not "
- "been cleaned. You will need to rerun the RELEASERUV task on this replica\n",
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica (%s) has not "
+ "been released. You will need to rerun the task\n",
slapi_sdn_get_dn(dn));
rc = crc;
}
@@ -1364,9 +1553,9 @@ done:
if(rc == 0){
set_released_rid(ALREADY_RELEASED);
delete_cleaned_rid();
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseRUV_task: Successfully released rid (%d)\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully released rid (%d)\n", rid);
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: Failed to release rid (%d), error (%d)\n", rid, rc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Failed to release rid (%d), error (%d)\n", rid, rc);
}
if(payload)
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index e4abde0..f6378d2 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1388,18 +1388,21 @@ free_and_return:
int
multimaster_extop_cleanruv(Slapi_PBlock *pb){
multimaster_mtnode_extension *mtnode_ext;
+ PRThread *thread = NULL;
Repl_Connection *conn;
const Slapi_DN *dn;
Replica *r = NULL;
Object *agmt_obj;
Repl_Agmt *agmt;
ConnResult crc;
+ cleanruv_data *data = NULL;
struct berval *extop_value;
char *extop_oid;
char *repl_root;
char *payload = NULL;
char *iter;
int send_msgid = 0;
+ int agmt_count = 0;
int rid = 0;
int rc = 0;
@@ -1411,41 +1414,39 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb){
/* something is wrong, error out */
return -1;
}
-
/*
* Extract the rid and repl_root from the payload
*/
if(decode_cleanruv_payload(extop_value, &payload)){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to decode payload. Aborting ext op\n");
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to decode payload. Aborting ext op\n");
return -1;
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: cleaning rid (%d)...\n",rid);
-
/*
* If we already cleaned this server, just return success
*/
if(is_cleaned_rid(rid)){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: rid (%d) has already been cleaned, skipping\n",rid);
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_extop: rid (%d) has already been cleaned, skipping\n",rid);
return rc;
} else {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: cleaning rid (%d)...\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: cleaning rid (%d)...\n", rid);
+ set_cleaned_rid(rid);
}
/*
* Get the node, so we can get the replica and its agreements
*/
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to get replication node "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to get replication node "
"from (%s), aborting operation\n", repl_root);
return -1;
}
if (mtnode_ext->replica)
object_acquire (mtnode_ext->replica);
if (mtnode_ext->replica == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: replica is missing from (%s), "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: replica is missing from (%s), "
"aborting operation\n",repl_root);
rc = LDAP_OPERATIONS_ERROR;
goto free_and_return;
@@ -1466,36 +1467,37 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb){
conn = (Repl_Connection *)agmt_get_connection(agmt);
if(conn == NULL){
/* no connection for this agreement, move on to the next agmt */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: the replica (%s), is "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: the replica (%s), is "
"missing the connection. This replica will not be cleaned.\n", slapi_sdn_get_dn(dn));
agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
continue;
}
crc = conn_connect(conn);
if (CONN_OPERATION_FAILED == crc ){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to connect "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to connect "
"to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
rc = LDAP_OPERATIONS_ERROR;
} else if (CONN_SSL_NOT_ENABLED == crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to acquire "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to acquire "
"repl agmt connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
rc = LDAP_OPERATIONS_ERROR;
} else {
conn_cancel_linger(conn);
crc = conn_send_extended_operation(conn, REPL_CLEANRUV_OID, extop_value, NULL, &send_msgid);
if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to send "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to send "
"clean_ruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
rc = LDAP_OPERATIONS_ERROR;
} else {
/* success */
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: successfully sent "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: successfully sent "
"extended op to (%s)\n",slapi_sdn_get_dn(dn) );
+ agmt_count++;
}
conn_start_linger(conn);
}
if(crc != CONN_OPERATION_SUCCESS){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: replica (%s) has not "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: replica (%s) has not "
"been cleaned. You will need to rerun the CLEANALLRUV task on this replica\n",
slapi_sdn_get_dn(dn) );
rc = LDAP_OPERATIONS_ERROR;
@@ -1508,10 +1510,30 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb){
free_and_return:
- if(rc == 0){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: cleaned rid (%d)\n", rid);
+ if(rc == 0 && agmt_count > 0){
+ /*
+ * Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid
+ */
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to allocate "
+ "cleanruv_Data\n");
+ return -1;
+ }
+ data->repl_obj = mtnode_ext->replica;
+ data->rid = rid;
+
+ thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_monitor_thread,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: unable to create cleanAllRUV "
+ "monitoring thread. Aborting task.\n");
+ }
+ } else if (rc == 0){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: Successfully Finished.\n");
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to clean rid (%d), error (%d)\n",rid, rc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanALLRUV_extop: failed to clean rid (%d), error (%d)\n",rid, rc);
}
if (mtnode_ext->replica)
@@ -1558,34 +1580,34 @@ multimaster_extop_releaseruv(Slapi_PBlock *pb){
}
if(decode_cleanruv_payload(extop_value, &payload)){
- slapi_log_error(SLAPI_LOG_FATAL,repl_plugin_name, "releaseruv_extop: failed to decode payload, aborting ext op\n");
+ slapi_log_error(SLAPI_LOG_FATAL,repl_plugin_name, "releaseRUV_extop: failed to decode payload, aborting ext op.\n");
return -1;
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: releasing rid (%d)...\n",rid);
/*
* If we already released this ruv, just return.
*/
if(is_released_rid(rid) || is_already_released_rid()){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: rid (%d) has already been released, skipping\n",rid);
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_extop: rid (%d) has already been released, skipping.\n",rid);
return 0;
} else {
/* set the released rid, and trigger trimming */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: releasing rid (%d)...\n", rid);
set_released_rid((int)rid);
trigger_cl_trimming();
}
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to get node "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: failed to get node "
"from replication root dn(%s), aborting operation.\n", repl_root);
return -1;
}
if (mtnode_ext->replica)
object_acquire (mtnode_ext->replica);
if (mtnode_ext->replica == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: replica is missing from (%s), "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: replica is missing from (%s), "
"aborting operation.\n", repl_root);
rc = LDAP_OPERATIONS_ERROR;
goto free_and_return;
@@ -1606,38 +1628,38 @@ multimaster_extop_releaseruv(Slapi_PBlock *pb){
conn = (Repl_Connection *)agmt_get_connection(agmt);
if(conn == NULL){
/* no connection for this agreement, log error, and move on */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: the replica (%s), is "
- "missing the connection. This replica will not be cleaned.\n", slapi_sdn_get_dn(dn));
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: the replica (%s), is "
+ "missing the connection. This replica will not be released.\n", slapi_sdn_get_dn(dn));
agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
continue;
}
crc = conn_connect(conn);
if (CONN_OPERATION_FAILED == crc ){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to connect "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: failed to connect "
"to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
rc = LDAP_OPERATIONS_ERROR;
} else if (CONN_SSL_NOT_ENABLED == crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to acquire "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: failed to acquire "
"repl agmt connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
rc = LDAP_OPERATIONS_ERROR;
} else {
conn_cancel_linger(conn);
crc = conn_send_extended_operation(conn, REPL_RELEASERUV_OID, extop_value, NULL, &send_msgid);
if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to send "
- "releaseruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to send "
+ "releaseRUV extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
rc = LDAP_OPERATIONS_ERROR;
} else {
/* success */
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: successfully sent "
- "extended op to (%s)\n",slapi_sdn_get_dn(dn) );
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: successfully sent "
+ "releaseRUV extended op to (%s)\n",slapi_sdn_get_dn(dn) );
rc = 0;
}
conn_start_linger(conn);
}
if(crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: replica (%s) has not "
- "been cleaned. You will need to rerun the RELEASERUV task on this replica\n",
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: replica (%s) has not "
+ "been released. You will need to rerun the task.\n",
slapi_sdn_get_dn(dn) );
}
agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
@@ -1650,9 +1672,10 @@ free_and_return:
if(rc == 0){
set_released_rid(ALREADY_RELEASED);
delete_cleaned_rid();
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: released rid (%d) successfully\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: Successfully released rid (%d)\n", rid);
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to release rid(%d), error (%d), please retry the task\n",rid, rc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: Failed to release rid(%d), error (%d), "
+ "please retry the task.\n",rid, rc);
}
if(mtnode_ext->replica)
commit 8f17da54a0bddbf6f01549cfdadbce66a52aae37
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri May 25 12:26:02 2012 -0400
Ticket #110 - RFE limiting root DN by host, IP, time of day, day of week
RFE Description: There is no way to restrict when and where some one can attempt
root DN binds. An intruder can brute force guess the password all
day long until they succeed, especailly if the DS is publicly
available.
Fix Description: Created a new plugin, type "internalpreoperation" and an internal
preop bind function. You can configure the plugin with some basic
access control:
rootdn-open-time: 0800
rootdn-close-time: 1700
rootdn-days-allowed: Mon, Tue, Wed, Thu, Fri
rootdn-allow-host: *.redhat.com
rootdn-allow-host: *.fedora.com
rootdn-deny-host: dangerous.boracle.com
rootdn-allow-ip: 127.0.0.1
rootdn-allow-ip: 2000:db8:de30::11
rootdn-deny-ip: 192.168.1.*
As with our other ACL code, deny's always override the allow rules.
https://fedorahosted.org/389/ticket/110
Reviewed by: richm(Thanks Rich!)
(cherry picked from commit c61ee8e16c3e3ca91ffef725fadbeb0a62fb5e80)
diff --git a/Makefile.am b/Makefile.am
index cf91842..d90cd4b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -205,7 +205,7 @@ serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \
libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \
libroles-plugin.la libstatechange-plugin.la libsyntax-plugin.la \
libviews-plugin.la libschemareload-plugin.la libusn-plugin.la \
- libacctusability-plugin.la $(LIBACCTPOLICY_PLUGIN) \
+ libacctusability-plugin.la librootdn-access-plugin.la $(LIBACCTPOLICY_PLUGIN) \
$(LIBPAM_PASSTHRU_PLUGIN) $(LIBDNA_PLUGIN) \
$(LIBBITWISE_PLUGIN) $(LIBPRESENCE_PLUGIN)
@@ -822,6 +822,17 @@ libacl_plugin_la_LDFLAGS = -avoid-version
libacl_plugin_la_LINK = $(CXXLINK) -avoid-version
#------------------------
+# librootdn-access-plugin
+#------------------------
+#
+librootdn_access_plugin_la_SOURCES = ldap/servers/plugins/rootdn_access/rootdn_access.c
+
+librootdn_access_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+librootdn_access_plugin_la_LIBADD = libslapd.la $(NSPR_LINK)
+librootdn_access_plugin_la_LDFLAGS = -avoid-version
+
+
+#------------------------
# libautomember-plugin
#------------------------
libautomember_plugin_la_SOURCES = ldap/servers/plugins/automember/automember.c
diff --git a/Makefile.in b/Makefile.in
index ab2f657..915e978 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -581,6 +581,15 @@ libroles_plugin_la_OBJECTS = $(am_libroles_plugin_la_OBJECTS)
libroles_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libroles_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
+librootdn_access_plugin_la_DEPENDENCIES = libslapd.la \
+ $(am__DEPENDENCIES_1)
+am_librootdn_access_plugin_la_OBJECTS = ldap/servers/plugins/rootdn_access/librootdn_access_plugin_la-rootdn_access.lo
+librootdn_access_plugin_la_OBJECTS = \
+ $(am_librootdn_access_plugin_la_OBJECTS)
+librootdn_access_plugin_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(librootdn_access_plugin_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
libschemareload_plugin_la_DEPENDENCIES = libslapd.la \
$(am__DEPENDENCIES_1)
am_libschemareload_plugin_la_OBJECTS = ldap/servers/plugins/schema_reload/libschemareload_plugin_la-schema_reload.lo
@@ -1001,6 +1010,7 @@ SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
$(libreferint_plugin_la_SOURCES) \
$(libreplication_plugin_la_SOURCES) \
$(libretrocl_plugin_la_SOURCES) $(libroles_plugin_la_SOURCES) \
+ $(librootdn_access_plugin_la_SOURCES) \
$(libschemareload_plugin_la_SOURCES) $(libslapd_la_SOURCES) \
$(libstatechange_plugin_la_SOURCES) \
$(libsyntax_plugin_la_SOURCES) $(libusn_plugin_la_SOURCES) \
@@ -1033,6 +1043,7 @@ DIST_SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
$(libreferint_plugin_la_SOURCES) \
$(libreplication_plugin_la_SOURCES) \
$(libretrocl_plugin_la_SOURCES) $(libroles_plugin_la_SOURCES) \
+ $(librootdn_access_plugin_la_SOURCES) \
$(libschemareload_plugin_la_SOURCES) \
$(am__libslapd_la_SOURCES_DIST) \
$(libstatechange_plugin_la_SOURCES) \
@@ -1411,7 +1422,7 @@ serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \
libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \
libroles-plugin.la libstatechange-plugin.la libsyntax-plugin.la \
libviews-plugin.la libschemareload-plugin.la libusn-plugin.la \
- libacctusability-plugin.la $(LIBACCTPOLICY_PLUGIN) \
+ libacctusability-plugin.la librootdn-access-plugin.la $(LIBACCTPOLICY_PLUGIN) \
$(LIBPAM_PASSTHRU_PLUGIN) $(LIBDNA_PLUGIN) \
$(LIBBITWISE_PLUGIN) $(LIBPRESENCE_PLUGIN)
@@ -1968,6 +1979,15 @@ libacl_plugin_la_LDFLAGS = -avoid-version
libacl_plugin_la_LINK = $(CXXLINK) -avoid-version
#------------------------
+# librootdn-access-plugin
+#------------------------
+#
+librootdn_access_plugin_la_SOURCES = ldap/servers/plugins/rootdn_access/rootdn_access.c
+librootdn_access_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+librootdn_access_plugin_la_LIBADD = libslapd.la $(NSPR_LINK)
+librootdn_access_plugin_la_LDFLAGS = -avoid-version
+
+#------------------------
# libautomember-plugin
#------------------------
libautomember_plugin_la_SOURCES = ldap/servers/plugins/automember/automember.c
@@ -3784,6 +3804,17 @@ ldap/servers/plugins/roles/libroles_plugin_la-roles_plugin.lo: \
ldap/servers/plugins/roles/$(DEPDIR)/$(am__dirstamp)
libroles-plugin.la: $(libroles_plugin_la_OBJECTS) $(libroles_plugin_la_DEPENDENCIES)
$(libroles_plugin_la_LINK) -rpath $(serverplugindir) $(libroles_plugin_la_OBJECTS) $(libroles_plugin_la_LIBADD) $(LIBS)
+ldap/servers/plugins/rootdn_access/$(am__dirstamp):
+ @$(MKDIR_P) ldap/servers/plugins/rootdn_access
+ @: > ldap/servers/plugins/rootdn_access/$(am__dirstamp)
+ldap/servers/plugins/rootdn_access/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) ldap/servers/plugins/rootdn_access/$(DEPDIR)
+ @: > ldap/servers/plugins/rootdn_access/$(DEPDIR)/$(am__dirstamp)
+ldap/servers/plugins/rootdn_access/librootdn_access_plugin_la-rootdn_access.lo: \
+ ldap/servers/plugins/rootdn_access/$(am__dirstamp) \
+ ldap/servers/plugins/rootdn_access/$(DEPDIR)/$(am__dirstamp)
+librootdn-access-plugin.la: $(librootdn_access_plugin_la_OBJECTS) $(librootdn_access_plugin_la_DEPENDENCIES)
+ $(librootdn_access_plugin_la_LINK) -rpath $(serverplugindir) $(librootdn_access_plugin_la_OBJECTS) $(librootdn_access_plugin_la_LIBADD) $(LIBS)
ldap/servers/plugins/schema_reload/$(am__dirstamp):
@$(MKDIR_P) ldap/servers/plugins/schema_reload
@: > ldap/servers/plugins/schema_reload/$(am__dirstamp)
@@ -5017,6 +5048,8 @@ mostlyclean-compile:
-rm -f ldap/servers/plugins/roles/libroles_plugin_la-roles_cache.lo
-rm -f ldap/servers/plugins/roles/libroles_plugin_la-roles_plugin.$(OBJEXT)
-rm -f ldap/servers/plugins/roles/libroles_plugin_la-roles_plugin.lo
+ -rm -f ldap/servers/plugins/rootdn_access/librootdn_access_plugin_la-rootdn_access.$(OBJEXT)
+ -rm -f ldap/servers/plugins/rootdn_access/librootdn_access_plugin_la-rootdn_access.lo
-rm -f ldap/servers/plugins/schema_reload/libschemareload_plugin_la-schema_reload.$(OBJEXT)
-rm -f ldap/servers/plugins/schema_reload/libschemareload_plugin_la-schema_reload.lo
-rm -f ldap/servers/plugins/statechange/libstatechange_plugin_la-statechange.$(OBJEXT)
@@ -5714,6 +5747,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/rever/$(DEPDIR)/libdes_plugin_la-rever.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/roles/$(DEPDIR)/libroles_plugin_la-roles_cache.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/roles/$(DEPDIR)/libroles_plugin_la-roles_plugin.Plo(a)am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/rootdn_access/$(DEPDIR)/librootdn_access_plugin_la-rootdn_access.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/schema_reload/$(DEPDIR)/libschemareload_plugin_la-schema_reload.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/statechange/$(DEPDIR)/libstatechange_plugin_la-statechange.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-bin.Plo(a)am__quote@
@@ -7758,6 +7792,13 @@ ldap/servers/plugins/roles/libroles_plugin_la-roles_plugin.lo: ldap/servers/plug
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libroles_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/roles/libroles_plugin_la-roles_plugin.lo `test -f 'ldap/servers/plugins/roles/roles_plugin.c' || echo '$(srcdir)/'`ldap/servers/plugins/roles/roles_plugin.c
+ldap/servers/plugins/rootdn_access/librootdn_access_plugin_la-rootdn_access.lo: ldap/servers/plugins/rootdn_access/rootdn_access.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librootdn_access_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/rootdn_access/librootdn_access_plugin_la-rootdn_access.lo -MD -MP -MF ldap/servers/plugins/rootdn_access/$(DEPDIR)/librootdn_access_plugin_la-rootdn_access.Tpo -c -o ldap/servers/plugins/rootdn_access/librootdn_access_plugin_la-rootdn_access.lo `test -f 'ldap/servers/plugins/rootdn_access/rootdn_access.c' || echo '$(srcdir)/'`ldap/servers/plugins/rootdn_access/rootdn_access.c
+@am__fastdepCC_TRUE@ $(am__mv) ldap/servers/plugins/rootdn_access/$(DEPDIR)/librootdn_access_plugin_la-rootdn_access.Tpo ldap/servers/plugins/rootdn_access/$(DEPDIR)/librootdn_access_plugin_la-rootdn_access.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ldap/servers/plugins/rootdn_access/rootdn_access.c' object='ldap/servers/plugins/rootdn_access/librootdn_access_plugin_la-rootdn_access.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librootdn_access_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/rootdn_access/librootdn_access_plugin_la-rootdn_access.lo `test -f 'ldap/servers/plugins/rootdn_access/rootdn_access.c' || echo '$(srcdir)/'`ldap/servers/plugins/rootdn_access/rootdn_access.c
+
ldap/servers/plugins/schema_reload/libschemareload_plugin_la-schema_reload.lo: ldap/servers/plugins/schema_reload/schema_reload.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libschemareload_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/schema_reload/libschemareload_plugin_la-schema_reload.lo -MD -MP -MF ldap/servers/plugins/schema_reload/$(DEPDIR)/libschemareload_plugin_la-schema_reload.Tpo -c -o ldap/servers/plugins/schema_reload/libschemareload_plugin_la-schema_reload.lo `test -f 'ldap/servers/plugins/schema_reload/schema_reload.c' || echo '$(srcdir)/'`ldap/servers/plugins/schema_reload/schema_reload.c
@am__fastdepCC_TRUE@ $(am__mv) ldap/servers/plugins/schema_reload/$(DEPDIR)/libschemareload_plugin_la-schema_reload.Tpo ldap/servers/plugins/schema_reload/$(DEPDIR)/libschemareload_plugin_la-schema_reload.Plo
@@ -9779,6 +9820,7 @@ clean-libtool:
-rm -rf ldap/servers/plugins/retrocl/.libs ldap/servers/plugins/retrocl/_libs
-rm -rf ldap/servers/plugins/rever/.libs ldap/servers/plugins/rever/_libs
-rm -rf ldap/servers/plugins/roles/.libs ldap/servers/plugins/roles/_libs
+ -rm -rf ldap/servers/plugins/rootdn_access/.libs ldap/servers/plugins/rootdn_access/_libs
-rm -rf ldap/servers/plugins/schema_reload/.libs ldap/servers/plugins/schema_reload/_libs
-rm -rf ldap/servers/plugins/statechange/.libs ldap/servers/plugins/statechange/_libs
-rm -rf ldap/servers/plugins/syntaxes/.libs ldap/servers/plugins/syntaxes/_libs
@@ -10425,6 +10467,8 @@ distclean-generic:
-rm -f ldap/servers/plugins/rever/$(am__dirstamp)
-rm -f ldap/servers/plugins/roles/$(DEPDIR)/$(am__dirstamp)
-rm -f ldap/servers/plugins/roles/$(am__dirstamp)
+ -rm -f ldap/servers/plugins/rootdn_access/$(DEPDIR)/$(am__dirstamp)
+ -rm -f ldap/servers/plugins/rootdn_access/$(am__dirstamp)
-rm -f ldap/servers/plugins/schema_reload/$(DEPDIR)/$(am__dirstamp)
-rm -f ldap/servers/plugins/schema_reload/$(am__dirstamp)
-rm -f ldap/servers/plugins/statechange/$(DEPDIR)/$(am__dirstamp)
@@ -10475,7 +10519,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acct_usability/$(DEPDIR) ldap/servers/plugins/acctpolicy/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/automember/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR)
ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
+ -rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acct_usability/$(DEPDIR) ldap/servers/plugins/acctpolicy/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/automember/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR)
ldap/servers/plugins/rootdn_access/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags
@@ -10531,7 +10575,7 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
- -rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acct_usability/$(DEPDIR) ldap/servers/plugins/acctpolicy/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/automember/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR)
ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
+ -rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acct_usability/$(DEPDIR) ldap/servers/plugins/acctpolicy/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/automember/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR)
ldap/servers/plugins/rootdn_access/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in
index 5107d72..ddf2b35 100644
--- a/ldap/ldif/template-dse.ldif.in
+++ b/ldap/ldif/template-dse.ldif.in
@@ -734,6 +734,17 @@ nsslapd-plugintype: object
nsslapd-pluginenabled: off
nsslapd-plugin-depends-on-type: database
+dn: cn=RootDN Access Control,cn=plugins,cn=config
+objectclass: top
+objectclass: nsSlapdPlugin
+objectclass: extensibleObject
+cn: RootDN Access Control
+nsslapd-pluginpath: librootdn-access-plugin.so
+nsslapd-plugininitfunc: rootdn_init
+nsslapd-plugintype: internalpreoperation
+nsslapd-pluginenabled: off
+nsslapd-plugin-depends-on-type: database
+
dn: cn=ldbm database,cn=plugins,cn=config
objectclass: top
objectclass: nsSlapdPlugin
diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c
new file mode 100644
index 0000000..7fb5615
--- /dev/null
+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c
@@ -0,0 +1,663 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/*
+ * Root DN Access Control plug-in
+ */
+#include "rootdn_access.h"
+#include <nspr.h>
+#include <time.h>
+#include <ctype.h>
+
+/*
+ * Add an entry like the following to dse.ldif to enable this plugin:
+ *
+ * dn: cn=RootDN Access Control,cn=plugins,cn=config
+ * objectclass: top
+ * objectclass: nsSlapdPlugin
+ * objectclass: extensibleObject
+ * cn: RootDN Access Control
+ * nsslapd-pluginpath: librootdn-access-plugin.so
+ * nsslapd-plugininitfunc: rootdn_init
+ * nsslapd-plugintype: rootdnpreoperation
+ * nsslapd-pluginenabled: on
+ * nsslapd-plugin-depends-on-type: database
+ * nsslapd-pluginid: rootdn-access-control
+ * rootdn-open-time: 0800
+ * rootdn-close-time: 1700
+ * rootdn-days-allowed: Mon, Tue, Wed, Thu, Fri
+ * rootdn-allow-host: *.redhat.com
+ * rootdn-allow-host: *.fedora.com
+ * rootdn-deny-host: dangerous.boracle.com
+ * rootdn-allow-ip: 127.0.0.1
+ * rootdn-allow-ip: 2000:db8:de30::11
+ * rootdn-deny-ip: 192.168.1.*
+ *
+ */
+
+/*
+ * Plugin Functions
+ */
+int rootdn_init(Slapi_PBlock *pb);
+static int rootdn_start(Slapi_PBlock *pb);
+static int rootdn_load_config(Slapi_PBlock *pb);
+static int rootdn_check_access(Slapi_PBlock *pb);
+static int rootdn_check_host_wildcard(char *host, char *client_host);
+static int rootdn_check_ip_wildcard(char *ip, char *client_ip);
+static int rootdn_preop_bind_init(Slapi_PBlock *pb);
+char * strToLower(char *str);
+
+/*
+ * Plug-in globals
+ */
+static void *_PluginID = NULL;
+static char *_PluginDN = NULL;
+static int g_plugin_started = 0;
+static int open_time = 0;
+static int close_time = 0;
+static char *daysAllowed = NULL;
+static char **hosts = NULL;
+static char **hosts_to_deny = NULL;
+static char **ips = NULL;
+static char **ips_to_deny = NULL;
+
+static Slapi_PluginDesc pdesc = { ROOTDN_FEATURE_DESC,
+ VENDOR,
+ DS_PACKAGE_VERSION,
+ ROOTDN_PLUGIN_DESC };
+
+/*
+ * Plugin identity functions
+ */
+void
+rootdn_set_plugin_id(void *pluginID)
+{
+ _PluginID = pluginID;
+}
+
+void *
+rootdn_get_plugin_id()
+{
+ return _PluginID;
+}
+
+void
+rootdn_set_plugin_dn(char *pluginDN)
+{
+ _PluginDN = pluginDN;
+}
+
+char *
+rootdn_get_plugin_dn()
+{
+ return _PluginDN;
+}
+
+
+int
+rootdn_init(Slapi_PBlock *pb){
+ int status = 0;
+ char *plugin_identity = NULL;
+
+ slapi_log_error(SLAPI_LOG_TRACE, ROOTDN_PLUGIN_SUBSYSTEM,
+ "--> rootdn_init\n");
+
+ /* Store the plugin identity for later use. Used for internal operations. */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &plugin_identity);
+ PR_ASSERT(plugin_identity);
+ rootdn_set_plugin_id(plugin_identity);
+
+ /* Register callbacks */
+ if(slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *) rootdn_start) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *) &pdesc) != 0 )
+ {
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_init: failed to register plugin\n");
+ status = -1;
+ }
+
+ /* for this plugin we don't want to skip over root dn's when binding */
+ slapi_set_plugin_open_rootdn_bind(pb);
+
+ if (!status &&
+ slapi_register_plugin("internalpreoperation", /* op type */
+ 1, /* Enabled */
+ "rootdn_preop_bind_init", /* this function desc */
+ rootdn_preop_bind_init, /* init func */
+ ROOTDN_PLUGIN_DESC, /* plugin desc */
+ NULL, /* ? */
+ plugin_identity /* access control */
+ )) {
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM,
+ "rootdn_init: failed to register rootdn preoperation plugin\n");
+ status = -1;
+ }
+
+ /*
+ * Load the config
+ */
+ if(rootdn_load_config(pb) != 0){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM,
+ "rootdn_start: unable to load plug-in configuration\n");
+ return -1;
+ }
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM,"<-- rootdn_init\n");
+ return status;
+}
+
+static int
+rootdn_preop_bind_init(Slapi_PBlock *pb)
+{
+ if(slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN, (void *) rootdn_check_access) != 0){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM,"rootdn_preop_bind_init: "
+ "failed to register function\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+rootdn_start(Slapi_PBlock *pb){
+ /* Check if we're already started */
+ if (g_plugin_started) {
+ goto done;
+ }
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "--> rootdn_start\n");
+
+ g_plugin_started = 1;
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "<-- rootdn_start\n");
+
+done:
+ return 0;
+}
+
+static int
+rootdn_load_config(Slapi_PBlock *pb)
+{
+ Slapi_Entry *e = NULL;
+ char *openTime, *closeTime;
+ char hour[3], min[3];
+ int result = 0;
+ int i;
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "--> rootdn_load_config\n");
+
+ if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &e) == 0) && e){
+ /*
+ * Grab our plugin settings
+ */
+ openTime = slapi_entry_attr_get_charptr(e, "rootdn-open-time");
+ closeTime = slapi_entry_attr_get_charptr(e, "rootdn-close-time");
+ daysAllowed = slapi_entry_attr_get_charptr(e, "rootdn-days-allowed");
+ hosts = slapi_entry_attr_get_charray(e, "rootdn-allow-host");
+ hosts_to_deny = slapi_entry_attr_get_charray(e, "rootdn-deny-host");
+ ips = slapi_entry_attr_get_charray(e, "rootdn-allow-ip");
+ ips_to_deny = slapi_entry_attr_get_charray(e, "rootdn-deny-ip");
+ /*
+ * Validate out settings
+ */
+ if(daysAllowed){
+ if(strcspn(daysAllowed, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ,")){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "invalid rootdn-days-allowed value (%s), must be all letters, and comma separators\n",closeTime);
+ slapi_ch_free_string(&daysAllowed);
+ return -1;
+ }
+ daysAllowed = strToLower(daysAllowed);
+ }
+ if(openTime){
+ if (strcspn(openTime, "0123456789")){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "invalid rootdn-open-time value (%s), must be all digits\n",openTime);
+ slapi_ch_free_string(&openTime);
+ return -1;
+ }
+ if(strlen(openTime) != 4){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "invalid format for rootdn-open-time value (%s). Should be HHMM\n", openTime);
+ slapi_ch_free_string(&openTime);
+ return -1;
+ }
+ /*
+ * convert the time to all seconds
+ */
+ strncpy(hour, openTime,2);
+ strncpy(min, openTime+2,2);
+ open_time = (atoi(hour) * 3600) + (atoi(min) * 60);
+ }
+ if(closeTime){
+ if (strcspn(closeTime, "0123456789")){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "invalid rootdn-open-time value (%s), must be all digits, and should be HHMM\n",closeTime);
+ slapi_ch_free_string(&closeTime);
+ return -1;
+ }
+ if(strlen(closeTime) != 4){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "invalid format for rootdn-open-time value (%s), should be HHMM\n", closeTime);
+ slapi_ch_free_string(&closeTime);
+ return -1;
+ }
+ /*
+ * convert the time to all seconds
+ */
+
+ strncpy(hour, closeTime,2);
+ strncpy(min, closeTime+2,2);
+ close_time = (atoi(hour) * 3600) + (atoi(min) * 60);
+ }
+ if((openTime && closeTime == NULL) || (openTime == NULL && closeTime)){
+ /* If you are using TOD access control, you must have a open and close time */
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "there must be a open and a close time\n");
+ slapi_ch_free_string(&closeTime);
+ slapi_ch_free_string(&openTime);
+ return -1;
+ }
+ if(close_time && open_time && close_time <= open_time){
+ /* Make sure the closing time is greater than the open time */
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "the close time must be greater than the open time\n");
+ result = -1;
+ }
+ if(hosts){
+ for(i = 0; hosts[i] != NULL; i++){
+ if(strcspn(hosts[i], "0123456789.*-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "hostname (%s) contians invalid characters, skipping\n",hosts[i]);
+ slapi_ch_free_string(&hosts[i]);
+ hosts[i] = slapi_ch_strdup("!invalid");
+ continue;
+ }
+ }
+ }
+ if(hosts_to_deny){
+ for(i = 0; hosts_to_deny[i] != NULL; i++){
+ if(strcspn(hosts_to_deny[i], "0123456789.*-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "hostname (%s) contians invalid characters, skipping\n",hosts_to_deny[i]);
+ slapi_ch_free_string(&hosts_to_deny[i]);
+ hosts_to_deny[i] = slapi_ch_strdup("!invalid");
+ continue;
+ }
+ }
+ }
+ if(ips){
+ for(i = 0; ips[i] != NULL; i++){
+ if(strcspn(ips[i], "0123456789:ABCDEFabcdef.*")){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "IP address contains invalid characters (%s), skipping\n", ips[i]);
+ slapi_ch_free_string(&ips[i]);
+ ips[i] = slapi_ch_strdup("!invalid");
+ continue;
+ }
+ if(strstr(ips[i],":") == 0){
+ /*
+ * IPv4 - make sure it's just numbers, dots, and wildcard
+ */
+ if(strcspn(ips[i], "0123456789.*")){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "IPv4 address contains invalid characters (%s), skipping\n", ips[i]);
+ slapi_ch_free_string(&ips[i]);
+ ips[i] = slapi_ch_strdup("!invalid");
+ continue;
+ }
+ }
+ }
+ }
+ if(ips_to_deny){
+ for(i = 0; ips_to_deny[i] != NULL; i++){
+ if(strcspn(ips_to_deny[i], "0123456789:ABCDEFabcdef.*")){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "IP address contains invalid characters (%s), skipping\n", ips_to_deny[i]);
+ slapi_ch_free_string(&ips_to_deny[i]);
+ ips_to_deny[i] = slapi_ch_strdup("!invalid");
+ continue;
+ }
+ if(strstr(ips_to_deny[i],":") == 0){
+ /*
+ * IPv4 - make sure it's just numbers, dots, and wildcard
+ */
+ if(strcspn(ips_to_deny[i], "0123456789.*")){
+ slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config: "
+ "IPv4 address contains invalid characters (%s), skipping\n", ips_to_deny[i]);
+ slapi_ch_free_string(&ips_to_deny[i]);
+ ips_to_deny[i] = slapi_ch_strdup("!invalid");
+ continue;
+ }
+ }
+ }
+ }
+ slapi_ch_free_string(&openTime);
+ slapi_ch_free_string(&closeTime);
+ } else {
+ /* failed to get the plugin entry */
+ result = -1;
+ }
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "<-- rootdn_load_config (%d)\n", result);
+
+ return result;
+}
+
+
+static int
+rootdn_check_access(Slapi_PBlock *pb){
+ PRNetAddr *client_addr = NULL;
+ PRHostEnt *host_entry = NULL;
+ time_t curr_time;
+ struct tm *timeinfo;
+ char *dnsName = NULL;
+ int isRoot = 0;
+ int rc = 0;
+ int i;
+
+ /*
+ * Verify this is a root DN
+ */
+ slapi_pblock_get ( pb, SLAPI_REQUESTOR_ISROOT, &isRoot );
+ if(!isRoot){
+ return 0;
+ }
+ /*
+ * grab the current time/info if we need it
+ */
+ if(open_time || daysAllowed){
+ time(&curr_time);
+ timeinfo = localtime(&curr_time);
+ }
+ /*
+ * First check TOD restrictions, continue through if we are in the open "window"
+ */
+ if(open_time){
+ int curr_total;
+
+ curr_total = (timeinfo->tm_hour * 3600) + (timeinfo->tm_min * 60);
+
+ if((curr_total < open_time) || (curr_total >= close_time)){
+ slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: bind not in the "
+ "allowed time window\n");
+ return -1;
+ }
+ }
+ /*
+ * Check if today is an allowed day
+ */
+ if(daysAllowed){
+ char *timestr;
+ char day[4];
+ char *today = day;
+
+ timestr = asctime(timeinfo); // DDD MMM dd hh:mm:ss YYYY
+ 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");
+ return -1;
+ }
+ }
+ /*
+ * Check the host restrictions, deny always overrides allow
+ */
+ if(hosts || hosts_to_deny){
+ char buf[PR_NETDB_BUF_SIZE];
+ char *host;
+
+ /*
+ * Get the client address
+ */
+ client_addr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr));
+ if ( slapi_pblock_get( pb, SLAPI_CONN_CLIENTNETADDR, client_addr ) != 0 ) {
+ slapi_log_error( SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: Could not get client address for hosts.\n" );
+ rc = -1;
+ goto free_and_return;
+ }
+ /*
+ * Get the hostname from the client address
+ */
+ host_entry = (PRHostEnt *)slapi_ch_malloc( sizeof(PRHostEnt) );
+ if ( PR_GetHostByAddr(client_addr, buf, sizeof(buf), host_entry ) == PR_SUCCESS ) {
+ if ( host_entry->h_name != NULL ) {
+ /* copy the hostname */
+ dnsName = slapi_ch_strdup( host_entry->h_name );
+ } else {
+ /* no hostname */
+ slapi_log_error( SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: client address missing hostname\n");
+ rc = -1;
+ goto free_and_return;
+ }
+ } else {
+ slapi_log_error( SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: client IP address could not be resolved\n");
+ rc = -1;
+ goto free_and_return;
+ }
+ /*
+ * Now we have our hostname, now do our checks
+ */
+ if(hosts_to_deny){
+ for(i = 0; hosts_to_deny[i] != NULL; i++){
+ host = hosts_to_deny[i];
+ /* check for wild cards */
+ if(host[0] == '*'){
+ if(rootdn_check_host_wildcard(host, dnsName) == 0){
+ /* match, return failure */
+ rc = -1;
+ goto free_and_return;
+ }
+ } else {
+ if(strcasecmp(host,dnsName) == 0){
+ /* we have a match, return failure */
+ rc = -1;
+ goto free_and_return;
+ }
+ }
+ }
+ rc = 0;
+ }
+ if(hosts){
+ for(i = 0; hosts[i] != NULL; i++){
+ host = hosts[i];
+ /* check for wild cards */
+ if(host[0] == '*'){
+ if(rootdn_check_host_wildcard(host, dnsName) == 0){
+ /* match */
+ rc = 0;
+ goto free_and_return;
+ }
+ } else {
+ if(strcasecmp(host,dnsName) == 0){
+ /* we have a match, */
+ rc = 0;
+ goto free_and_return;
+ }
+ }
+ }
+ rc = -1;
+ }
+ }
+ /*
+ * Check the IP address restrictions, deny always overrides allow
+ */
+ if(ips || ips_to_deny){
+ char ip_str[256];
+ char *ip;
+ int ip_len, i;
+
+ if(client_addr == NULL){
+ client_addr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr));
+ if ( slapi_pblock_get( pb, SLAPI_CONN_CLIENTNETADDR, client_addr ) != 0 ) {
+ slapi_log_error( SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: Could not get client address for IP.\n" );
+ rc = -1;
+ goto free_and_return;
+ }
+ }
+ /*
+ * Check if we are IPv4, so we can grab the correct IP addr for "ip_str"
+ */
+ if ( PR_IsNetAddrType( client_addr, PR_IpAddrV4Mapped ) ) {
+ PRNetAddr v4addr;
+ memset( &v4addr, 0, sizeof( v4addr ) );
+ v4addr.inet.family = PR_AF_INET;
+ v4addr.inet.ip = client_addr->ipv6.ip.pr_s6_addr32[3];
+ if( PR_NetAddrToString( &v4addr, ip_str, sizeof( ip_str )) != PR_SUCCESS){
+ slapi_log_error( SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: Could not get IPv4 from client address.\n" );
+ rc = -1;
+ goto free_and_return;
+ }
+ } else {
+ if( PR_NetAddrToString(client_addr, ip_str, sizeof(ip_str)) != PR_SUCCESS){
+ slapi_log_error( SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access: Could not get IPv6 from client address.\n" );
+ rc = -1;
+ goto free_and_return;
+ }
+ }
+ /*
+ * Now we have our IP address, do our checks
+ */
+ if(ips_to_deny){
+ for(i = 0; ips_to_deny[i] != NULL; i++){
+ ip = ips_to_deny[i];
+ ip_len = strlen(ip);
+ if(ip[ip_len - 1] == '*'){
+ if(rootdn_check_ip_wildcard(ips_to_deny[i], ip_str) == 0){
+ /* match, return failure */
+ rc = -1;
+ goto free_and_return;
+ }
+ } else {
+ if(strcasecmp(ip_str, ip)==0){
+ /* match, return failure */
+ rc = -1;
+ goto free_and_return;
+ }
+ }
+ }
+ rc = 0;
+ }
+ if(ips){
+ for(i = 0; ips[i] != NULL; i++){
+ ip = ips[i];
+ ip_len = strlen(ip);
+ if(ip[ip_len - 1] == '*'){
+ if(rootdn_check_ip_wildcard(ip, ip_str) == 0){
+ /* match, return success */
+ rc = 0;
+ goto free_and_return;
+ }
+ } else {
+ if(strcasecmp(ip_str, ip)==0){
+ /* match, return success */
+ rc = 0;
+ goto free_and_return;
+ }
+ }
+ }
+ rc = -1;
+ }
+ }
+
+free_and_return:
+ slapi_ch_free((void **)&client_addr);
+ slapi_ch_free((void **)&host_entry);
+ slapi_ch_free_string(&dnsName);
+
+ return rc;
+}
+
+static int
+rootdn_check_host_wildcard(char *host, char *client_host)
+{
+ int host_len = strlen(host);
+ int client_len = strlen(client_host);
+ int i, j;
+ /*
+ * Start at the end of the string and move backwards, and skip the first char "*"
+ */
+ if(client_len < host_len){
+ /* this can't be a match */
+ return -1;
+ }
+ for(i = host_len - 1, j = client_len - 1; i > 0; i--, j--){
+ if(host[i] != client_host[j]){
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+rootdn_check_ip_wildcard(char *ip, char *client_ip)
+{
+ int ip_len = strlen(ip);
+ int i;
+ /*
+ * Start at the beginning of the string and move forward, and skip the last char "*"
+ */
+ if(strlen(client_ip) < ip_len){
+ /* this can't be a match */
+ return -1;
+ }
+ for(i = 0; i < ip_len - 1; i++){
+ if(ip[i] != client_ip[i]){
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+char *
+strToLower(char *str){
+ int i;
+
+ for(i = 0; i < strlen(str); i++){
+ str[i] = tolower(str[i]);
+ }
+ return str;
+}
+
+
diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.h b/ldap/servers/plugins/rootdn_access/rootdn_access.h
new file mode 100644
index 0000000..80b8d4a
--- /dev/null
+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.h
@@ -0,0 +1,57 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2011 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/*
+ * Root DN access control plug-in header file
+ */
+#include "slapi-plugin.h"
+#include <nspr.h>
+#include <time.h>
+#include <ctype.h>
+
+#define ROOTDN_PLUGIN_SUBSYSTEM "rootdn-access-control-plugin"
+#define ROOTDN_FEATURE_DESC "Root DN Access Control"
+#define ROOTDN_PLUGIN_DESC "Root DN Access Control plugin"
+#define ROOTDN_PLUGIN_TYPE_DESC "Root DN Access Control plugin"
+
+
+
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index d725d5c..d4d3b49 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -614,21 +614,41 @@ do_bind( Slapi_PBlock *pb )
Slapi_Value cv;
slapi_value_init_berval(&cv,&cred);
- /* right dn and passwd - authorize */
+ /*
+ * Call pre bind root dn plugin for checking root dn access control.
+ *
+ * Do this before checking the password so that we give a consistent error,
+ * regardless if the password is correct or not. Or else it would still be
+ * possible to brute force guess the password even though access would still
+ * be denied.
+ */
+ if (plugin_call_plugins(pb, SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN) != 0){
+ send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
+ "RootDN access control violation", 0, NULL );
+ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
+ value_done(&cv);
+ goto free_and_return;
+ }
+ /*
+ * Check the dn and password
+ */
if ( is_root_dn_pw( slapi_sdn_get_ndn(sdn), &cv )) {
- bind_credentials_set( pb->pb_conn, SLAPD_AUTH_SIMPLE,
- slapi_ch_strdup( slapi_sdn_get_ndn(sdn) ),
+ /*
+ * right dn and passwd - authorize
+ */
+ bind_credentials_set( pb->pb_conn, SLAPD_AUTH_SIMPLE, slapi_ch_strdup(slapi_sdn_get_ndn(sdn)),
NULL, NULL, NULL , NULL);
-
- /* right dn, wrong passwd - reject with invalid creds */
} else {
- send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL,
- NULL, 0, NULL );
+ /*
+ * right dn, wrong passwd - reject with invalid credentials
+ */
+ send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL );
/* increment BindSecurityErrorcount */
slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
value_done(&cv);
goto free_and_return;
}
+
value_done(&cv);
}
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
index 76c031a..4be8efd 100644
--- a/ldap/servers/slapd/pblock.c
+++ b/ldap/servers/slapd/pblock.c
@@ -1062,6 +1062,14 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
(*(IFP *)value) = pblock->pb_plugin->plg_internal_post_delete;
break;
+ /* rootDN pre bind operation plugin */
+ case SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN:
+ if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_INTERNAL_PREOPERATION) {
+ return( -1 );
+ }
+ (*(IFP *)value) = pblock->pb_plugin->plg_internal_pre_bind;
+ break;
+
/* backend pre txn operation plugin */
case SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN:
if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_BETXNPREOPERATION) {
@@ -2620,6 +2628,12 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value )
}
pblock->pb_plugin->plg_internal_pre_delete = (IFP) value;
break;
+ case SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN:
+ if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_INTERNAL_PREOPERATION) {
+ return( -1 );
+ }
+ pblock->pb_plugin->plg_internal_pre_bind = (IFP) value;
+ break;
/* internal postoperation plugin */
case SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN:
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 8aa95ac..436cc02 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -363,6 +363,7 @@ plugin_call_plugins( Slapi_PBlock *pb, int whichfunction )
case SLAPI_PLUGIN_INTERNAL_PRE_MODRDN_FN:
case SLAPI_PLUGIN_INTERNAL_PRE_ADD_FN:
case SLAPI_PLUGIN_INTERNAL_PRE_DELETE_FN:
+ case SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN:
plugin_list_number= PLUGIN_LIST_INTERNAL_PREOPERATION;
break;
case SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN:
@@ -387,6 +388,7 @@ plugin_call_plugins( Slapi_PBlock *pb, int whichfunction )
do_op = 1; /* always allow backend callbacks (even during startup) */
break;
}
+
if(plugin_list_number!=-1 && do_op)
{
/* We stash the pblock plugin pointer to preserve the callers context */
@@ -1705,7 +1707,7 @@ plugin_get_type_and_list(
} else if ( strcasecmp( plugintype, "index" ) == 0 ) {
*type = SLAPI_PLUGIN_INDEX;
plugin_list_index= PLUGIN_LIST_INDEX;
- } else {
+ } else {
return( 1 ); /* unknown plugin type - pass to backend */
}
@@ -3205,3 +3207,10 @@ slapi_get_plugin_default_config(char *type, Slapi_ValueSet **valueset)
return rc;
}
+
+void
+slapi_set_plugin_open_rootdn_bind(Slapi_PBlock *pb){
+ struct pluginconfig *config = &pb->pb_plugin->plg_conf;
+
+ ptd_set_special_data(&(config->plgc_bind_subtrees), PLGC_DATA_BIND_ROOT);
+}
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index b896755..7ca9a35 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1004,11 +1004,13 @@ struct slapdplugin {
IFP plg_un_internal_pre_modrdn; /* modrdn */
IFP plg_un_internal_pre_add; /* add */
IFP plg_un_internal_pre_delete; /* delete */
+ IFP plg_un_internal_pre_bind; /* bind */
} plg_un_internal_pre;
#define plg_internal_pre_modify plg_un.plg_un_internal_pre.plg_un_internal_pre_modify
#define plg_internal_pre_modrdn plg_un.plg_un_internal_pre.plg_un_internal_pre_modrdn
#define plg_internal_pre_add plg_un.plg_un_internal_pre.plg_un_internal_pre_add
#define plg_internal_pre_delete plg_un.plg_un_internal_pre.plg_un_internal_pre_delete
+#define plg_internal_pre_bind plg_un.plg_un_internal_pre.plg_un_internal_pre_bind
/* internal post-operation plugin structure */
struct plg_un_internal_post_operation {
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 659ac61..0aa764d 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6296,6 +6296,7 @@ typedef struct slapi_plugindesc {
#define SLAPI_PLUGIN_INTERNAL_PRE_MODIFY_FN 421
#define SLAPI_PLUGIN_INTERNAL_PRE_MODRDN_FN 422
#define SLAPI_PLUGIN_INTERNAL_PRE_DELETE_FN 423
+#define SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN 424
/* preoperation plugin to the backend */
#define SLAPI_PLUGIN_BE_PRE_ADD_FN 450
@@ -7069,6 +7070,8 @@ uint32_t slapi_str_to_u32(const char *s);
*/
uint64_t slapi_str_to_u64(const char *s);
+void slapi_set_plugin_open_rootdn_bind(Slapi_PBlock *pb);
+
#ifdef __cplusplus
}
#endif
11 years, 10 months
ldap/servers
by Mark Reynolds
ldap/servers/plugins/linkedattrs/fixup_task.c | 2 -
ldap/servers/plugins/linkedattrs/linked_attrs.h | 2 -
ldap/servers/plugins/memberof/memberof.c | 2 -
ldap/servers/plugins/memberof/memberof.h | 2 -
ldap/servers/plugins/replication/cl5_api.c | 4 --
ldap/servers/plugins/replication/repl5_replica.c | 5 ---
ldap/servers/plugins/replication/repl5_replica_config.c | 3 --
ldap/servers/plugins/usn/usn_cleanup.c | 2 -
ldap/servers/slapd/libglobs.c | 5 +++
ldap/servers/slapd/slapi-plugin.h | 22 +++++++++++++++-
10 files changed, 32 insertions(+), 17 deletions(-)
New commits:
commit 4d564ef42db022a5102c9b6ae1bdd41a18c1dd7f
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed May 30 13:30:44 2012 -0400
Update the slapi-plugin documentation on new slapi functions, and added a slapi function for checking on shutdowns
Fix Description: removed the g_get_shutdown() functions from the plugins, and replaced them with the slapi version
Reviewed by: Richm (Thanks!)
diff --git a/ldap/servers/plugins/linkedattrs/fixup_task.c b/ldap/servers/plugins/linkedattrs/fixup_task.c
index b19d3ab..9fa7f6f 100644
--- a/ldap/servers/plugins/linkedattrs/fixup_task.c
+++ b/ldap/servers/plugins/linkedattrs/fixup_task.c
@@ -355,7 +355,7 @@ linked_attrs_add_backlinks_callback(Slapi_Entry *e, void *callback_data)
int perform_update = 0;
Slapi_DN *targetsdn = NULL;
- if (g_get_shutdown()) {
+ if (slapi_is_shutting_down()) {
rc = -1;
goto done;
}
diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.h b/ldap/servers/plugins/linkedattrs/linked_attrs.h
index 2eba62f..d0909ca 100644
--- a/ldap/servers/plugins/linkedattrs/linked_attrs.h
+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.h
@@ -138,8 +138,6 @@ int linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *eAfter, int *returncode,
char *returntext, void *arg);
-int g_get_shutdown(); /* declared in proto-slap.h */
-
/*
* misc
*/
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
index c98d8ad..fc4529d 100644
--- a/ldap/servers/plugins/memberof/memberof.c
+++ b/ldap/servers/plugins/memberof/memberof.c
@@ -1670,7 +1670,7 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data)
Slapi_ValueSet *groupvals = *((memberof_get_groups_data*)callback_data)->groupvals;
int rc = 0;
- if(g_get_shutdown()){
+ if(slapi_is_shutting_down()){
rc = -1;
goto bail;
}
diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h
index 36901e3..65398aa 100644
--- a/ldap/servers/plugins/memberof/memberof.h
+++ b/ldap/servers/plugins/memberof/memberof.h
@@ -96,6 +96,4 @@ void memberof_wlock_config();
void memberof_unlock_config();
int memberof_config_get_all_backends();
-int g_get_shutdown(); /* declared in proto-slap.h */
-
#endif /* _MEMBEROF_H_ */
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index eac76a8..08bf771 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -265,8 +265,6 @@ typedef struct cl5desc
typedef void (*VFP)(void *);
-int g_get_shutdown(); /* declared in proto-slap.h */
-
/***** Global Variables *****/
static CL5Desc s_cl5Desc;
@@ -3472,7 +3470,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim)
entry.op = &op;
- while ( !finished && !g_get_shutdown() )
+ while ( !finished && !slapi_is_shutting_down() )
{
it = NULL;
count = 0;
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 6434dbd..ccaa29d 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -50,9 +50,6 @@
#include "csnpl.h"
#include "cl5_api.h"
-/* from proto-slap.h */
-int g_get_shutdown();
-
#define RUV_SAVE_INTERVAL (30 * 1000) /* 30 seconds */
#define START_UPDATE_DELAY 2 /* 2 second */
@@ -2506,7 +2503,7 @@ process_reap_entry (Slapi_Entry *entry, void *cb_data)
int rc = -1;
/* abort reaping if we've been told to stop or we're shutting down */
- if (*tombstone_reap_stop || g_get_shutdown()) {
+ if (*tombstone_reap_stop || slapi_is_shutting_down()) {
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
"process_reap_entry: the tombstone reap process "
" has been stopped\n");
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index ca646e9..8d338c0 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -86,7 +86,6 @@ static struct berval *create_ruv_payload(char *value);
static int replica_cleanup_task (Object *r, const char *task_name, char *returntext, int apply_mods);
static int replica_task_done(Replica *replica);
static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry *e);
-int g_get_shutdown();
/*
* Note: internal add/modify/delete operations should not be run while
@@ -1326,7 +1325,7 @@ replica_cleanallruv_monitor_thread(void *arg)
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Waiting for all the replicas to get cleaned...\n");
- while(!g_get_shutdown())
+ while(!slapi_is_shutting_down())
{
DS_Sleep(PR_SecondsToInterval(10));
found = 0;
diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c
index 6f9410e..ab6362f 100644
--- a/ldap/servers/plugins/usn/usn_cleanup.c
+++ b/ldap/servers/plugins/usn/usn_cleanup.c
@@ -148,7 +148,7 @@ usn_cleanup_thread(void *arg)
int opflags = OP_FLAG_TOMBSTONE_ENTRY;
/* check for shutdown */
- if(g_get_shutdown()){
+ if(slapi_is_shutting_down()){
slapi_task_log_notice(task, "USN tombstone cleanup task aborted due to shutdown.");
slapi_task_log_status(task, "USN tombstone cleanup task aborted due to shutdown.");
slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 2540e25..c1e4051 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -890,6 +890,11 @@ int g_get_shutdown()
return slapd_shutdown;
}
+int slapi_is_shutting_down()
+{
+ return slapd_shutdown;
+}
+
static int cmd_shutdown;
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 63c37f0..bad97f8 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5301,6 +5301,13 @@ void slapi_ch_array_add( char ***array, char *string );
*/
int slapi_ch_array_utf8_inlist(char **array, char *string);
+/**
+ * Check if the server has started shutting down
+ *
+ * \return 1 if the server is shutting down
+ */
+int slapi_is_shutting_down();
+
/*
* checking routines for allocating and freeing memory
*/
@@ -6742,7 +6749,20 @@ int slapi_re_exec( Slapi_Regex *re_handle, const char *subject, time_t time_up )
* \warning The regex handler should be released by slapi_re_free().
*/
int slapi_re_subs( Slapi_Regex *re_handle, const char *subject, const char *src, char **dst, unsigned long dstlen );
-/* extension to handle search filters properly */
+/**
+ * Substitutes '&' or '\#' in the param src with the matched string. If the 'src' is a search filter
+ * do not remove & if it is part of a compound filter.
+ *
+ * \param re_handle The regex handler returned from slapi_re_comp.
+ * \param subject A string checked against the compiled pattern.
+ * \param src A given string which could contain the substitution symbols.
+ * \param dst A pointer pointing to the memory which stores the output string.
+ * \param dstlen Size of the memory dst.
+ * \param filter Set to 1 if the src is a ldap search filter
+ * \return This function returns 1 if the substitution was successful.
+ * \return This function returns 0 if the substitution failed.
+ * \warning The regex handler should be released by slapi_re_free().
+ */
int slapi_re_subs_ext( Slapi_Regex *re_handle, const char *subject, const char *src, char **dst, unsigned long dstlen, int filter );
/**
* Releases the regex handler which was returned from slapi_re_comp.
11 years, 10 months
ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/cl5_clcache.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
New commits:
commit a640ac21971fef404c690594c83a7f54c334fe90
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed May 30 11:06:55 2012 -0400
Ticket #369 - restore of replica ldif file on second master after deleting two records shows only 1 deletion
Bug Description: If you take a "db2ldif -r" on a consumer and later restore it "ldif2db"
any changes made on that consumer after the backup(db2ldif), will not be
replayed back to the consumer after it has been restored(ldif2db).
Fix Description: When we check if we can skip updates from the change log, check if the
consumer csn is "newer" than its current max csn. If it is, then it
needs to be replayed back to itself.
https://fedorahosted.org/389/ticket/369
Reviewed by: Nathan & Rich (Thanks!)
diff --git a/ldap/servers/plugins/replication/cl5_clcache.c b/ldap/servers/plugins/replication/cl5_clcache.c
index 327cb6f..5816837 100644
--- a/ldap/servers/plugins/replication/cl5_clcache.c
+++ b/ldap/servers/plugins/replication/cl5_clcache.c
@@ -664,13 +664,24 @@ clcache_skip_change ( CLC_Buffer *buf )
rid = csn_get_replicaid ( buf->buf_current_csn );
/*
- * Skip CSN that is originated from the consumer.
+ * Skip CSN that is originated from the consumer,
+ * unless the CSN is newer than the maxcsn.
* If RID==65535, the CSN is originated from a
* legacy consumer. In this case the supplier
* and the consumer may have the same RID.
*/
- if (rid == buf->buf_consumer_rid && rid != MAX_REPLICA_ID)
+ if (rid == buf->buf_consumer_rid && rid != MAX_REPLICA_ID){
+ CSN *cons_maxcsn = NULL;
+
+ ruv_get_max_csn(buf->buf_consumer_ruv, &cons_maxcsn);
+ if ( csn_compare ( buf->buf_current_csn, cons_maxcsn) > 0 ) {
+ /*
+ * The consumer must have been "restored" and needs this newer update.
+ */
+ skip = 0;
+ }
break;
+ }
/* Skip helper entry (ENTRY_COUNT, PURGE_RUV and so on) */
if ( cl5HelperEntry ( NULL, buf->buf_current_csn ) == PR_TRUE ) {
11 years, 10 months