ldap/servers
by Mark Reynolds
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
New commits:
commit 4ae67943e807b869aeda213dcd39b59feb5f8259
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Thu Dec 18 09:08:52 2014 -0500
Ticket 47750 - During delete operation do not refresh cache entry if it is a tombstone
Bug Description: After calling the betxn postop plugins do not attempt to refresh the
entry if it was converted to a tombstone. A tombstone entry does
not have its entry mutex allocated, and it will be dereferenced.
Fix Description: If the entry is converted to a tombstone, there is no need to
refresh it in the first place. Skip the cache refresh if its a
tombstone. If its not a tombstone, we also need to return the
cache entry if it was not changed in betxn postop, because we
incremented its refcnt while checking if it was updated.
https://fedorahosted.org/389/ticket/47750
Reviewed by: nhosoi(Thanks!)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index eaac39d..3de8efa 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -1261,12 +1261,15 @@ ldbm_back_delete( Slapi_PBlock *pb )
/* delete from cache and clean up */
if (e) {
- struct backentry *old_e = e;
-
- e = cache_find_id(&inst->inst_cache,e->ep_id);
- if(e != old_e){
- /* return the old entry, and proceed with the new one */
- CACHE_RETURN(&inst->inst_cache, &old_e);
+ if(!create_tombstone_entry){
+ struct backentry *old_e = e;
+ e = cache_find_id(&inst->inst_cache,e->ep_id);
+ if(e != old_e){
+ cache_unlock_entry(&inst->inst_cache, old_e);
+ CACHE_RETURN(&inst->inst_cache, &old_e);
+ } else {
+ CACHE_RETURN(&inst->inst_cache, &e);
+ }
}
if (cache_is_in_cache(&inst->inst_cache, e)) {
ep_id = e->ep_id; /* Otherwise, e might have been freed. */
9 years, 4 months
Branch '389-ds-base-1.3.3' - wrappers/systemd.template.service.in
by Noriko Hosoi
wrappers/systemd.template.service.in | 1 +
1 file changed, 1 insertion(+)
New commits:
commit 6e4e21ff010041eb636cc06b23bb3ed0de78ef1d
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Dec 16 13:42:56 2014 -0800
Ticket #47947 - start dirsrv after chrony on RHEL7 and Fedora
Description: After=chronyd.service to systemd.template.service.in,
which is installed as this file:
/usr/lib/systemd/system/dirsrv@.service
and pointed by each server's service file:
/etc/systemd/system/dirsrv.target.wants/dirsrv(a)YOURID.service
https://fedorahosted.org/389/ticket/47947
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
(cherry picked from commit c3389a46c584fa39b2278a295f8b2b6dad726d31)
diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in
index 42c7c23..9432cb0 100644
--- a/wrappers/systemd.template.service.in
+++ b/wrappers/systemd.template.service.in
@@ -15,6 +15,7 @@
[Unit]
Description=@capbrand@ Directory Server %i.
PartOf=@systemdgroupname@
+After=chronyd.service
[Service]
Type=forking
9 years, 4 months
wrappers/systemd.template.service.in
by Noriko Hosoi
wrappers/systemd.template.service.in | 1 +
1 file changed, 1 insertion(+)
New commits:
commit c3389a46c584fa39b2278a295f8b2b6dad726d31
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Dec 16 13:42:56 2014 -0800
Ticket #47947 - start dirsrv after chrony on RHEL7 and Fedora
Description: After=chronyd.service to systemd.template.service.in,
which is installed as this file:
/usr/lib/systemd/system/dirsrv@.service
and pointed by each server's service file:
/etc/systemd/system/dirsrv.target.wants/dirsrv(a)YOURID.service
https://fedorahosted.org/389/ticket/47947
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in
index 42c7c23..9432cb0 100644
--- a/wrappers/systemd.template.service.in
+++ b/wrappers/systemd.template.service.in
@@ -15,6 +15,7 @@
[Unit]
Description=@capbrand@ Directory Server %i.
PartOf=@systemdgroupname@
+After=chronyd.service
[Service]
Type=forking
9 years, 4 months
Branch '389-ds-base-1.3.3' - 2 commits - ldap/servers
by Ludwig Krispenz
ldap/servers/plugins/memberof/memberof.c | 46 ++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 10 deletions(-)
New commits:
commit 4760dc6c66249a793c8485a23c147954265f6fd3
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Wed Dec 17 19:54:33 2014 +0100
fix jenkins warning
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
index cc42c6c..b8e2386 100644
--- a/ldap/servers/plugins/memberof/memberof.c
+++ b/ldap/servers/plugins/memberof/memberof.c
@@ -921,7 +921,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
}
if(ret == LDAP_SUCCESS) {
memberof_del_dn_data del_data = {0, configCopy.memberof_attr};
- if(ret = memberof_del_dn_type_callback(post_e, &del_data)){
+ if((ret = memberof_del_dn_type_callback(post_e, &del_data))){
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
"memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n",
slapi_entry_get_dn(post_e), ret);
commit c8951669b3a74cb9fda013ffe914031b76e2e452
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Wed Dec 17 18:11:44 2014 +0100
Additional fix for ticket 47526 v3
In modrdn we need to distinguish if the entry is changed is a group or a
regular memebr of a group. for the group case do the same as when deleting a group
For the modrdn of an user entry, the case where no memberof attribute exists has
to succeed.
Reviewed by: noriko, thanks
https://fedorahosted.org/389/ticket/47526
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
index 5568ba6..cc42c6c 100644
--- a/ldap/servers/plugins/memberof/memberof.c
+++ b/ldap/servers/plugins/memberof/memberof.c
@@ -566,7 +566,7 @@ int memberof_postop_del(Slapi_PBlock *pb)
}
/* is the entry of interest as a group? */
- if(e && configCopy.group_filter && !slapi_filter_test_simple(e, configCopy.group_filter))
+ if(e && configCopy.group_filter && 0 == slapi_filter_test_simple(e, configCopy.group_filter))
{
int i = 0;
Slapi_Attr *attr = 0;
@@ -664,6 +664,12 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
slapi_pblock_destroy(mod_pb);
+ if (rc == LDAP_NO_SUCH_ATTRIBUTE && val[0] == NULL) {
+ /* if no memberof attribut exists
+ * handle as success
+ */
+ rc = LDAP_SUCCESS;
+ }
return rc;
}
@@ -861,7 +867,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
/* update any downstream members */
if(pre_sdn && post_sdn && configCopy.group_filter &&
- !slapi_filter_test_simple(post_e, configCopy.group_filter))
+ 0 == slapi_filter_test_simple(post_e, configCopy.group_filter))
{
int i = 0;
Slapi_Attr *attr = 0;
@@ -890,17 +896,37 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
if (ret == LDAP_SUCCESS && pre_sdn && post_sdn) {
if ((entry_scope && !slapi_sdn_issuffix(post_sdn, entry_scope)) ||
(entry_scope_exclude_subtree && slapi_sdn_issuffix(post_sdn, entry_scope_exclude_subtree))) {
- memberof_del_dn_data del_data = {0, configCopy.memberof_attr};
if((ret = memberof_del_dn_from_groups(pb, &configCopy, pre_sdn))){
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
"memberof_postop_modrdn - delete dn failed for (%s), error (%d)\n",
slapi_sdn_get_dn(pre_sdn), ret);
}
- if(ret == LDAP_SUCCESS && (ret = memberof_del_dn_type_callback(post_e, &del_data))){
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n",
- slapi_entry_get_dn(post_e), ret);
- }
+ if(ret == LDAP_SUCCESS && pre_e && configCopy.group_filter &&
+ 0 == slapi_filter_test_simple(pre_e, configCopy.group_filter)) {
+ /* is the entry of interest as a group? */
+ int i = 0;
+ Slapi_Attr *attr = 0;
+
+ /* Loop through to find each grouping attribute separately. */
+ for (i = 0; configCopy.groupattrs[i] && ret == LDAP_SUCCESS; i++) {
+ if (0 == slapi_entry_attr_find(pre_e, configCopy.groupattrs[i], &attr)) {
+ if((ret = memberof_del_attr_list(pb, &configCopy, pre_sdn, attr))){
+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
+ "memberof_postop_modrdn: error deleting attr list - dn (%s). Error (%d)\n",
+ slapi_sdn_get_dn(pre_sdn),ret);
+ }
+
+ }
+ }
+ }
+ if(ret == LDAP_SUCCESS) {
+ memberof_del_dn_data del_data = {0, configCopy.memberof_attr};
+ if(ret = memberof_del_dn_type_callback(post_e, &del_data)){
+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
+ "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n",
+ slapi_entry_get_dn(post_e), ret);
+ }
+ }
} else {
if((ret = memberof_replace_dn_from_groups(pb, &configCopy, pre_sdn, post_sdn))){
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
@@ -1261,7 +1287,7 @@ int memberof_postop_add(Slapi_PBlock *pb)
memberof_rlock_config();
mainConfig = memberof_get_config();
if(e && mainConfig && mainConfig->group_filter &&
- !slapi_filter_test_simple(e, mainConfig->group_filter))
+ 0 == slapi_filter_test_simple(e, mainConfig->group_filter))
{
interested = 1;
/* copy config so it doesn't change out from under us */
@@ -1554,7 +1580,7 @@ memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
"memberof_modop_one_replace_r: %s %s in %s\n"
,op_str, op_this, op_to);
- if(config->group_filter && !slapi_filter_test_simple(e, config->group_filter))
+ if(config->group_filter && 0 == slapi_filter_test_simple(e, config->group_filter))
{
/* group */
Slapi_Value *ll_dn_val = 0;
9 years, 4 months
ldap/servers
by Ludwig Krispenz
ldap/servers/plugins/memberof/memberof.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 31f4f341b8f1d2ae04ae1606f0822169201d2737
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Wed Dec 17 19:54:33 2014 +0100
fix jenkins warning
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
index cc42c6c..b8e2386 100644
--- a/ldap/servers/plugins/memberof/memberof.c
+++ b/ldap/servers/plugins/memberof/memberof.c
@@ -921,7 +921,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
}
if(ret == LDAP_SUCCESS) {
memberof_del_dn_data del_data = {0, configCopy.memberof_attr};
- if(ret = memberof_del_dn_type_callback(post_e, &del_data)){
+ if((ret = memberof_del_dn_type_callback(post_e, &del_data))){
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
"memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n",
slapi_entry_get_dn(post_e), ret);
9 years, 4 months
ldap/servers
by Ludwig Krispenz
ldap/servers/plugins/memberof/memberof.c | 46 ++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 10 deletions(-)
New commits:
commit c46cceae924459118588b61e3f3aa988be81e71c
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Wed Dec 17 18:11:44 2014 +0100
Additional fix for ticket 47526 v3
In modrdn we need to distinguish if the entry is changed is a group or a
regular memebr of a group. for the group case do the same as when deleting a group
For the modrdn of an user entry, the case where no memberof attribute exists has
to succeed.
Reviewed by: noriko, thanks
https://fedorahosted.org/389/ticket/47526
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
index 5568ba6..cc42c6c 100644
--- a/ldap/servers/plugins/memberof/memberof.c
+++ b/ldap/servers/plugins/memberof/memberof.c
@@ -566,7 +566,7 @@ int memberof_postop_del(Slapi_PBlock *pb)
}
/* is the entry of interest as a group? */
- if(e && configCopy.group_filter && !slapi_filter_test_simple(e, configCopy.group_filter))
+ if(e && configCopy.group_filter && 0 == slapi_filter_test_simple(e, configCopy.group_filter))
{
int i = 0;
Slapi_Attr *attr = 0;
@@ -664,6 +664,12 @@ memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
slapi_pblock_destroy(mod_pb);
+ if (rc == LDAP_NO_SUCH_ATTRIBUTE && val[0] == NULL) {
+ /* if no memberof attribut exists
+ * handle as success
+ */
+ rc = LDAP_SUCCESS;
+ }
return rc;
}
@@ -861,7 +867,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
/* update any downstream members */
if(pre_sdn && post_sdn && configCopy.group_filter &&
- !slapi_filter_test_simple(post_e, configCopy.group_filter))
+ 0 == slapi_filter_test_simple(post_e, configCopy.group_filter))
{
int i = 0;
Slapi_Attr *attr = 0;
@@ -890,17 +896,37 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
if (ret == LDAP_SUCCESS && pre_sdn && post_sdn) {
if ((entry_scope && !slapi_sdn_issuffix(post_sdn, entry_scope)) ||
(entry_scope_exclude_subtree && slapi_sdn_issuffix(post_sdn, entry_scope_exclude_subtree))) {
- memberof_del_dn_data del_data = {0, configCopy.memberof_attr};
if((ret = memberof_del_dn_from_groups(pb, &configCopy, pre_sdn))){
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
"memberof_postop_modrdn - delete dn failed for (%s), error (%d)\n",
slapi_sdn_get_dn(pre_sdn), ret);
}
- if(ret == LDAP_SUCCESS && (ret = memberof_del_dn_type_callback(post_e, &del_data))){
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n",
- slapi_entry_get_dn(post_e), ret);
- }
+ if(ret == LDAP_SUCCESS && pre_e && configCopy.group_filter &&
+ 0 == slapi_filter_test_simple(pre_e, configCopy.group_filter)) {
+ /* is the entry of interest as a group? */
+ int i = 0;
+ Slapi_Attr *attr = 0;
+
+ /* Loop through to find each grouping attribute separately. */
+ for (i = 0; configCopy.groupattrs[i] && ret == LDAP_SUCCESS; i++) {
+ if (0 == slapi_entry_attr_find(pre_e, configCopy.groupattrs[i], &attr)) {
+ if((ret = memberof_del_attr_list(pb, &configCopy, pre_sdn, attr))){
+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
+ "memberof_postop_modrdn: error deleting attr list - dn (%s). Error (%d)\n",
+ slapi_sdn_get_dn(pre_sdn),ret);
+ }
+
+ }
+ }
+ }
+ if(ret == LDAP_SUCCESS) {
+ memberof_del_dn_data del_data = {0, configCopy.memberof_attr};
+ if(ret = memberof_del_dn_type_callback(post_e, &del_data)){
+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
+ "memberof_postop_modrdn - delete dn callback failed for (%s), error (%d)\n",
+ slapi_entry_get_dn(post_e), ret);
+ }
+ }
} else {
if((ret = memberof_replace_dn_from_groups(pb, &configCopy, pre_sdn, post_sdn))){
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
@@ -1261,7 +1287,7 @@ int memberof_postop_add(Slapi_PBlock *pb)
memberof_rlock_config();
mainConfig = memberof_get_config();
if(e && mainConfig && mainConfig->group_filter &&
- !slapi_filter_test_simple(e, mainConfig->group_filter))
+ 0 == slapi_filter_test_simple(e, mainConfig->group_filter))
{
interested = 1;
/* copy config so it doesn't change out from under us */
@@ -1554,7 +1580,7 @@ memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
"memberof_modop_one_replace_r: %s %s in %s\n"
,op_str, op_this, op_to);
- if(config->group_filter && !slapi_filter_test_simple(e, config->group_filter))
+ if(config->group_filter && 0 == slapi_filter_test_simple(e, config->group_filter))
{
/* group */
Slapi_Value *ll_dn_val = 0;
9 years, 4 months
ldap/servers
by thierry bordaz
ldap/servers/plugins/replication/repl5.h | 9 ++--
ldap/servers/plugins/replication/repl5_agmt.c | 30 +++++++++++---
ldap/servers/plugins/replication/repl5_agmtlist.c | 2
ldap/servers/plugins/replication/repl5_connection.c | 31 ++++++++++++++
ldap/servers/plugins/replication/repl5_protocol.c | 2
ldap/servers/plugins/replication/repl5_tot_protocol.c | 34 ++++++++--------
ldap/servers/plugins/replication/windows_tot_protocol.c | 12 ++---
7 files changed, 88 insertions(+), 32 deletions(-)
New commits:
commit c70b88d187aabdffe601572eeed75822c5dd89d9
Author: Thierry bordaz (tbordaz) <tbordaz(a)redhat.com>
Date: Tue Oct 14 10:44:09 2014 +0200
Ticket 47901: After total init, nsds5replicaLastInitStatus can report an erroneous error status (like 'Referral')
Bug Description:
Total update may fails for several reasons:
- consumer ldap server returning an error to the extended op
- replication problem (replica not acquired, replication disabled)
- connection timeout
When the replica is acquired and the total update starts, each
entry is sent by send_entry. send_entry returns a conn_Result not a ldap error
Fix Description:
Change agmt_set_last_init_status to that the 3 errors (ldap, replication, connection)
are reported.
http://fedorahosted.org/389/ticket/47901
Reviewed by: Ludwig Krispenz, Rich Megginson (Thanks Ludwig, thanks Rich)
Platforms tested: F17
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index e2b6209..39d25bb 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -384,7 +384,7 @@ void agmt_set_update_in_progress (Repl_Agmt *ra, PRBool in_progress);
PRBool agmt_get_update_in_progress (const Repl_Agmt *ra);
void agmt_set_last_init_start (Repl_Agmt *ra, time_t start_time);
void agmt_set_last_init_end (Repl_Agmt *ra, time_t end_time);
-void agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *msg);
+void agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, int connrc, const char *msg);
void agmt_inc_last_update_changecount (Repl_Agmt *ra, ReplicaId rid, int skipped);
void agmt_get_changecount_string (Repl_Agmt *ra, char *buf, int bufsize);
int agmt_set_replicated_attributes_from_entry(Repl_Agmt *ra, const Slapi_Entry *e);
@@ -431,7 +431,9 @@ time_t backoff_step(Backoff_Timer *bt);
int backoff_expired(Backoff_Timer *bt, int margin);
void backoff_delete(Backoff_Timer **btp);
-/* In repl5_connection.c */
+/* In repl5_connection.c
+ * keep in sync with conn_result2string
+ */
typedef struct repl_connection Repl_Connection;
typedef enum
{
@@ -456,8 +458,9 @@ typedef enum
CONN_NOT_WIN2K3,
CONN_SUPPORTS_DS90_REPL,
CONN_DOES_NOT_SUPPORT_DS90_REPL
-} ConnResult;
+} ConnResult;
+char *conn_result2string (int result);
Repl_Connection *conn_new(Repl_Agmt *agmt);
ConnResult conn_connect(Repl_Connection *conn);
void conn_disconnect(Repl_Connection *conn);
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 91be757..83694b3 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2424,15 +2424,25 @@ agmt_set_last_update_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *
}
void
-agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *message)
+agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, int connrc, const char *message)
{
+ char *connmsg = NULL;
+ char unknown_connrc[100] = {0};
+
+ connmsg = conn_result2string(connrc);
+ if (connrc && (connmsg == NULL)) {
+ /* That was an unknown connection error */
+ PR_snprintf(unknown_connrc, sizeof(unknown_connrc), "Unknown connection error (%d)", connrc);
+ connmsg = unknown_connrc;
+ }
+
PR_ASSERT(NULL != ra);
if (NULL != ra)
{
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 */
@@ -2440,9 +2450,10 @@ agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *me
replmsg = NULL;
}
}
- PR_snprintf(ra->last_init_status, STATUS_LEN, "%d %s%sLDAP error: %s%s%s",
+ PR_snprintf(ra->last_init_status, STATUS_LEN, "%d %s%sLDAP error: %s%s%s%s%s",
ldaprc, message?message:"",message?"":" - ",
- slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "");
+ slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "",
+ connrc ? " - " : "", connrc ? connmsg : "");
}
/* ldaprc == LDAP_SUCCESS */
else if (replrc != 0)
@@ -2476,11 +2487,18 @@ agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *me
else
{
PR_snprintf(ra->last_init_status, STATUS_LEN,
- "%d Replication error acquiring replica: %s%s%s",
+ "%d Replication error acquiring replica: %s%s%s%s%s",
replrc, protocol_response2string(replrc),
- message?" - ":"",message?message:"");
+ message?" - ":"",message?message:"",
+ connrc?" - ":"",connrc?connmsg:"");
}
}
+ else if (connrc != CONN_OPERATION_SUCCESS) {
+ PR_snprintf(ra->last_init_status, STATUS_LEN,
+ "%d connection error: %s%s%s",
+ connrc, connmsg,
+ message?" - ":"",message?message:"");
+ }
else if (message != NULL) /* replrc == NSDS50_REPL_REPLICA_READY == 0 */
{
PR_snprintf(ra->last_init_status, STATUS_LEN,
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index 4a1ff5d..e414e0b 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -592,7 +592,7 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
{
if (agmt_initialize_replica(agmt) != 0) {
/* The suffix/repl agmt is disabled */
- agmt_set_last_init_status(agmt, 0, NSDS50_REPL_DISABLED, NULL);
+ agmt_set_last_init_status(agmt, 0, NSDS50_REPL_DISABLED, 0, NULL);
if(agmt_is_enabled(agmt)){
PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Suffix is disabled");
} else {
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index 2971025..969aa07 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -147,6 +147,37 @@ static void repl5_debug_timeout_callback(time_t when, void *arg);
static void close_connection_internal(Repl_Connection *conn);
static void conn_delete_internal(Repl_Connection *conn);
+
+/* converts consumer's response to a string */
+char *
+conn_result2string (int result)
+{
+ switch (result)
+ {
+ case CONN_OPERATION_SUCCESS: return "operation success";
+ case CONN_OPERATION_FAILED: return "operation failure";
+ case CONN_NOT_CONNECTED: return "not connected";
+ case CONN_SUPPORTS_DS5_REPL: return "consumer supports all DS5 extop";
+ case CONN_DOES_NOT_SUPPORT_DS5_REPL: return "consumer does not support all DS5 extop";
+ case CONN_SCHEMA_UPDATED: return "consumer schema updated";
+ case CONN_SCHEMA_NO_UPDATE_NEEDED: return "consumer schema up to date";
+ case CONN_LOCAL_ERROR: return "local error";
+ case CONN_BUSY: return "consumer is busy";
+ case CONN_SSL_NOT_ENABLED: return "NSS not initialized";
+ case CONN_TIMEOUT: return "time out";
+ case CONN_SUPPORTS_DS71_REPL: return "consumer supports all DS71 extop";
+ case CONN_DOES_NOT_SUPPORT_DS71_REPL: return "consumer does not support all DS7.1 extop";
+ case CONN_IS_READONLY: return "consumer is read only";
+ case CONN_IS_NOT_READONLY: return "consumer is not read only";
+ case CONN_SUPPORTS_DIRSYNC: return "consumer supports DIRSYNC control";
+ case CONN_DOES_NOT_SUPPORT_DIRSYNC: return "consumer does not support DIRSYNC control";
+ case CONN_IS_WIN2K3: return "consumer is W2K3 or after";
+ case CONN_NOT_WIN2K3: return "consumer is before W2K3";
+ case CONN_SUPPORTS_DS90_REPL: return "consumer supports all DS90 extop";
+ case CONN_DOES_NOT_SUPPORT_DS90_REPL: return "consumer does not support all DS90 extop";
+ default: return NULL;
+ }
+}
/*
* Create a new connection object. Returns a pointer to the object, or
* NULL if an error occurs.
diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c
index 0e9668d..e8ec16a 100644
--- a/ldap/servers/plugins/replication/repl5_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_protocol.c
@@ -244,7 +244,7 @@ prot_initialize_replica(Repl_Protocol *rp)
rp->next_state = STATE_PERFORMING_TOTAL_UPDATE;
/* Stop the incremental protocol, if running */
rp->prp_incremental->stop(rp->prp_incremental);
- if (rp->prp_total) agmt_set_last_init_status(rp->prp_total->agmt, 0, 0, NULL);
+ if (rp->prp_total) agmt_set_last_init_status(rp->prp_total->agmt, 0, 0, 0, NULL);
PR_Unlock(rp->lock);
}
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
index adadd44..43b0de5 100644
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
@@ -369,7 +369,7 @@ repl5_tot_run(Private_Repl_Protocol *prp)
int optype, ldaprc;
conn_get_error(prp->conn, &optype, &ldaprc);
agmt_set_last_init_status(prp->agmt, ldaprc,
- prp->last_acquire_response_code, NULL);
+ prp->last_acquire_response_code, 0, NULL);
goto done;
}
else if (prp->terminate)
@@ -381,7 +381,7 @@ repl5_tot_run(Private_Repl_Protocol *prp)
hostname = agmt_get_hostname(prp->agmt);
portnum = agmt_get_port(prp->agmt);
- agmt_set_last_init_status(prp->agmt, 0, 0, "Total schema update in progress");
+ agmt_set_last_init_status(prp->agmt, 0, 0, 0, "Total schema update in progress");
remote_schema_csn = agmt_get_consumer_schema_csn ( prp->agmt );
rc = conn_push_schema(prp->conn, &remote_schema_csn);
@@ -396,11 +396,11 @@ repl5_tot_run(Private_Repl_Protocol *prp)
"total update session.\n",
hostname, portnum);
/* But keep going */
- agmt_set_last_init_status(prp->agmt, 0, rc, "Total schema update failed");
+ agmt_set_last_init_status(prp->agmt, 0, rc, 0, "Total schema update failed");
}
else
{
- agmt_set_last_init_status(prp->agmt, 0, 0, "Total schema update succeeded");
+ agmt_set_last_init_status(prp->agmt, 0, 0, 0, "Total schema update succeeded");
}
/* ONREPL - big assumption here is that entries a returned in the id order
@@ -409,7 +409,7 @@ repl5_tot_run(Private_Repl_Protocol *prp)
properly updated because bulk import at the moment skips orphand entries. */
/* XXXggood above assumption may not be valid if orphaned entry moved???? */
- agmt_set_last_init_status(prp->agmt, 0, 0, "Total update in progress");
+ agmt_set_last_init_status(prp->agmt, 0, 0, 0, "Total update in progress");
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Beginning total update of replica "
"\"%s\".\n", agmt_get_long_name(prp->agmt));
@@ -459,7 +459,9 @@ repl5_tot_run(Private_Repl_Protocol *prp)
}
/* this search get all the entries from the replicated area including tombstones
- and referrals */
+ and referrals
+ Note that cb_data.rc contains values from ConnResult
+ */
slapi_search_internal_callback_pb (pb, &cb_data /* callback data */,
get_result /* result callback */,
send_entry /* entry callback */,
@@ -474,7 +476,7 @@ repl5_tot_run(Private_Repl_Protocol *prp)
if (!prp->repl50consumer)
{
- if(cb_data.rc == LDAP_SUCCESS){ /* no need to wait if we already failed */
+ if(cb_data.rc == CONN_OPERATION_SUCCESS){ /* no need to wait if we already failed */
repl5_tot_waitfor_async_results(&cb_data);
}
rc = repl5_tot_destroy_async_result_thread(&cb_data);
@@ -498,16 +500,16 @@ repl5_tot_run(Private_Repl_Protocol *prp)
agmt_update_done(prp->agmt, 1);
release_replica(prp);
- if (rc != LDAP_SUCCESS)
+ if (rc != CONN_OPERATION_SUCCESS)
{
slapi_log_error (SLAPI_LOG_FATAL, repl_plugin_name, "Total update failed for replica \"%s\", "
"error (%d)\n", agmt_get_long_name(prp->agmt), rc);
- agmt_set_last_init_status(prp->agmt, rc, 0, "Total update aborted");
+ agmt_set_last_init_status(prp->agmt, 0, 0, rc, "Total update aborted");
} else {
slapi_log_error (SLAPI_LOG_FATAL, repl_plugin_name, "Finished total update of replica "
"\"%s\". Sent %lu entries.\n",
agmt_get_long_name(prp->agmt), cb_data.num_entries);
- agmt_set_last_init_status(prp->agmt, 0, 0, "Total update succeeded");
+ agmt_set_last_init_status(prp->agmt, 0, 0, 0, "Total update succeeded");
}
done:
@@ -825,12 +827,14 @@ int send_entry (Slapi_Entry *e, void *cb_data)
if (CONN_NOT_CONNECTED == rc) {
((callback_data*)cb_data)->rc = -2;
retval = -1;
- } else if (CONN_OPERATION_SUCCESS == rc) {
- retval = 0;
} else {
- ((callback_data*)cb_data)->rc = rc;
- retval = -1;
- }
+ ((callback_data*) cb_data)->rc = rc;
+ if (CONN_OPERATION_SUCCESS == rc) {
+ retval = 0;
+ } else {
+ retval = -1;
+ }
+ }
error:
return retval;
}
diff --git a/ldap/servers/plugins/replication/windows_tot_protocol.c b/ldap/servers/plugins/replication/windows_tot_protocol.c
index c81974b..f739944 100644
--- a/ldap/servers/plugins/replication/windows_tot_protocol.c
+++ b/ldap/servers/plugins/replication/windows_tot_protocol.c
@@ -182,7 +182,7 @@ windows_tot_run(Private_Repl_Protocol *prp)
int optype, ldaprc;
windows_conn_get_error(prp->conn, &optype, &ldaprc);
agmt_set_last_init_status(prp->agmt, ldaprc,
- prp->last_acquire_response_code, NULL);
+ prp->last_acquire_response_code, 0, NULL);
goto done;
}
else if (prp->terminate)
@@ -192,9 +192,9 @@ windows_tot_run(Private_Repl_Protocol *prp)
goto done;
}
- agmt_set_last_init_status(prp->agmt, 0, 0, "Total schema update in progress");
+ agmt_set_last_init_status(prp->agmt, 0, 0, 0, "Total schema update in progress");
- agmt_set_last_init_status(prp->agmt, 0, 0, "Total update in progress");
+ agmt_set_last_init_status(prp->agmt, 0, 0, 0, "Total update in progress");
agmt_set_update_in_progress(prp->agmt, PR_TRUE);
@@ -253,15 +253,15 @@ windows_tot_run(Private_Repl_Protocol *prp)
rc = cb_data.rc;
windows_release_replica(prp);
- if (rc != LDAP_SUCCESS) {
+ if (rc != CONN_OPERATION_SUCCESS) {
slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name, "%s: windows_tot_run: "
"failed to obtain data to send to the consumer; LDAP error - %d\n",
agmt_get_long_name(prp->agmt), rc);
- agmt_set_last_init_status(prp->agmt, rc, 0, "Total update aborted");
+ agmt_set_last_init_status(prp->agmt, 0, 0, rc, "Total update aborted");
} else {
slapi_log_error(SLAPI_LOG_FATAL, windows_repl_plugin_name, "Finished total update of replica "
"\"%s\". Sent %lu entries.\n", agmt_get_long_name(prp->agmt), cb_data.num_entries);
- agmt_set_last_init_status(prp->agmt, 0, 0, "Total update succeeded");
+ agmt_set_last_init_status(prp->agmt, 0, 0, 0, "Total update succeeded");
/* Now update our consumer RUV for this agreement.
* This ensures that future incrememental updates work.
*/
9 years, 4 months
Branch '389-ds-base-1.3.3' - dirsrvtests/suites
by Mark Reynolds
dirsrvtests/suites/dynamic-plugins/constants.py | 33
dirsrvtests/suites/dynamic-plugins/finalizer.py | 57
dirsrvtests/suites/dynamic-plugins/plugin_tests.py | 1973 +++++++++++++
dirsrvtests/suites/dynamic-plugins/stress_tests.py | 133
dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py | 315 ++
5 files changed, 2511 insertions(+)
New commits:
commit 2ace01377aec2872579f9f892361946f1d5b07d2
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Dec 16 16:44:33 2014 -0500
Ticket 47451 - Add Dynamic Plugin CI Suite
Description: Add lib389(CI) testsuite for Dynamic Plugins
Perform functional tests for plugins that have configuration settings
- Restart the plugin
- Make condfig change
- Test the plugin
- Make another config change
- Test plugin
- Test plugin dependency
- Cleanup
Perform memory corruption test
- This test forces the global plugin linked list, DSE callbacks,
and task handlers to be rewritten in various orders while
testing all the plugins.
Perform Stress tests
- Perform a series of operations that engage two plugins. While
there operations are being performed restart various plugins.
- Verify the server does not crash, and that hte plugins work
correctly.
https://fedorahosted.org/389/ticket/47451
Reviewed by: nhosoi(Thanks!)
(cherry picked from commit 4e39dbbfde56ca68f5a26d0bf2ac3a261234c8cd)
diff --git a/dirsrvtests/suites/dynamic-plugins/constants.py b/dirsrvtests/suites/dynamic-plugins/constants.py
new file mode 100644
index 0000000..cbc310e
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/constants.py
@@ -0,0 +1,33 @@
+'''
+Created on Dec 09, 2014
+
+@author: mreynolds
+'''
+import os
+from lib389 import DN_DM
+from lib389._constants import *
+from lib389.properties import *
+
+SUFFIX = 'dc=example,dc=com'
+PASSWORD = 'password'
+
+# Used for standalone topology
+HOST_STANDALONE = LOCALHOST
+PORT_STANDALONE = 33389
+SERVERID_STANDALONE = 'dynamic-plugins'
+
+# Each defined instance above must be added in that list
+ALL_INSTANCES = [ {SER_HOST: HOST_STANDALONE, SER_PORT: PORT_STANDALONE, SER_SERVERID_PROP: SERVERID_STANDALONE},
+ ]
+# This is a template
+args_instance = {
+ SER_DEPLOYED_DIR: os.environ.get('PREFIX', None),
+ SER_BACKUP_INST_DIR: os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR),
+ SER_ROOT_DN: DN_DM,
+ SER_ROOT_PW: PASSWORD,
+ SER_HOST: LOCALHOST,
+ SER_PORT: DEFAULT_PORT,
+ SER_SERVERID_PROP: "template",
+ SER_CREATION_SUFFIX: DEFAULT_SUFFIX}
+
+
diff --git a/dirsrvtests/suites/dynamic-plugins/finalizer.py b/dirsrvtests/suites/dynamic-plugins/finalizer.py
new file mode 100644
index 0000000..eb02332
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/finalizer.py
@@ -0,0 +1,57 @@
+'''
+Created on Nov 5, 2013
+
+@author: tbordaz
+'''
+import os
+import sys
+import time
+import ldap
+import logging
+import socket
+import time
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools
+from lib389.tools import DirSrvTools
+from lib389._constants import DN_DM
+from lib389.properties import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+global installation_prefix
+installation_prefix=os.getenv('PREFIX')
+
+def test_finalizer():
+ global installation_prefix
+
+ # for each defined instance, remove it
+ for args_instance in ALL_INSTANCES:
+ if installation_prefix:
+ # overwrite the environment setting
+ args_instance[SER_DEPLOYED_DIR] = installation_prefix
+
+ instance = DirSrv(verbose=True)
+ instance.allocate(args_instance)
+ if instance.exists():
+ instance.delete()
+
+ # remove any existing backup for this instance
+ instance.clearBackupFS()
+
+def run_isolated():
+ '''
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+ To run isolated without py.test, you need to
+ - set the installation prefix
+ - run this program
+ '''
+ global installation_prefix
+ installation_prefix = None
+
+ test_finalizer()
+
+if __name__ == '__main__':
+ run_isolated()
+
diff --git a/dirsrvtests/suites/dynamic-plugins/plugin_tests.py b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py
new file mode 100644
index 0000000..fa88145
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py
@@ -0,0 +1,1973 @@
+'''
+Created on Dec 09, 2014
+
+@author: mreynolds
+'''
+import os
+import sys
+import time
+import ldap
+import time
+import logging
+import socket
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
+USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX
+USER3_DN = 'uid=user3,' + DEFAULT_SUFFIX
+BUSER1_DN = 'uid=user1,ou=branch1,' + DEFAULT_SUFFIX
+BUSER2_DN = 'uid=user2,ou=branch2,' + DEFAULT_SUFFIX
+BUSER3_DN = 'uid=user3,ou=branch2,' + DEFAULT_SUFFIX
+BRANCH1_DN = 'ou=branch1,' + DEFAULT_SUFFIX
+BRANCH2_DN = 'ou=branch2,' + DEFAULT_SUFFIX
+GROUP_OU = 'ou=groups,' + DEFAULT_SUFFIX
+PEOPLE_OU = 'ou=people,' + DEFAULT_SUFFIX
+GROUP_DN = 'cn=group,' + DEFAULT_SUFFIX
+
+'''
+ Functional tests for each plugin
+
+ Test:
+ plugin restarts (test when on and off)
+ plugin config validation
+ plugin dependencies
+ plugin functionality (including plugin tasks)
+'''
+
+
+################################################################################
+#
+# Test Plugin Dependency
+#
+################################################################################
+def test_dependency(inst, plugin):
+ """
+ Set the "account usabilty" plugin to depend on this plugin. This plugin
+ is generic, always enabled, and perfect for our testing
+ """
+
+ try:
+ inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config',
+ [(ldap.MOD_REPLACE, 'nsslapd-plugin-depends-on-named', plugin)])
+
+ except ldap.LDAPError, e:
+ log.error('test_dependency: Failed to modify ' + PLUGIN_ACCT_USABILITY + ': error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.modify_s('cn=' + plugin + ',cn=plugins,cn=config',
+ [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'off')])
+
+ except ldap.UNWILLING_TO_PERFORM:
+ # failed as expected
+ pass
+ else:
+ # Incorrectly succeeded
+ log.error('test_dependency: Plugin dependency check failed (%s)' % plugin)
+ assert False
+
+ # Now undo the change
+ try:
+ inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config',
+ [(ldap.MOD_DELETE, 'nsslapd-plugin-depends-on-named', None)])
+ except ldap.LDAPError, e:
+ log.error('test_dependency: Failed to reset ' + plugin + ': error ' + e.message['desc'])
+ assert False
+
+
+################################################################################
+#
+# Test Account Policy Plugin (0)
+#
+################################################################################
+def test_acctpolicy(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_ACCT_POLICY)
+ inst.plugins.enable(name=PLUGIN_ACCT_POLICY)
+
+ if args == "restart":
+ return True
+
+ CONFIG_DN = 'cn=config,cn=Account Policy Plugin,cn=plugins,cn=config'
+ log.info('Testing ' + PLUGIN_ACCT_POLICY + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add the config entry
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'config',
+ 'alwaysrecordlogin': 'yes',
+ 'stateattrname': 'lastLoginTime'
+ })))
+ except ldap.ALREADY_EXISTS:
+ try:
+ inst.modify_s(CONFIG_DN,
+ [(ldap.MOD_REPLACE, 'alwaysrecordlogin', 'yes'),
+ (ldap.MOD_REPLACE, 'stateattrname', 'lastLoginTime')])
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc'])
+ assert False
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ # Now set the config entry in the plugin entry
+ #try:
+ # inst.modify_s('cn=' + PLUGIN_ACCT_POLICY + ',cn=plugins,cn=config',
+ # [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', CONFIG_DN)])
+ #except ldap.LDAPError, e:
+ # log.error('test_acctpolicy: Failed to set config entry in plugin entry: error ' + e.message['desc'])
+ # assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # !!!! acctpolicy does have have a dse callabck to check for live updates - restart plugin for now !!!!
+ inst.plugins.disable(name=PLUGIN_ACCT_POLICY)
+ inst.plugins.enable(name=PLUGIN_ACCT_POLICY)
+
+ # Add an entry
+ try:
+ inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(),
+ 'sn': '1',
+ 'cn': 'user 1',
+ 'uid': 'user1',
+ 'userpassword': 'password'})))
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to add test user' + USER1_DN + ': error ' + e.message['desc'])
+ assert False
+
+ # bind as user
+ try:
+ inst.simple_bind_s(USER1_DN, "password")
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy:Failed to bind as user1: ' + e.message['desc'])
+ assert False
+
+ # Bind as Root DN
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc'])
+ assert False
+
+ # Check lastLoginTime of USER1
+ try:
+ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'lastLoginTime=*')
+ if not entries:
+ log.fatal('test_acctpolicy: Search failed to find an entry with lastLoginTime.')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_acctpolicy: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change config - change the stateAttrName to a new attribute
+ ############################################################################
+
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'stateattrname', 'testLastLoginTime')])
+
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc'])
+ assert False
+
+ # !!!! must restart for now !!!!!
+ inst.plugins.disable(name=PLUGIN_ACCT_POLICY)
+ inst.plugins.enable(name=PLUGIN_ACCT_POLICY)
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # login as user
+ try:
+ inst.simple_bind_s(USER1_DN, "password")
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to bind(2nd) as user1: ' + e.message['desc'])
+ assert False
+
+ # Bind as Root DN
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc'])
+ assert False
+
+ # Check testLastLoginTime was added to USER1
+ try:
+ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(testLastLoginTime=*)')
+ if not entries:
+ log.fatal('test_acctpolicy: Search failed to find an entry with testLastLoginTime.')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_acctpolicy: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_ACCT_POLICY)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to delete test entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_acctpolicy: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Attribute Uniqueness Plugin (1)
+#
+################################################################################
+def test_attruniq(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_ATTR_UNIQUENESS)
+ inst.plugins.enable(name=PLUGIN_ATTR_UNIQUENESS)
+
+ if args == "restart":
+ return
+
+ log.info('Testing ' + PLUGIN_ATTR_UNIQUENESS + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ try:
+ inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',
+ [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'uid')])
+
+ except ldap.LDAPError, e:
+ log.error('test_attruniq: Failed to configure plugin for "uid": error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add an entry
+ try:
+ inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(),
+ 'sn': '1',
+ 'cn': 'user 1',
+ 'uid': 'user1',
+ 'mail': 'user1(a)example.com',
+ 'userpassword': 'password'})))
+ except ldap.LDAPError, e:
+ log.error('test_attruniq: Failed to add test user' + USER1_DN + ': error ' + e.message['desc'])
+ assert False
+
+ # Add an entry with a duplicate "uid"
+ try:
+ inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
+ 'sn': '2',
+ 'cn': 'user 2',
+ 'uid': 'user2',
+ 'uid': 'user1',
+ 'userpassword': 'password'})))
+
+ except ldap.CONSTRAINT_VIOLATION:
+ pass
+ else:
+ log.error('test_attruniq: Adding of 2nd entry(uid) incorrectly succeeded')
+ assert False
+
+ ############################################################################
+ # Change config to use "mail" instead of "uid"
+ ############################################################################
+
+ try:
+ inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',
+ [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'mail')])
+
+ except ldap.LDAPError, e:
+ log.error('test_attruniq: Failed to configure plugin for "mail": error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin - Add an entry, that has a duplicate "mail" value
+ ############################################################################
+
+ try:
+ inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
+ 'sn': '2',
+ 'cn': 'user 2',
+ 'uid': 'user2',
+ 'mail': 'user1(a)example.com',
+ 'userpassword': 'password'})))
+ except ldap.CONSTRAINT_VIOLATION:
+ pass
+ else:
+ log.error('test_attruniq: Adding of 2nd entry(mail) incorrectly succeeded')
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_ATTR_UNIQUENESS)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_attruniq: Failed to delete test entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_attruniq: PASS\n')
+ return
+
+
+################################################################################
+#
+# Test Auto Membership Plugin (2)
+#
+################################################################################
+def test_automember(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_AUTOMEMBER)
+ inst.plugins.enable(name=PLUGIN_AUTOMEMBER)
+
+ if args == "restart":
+ return
+
+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_AUTOMEMBER + ',cn=plugins,cn=config'
+
+ log.info('Testing ' + PLUGIN_AUTOMEMBER + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add the automember group
+ try:
+ inst.add_s(Entry((GROUP_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'group'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add group: error ' + e.message['desc'])
+ assert False
+
+ # Add ou=branch1
+ try:
+ inst.add_s(Entry((BRANCH1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'branch1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add branch1: error ' + e.message['desc'])
+ assert False
+
+ # Add ou=branch2
+ try:
+ inst.add_s(Entry((BRANCH2_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'branch2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add branch2: error ' + e.message['desc'])
+ assert False
+
+ # Add the automember config entry
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top autoMemberDefinition'.split(),
+ 'cn': 'config',
+ 'autoMemberScope': 'ou=branch1,' + DEFAULT_SUFFIX,
+ 'autoMemberFilter': 'objectclass=top',
+ 'autoMemberDefaultGroup': 'cn=group,' + DEFAULT_SUFFIX,
+ 'autoMemberGroupingAttr': 'member:dn'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test the plugin
+ ############################################################################
+
+ # Add a user that should get added to the group
+ try:
+ inst.add_s(Entry((BUSER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add user: error ' + e.message['desc'])
+ assert False
+
+ # Check the group
+ try:
+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
+ '(member=' + BUSER1_DN + ')')
+ if not entries:
+ log.fatal('test_automember: Search failed to find member user1')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_automember: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change config
+ ############################################################################
+
+ try:
+ inst.modify_s(CONFIG_DN,
+ [(ldap.MOD_REPLACE, 'autoMemberGroupingAttr', 'uniquemember:dn'),
+ (ldap.MOD_REPLACE, 'autoMemberScope', 'ou=branch2,' + DEFAULT_SUFFIX)])
+
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to modify config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add a user that should get added to the group
+ try:
+ inst.add_s(Entry((BUSER2_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to user to branch2: error ' + e.message['desc'])
+ assert False
+
+ # Check the group
+ try:
+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
+ '(uniquemember=' + BUSER2_DN + ')')
+ if not entries:
+ log.fatal('test_automember: Search failed to find uniquemember user2')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_automember: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test Task
+ ############################################################################
+
+ # Disable plugin
+ inst.plugins.disable(name=PLUGIN_AUTOMEMBER)
+
+ # Add an entry that should be picked up by automember - verify it is not(yet)
+ try:
+ inst.add_s(Entry((BUSER3_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user3'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to user3 to branch2: error ' + e.message['desc'])
+ assert False
+
+ # Check the group - uniquemember sahould not exist
+ try:
+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
+ '(uniquemember=' + BUSER3_DN + ')')
+ if entries:
+ log.fatal('test_automember: user3 was incorrectly added to the group')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_automember: Search failed: ' + e.message['desc'])
+ assert False
+
+ # Enable plugin
+ inst.plugins.enable(name=PLUGIN_AUTOMEMBER)
+
+ # Add the task
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=automember rebuild membership,cn=tasks,cn=config', {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': 'ou=branch2,' + DEFAULT_SUFFIX,
+ 'filter': 'objectclass=top'})))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do its work
+
+ # Verify the fixup task worked
+ try:
+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
+ '(uniquemember=' + BUSER3_DN + ')')
+ if not entries:
+ log.fatal('test_automember: user3 was not added to the group')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_automember: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_AUTOMEMBER)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(BUSER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test entry1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BUSER2_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test entry2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BUSER3_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test entry3: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete branch1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH2_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test branch2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(GROUP_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test group: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(CONFIG_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete plugin config entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_automember: PASS\n')
+ return
+
+
+################################################################################
+#
+# Test DNA Plugin (3)
+#
+################################################################################
+def test_dna(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_DNA)
+ inst.plugins.enable(name=PLUGIN_DNA)
+
+ if args == "restart":
+ return
+
+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_DNA + ',cn=plugins,cn=config'
+
+ log.info('Testing ' + PLUGIN_DNA + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top dnaPluginConfig'.split(),
+ 'cn': 'config',
+ 'dnatype': 'uidNumber',
+ 'dnafilter': '(objectclass=top)',
+ 'dnascope': DEFAULT_SUFFIX,
+ 'dnaMagicRegen': '-1',
+ 'dnaMaxValue': '50000',
+ 'dnaNextValue': '1'
+ })))
+ except ldap.ALREADY_EXISTS:
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaNextValue', '1'),
+ (ldap.MOD_REPLACE, 'dnaMagicRegen', '-1')])
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to set the DNA plugin: error ' + e.message['desc'])
+ assert False
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to user1: error ' + e.message['desc'])
+ assert False
+
+ # See if the entry now has the new uidNumber assignment - uidNumber=1
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=1)')
+ if not entries:
+ log.fatal('test_dna: user1 was not updated - (looking for uidNumber: 1)')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Test the magic regen value
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-1')])
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to set the magic reg value: error ' + e.message['desc'])
+ assert False
+
+ # See if the entry now has the new uidNumber assignment - uidNumber=2
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=2)')
+ if not entries:
+ log.fatal('test_dna: user1 was not updated (looking for uidNumber: 2)')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ################################################################################
+ # Change the config
+ ################################################################################
+
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaMagicRegen', '-2')])
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to set the magic reg value to -2: error ' + e.message['desc'])
+ assert False
+
+ ################################################################################
+ # Test plugin
+ ################################################################################
+
+ # Test the magic regen value
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-2')])
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to set the magic reg value: error ' + e.message['desc'])
+ assert False
+
+ # See if the entry now has the new uidNumber assignment - uidNumber=3
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=3)')
+ if not entries:
+ log.fatal('test_dna: user1 was not updated (looking for uidNumber: 3)')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_AUTOMEMBER)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test entry1: ' + e.message['desc'])
+ assert False
+
+ inst.plugins.disable(name=PLUGIN_DNA)
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_dna: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Linked Attrs Plugin (4)
+#
+################################################################################
+def test_linkedattrs(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_LINKED_ATTRS)
+ inst.plugins.enable(name=PLUGIN_LINKED_ATTRS)
+
+ if args == "restart":
+ return
+
+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_LINKED_ATTRS + ',cn=plugins,cn=config'
+
+ log.info('Testing ' + PLUGIN_LINKED_ATTRS + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add test entries
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to user1: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((USER2_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to user1: error ' + e.message['desc'])
+ assert False
+
+ # Add the linked attrs config entry
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'config',
+ 'linkType': 'directReport',
+ 'managedType': 'manager'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Set "directReport" should add "manager" to the other entry
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was added to the other entry
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if not entries:
+ log.fatal('test_linkedattrs: user2 missing "manager" attribute')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Remove "directReport" should remove "manager" to the other entry
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'directReport', None)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was removed
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 "manager" attribute not removed')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change the config - using linkType "indirectReport" now
+ ############################################################################
+
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'linkType', 'indirectReport')])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to set linkTypee: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Make sure the old linkType(directManager) is not working
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was added to the other entry, better not be...
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 had "manager" added unexpectedly')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])
+ assert False
+
+ # Now, set the new linkType "indirectReport", which should add "manager" to the other entry
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was added to the other entry, better not be
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if not entries:
+ log.fatal('test_linkedattrs: user2 missing "manager"')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])
+ assert False
+
+ # Remove "indirectReport" should remove "manager" to the other entry
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'indirectReport', None)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was removed
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 "manager" attribute not removed')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test Fixup Task
+ ############################################################################
+
+ # Disable plugin and make some updates that would of triggered the plugin
+ inst.plugins.disable(name=PLUGIN_LINKED_ATTRS)
+
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc'])
+ assert False
+
+ # The entry should not have a manager attribute
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 incorrectly has a "manager" attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Verify that the task does not work yet(not until we enable the plugin)
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config', {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': DEFAULT_SUFFIX,
+ 'filter': '(objectclass=top)'})))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do, or not do, its work
+
+ # The entry should still not have a manager attribute
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 incorrectly has a "manager" attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])
+ assert False
+
+ # Enable the plugin and rerun the task entry
+ inst.plugins.enable(name=PLUGIN_LINKED_ATTRS)
+
+ # Add the task again
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config', {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': DEFAULT_SUFFIX,
+ 'filter': 'objectclass=top'})))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do its work
+
+ # Check if user2 now has a manager attribute now
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if not entries:
+ log.fatal('test_linkedattrs: task failed: user2 missing "manager" attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_LINKED_ATTRS)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete test entry1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(USER2_DN)
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete test entry2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(CONFIG_DN)
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete plugin config entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_linkedattrs: PASS\n')
+ return
+
+
+################################################################################
+#
+# Test MemberOf Plugin (5)
+#
+################################################################################
+def test_memberof(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_MEMBER_OF)
+ inst.plugins.enable(name=PLUGIN_MEMBER_OF)
+
+ if args == "restart":
+ return
+
+ PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config'
+
+ log.info('Testing ' + PLUGIN_MEMBER_OF + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'member')])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to update config(member): error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add our test entries
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((GROUP_DN, {
+ 'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(),
+ 'cn': 'group',
+ 'member': USER1_DN
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add group: error ' + e.message['desc'])
+ assert False
+
+ # Check if the user now has a "memberOf" attribute
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if not entries:
+ log.fatal('test_memberof: user1 missing memberOf')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Remove "member" should remove "memberOf" from the entry
+ try:
+ inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'member', None)])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to delete member: error ' + e.message['desc'])
+ assert False
+
+ # Check that "memberOf" was removed
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if entries:
+ log.fatal('test_memberof: user1 incorrect has memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to update config(uniquemember): error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ try:
+ inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])
+ assert False
+
+ # Check if the user now has a "memberOf" attribute
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if not entries:
+ log.fatal('test_memberof: user1 missing memberOf')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Remove "uniquemember" should remove "memberOf" from the entry
+ try:
+ inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'uniquemember', None)])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to delete member: error ' + e.message['desc'])
+ assert False
+
+ # Check that "memberOf" was removed
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if entries:
+ log.fatal('test_memberof: user1 incorrect has memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test Fixup Task
+ ############################################################################
+
+ inst.plugins.disable(name=PLUGIN_MEMBER_OF)
+
+ # Add uniquemember, should not update USER1
+ try:
+ inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])
+ assert False
+
+ # Check for "memberOf"
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if entries:
+ log.fatal('test_memberof: user1 incorrect has memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Run fixup task while plugin disabled - should not add "memberOf
+ # Verify that the task does not work yet(not until we enable the plugin)
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': DEFAULT_SUFFIX,
+ 'filter': 'objectclass=top'})))
+ except ldap.NO_SUCH_OBJECT:
+ pass
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do, or not do, its work
+
+ # Check for "memberOf"
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if entries:
+ log.fatal('test_memberof: user1 incorrectly has memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Enable the plugin, and run the task
+ inst.plugins.enable(name=PLUGIN_MEMBER_OF)
+
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': DEFAULT_SUFFIX,
+ 'filter': 'objectclass=top'})))
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do its work
+
+ # Check for "memberOf"
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if not entries:
+ log.fatal('test_memberof: user1 missing memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_MEMBER_OF)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to delete test entry1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(GROUP_DN)
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to delete test group: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_memberof: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Managed Entry Plugin (6)
+#
+################################################################################
+def test_mep(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY)
+ inst.plugins.enable(name=PLUGIN_MANAGED_ENTRY)
+
+ if args == "restart":
+ return
+
+ USER_DN = 'uid=user1,ou=people,' + DEFAULT_SUFFIX
+ MEP_USER_DN = 'cn=user1,ou=groups,' + DEFAULT_SUFFIX
+ USER_DN2 = 'uid=user 1,ou=people,' + DEFAULT_SUFFIX
+ MEP_USER_DN2 = 'uid=user 1,ou=groups,' + DEFAULT_SUFFIX
+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_MANAGED_ENTRY + ',cn=plugins,cn=config'
+ TEMPLATE_DN = 'cn=MEP Template,' + DEFAULT_SUFFIX
+ TEMPLATE_DN2 = 'cn=MEP Template2,' + DEFAULT_SUFFIX
+
+ log.info('Testing ' + PLUGIN_MANAGED_ENTRY + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add our org units
+ try:
+ inst.add_s(Entry((PEOPLE_OU, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'people'})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add people org unit: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((GROUP_OU, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'people'})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add people org unit: error ' + e.message['desc'])
+ assert False
+
+ # Add the template entry
+ try:
+ inst.add_s(Entry((TEMPLATE_DN, {
+ 'objectclass': 'top mepTemplateEntry extensibleObject'.split(),
+ 'cn': 'MEP Template',
+ 'mepRDNAttr': 'cn',
+ 'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'),
+ 'mepMappedAttr': 'cn: $cn|uid: $cn|gidNumber: $uidNumber'.split('|')
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add template entry: error ' + e.message['desc'])
+ assert False
+
+ # log.info('geb.....')
+ # time.sleep(30)
+
+ # Add the config entry
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'config',
+ 'originScope': PEOPLE_OU,
+ 'originFilter': 'objectclass=posixAccount',
+ 'managedBase': GROUP_OU,
+ 'managedTemplate': TEMPLATE_DN
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add an entry that meets the MEP scope
+ try:
+ inst.add_s(Entry((USER_DN, {
+ 'objectclass': 'top posixAccount extensibleObject'.split(),
+ 'uid': 'user1',
+ 'cn': 'user1',
+ 'uidNumber': '1',
+ 'gidNumber': '1',
+ 'homeDirectory': '/home/user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to user1: error ' + e.message['desc'])
+ assert False
+
+ # Check if a managed group entry was created
+ try:
+ inst.search_s(MEP_USER_DN, ldap.SCOPE_BASE, '(objectclass=top)')
+ except ldap.LDAPError, e:
+ log.fatal('test_mep: Unable to find MEP entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ # Add a new template entry
+ try:
+ inst.add_s(Entry((TEMPLATE_DN2, {
+ 'objectclass': 'top mepTemplateEntry extensibleObject'.split(),
+ 'cn': 'MEP Template2',
+ 'mepRDNAttr': 'uid',
+ 'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'),
+ 'mepMappedAttr': 'cn: $uid|uid: $cn|gidNumber: $gidNumber'.split('|')
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add template entry2: error ' + e.message['desc'])
+ assert False
+
+ # Set the new template dn
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'managedTemplate', TEMPLATE_DN2)])
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to set mep plugin config: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add an entry that meets the MEP scope
+ try:
+ inst.add_s(Entry((USER_DN2, {
+ 'objectclass': 'top posixAccount extensibleObject'.split(),
+ 'uid': 'user 1',
+ 'cn': 'user 1',
+ 'uidNumber': '1',
+ 'gidNumber': '1',
+ 'homeDirectory': '/home/user2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to user2: error ' + e.message['desc'])
+ assert False
+
+ # Check if a managed group entry was created
+ try:
+ inst.search_s(MEP_USER_DN2, ldap.SCOPE_BASE, '(objectclass=top)')
+ except ldap.LDAPError, e:
+ log.fatal('test_mep: Unable to find MEP entry2: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_MANAGED_ENTRY)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER_DN)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete test user1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(USER_DN2)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete test user 2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(TEMPLATE_DN)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete template1: ' + e.message['desc'])
+ assert False
+
+ inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY)
+
+ try:
+ inst.delete_s(TEMPLATE_DN2)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete template2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(CONFIG_DN)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete config: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_mep: PASS\n')
+ return
+
+
+################################################################################
+#
+# Test Passthru Plugin (7)
+#
+################################################################################
+def test_passthru(inst, args=None):
+ # Passthru is a bit picky about the state of the entry - we can't just restart it
+ if args == "restart":
+ return
+
+ # stop the plugin
+ inst.plugins.disable(name=PLUGIN_PASSTHRU)
+
+ PLUGIN_DN = 'cn=' + PLUGIN_PASSTHRU + ',cn=plugins,cn=config'
+ PASSTHRU_DN = 'uid=admin,dc=pass,dc=thru'
+ PASSTHRU_DN2 = 'uid=admin2,dc=pass2,dc=thru'
+ PASS_SUFFIX1 = 'dc=pass,dc=thru'
+ PASS_SUFFIX2 = 'dc=pass2,dc=thru'
+ PASS_BE2 = 'PASS2'
+
+ log.info('Testing ' + PLUGIN_PASSTHRU + '...')
+
+ ############################################################################
+ # Add a new "remote" instance, and a user for auth
+ ############################################################################
+
+ # Create second instance
+ passthru_inst = DirSrv(verbose=False)
+
+ #if installation1_prefix:
+ # args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+ # Args for the master1 instance
+ """
+ args_instance[SER_HOST] = '127.0.0.1'
+ args_instance[SER_PORT] = '33333'
+ args_instance[SER_SERVERID_PROP] = 'passthru'
+ """
+ args_instance[SER_HOST] = 'localhost.localdomain'
+ args_instance[SER_PORT] = 33333
+ args_instance[SER_SERVERID_PROP] = 'passthru'
+
+ args_instance[SER_CREATION_SUFFIX] = PASS_SUFFIX1
+ args_passthru_inst = args_instance.copy()
+ passthru_inst.allocate(args_passthru_inst)
+ passthru_inst.create()
+ passthru_inst.open()
+
+ # Create a second backend
+ passthru_inst.backend.create(PASS_SUFFIX2, {BACKEND_NAME: PASS_BE2})
+ passthru_inst.mappingtree.create(PASS_SUFFIX2, bename=PASS_BE2)
+
+ # Create the top of the tree
+ try:
+ passthru_inst.add_s(Entry((PASS_SUFFIX2, {
+ 'objectclass': 'top domain'.split(),
+ 'dc': 'pass2'})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to create suffix entry: error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ # Add user to suffix1
+ try:
+ passthru_inst.add_s(Entry((PASSTHRU_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'admin',
+ 'userpassword': 'password'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to admin1: error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ # Add user to suffix 2
+ try:
+ passthru_inst.add_s(Entry((PASSTHRU_DN2, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'admin2',
+ 'userpassword': 'password'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to admin2 : error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Configure and start plugin
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'on'),
+ (ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass,dc=thru')])
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to set mep plugin config: error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # login as user
+ try:
+ inst.simple_bind_s(PASSTHRU_DN, "password")
+ except ldap.LDAPError, e:
+ log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ # login as root DN
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass2,dc=thru')])
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to set mep plugin config: error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # login as user
+ try:
+ inst.simple_bind_s(PASSTHRU_DN2, "password")
+ except ldap.LDAPError, e:
+ log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ # login as root DN
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_PASSTHRU)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ # remove the passthru instance
+ passthru_inst.delete()
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_passthru: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Referential Integrity Plugin (8)
+#
+################################################################################
+def test_referint(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_REFER_INTEGRITY)
+ inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
+
+ if args == "restart":
+ return
+
+ log.info('Testing ' + PLUGIN_REFER_INTEGRITY + '...')
+ PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config'
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'member')])
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to configure RI plugin: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add some users and a group
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((USER2_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to add user2: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((GROUP_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'group',
+ 'member': USER1_DN,
+ 'uniquemember': USER2_DN
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to add group: error ' + e.message['desc'])
+ assert False
+
+ # Delete a user
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ # Check for integrity
+ try:
+ entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(member=' + USER1_DN + ')')
+ if entry:
+ log.error('test_referint: user1 was not removed from group')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_referint: Unable to search group: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')])
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to configure RI plugin: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Delete a user
+ try:
+ inst.delete_s(USER2_DN)
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ # Check for integrity
+ try:
+ entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(uniquemember=' + USER2_DN + ')')
+ if entry:
+ log.error('test_referint: user2 was not removed from group')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_referint: Unable to search group: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_REFER_INTEGRITY)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(GROUP_DN)
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_referint: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Retro Changelog Plugin (9)
+#
+################################################################################
+def test_retrocl(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)
+ inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
+
+ if args == "restart":
+ return
+
+ log.info('Testing ' + PLUGIN_RETRO_CHANGELOG + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Gather the current change count (it's not 1 once we start the stabilty tests)
+ try:
+ entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')
+ except ldap.LDAPError, e:
+ log.error('test_retrocl: Failed to get the count: error ' + e.message['desc'])
+ assert False
+
+ entry_count = len(entry)
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add a user
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_retrocl: Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ # Check we logged this in the retro cl
+ try:
+ entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')
+ if not entry or len(entry) == entry_count:
+ log.error('test_retrocl: changelog not updated')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_retrocl: Unable to search group: ' + e.message['desc'])
+ assert False
+
+ entry_count += 1
+
+ ############################################################################
+ # Change the config - disable plugin
+ ############################################################################
+
+ inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_retrocl: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ # Check we didn't logged this in the retro cl
+ try:
+ entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')
+ if len(entry) != entry_count:
+ log.error('test_retrocl: changelog incorrectly updated - change count: '
+ + str(len(entry)) + ' - expected 1')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_retrocl: Unable to search retro changelog: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
+ test_dependency(inst, PLUGIN_RETRO_CHANGELOG)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ # None
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_retrocl: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Root DN Access Control Plugin (10)
+#
+################################################################################
+def test_rootdn(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_ROOTDN_ACCESS)
+ inst.plugins.enable(name=PLUGIN_ROOTDN_ACCESS)
+
+ if args == "restart":
+ return
+
+ PLUGIN_DN = 'cn=' + PLUGIN_ROOTDN_ACCESS + ',cn=plugins,cn=config'
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add an user and aci to open up cn=config
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1',
+ 'userpassword': 'password'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_retrocl: Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ # Set an aci so we can modify the plugin after ew deny the root dn
+ ACI = '(target ="ldap:///cn=config")(targetattr = "*")(version 3.0;acl "all access";allow (all)(userdn="ldap:///anyone");)'
+ try:
+ inst.modify_s(DN_CONFIG, [(ldap.MOD_ADD, 'aci', ACI)])
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to add aci to config: error ' + e.message['desc'])
+ assert False
+
+ # Set allowed IP to an unknown host - blocks root dn
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'rootdn-allow-ip', '10.10.10.10')])
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Bind as Root DN
+ failed = False
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ failed = True
+
+ if not failed:
+ log.error('test_rootdn: Root DN was incorrectly able to bind')
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ try:
+ inst.simple_bind_s(USER1_DN, 'password')
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: failed to bind as user1')
+ assert False
+
+ # Remove the restriction
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_DELETE, 'rootdn-allow-ip', None)])
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Bind as Root DN
+ failed = False
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ failed = True
+
+ if failed:
+ log.error('test_rootdn: Root DN was not able to bind')
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_ROOTDN_ACCESS)
+
+ ############################################################################
+ # Cleanup - remove ACI from cn=config and test user
+ ############################################################################
+
+ try:
+ inst.modify_s(DN_CONFIG, [(ldap.MOD_DELETE, 'aci', ACI)])
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to add aci to config: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_rootdn: PASS\n')
+
+ return
+
+
+# Array of test functions
+func_tests = [test_acctpolicy, test_attruniq, test_automember, test_dna,
+ test_linkedattrs, test_memberof, test_mep, test_passthru,
+ test_referint, test_retrocl, test_rootdn]
+
+
+def test_all_plugins(inst, args=None):
+ for func in func_tests:
+ func(inst, args)
+
+ return
+
diff --git a/dirsrvtests/suites/dynamic-plugins/stress_tests.py b/dirsrvtests/suites/dynamic-plugins/stress_tests.py
new file mode 100644
index 0000000..a1f666d
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/stress_tests.py
@@ -0,0 +1,133 @@
+'''
+Created on Dec 16, 2014
+
+@author: mreynolds
+'''
+import os
+import sys
+import time
+import ldap
+import time
+import logging
+import socket
+import pytest
+import threading
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+NUM_USERS = 250
+
+
+def openConnection(inst):
+ # Open a new connection to our LDAP server
+ server = DirSrv(verbose=False)
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_standalone = args_instance.copy()
+ server.allocate(args_standalone)
+ server.open()
+
+ return server
+
+
+# Configure Referential Integrity Plugin for stress test
+def configureRI(inst):
+ inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
+ PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config'
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')])
+ except ldap.LDAPError, e:
+ log.error('configureRI: Failed to configure RI plugin: error ' + e.message['desc'])
+ assert False
+
+
+# Configure MemberOf Plugin for stress test
+def configureMO(inst):
+ inst.plugins.enable(name=PLUGIN_MEMBER_OF)
+ PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config'
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])
+ except ldap.LDAPError, e:
+ log.error('configureMO: Failed to update config(uniquemember): error ' + e.message['desc'])
+ assert False
+
+
+class DelUsers(threading.Thread):
+ def __init__(self, inst, rdnval):
+ threading.Thread.__init__(self)
+ self.daemon = True
+ self.inst = inst
+ self.rdnval = rdnval
+
+ def run(self):
+ conn = openConnection(self.inst)
+ idx = 0
+ log.info('DelUsers - Deleting ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...')
+ while idx < NUM_USERS:
+ USER_DN = 'uid=' + self.rdnval + str(idx) + ',' + DEFAULT_SUFFIX
+ try:
+ conn.delete_s(USER_DN)
+ except ldap.LDAPError, e:
+ log.error('DeleteUsers: failed to delete (' + USER_DN + ') error: ' + e.message['desc'])
+ assert False
+
+ idx += 1
+
+ conn.close()
+ log.info('DelUsers - Finished deleting ' + str(NUM_USERS) + ' entries (' + self.rdnval + ').')
+
+
+class AddUsers(threading.Thread):
+ def __init__(self, inst, rdnval, addToGroup):
+ threading.Thread.__init__(self)
+ self.daemon = True
+ self.inst = inst
+ self.addToGroup = addToGroup
+ self.rdnval = rdnval
+
+ def run(self):
+ # Start adding users
+ conn = openConnection(self.inst)
+ idx = 0
+
+ if self.addToGroup:
+ GROUP_DN = 'cn=stress-group,' + DEFAULT_SUFFIX
+ try:
+ conn.add_s(Entry((GROUP_DN,
+ {'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(),
+ 'uid': 'user' + str(idx)})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('AddUsers: failed to add group (' + USER_DN + ') error: ' + e.message['desc'])
+ assert False
+
+ log.info('AddUsers - Adding ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...')
+
+ while idx < NUM_USERS:
+ USER_DN = 'uid=' + self.rdnval + str(idx) + ',' + DEFAULT_SUFFIX
+ try:
+ conn.add_s(Entry((USER_DN, {'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user' + str(idx)})))
+ except ldap.LDAPError, e:
+ log.error('AddUsers: failed to add (' + USER_DN + ') error: ' + e.message['desc'])
+ assert False
+
+ if self.addToGroup:
+ # Add the user to the group
+ try:
+ conn.modify_s(GROUP_DN, [(ldap.MOD_ADD, 'uniquemember', USER_DN)])
+ except ldap.LDAPError, e:
+ log.error('AddUsers: Failed to add user' + USER_DN + ' to group: error ' + e.message['desc'])
+ assert False
+
+ idx += 1
+
+ conn.close()
+ log.info('AddUsers - Finished adding ' + str(NUM_USERS) + ' entries (' + self.rdnval + ').')
diff --git a/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py b/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py
new file mode 100644
index 0000000..3677fd5
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py
@@ -0,0 +1,315 @@
+'''
+Created on Dec 09, 2014
+
+@author: mreynolds
+'''
+import os
+import sys
+import time
+import ldap
+import ldap.sasl
+import logging
+import socket
+import pytest
+import plugin_tests
+import stress_tests
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+installation_prefix = None
+
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ '''
+ This fixture is used to standalone topology for the 'module'.
+ At the beginning, It may exists a standalone instance.
+ It may also exists a backup for the standalone instance.
+
+ Principle:
+ If standalone instance exists:
+ restart it
+ If backup of standalone exists:
+ create/rebind to standalone
+
+ restore standalone instance from backup
+ else:
+ Cleanup everything
+ remove instance
+ remove backup
+ Create instance
+ Create backup
+ '''
+ global installation_prefix
+
+ if installation_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation_prefix
+
+ standalone = DirSrv(verbose=False)
+
+ # Args for the standalone instance
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+
+ # Get the status of the backups
+ backup_standalone = standalone.checkBackupFS()
+
+ # Get the status of the instance and restart it if it exists
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ # assuming the instance is already stopped, just wait 5 sec max
+ standalone.stop(timeout=5)
+ standalone.start(timeout=10)
+
+ if backup_standalone:
+ # The backup exist, assuming it is correct
+ # we just re-init the instance with it
+ if not instance_standalone:
+ standalone.create()
+ # Used to retrieve configuration information (dbdir, confdir...)
+ standalone.open()
+
+ # restore standalone instance from backup
+ standalone.stop(timeout=10)
+ standalone.restoreFS(backup_standalone)
+ standalone.start(timeout=10)
+
+ else:
+ # We should be here only in two conditions
+ # - This is the first time a test involve standalone instance
+ # - Something weird happened (instance/backup destroyed)
+ # so we discard everything and recreate all
+
+ # Remove the backup. So even if we have a specific backup file
+ # (e.g backup_standalone) we clear backup that an instance may have created
+ if backup_standalone:
+ standalone.clearBackupFS()
+
+ # Remove the instance
+ if instance_standalone:
+ standalone.delete()
+
+ # Create the instance
+ standalone.create()
+
+ # Used to retrieve configuration information (dbdir, confdir...)
+ standalone.open()
+
+ # Time to create the backups
+ standalone.stop(timeout=10)
+ standalone.backupfile = standalone.backupFS()
+ standalone.start(timeout=10)
+
+ #
+ # Here we have standalone instance up and running
+ # Either coming from a backup recovery
+ # or from a fresh (re)init
+ # Time to return the topology
+ return TopologyStandalone(standalone)
+
+
+def test_dynamic_plugins(topology):
+ """
+ Test Dynamic Plugins - exercise each plugin and its main features, while
+ changing the configuration without restarting the server.
+
+ Need to test: functionality, stability, and stress.
+
+ Functionality - Make sure that as configuration changes are made they take
+ effect immediately. Cross plugin interaction (e.g. automember/memberOf)
+ needs to tested, as well as plugin tasks. Need to test plugin
+ config validation(dependencies, etc).
+
+ Memory Corruption - Restart the plugins many times, and in different orders and test
+ functionality, and stability. This will excerise the internal
+ plugin linked lists, dse callabcks, and task handlers.
+
+ Stress - Put the server under some type of load that is using a particular
+ plugin for each operation, and then make changes to that plugin.
+ The new changes should take effect, and the server should not crash.
+
+ """
+
+ ############################################################################
+ # Test plugin functionality
+ ############################################################################
+
+ # First enable dynamic plugins
+ try:
+ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', 'on')])
+ except ldap.LDAPError, e:
+ ldap.error('Failed to enable dynamic plugin!' + e.message['desc'])
+ assert False
+
+ log.info('#####################################################')
+ log.info('Testing Dynamic Plugins Functionality...')
+ log.info('#####################################################\n')
+
+ plugin_tests.test_all_plugins(topology.standalone)
+
+ log.info('#####################################################')
+ log.info('Successfully Tested Dynamic Plugins Functionality.')
+ log.info('#####################################################\n')
+
+ ############################################################################
+ # Test the stability by exercising the internal lists, callabcks, and task handlers
+ ############################################################################
+
+ log.info('#####################################################')
+ log.info('Testing Dynamic Plugins for Memory Corruption...')
+ log.info('#####################################################\n')
+ prev_plugin_test = None
+ prev_prev_plugin_test = None
+ for plugin_test in plugin_tests.func_tests:
+ #
+ # Restart the plugin several times (and prev plugins) - work that linked list
+ #
+ plugin_test(topology.standalone, "restart")
+
+ if prev_prev_plugin_test:
+ prev_prev_plugin_test(topology.standalone, "restart")
+
+ plugin_test(topology.standalone, "restart")
+
+ if prev_plugin_test:
+ prev_plugin_test(topology.standalone, "restart")
+
+ plugin_test(topology.standalone, "restart")
+
+ # Now run the functional test
+ plugin_test(topology.standalone)
+
+ # Set the previous tests
+ if prev_plugin_test:
+ prev_prev_plugin_test = prev_plugin_test
+ prev_plugin_test = plugin_test
+
+ log.info('#####################################################')
+ log.info('Successfully Tested Dynamic Plugins for Memory Corruption.')
+ log.info('#####################################################\n')
+
+ ############################################################################
+ # Stress two plugins while restarting it, and while restarting other plugins.
+ # The goal is to not crash, and have the plugins work after stressing it.
+ ############################################################################
+
+ log.info('#####################################################')
+ log.info('Stressing Dynamic Plugins...')
+ log.info('#####################################################\n')
+
+ # Configure the plugins
+ stress_tests.configureMO(topology.standalone)
+ stress_tests.configureRI(topology.standalone)
+
+ # Launch three new threads to add a bunch of users
+ add_users = stress_tests.AddUsers(topology.standalone, 'user', True)
+ add_users.start()
+ add_users2 = stress_tests.AddUsers(topology.standalone, 'entry', True)
+ add_users2.start()
+ add_users3 = stress_tests.AddUsers(topology.standalone, 'person', True)
+ add_users3.start()
+ time.sleep(1)
+
+ # While we are adding users restart the MO plugin
+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
+ time.sleep(3)
+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
+ time.sleep(1)
+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
+
+ # Restart idle plugin
+ topology.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)
+ topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)
+
+ # Wait for the 'adding' threads to complete
+ add_users.join()
+ add_users2.join()
+ add_users3.join()
+
+ # Now launch three threads to delete the users, and restart both the MO and RI plugins
+ del_users = stress_tests.DelUsers(topology.standalone, 'user')
+ del_users.start()
+ del_users2 = stress_tests.DelUsers(topology.standalone, 'entry')
+ del_users2.start()
+ del_users3 = stress_tests.DelUsers(topology.standalone, 'person')
+ del_users3.start()
+ time.sleep(1)
+
+ # Restart the both the MO and RI plugins during these deletes
+
+ topology.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)
+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
+ topology.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
+ time.sleep(3)
+ topology.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)
+ time.sleep(1)
+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
+ time.sleep(1)
+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
+ time.sleep(1)
+ topology.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
+
+ # Restart idle plugin
+ topology.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)
+ topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)
+
+ # Wait for the 'deleting' threads to complete
+ del_users.join()
+ del_users2.join()
+ del_users3.join()
+
+ # Now make sure both the MO and RI plugins still work
+ plugin_tests.func_tests[8](topology.standalone) # RI plugin
+ plugin_tests.func_tests[5](topology.standalone) # MO plugin
+
+ log.info('#####################################################')
+ log.info('Successfully Stressed Dynamic Plugins.')
+ log.info('#####################################################\n')
+
+ ############################################################################
+ # We made it to the end!
+ ############################################################################
+
+ log.info('#####################################################')
+ log.info('#####################################################')
+ log.info("Dynamic Plugins Testsuite: Completed Successfully!")
+ log.info('#####################################################')
+ log.info('#####################################################')
+
+def test_dynamic_plugins_final(topology):
+ topology.standalone.stop(timeout=10)
+
+
+def run_isolated():
+ '''
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+ To run isolated without py.test, you need to
+ - edit this file and comment '@pytest.fixture' line before 'topology' function.
+ - set the installation prefix
+ - run this program
+ '''
+ global installation_prefix
+ installation_prefix = None
+
+ topo = topology(True)
+ test_dynamic_plugins(topo)
+
+if __name__ == '__main__':
+ run_isolated()
9 years, 4 months
dirsrvtests/suites
by Mark Reynolds
dirsrvtests/suites/dynamic-plugins/constants.py | 33
dirsrvtests/suites/dynamic-plugins/finalizer.py | 57
dirsrvtests/suites/dynamic-plugins/plugin_tests.py | 1973 +++++++++++++
dirsrvtests/suites/dynamic-plugins/stress_tests.py | 133
dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py | 315 ++
5 files changed, 2511 insertions(+)
New commits:
commit 4e39dbbfde56ca68f5a26d0bf2ac3a261234c8cd
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Dec 16 16:44:33 2014 -0500
Ticket 47451 - Add Dynamic Plugin CI Suite
Description: Add lib389(CI) testsuite for Dynamic Plugins
Perform functional tests for plugins that have configuration settings
- Restart the plugin
- Make condfig change
- Test the plugin
- Make another config change
- Test plugin
- Test plugin dependency
- Cleanup
Perform memory corruption test
- This test forces the global plugin linked list, DSE callbacks,
and task handlers to be rewritten in various orders while
testing all the plugins.
Perform Stress tests
- Perform a series of operations that engage two plugins. While
there operations are being performed restart various plugins.
- Verify the server does not crash, and that hte plugins work
correctly.
https://fedorahosted.org/389/ticket/47451
Reviewed by: nhosoi(Thanks!)
diff --git a/dirsrvtests/suites/dynamic-plugins/constants.py b/dirsrvtests/suites/dynamic-plugins/constants.py
new file mode 100644
index 0000000..cbc310e
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/constants.py
@@ -0,0 +1,33 @@
+'''
+Created on Dec 09, 2014
+
+@author: mreynolds
+'''
+import os
+from lib389 import DN_DM
+from lib389._constants import *
+from lib389.properties import *
+
+SUFFIX = 'dc=example,dc=com'
+PASSWORD = 'password'
+
+# Used for standalone topology
+HOST_STANDALONE = LOCALHOST
+PORT_STANDALONE = 33389
+SERVERID_STANDALONE = 'dynamic-plugins'
+
+# Each defined instance above must be added in that list
+ALL_INSTANCES = [ {SER_HOST: HOST_STANDALONE, SER_PORT: PORT_STANDALONE, SER_SERVERID_PROP: SERVERID_STANDALONE},
+ ]
+# This is a template
+args_instance = {
+ SER_DEPLOYED_DIR: os.environ.get('PREFIX', None),
+ SER_BACKUP_INST_DIR: os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR),
+ SER_ROOT_DN: DN_DM,
+ SER_ROOT_PW: PASSWORD,
+ SER_HOST: LOCALHOST,
+ SER_PORT: DEFAULT_PORT,
+ SER_SERVERID_PROP: "template",
+ SER_CREATION_SUFFIX: DEFAULT_SUFFIX}
+
+
diff --git a/dirsrvtests/suites/dynamic-plugins/finalizer.py b/dirsrvtests/suites/dynamic-plugins/finalizer.py
new file mode 100644
index 0000000..eb02332
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/finalizer.py
@@ -0,0 +1,57 @@
+'''
+Created on Nov 5, 2013
+
+@author: tbordaz
+'''
+import os
+import sys
+import time
+import ldap
+import logging
+import socket
+import time
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools
+from lib389.tools import DirSrvTools
+from lib389._constants import DN_DM
+from lib389.properties import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+global installation_prefix
+installation_prefix=os.getenv('PREFIX')
+
+def test_finalizer():
+ global installation_prefix
+
+ # for each defined instance, remove it
+ for args_instance in ALL_INSTANCES:
+ if installation_prefix:
+ # overwrite the environment setting
+ args_instance[SER_DEPLOYED_DIR] = installation_prefix
+
+ instance = DirSrv(verbose=True)
+ instance.allocate(args_instance)
+ if instance.exists():
+ instance.delete()
+
+ # remove any existing backup for this instance
+ instance.clearBackupFS()
+
+def run_isolated():
+ '''
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+ To run isolated without py.test, you need to
+ - set the installation prefix
+ - run this program
+ '''
+ global installation_prefix
+ installation_prefix = None
+
+ test_finalizer()
+
+if __name__ == '__main__':
+ run_isolated()
+
diff --git a/dirsrvtests/suites/dynamic-plugins/plugin_tests.py b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py
new file mode 100644
index 0000000..fa88145
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/plugin_tests.py
@@ -0,0 +1,1973 @@
+'''
+Created on Dec 09, 2014
+
+@author: mreynolds
+'''
+import os
+import sys
+import time
+import ldap
+import time
+import logging
+import socket
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
+USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX
+USER3_DN = 'uid=user3,' + DEFAULT_SUFFIX
+BUSER1_DN = 'uid=user1,ou=branch1,' + DEFAULT_SUFFIX
+BUSER2_DN = 'uid=user2,ou=branch2,' + DEFAULT_SUFFIX
+BUSER3_DN = 'uid=user3,ou=branch2,' + DEFAULT_SUFFIX
+BRANCH1_DN = 'ou=branch1,' + DEFAULT_SUFFIX
+BRANCH2_DN = 'ou=branch2,' + DEFAULT_SUFFIX
+GROUP_OU = 'ou=groups,' + DEFAULT_SUFFIX
+PEOPLE_OU = 'ou=people,' + DEFAULT_SUFFIX
+GROUP_DN = 'cn=group,' + DEFAULT_SUFFIX
+
+'''
+ Functional tests for each plugin
+
+ Test:
+ plugin restarts (test when on and off)
+ plugin config validation
+ plugin dependencies
+ plugin functionality (including plugin tasks)
+'''
+
+
+################################################################################
+#
+# Test Plugin Dependency
+#
+################################################################################
+def test_dependency(inst, plugin):
+ """
+ Set the "account usabilty" plugin to depend on this plugin. This plugin
+ is generic, always enabled, and perfect for our testing
+ """
+
+ try:
+ inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config',
+ [(ldap.MOD_REPLACE, 'nsslapd-plugin-depends-on-named', plugin)])
+
+ except ldap.LDAPError, e:
+ log.error('test_dependency: Failed to modify ' + PLUGIN_ACCT_USABILITY + ': error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.modify_s('cn=' + plugin + ',cn=plugins,cn=config',
+ [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'off')])
+
+ except ldap.UNWILLING_TO_PERFORM:
+ # failed as expected
+ pass
+ else:
+ # Incorrectly succeeded
+ log.error('test_dependency: Plugin dependency check failed (%s)' % plugin)
+ assert False
+
+ # Now undo the change
+ try:
+ inst.modify_s('cn=' + PLUGIN_ACCT_USABILITY + ',cn=plugins,cn=config',
+ [(ldap.MOD_DELETE, 'nsslapd-plugin-depends-on-named', None)])
+ except ldap.LDAPError, e:
+ log.error('test_dependency: Failed to reset ' + plugin + ': error ' + e.message['desc'])
+ assert False
+
+
+################################################################################
+#
+# Test Account Policy Plugin (0)
+#
+################################################################################
+def test_acctpolicy(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_ACCT_POLICY)
+ inst.plugins.enable(name=PLUGIN_ACCT_POLICY)
+
+ if args == "restart":
+ return True
+
+ CONFIG_DN = 'cn=config,cn=Account Policy Plugin,cn=plugins,cn=config'
+ log.info('Testing ' + PLUGIN_ACCT_POLICY + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add the config entry
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'config',
+ 'alwaysrecordlogin': 'yes',
+ 'stateattrname': 'lastLoginTime'
+ })))
+ except ldap.ALREADY_EXISTS:
+ try:
+ inst.modify_s(CONFIG_DN,
+ [(ldap.MOD_REPLACE, 'alwaysrecordlogin', 'yes'),
+ (ldap.MOD_REPLACE, 'stateattrname', 'lastLoginTime')])
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc'])
+ assert False
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ # Now set the config entry in the plugin entry
+ #try:
+ # inst.modify_s('cn=' + PLUGIN_ACCT_POLICY + ',cn=plugins,cn=config',
+ # [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', CONFIG_DN)])
+ #except ldap.LDAPError, e:
+ # log.error('test_acctpolicy: Failed to set config entry in plugin entry: error ' + e.message['desc'])
+ # assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # !!!! acctpolicy does have have a dse callabck to check for live updates - restart plugin for now !!!!
+ inst.plugins.disable(name=PLUGIN_ACCT_POLICY)
+ inst.plugins.enable(name=PLUGIN_ACCT_POLICY)
+
+ # Add an entry
+ try:
+ inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(),
+ 'sn': '1',
+ 'cn': 'user 1',
+ 'uid': 'user1',
+ 'userpassword': 'password'})))
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to add test user' + USER1_DN + ': error ' + e.message['desc'])
+ assert False
+
+ # bind as user
+ try:
+ inst.simple_bind_s(USER1_DN, "password")
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy:Failed to bind as user1: ' + e.message['desc'])
+ assert False
+
+ # Bind as Root DN
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc'])
+ assert False
+
+ # Check lastLoginTime of USER1
+ try:
+ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'lastLoginTime=*')
+ if not entries:
+ log.fatal('test_acctpolicy: Search failed to find an entry with lastLoginTime.')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_acctpolicy: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change config - change the stateAttrName to a new attribute
+ ############################################################################
+
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'stateattrname', 'testLastLoginTime')])
+
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to modify config entry: error ' + e.message['desc'])
+ assert False
+
+ # !!!! must restart for now !!!!!
+ inst.plugins.disable(name=PLUGIN_ACCT_POLICY)
+ inst.plugins.enable(name=PLUGIN_ACCT_POLICY)
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # login as user
+ try:
+ inst.simple_bind_s(USER1_DN, "password")
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to bind(2nd) as user1: ' + e.message['desc'])
+ assert False
+
+ # Bind as Root DN
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to bind as rootDN: ' + e.message['desc'])
+ assert False
+
+ # Check testLastLoginTime was added to USER1
+ try:
+ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(testLastLoginTime=*)')
+ if not entries:
+ log.fatal('test_acctpolicy: Search failed to find an entry with testLastLoginTime.')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_acctpolicy: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_ACCT_POLICY)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_acctpolicy: Failed to delete test entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_acctpolicy: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Attribute Uniqueness Plugin (1)
+#
+################################################################################
+def test_attruniq(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_ATTR_UNIQUENESS)
+ inst.plugins.enable(name=PLUGIN_ATTR_UNIQUENESS)
+
+ if args == "restart":
+ return
+
+ log.info('Testing ' + PLUGIN_ATTR_UNIQUENESS + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ try:
+ inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',
+ [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'uid')])
+
+ except ldap.LDAPError, e:
+ log.error('test_attruniq: Failed to configure plugin for "uid": error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add an entry
+ try:
+ inst.add_s(Entry((USER1_DN, {'objectclass': "top extensibleObject".split(),
+ 'sn': '1',
+ 'cn': 'user 1',
+ 'uid': 'user1',
+ 'mail': 'user1(a)example.com',
+ 'userpassword': 'password'})))
+ except ldap.LDAPError, e:
+ log.error('test_attruniq: Failed to add test user' + USER1_DN + ': error ' + e.message['desc'])
+ assert False
+
+ # Add an entry with a duplicate "uid"
+ try:
+ inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
+ 'sn': '2',
+ 'cn': 'user 2',
+ 'uid': 'user2',
+ 'uid': 'user1',
+ 'userpassword': 'password'})))
+
+ except ldap.CONSTRAINT_VIOLATION:
+ pass
+ else:
+ log.error('test_attruniq: Adding of 2nd entry(uid) incorrectly succeeded')
+ assert False
+
+ ############################################################################
+ # Change config to use "mail" instead of "uid"
+ ############################################################################
+
+ try:
+ inst.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config',
+ [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', 'mail')])
+
+ except ldap.LDAPError, e:
+ log.error('test_attruniq: Failed to configure plugin for "mail": error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin - Add an entry, that has a duplicate "mail" value
+ ############################################################################
+
+ try:
+ inst.add_s(Entry((USER2_DN, {'objectclass': "top extensibleObject".split(),
+ 'sn': '2',
+ 'cn': 'user 2',
+ 'uid': 'user2',
+ 'mail': 'user1(a)example.com',
+ 'userpassword': 'password'})))
+ except ldap.CONSTRAINT_VIOLATION:
+ pass
+ else:
+ log.error('test_attruniq: Adding of 2nd entry(mail) incorrectly succeeded')
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_ATTR_UNIQUENESS)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_attruniq: Failed to delete test entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_attruniq: PASS\n')
+ return
+
+
+################################################################################
+#
+# Test Auto Membership Plugin (2)
+#
+################################################################################
+def test_automember(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_AUTOMEMBER)
+ inst.plugins.enable(name=PLUGIN_AUTOMEMBER)
+
+ if args == "restart":
+ return
+
+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_AUTOMEMBER + ',cn=plugins,cn=config'
+
+ log.info('Testing ' + PLUGIN_AUTOMEMBER + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add the automember group
+ try:
+ inst.add_s(Entry((GROUP_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'group'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add group: error ' + e.message['desc'])
+ assert False
+
+ # Add ou=branch1
+ try:
+ inst.add_s(Entry((BRANCH1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'branch1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add branch1: error ' + e.message['desc'])
+ assert False
+
+ # Add ou=branch2
+ try:
+ inst.add_s(Entry((BRANCH2_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'branch2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add branch2: error ' + e.message['desc'])
+ assert False
+
+ # Add the automember config entry
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top autoMemberDefinition'.split(),
+ 'cn': 'config',
+ 'autoMemberScope': 'ou=branch1,' + DEFAULT_SUFFIX,
+ 'autoMemberFilter': 'objectclass=top',
+ 'autoMemberDefaultGroup': 'cn=group,' + DEFAULT_SUFFIX,
+ 'autoMemberGroupingAttr': 'member:dn'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test the plugin
+ ############################################################################
+
+ # Add a user that should get added to the group
+ try:
+ inst.add_s(Entry((BUSER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add user: error ' + e.message['desc'])
+ assert False
+
+ # Check the group
+ try:
+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
+ '(member=' + BUSER1_DN + ')')
+ if not entries:
+ log.fatal('test_automember: Search failed to find member user1')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_automember: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change config
+ ############################################################################
+
+ try:
+ inst.modify_s(CONFIG_DN,
+ [(ldap.MOD_REPLACE, 'autoMemberGroupingAttr', 'uniquemember:dn'),
+ (ldap.MOD_REPLACE, 'autoMemberScope', 'ou=branch2,' + DEFAULT_SUFFIX)])
+
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to modify config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add a user that should get added to the group
+ try:
+ inst.add_s(Entry((BUSER2_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to user to branch2: error ' + e.message['desc'])
+ assert False
+
+ # Check the group
+ try:
+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
+ '(uniquemember=' + BUSER2_DN + ')')
+ if not entries:
+ log.fatal('test_automember: Search failed to find uniquemember user2')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_automember: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test Task
+ ############################################################################
+
+ # Disable plugin
+ inst.plugins.disable(name=PLUGIN_AUTOMEMBER)
+
+ # Add an entry that should be picked up by automember - verify it is not(yet)
+ try:
+ inst.add_s(Entry((BUSER3_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user3'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to user3 to branch2: error ' + e.message['desc'])
+ assert False
+
+ # Check the group - uniquemember sahould not exist
+ try:
+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
+ '(uniquemember=' + BUSER3_DN + ')')
+ if entries:
+ log.fatal('test_automember: user3 was incorrectly added to the group')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_automember: Search failed: ' + e.message['desc'])
+ assert False
+
+ # Enable plugin
+ inst.plugins.enable(name=PLUGIN_AUTOMEMBER)
+
+ # Add the task
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=automember rebuild membership,cn=tasks,cn=config', {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': 'ou=branch2,' + DEFAULT_SUFFIX,
+ 'filter': 'objectclass=top'})))
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do its work
+
+ # Verify the fixup task worked
+ try:
+ entries = inst.search_s(GROUP_DN, ldap.SCOPE_BASE,
+ '(uniquemember=' + BUSER3_DN + ')')
+ if not entries:
+ log.fatal('test_automember: user3 was not added to the group')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_automember: Search failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_AUTOMEMBER)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(BUSER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test entry1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BUSER2_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test entry2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BUSER3_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test entry3: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete branch1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH2_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test branch2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(GROUP_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test group: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(CONFIG_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete plugin config entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_automember: PASS\n')
+ return
+
+
+################################################################################
+#
+# Test DNA Plugin (3)
+#
+################################################################################
+def test_dna(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_DNA)
+ inst.plugins.enable(name=PLUGIN_DNA)
+
+ if args == "restart":
+ return
+
+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_DNA + ',cn=plugins,cn=config'
+
+ log.info('Testing ' + PLUGIN_DNA + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top dnaPluginConfig'.split(),
+ 'cn': 'config',
+ 'dnatype': 'uidNumber',
+ 'dnafilter': '(objectclass=top)',
+ 'dnascope': DEFAULT_SUFFIX,
+ 'dnaMagicRegen': '-1',
+ 'dnaMaxValue': '50000',
+ 'dnaNextValue': '1'
+ })))
+ except ldap.ALREADY_EXISTS:
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaNextValue', '1'),
+ (ldap.MOD_REPLACE, 'dnaMagicRegen', '-1')])
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to set the DNA plugin: error ' + e.message['desc'])
+ assert False
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to user1: error ' + e.message['desc'])
+ assert False
+
+ # See if the entry now has the new uidNumber assignment - uidNumber=1
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=1)')
+ if not entries:
+ log.fatal('test_dna: user1 was not updated - (looking for uidNumber: 1)')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Test the magic regen value
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-1')])
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to set the magic reg value: error ' + e.message['desc'])
+ assert False
+
+ # See if the entry now has the new uidNumber assignment - uidNumber=2
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=2)')
+ if not entries:
+ log.fatal('test_dna: user1 was not updated (looking for uidNumber: 2)')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ################################################################################
+ # Change the config
+ ################################################################################
+
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'dnaMagicRegen', '-2')])
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to set the magic reg value to -2: error ' + e.message['desc'])
+ assert False
+
+ ################################################################################
+ # Test plugin
+ ################################################################################
+
+ # Test the magic regen value
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'uidNumber', '-2')])
+ except ldap.LDAPError, e:
+ log.error('test_dna: Failed to set the magic reg value: error ' + e.message['desc'])
+ assert False
+
+ # See if the entry now has the new uidNumber assignment - uidNumber=3
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(uidNumber=3)')
+ if not entries:
+ log.fatal('test_dna: user1 was not updated (looking for uidNumber: 3)')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_dna: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_AUTOMEMBER)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_automember: Failed to delete test entry1: ' + e.message['desc'])
+ assert False
+
+ inst.plugins.disable(name=PLUGIN_DNA)
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_dna: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Linked Attrs Plugin (4)
+#
+################################################################################
+def test_linkedattrs(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_LINKED_ATTRS)
+ inst.plugins.enable(name=PLUGIN_LINKED_ATTRS)
+
+ if args == "restart":
+ return
+
+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_LINKED_ATTRS + ',cn=plugins,cn=config'
+
+ log.info('Testing ' + PLUGIN_LINKED_ATTRS + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add test entries
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to user1: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((USER2_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to user1: error ' + e.message['desc'])
+ assert False
+
+ # Add the linked attrs config entry
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'config',
+ 'linkType': 'directReport',
+ 'managedType': 'manager'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Set "directReport" should add "manager" to the other entry
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was added to the other entry
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if not entries:
+ log.fatal('test_linkedattrs: user2 missing "manager" attribute')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Remove "directReport" should remove "manager" to the other entry
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'directReport', None)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was removed
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 "manager" attribute not removed')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change the config - using linkType "indirectReport" now
+ ############################################################################
+
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'linkType', 'indirectReport')])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to set linkTypee: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Make sure the old linkType(directManager) is not working
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'directReport', USER2_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add "directReport" to user1: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was added to the other entry, better not be...
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 had "manager" added unexpectedly')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])
+ assert False
+
+ # Now, set the new linkType "indirectReport", which should add "manager" to the other entry
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was added to the other entry, better not be
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if not entries:
+ log.fatal('test_linkedattrs: user2 missing "manager"')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])
+ assert False
+
+ # Remove "indirectReport" should remove "manager" to the other entry
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'indirectReport', None)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete directReport: error ' + e.message['desc'])
+ assert False
+
+ # See if manager was removed
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 "manager" attribute not removed')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test Fixup Task
+ ############################################################################
+
+ # Disable plugin and make some updates that would of triggered the plugin
+ inst.plugins.disable(name=PLUGIN_LINKED_ATTRS)
+
+ try:
+ inst.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'indirectReport', USER2_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add "indirectReport" to user1: error ' + e.message['desc'])
+ assert False
+
+ # The entry should not have a manager attribute
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 incorrectly has a "manager" attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Verify that the task does not work yet(not until we enable the plugin)
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config', {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': DEFAULT_SUFFIX,
+ 'filter': '(objectclass=top)'})))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do, or not do, its work
+
+ # The entry should still not have a manager attribute
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if entries:
+ log.fatal('test_linkedattrs: user2 incorrectly has a "manager" attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user2 failed: ' + e.message['desc'])
+ assert False
+
+ # Enable the plugin and rerun the task entry
+ inst.plugins.enable(name=PLUGIN_LINKED_ATTRS)
+
+ # Add the task again
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',cn=fixup linked attributes,cn=tasks,cn=config', {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': DEFAULT_SUFFIX,
+ 'filter': 'objectclass=top'})))
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do its work
+
+ # Check if user2 now has a manager attribute now
+ try:
+ entries = inst.search_s(USER2_DN, ldap.SCOPE_BASE, '(manager=*)')
+ if not entries:
+ log.fatal('test_linkedattrs: task failed: user2 missing "manager" attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_linkedattrs: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_LINKED_ATTRS)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete test entry1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(USER2_DN)
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete test entry2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(CONFIG_DN)
+ except ldap.LDAPError, e:
+ log.error('test_linkedattrs: Failed to delete plugin config entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_linkedattrs: PASS\n')
+ return
+
+
+################################################################################
+#
+# Test MemberOf Plugin (5)
+#
+################################################################################
+def test_memberof(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_MEMBER_OF)
+ inst.plugins.enable(name=PLUGIN_MEMBER_OF)
+
+ if args == "restart":
+ return
+
+ PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config'
+
+ log.info('Testing ' + PLUGIN_MEMBER_OF + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'member')])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to update config(member): error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add our test entries
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((GROUP_DN, {
+ 'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(),
+ 'cn': 'group',
+ 'member': USER1_DN
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add group: error ' + e.message['desc'])
+ assert False
+
+ # Check if the user now has a "memberOf" attribute
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if not entries:
+ log.fatal('test_memberof: user1 missing memberOf')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Remove "member" should remove "memberOf" from the entry
+ try:
+ inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'member', None)])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to delete member: error ' + e.message['desc'])
+ assert False
+
+ # Check that "memberOf" was removed
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if entries:
+ log.fatal('test_memberof: user1 incorrect has memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to update config(uniquemember): error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ try:
+ inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])
+ assert False
+
+ # Check if the user now has a "memberOf" attribute
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if not entries:
+ log.fatal('test_memberof: user1 missing memberOf')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Remove "uniquemember" should remove "memberOf" from the entry
+ try:
+ inst.modify_s(GROUP_DN, [(ldap.MOD_DELETE, 'uniquemember', None)])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to delete member: error ' + e.message['desc'])
+ assert False
+
+ # Check that "memberOf" was removed
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if entries:
+ log.fatal('test_memberof: user1 incorrect has memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test Fixup Task
+ ############################################################################
+
+ inst.plugins.disable(name=PLUGIN_MEMBER_OF)
+
+ # Add uniquemember, should not update USER1
+ try:
+ inst.modify_s(GROUP_DN, [(ldap.MOD_REPLACE, 'uniquemember', USER1_DN)])
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add uniquemember: error ' + e.message['desc'])
+ assert False
+
+ # Check for "memberOf"
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if entries:
+ log.fatal('test_memberof: user1 incorrect has memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Run fixup task while plugin disabled - should not add "memberOf
+ # Verify that the task does not work yet(not until we enable the plugin)
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': DEFAULT_SUFFIX,
+ 'filter': 'objectclass=top'})))
+ except ldap.NO_SUCH_OBJECT:
+ pass
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do, or not do, its work
+
+ # Check for "memberOf"
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if entries:
+ log.fatal('test_memberof: user1 incorrectly has memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ # Enable the plugin, and run the task
+ inst.plugins.enable(name=PLUGIN_MEMBER_OF)
+
+ try:
+ inst.add_s(Entry(('cn=task-' + str(int(time.time())) + ',' + DN_MBO_TASK, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'basedn': DEFAULT_SUFFIX,
+ 'filter': 'objectclass=top'})))
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to add task: error ' + e.message['desc'])
+ assert False
+
+ time.sleep(3) # Wait for the task to do its work
+
+ # Check for "memberOf"
+ try:
+ entries = inst.search_s(USER1_DN, ldap.SCOPE_BASE, '(memberOf=*)')
+ if not entries:
+ log.fatal('test_memberof: user1 missing memberOf attr')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_memberof: Search for user1 failed: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_MEMBER_OF)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to delete test entry1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(GROUP_DN)
+ except ldap.LDAPError, e:
+ log.error('test_memberof: Failed to delete test group: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_memberof: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Managed Entry Plugin (6)
+#
+################################################################################
+def test_mep(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY)
+ inst.plugins.enable(name=PLUGIN_MANAGED_ENTRY)
+
+ if args == "restart":
+ return
+
+ USER_DN = 'uid=user1,ou=people,' + DEFAULT_SUFFIX
+ MEP_USER_DN = 'cn=user1,ou=groups,' + DEFAULT_SUFFIX
+ USER_DN2 = 'uid=user 1,ou=people,' + DEFAULT_SUFFIX
+ MEP_USER_DN2 = 'uid=user 1,ou=groups,' + DEFAULT_SUFFIX
+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_MANAGED_ENTRY + ',cn=plugins,cn=config'
+ TEMPLATE_DN = 'cn=MEP Template,' + DEFAULT_SUFFIX
+ TEMPLATE_DN2 = 'cn=MEP Template2,' + DEFAULT_SUFFIX
+
+ log.info('Testing ' + PLUGIN_MANAGED_ENTRY + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add our org units
+ try:
+ inst.add_s(Entry((PEOPLE_OU, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'people'})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add people org unit: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((GROUP_OU, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'people'})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add people org unit: error ' + e.message['desc'])
+ assert False
+
+ # Add the template entry
+ try:
+ inst.add_s(Entry((TEMPLATE_DN, {
+ 'objectclass': 'top mepTemplateEntry extensibleObject'.split(),
+ 'cn': 'MEP Template',
+ 'mepRDNAttr': 'cn',
+ 'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'),
+ 'mepMappedAttr': 'cn: $cn|uid: $cn|gidNumber: $uidNumber'.split('|')
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add template entry: error ' + e.message['desc'])
+ assert False
+
+ # log.info('geb.....')
+ # time.sleep(30)
+
+ # Add the config entry
+ try:
+ inst.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'config',
+ 'originScope': PEOPLE_OU,
+ 'originFilter': 'objectclass=posixAccount',
+ 'managedBase': GROUP_OU,
+ 'managedTemplate': TEMPLATE_DN
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add an entry that meets the MEP scope
+ try:
+ inst.add_s(Entry((USER_DN, {
+ 'objectclass': 'top posixAccount extensibleObject'.split(),
+ 'uid': 'user1',
+ 'cn': 'user1',
+ 'uidNumber': '1',
+ 'gidNumber': '1',
+ 'homeDirectory': '/home/user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to user1: error ' + e.message['desc'])
+ assert False
+
+ # Check if a managed group entry was created
+ try:
+ inst.search_s(MEP_USER_DN, ldap.SCOPE_BASE, '(objectclass=top)')
+ except ldap.LDAPError, e:
+ log.fatal('test_mep: Unable to find MEP entry: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ # Add a new template entry
+ try:
+ inst.add_s(Entry((TEMPLATE_DN2, {
+ 'objectclass': 'top mepTemplateEntry extensibleObject'.split(),
+ 'cn': 'MEP Template2',
+ 'mepRDNAttr': 'uid',
+ 'mepStaticAttr': 'objectclass: posixGroup|objectclass: extensibleObject'.split('|'),
+ 'mepMappedAttr': 'cn: $uid|uid: $cn|gidNumber: $gidNumber'.split('|')
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to add template entry2: error ' + e.message['desc'])
+ assert False
+
+ # Set the new template dn
+ try:
+ inst.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'managedTemplate', TEMPLATE_DN2)])
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to set mep plugin config: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add an entry that meets the MEP scope
+ try:
+ inst.add_s(Entry((USER_DN2, {
+ 'objectclass': 'top posixAccount extensibleObject'.split(),
+ 'uid': 'user 1',
+ 'cn': 'user 1',
+ 'uidNumber': '1',
+ 'gidNumber': '1',
+ 'homeDirectory': '/home/user2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to user2: error ' + e.message['desc'])
+ assert False
+
+ # Check if a managed group entry was created
+ try:
+ inst.search_s(MEP_USER_DN2, ldap.SCOPE_BASE, '(objectclass=top)')
+ except ldap.LDAPError, e:
+ log.fatal('test_mep: Unable to find MEP entry2: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_MANAGED_ENTRY)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(USER_DN)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete test user1: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(USER_DN2)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete test user 2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(TEMPLATE_DN)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete template1: ' + e.message['desc'])
+ assert False
+
+ inst.plugins.disable(name=PLUGIN_MANAGED_ENTRY)
+
+ try:
+ inst.delete_s(TEMPLATE_DN2)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete template2: ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(CONFIG_DN)
+ except ldap.LDAPError, e:
+ log.error('test_mep: Failed to delete config: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_mep: PASS\n')
+ return
+
+
+################################################################################
+#
+# Test Passthru Plugin (7)
+#
+################################################################################
+def test_passthru(inst, args=None):
+ # Passthru is a bit picky about the state of the entry - we can't just restart it
+ if args == "restart":
+ return
+
+ # stop the plugin
+ inst.plugins.disable(name=PLUGIN_PASSTHRU)
+
+ PLUGIN_DN = 'cn=' + PLUGIN_PASSTHRU + ',cn=plugins,cn=config'
+ PASSTHRU_DN = 'uid=admin,dc=pass,dc=thru'
+ PASSTHRU_DN2 = 'uid=admin2,dc=pass2,dc=thru'
+ PASS_SUFFIX1 = 'dc=pass,dc=thru'
+ PASS_SUFFIX2 = 'dc=pass2,dc=thru'
+ PASS_BE2 = 'PASS2'
+
+ log.info('Testing ' + PLUGIN_PASSTHRU + '...')
+
+ ############################################################################
+ # Add a new "remote" instance, and a user for auth
+ ############################################################################
+
+ # Create second instance
+ passthru_inst = DirSrv(verbose=False)
+
+ #if installation1_prefix:
+ # args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+ # Args for the master1 instance
+ """
+ args_instance[SER_HOST] = '127.0.0.1'
+ args_instance[SER_PORT] = '33333'
+ args_instance[SER_SERVERID_PROP] = 'passthru'
+ """
+ args_instance[SER_HOST] = 'localhost.localdomain'
+ args_instance[SER_PORT] = 33333
+ args_instance[SER_SERVERID_PROP] = 'passthru'
+
+ args_instance[SER_CREATION_SUFFIX] = PASS_SUFFIX1
+ args_passthru_inst = args_instance.copy()
+ passthru_inst.allocate(args_passthru_inst)
+ passthru_inst.create()
+ passthru_inst.open()
+
+ # Create a second backend
+ passthru_inst.backend.create(PASS_SUFFIX2, {BACKEND_NAME: PASS_BE2})
+ passthru_inst.mappingtree.create(PASS_SUFFIX2, bename=PASS_BE2)
+
+ # Create the top of the tree
+ try:
+ passthru_inst.add_s(Entry((PASS_SUFFIX2, {
+ 'objectclass': 'top domain'.split(),
+ 'dc': 'pass2'})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to create suffix entry: error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ # Add user to suffix1
+ try:
+ passthru_inst.add_s(Entry((PASSTHRU_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'admin',
+ 'userpassword': 'password'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to admin1: error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ # Add user to suffix 2
+ try:
+ passthru_inst.add_s(Entry((PASSTHRU_DN2, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'admin2',
+ 'userpassword': 'password'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to admin2 : error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Configure and start plugin
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginenabled', 'on'),
+ (ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass,dc=thru')])
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to set mep plugin config: error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # login as user
+ try:
+ inst.simple_bind_s(PASSTHRU_DN, "password")
+ except ldap.LDAPError, e:
+ log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ # login as root DN
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'nsslapd-pluginarg0', 'ldap://127.0.0.1:33333/dc=pass2,dc=thru')])
+ except ldap.LDAPError, e:
+ log.error('test_passthru: Failed to set mep plugin config: error ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # login as user
+ try:
+ inst.simple_bind_s(PASSTHRU_DN2, "password")
+ except ldap.LDAPError, e:
+ log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ # login as root DN
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ log.error('test_passthru: pass through bind failed: ' + e.message['desc'])
+ passthru_inst.delete()
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_PASSTHRU)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ # remove the passthru instance
+ passthru_inst.delete()
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_passthru: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Referential Integrity Plugin (8)
+#
+################################################################################
+def test_referint(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_REFER_INTEGRITY)
+ inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
+
+ if args == "restart":
+ return
+
+ log.info('Testing ' + PLUGIN_REFER_INTEGRITY + '...')
+ PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config'
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'member')])
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to configure RI plugin: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add some users and a group
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((USER2_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user2'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to add user2: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.add_s(Entry((GROUP_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'group',
+ 'member': USER1_DN,
+ 'uniquemember': USER2_DN
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to add group: error ' + e.message['desc'])
+ assert False
+
+ # Delete a user
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ # Check for integrity
+ try:
+ entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(member=' + USER1_DN + ')')
+ if entry:
+ log.error('test_referint: user1 was not removed from group')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_referint: Unable to search group: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')])
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to configure RI plugin: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Delete a user
+ try:
+ inst.delete_s(USER2_DN)
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ # Check for integrity
+ try:
+ entry = inst.search_s(GROUP_DN, ldap.SCOPE_BASE, '(uniquemember=' + USER2_DN + ')')
+ if entry:
+ log.error('test_referint: user2 was not removed from group')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_referint: Unable to search group: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_REFER_INTEGRITY)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ try:
+ inst.delete_s(GROUP_DN)
+ except ldap.LDAPError, e:
+ log.error('test_referint: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_referint: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Retro Changelog Plugin (9)
+#
+################################################################################
+def test_retrocl(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)
+ inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
+
+ if args == "restart":
+ return
+
+ log.info('Testing ' + PLUGIN_RETRO_CHANGELOG + '...')
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Gather the current change count (it's not 1 once we start the stabilty tests)
+ try:
+ entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')
+ except ldap.LDAPError, e:
+ log.error('test_retrocl: Failed to get the count: error ' + e.message['desc'])
+ assert False
+
+ entry_count = len(entry)
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Add a user
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_retrocl: Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ # Check we logged this in the retro cl
+ try:
+ entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')
+ if not entry or len(entry) == entry_count:
+ log.error('test_retrocl: changelog not updated')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_retrocl: Unable to search group: ' + e.message['desc'])
+ assert False
+
+ entry_count += 1
+
+ ############################################################################
+ # Change the config - disable plugin
+ ############################################################################
+
+ inst.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_retrocl: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ # Check we didn't logged this in the retro cl
+ try:
+ entry = inst.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(changenumber=*)')
+ if len(entry) != entry_count:
+ log.error('test_retrocl: changelog incorrectly updated - change count: '
+ + str(len(entry)) + ' - expected 1')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('test_retrocl: Unable to search retro changelog: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ inst.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
+ test_dependency(inst, PLUGIN_RETRO_CHANGELOG)
+
+ ############################################################################
+ # Cleanup
+ ############################################################################
+
+ # None
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_retrocl: PASS\n')
+
+ return
+
+
+################################################################################
+#
+# Test Root DN Access Control Plugin (10)
+#
+################################################################################
+def test_rootdn(inst, args=None):
+ # stop the plugin, and start it
+ inst.plugins.disable(name=PLUGIN_ROOTDN_ACCESS)
+ inst.plugins.enable(name=PLUGIN_ROOTDN_ACCESS)
+
+ if args == "restart":
+ return
+
+ PLUGIN_DN = 'cn=' + PLUGIN_ROOTDN_ACCESS + ',cn=plugins,cn=config'
+
+ ############################################################################
+ # Configure plugin
+ ############################################################################
+
+ # Add an user and aci to open up cn=config
+ try:
+ inst.add_s(Entry((USER1_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1',
+ 'userpassword': 'password'
+ })))
+ except ldap.LDAPError, e:
+ log.error('test_retrocl: Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ # Set an aci so we can modify the plugin after ew deny the root dn
+ ACI = '(target ="ldap:///cn=config")(targetattr = "*")(version 3.0;acl "all access";allow (all)(userdn="ldap:///anyone");)'
+ try:
+ inst.modify_s(DN_CONFIG, [(ldap.MOD_ADD, 'aci', ACI)])
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to add aci to config: error ' + e.message['desc'])
+ assert False
+
+ # Set allowed IP to an unknown host - blocks root dn
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'rootdn-allow-ip', '10.10.10.10')])
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Bind as Root DN
+ failed = False
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ failed = True
+
+ if not failed:
+ log.error('test_rootdn: Root DN was incorrectly able to bind')
+ assert False
+
+ ############################################################################
+ # Change the config
+ ############################################################################
+
+ try:
+ inst.simple_bind_s(USER1_DN, 'password')
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: failed to bind as user1')
+ assert False
+
+ # Remove the restriction
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_DELETE, 'rootdn-allow-ip', None)])
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to set rootDN plugin config: error ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test plugin
+ ############################################################################
+
+ # Bind as Root DN
+ failed = False
+ try:
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError, e:
+ failed = True
+
+ if failed:
+ log.error('test_rootdn: Root DN was not able to bind')
+ assert False
+
+ ############################################################################
+ # Test plugin dependency
+ ############################################################################
+
+ test_dependency(inst, PLUGIN_ROOTDN_ACCESS)
+
+ ############################################################################
+ # Cleanup - remove ACI from cn=config and test user
+ ############################################################################
+
+ try:
+ inst.modify_s(DN_CONFIG, [(ldap.MOD_DELETE, 'aci', ACI)])
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to add aci to config: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(USER1_DN)
+ except ldap.LDAPError, e:
+ log.error('test_rootdn: Failed to delete user1: ' + e.message['desc'])
+ assert False
+
+ ############################################################################
+ # Test passed
+ ############################################################################
+
+ log.info('test_rootdn: PASS\n')
+
+ return
+
+
+# Array of test functions
+func_tests = [test_acctpolicy, test_attruniq, test_automember, test_dna,
+ test_linkedattrs, test_memberof, test_mep, test_passthru,
+ test_referint, test_retrocl, test_rootdn]
+
+
+def test_all_plugins(inst, args=None):
+ for func in func_tests:
+ func(inst, args)
+
+ return
+
diff --git a/dirsrvtests/suites/dynamic-plugins/stress_tests.py b/dirsrvtests/suites/dynamic-plugins/stress_tests.py
new file mode 100644
index 0000000..a1f666d
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/stress_tests.py
@@ -0,0 +1,133 @@
+'''
+Created on Dec 16, 2014
+
+@author: mreynolds
+'''
+import os
+import sys
+import time
+import ldap
+import time
+import logging
+import socket
+import pytest
+import threading
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+NUM_USERS = 250
+
+
+def openConnection(inst):
+ # Open a new connection to our LDAP server
+ server = DirSrv(verbose=False)
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_standalone = args_instance.copy()
+ server.allocate(args_standalone)
+ server.open()
+
+ return server
+
+
+# Configure Referential Integrity Plugin for stress test
+def configureRI(inst):
+ inst.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
+ PLUGIN_DN = 'cn=' + PLUGIN_REFER_INTEGRITY + ',cn=plugins,cn=config'
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'referint-membership-attr', 'uniquemember')])
+ except ldap.LDAPError, e:
+ log.error('configureRI: Failed to configure RI plugin: error ' + e.message['desc'])
+ assert False
+
+
+# Configure MemberOf Plugin for stress test
+def configureMO(inst):
+ inst.plugins.enable(name=PLUGIN_MEMBER_OF)
+ PLUGIN_DN = 'cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config'
+ try:
+ inst.modify_s(PLUGIN_DN, [(ldap.MOD_REPLACE, 'memberofgroupattr', 'uniquemember')])
+ except ldap.LDAPError, e:
+ log.error('configureMO: Failed to update config(uniquemember): error ' + e.message['desc'])
+ assert False
+
+
+class DelUsers(threading.Thread):
+ def __init__(self, inst, rdnval):
+ threading.Thread.__init__(self)
+ self.daemon = True
+ self.inst = inst
+ self.rdnval = rdnval
+
+ def run(self):
+ conn = openConnection(self.inst)
+ idx = 0
+ log.info('DelUsers - Deleting ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...')
+ while idx < NUM_USERS:
+ USER_DN = 'uid=' + self.rdnval + str(idx) + ',' + DEFAULT_SUFFIX
+ try:
+ conn.delete_s(USER_DN)
+ except ldap.LDAPError, e:
+ log.error('DeleteUsers: failed to delete (' + USER_DN + ') error: ' + e.message['desc'])
+ assert False
+
+ idx += 1
+
+ conn.close()
+ log.info('DelUsers - Finished deleting ' + str(NUM_USERS) + ' entries (' + self.rdnval + ').')
+
+
+class AddUsers(threading.Thread):
+ def __init__(self, inst, rdnval, addToGroup):
+ threading.Thread.__init__(self)
+ self.daemon = True
+ self.inst = inst
+ self.addToGroup = addToGroup
+ self.rdnval = rdnval
+
+ def run(self):
+ # Start adding users
+ conn = openConnection(self.inst)
+ idx = 0
+
+ if self.addToGroup:
+ GROUP_DN = 'cn=stress-group,' + DEFAULT_SUFFIX
+ try:
+ conn.add_s(Entry((GROUP_DN,
+ {'objectclass': 'top groupOfNames groupOfUniqueNames extensibleObject'.split(),
+ 'uid': 'user' + str(idx)})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('AddUsers: failed to add group (' + USER_DN + ') error: ' + e.message['desc'])
+ assert False
+
+ log.info('AddUsers - Adding ' + str(NUM_USERS) + ' entries (' + self.rdnval + ')...')
+
+ while idx < NUM_USERS:
+ USER_DN = 'uid=' + self.rdnval + str(idx) + ',' + DEFAULT_SUFFIX
+ try:
+ conn.add_s(Entry((USER_DN, {'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user' + str(idx)})))
+ except ldap.LDAPError, e:
+ log.error('AddUsers: failed to add (' + USER_DN + ') error: ' + e.message['desc'])
+ assert False
+
+ if self.addToGroup:
+ # Add the user to the group
+ try:
+ conn.modify_s(GROUP_DN, [(ldap.MOD_ADD, 'uniquemember', USER_DN)])
+ except ldap.LDAPError, e:
+ log.error('AddUsers: Failed to add user' + USER_DN + ' to group: error ' + e.message['desc'])
+ assert False
+
+ idx += 1
+
+ conn.close()
+ log.info('AddUsers - Finished adding ' + str(NUM_USERS) + ' entries (' + self.rdnval + ').')
diff --git a/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py b/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py
new file mode 100644
index 0000000..3677fd5
--- /dev/null
+++ b/dirsrvtests/suites/dynamic-plugins/test_dynamic_plugins.py
@@ -0,0 +1,315 @@
+'''
+Created on Dec 09, 2014
+
+@author: mreynolds
+'''
+import os
+import sys
+import time
+import ldap
+import ldap.sasl
+import logging
+import socket
+import pytest
+import plugin_tests
+import stress_tests
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+installation_prefix = None
+
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ '''
+ This fixture is used to standalone topology for the 'module'.
+ At the beginning, It may exists a standalone instance.
+ It may also exists a backup for the standalone instance.
+
+ Principle:
+ If standalone instance exists:
+ restart it
+ If backup of standalone exists:
+ create/rebind to standalone
+
+ restore standalone instance from backup
+ else:
+ Cleanup everything
+ remove instance
+ remove backup
+ Create instance
+ Create backup
+ '''
+ global installation_prefix
+
+ if installation_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation_prefix
+
+ standalone = DirSrv(verbose=False)
+
+ # Args for the standalone instance
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+
+ # Get the status of the backups
+ backup_standalone = standalone.checkBackupFS()
+
+ # Get the status of the instance and restart it if it exists
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ # assuming the instance is already stopped, just wait 5 sec max
+ standalone.stop(timeout=5)
+ standalone.start(timeout=10)
+
+ if backup_standalone:
+ # The backup exist, assuming it is correct
+ # we just re-init the instance with it
+ if not instance_standalone:
+ standalone.create()
+ # Used to retrieve configuration information (dbdir, confdir...)
+ standalone.open()
+
+ # restore standalone instance from backup
+ standalone.stop(timeout=10)
+ standalone.restoreFS(backup_standalone)
+ standalone.start(timeout=10)
+
+ else:
+ # We should be here only in two conditions
+ # - This is the first time a test involve standalone instance
+ # - Something weird happened (instance/backup destroyed)
+ # so we discard everything and recreate all
+
+ # Remove the backup. So even if we have a specific backup file
+ # (e.g backup_standalone) we clear backup that an instance may have created
+ if backup_standalone:
+ standalone.clearBackupFS()
+
+ # Remove the instance
+ if instance_standalone:
+ standalone.delete()
+
+ # Create the instance
+ standalone.create()
+
+ # Used to retrieve configuration information (dbdir, confdir...)
+ standalone.open()
+
+ # Time to create the backups
+ standalone.stop(timeout=10)
+ standalone.backupfile = standalone.backupFS()
+ standalone.start(timeout=10)
+
+ #
+ # Here we have standalone instance up and running
+ # Either coming from a backup recovery
+ # or from a fresh (re)init
+ # Time to return the topology
+ return TopologyStandalone(standalone)
+
+
+def test_dynamic_plugins(topology):
+ """
+ Test Dynamic Plugins - exercise each plugin and its main features, while
+ changing the configuration without restarting the server.
+
+ Need to test: functionality, stability, and stress.
+
+ Functionality - Make sure that as configuration changes are made they take
+ effect immediately. Cross plugin interaction (e.g. automember/memberOf)
+ needs to tested, as well as plugin tasks. Need to test plugin
+ config validation(dependencies, etc).
+
+ Memory Corruption - Restart the plugins many times, and in different orders and test
+ functionality, and stability. This will excerise the internal
+ plugin linked lists, dse callabcks, and task handlers.
+
+ Stress - Put the server under some type of load that is using a particular
+ plugin for each operation, and then make changes to that plugin.
+ The new changes should take effect, and the server should not crash.
+
+ """
+
+ ############################################################################
+ # Test plugin functionality
+ ############################################################################
+
+ # First enable dynamic plugins
+ try:
+ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', 'on')])
+ except ldap.LDAPError, e:
+ ldap.error('Failed to enable dynamic plugin!' + e.message['desc'])
+ assert False
+
+ log.info('#####################################################')
+ log.info('Testing Dynamic Plugins Functionality...')
+ log.info('#####################################################\n')
+
+ plugin_tests.test_all_plugins(topology.standalone)
+
+ log.info('#####################################################')
+ log.info('Successfully Tested Dynamic Plugins Functionality.')
+ log.info('#####################################################\n')
+
+ ############################################################################
+ # Test the stability by exercising the internal lists, callabcks, and task handlers
+ ############################################################################
+
+ log.info('#####################################################')
+ log.info('Testing Dynamic Plugins for Memory Corruption...')
+ log.info('#####################################################\n')
+ prev_plugin_test = None
+ prev_prev_plugin_test = None
+ for plugin_test in plugin_tests.func_tests:
+ #
+ # Restart the plugin several times (and prev plugins) - work that linked list
+ #
+ plugin_test(topology.standalone, "restart")
+
+ if prev_prev_plugin_test:
+ prev_prev_plugin_test(topology.standalone, "restart")
+
+ plugin_test(topology.standalone, "restart")
+
+ if prev_plugin_test:
+ prev_plugin_test(topology.standalone, "restart")
+
+ plugin_test(topology.standalone, "restart")
+
+ # Now run the functional test
+ plugin_test(topology.standalone)
+
+ # Set the previous tests
+ if prev_plugin_test:
+ prev_prev_plugin_test = prev_plugin_test
+ prev_plugin_test = plugin_test
+
+ log.info('#####################################################')
+ log.info('Successfully Tested Dynamic Plugins for Memory Corruption.')
+ log.info('#####################################################\n')
+
+ ############################################################################
+ # Stress two plugins while restarting it, and while restarting other plugins.
+ # The goal is to not crash, and have the plugins work after stressing it.
+ ############################################################################
+
+ log.info('#####################################################')
+ log.info('Stressing Dynamic Plugins...')
+ log.info('#####################################################\n')
+
+ # Configure the plugins
+ stress_tests.configureMO(topology.standalone)
+ stress_tests.configureRI(topology.standalone)
+
+ # Launch three new threads to add a bunch of users
+ add_users = stress_tests.AddUsers(topology.standalone, 'user', True)
+ add_users.start()
+ add_users2 = stress_tests.AddUsers(topology.standalone, 'entry', True)
+ add_users2.start()
+ add_users3 = stress_tests.AddUsers(topology.standalone, 'person', True)
+ add_users3.start()
+ time.sleep(1)
+
+ # While we are adding users restart the MO plugin
+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
+ time.sleep(3)
+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
+ time.sleep(1)
+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
+
+ # Restart idle plugin
+ topology.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)
+ topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)
+
+ # Wait for the 'adding' threads to complete
+ add_users.join()
+ add_users2.join()
+ add_users3.join()
+
+ # Now launch three threads to delete the users, and restart both the MO and RI plugins
+ del_users = stress_tests.DelUsers(topology.standalone, 'user')
+ del_users.start()
+ del_users2 = stress_tests.DelUsers(topology.standalone, 'entry')
+ del_users2.start()
+ del_users3 = stress_tests.DelUsers(topology.standalone, 'person')
+ del_users3.start()
+ time.sleep(1)
+
+ # Restart the both the MO and RI plugins during these deletes
+
+ topology.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)
+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
+ topology.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
+ time.sleep(3)
+ topology.standalone.plugins.disable(name=PLUGIN_REFER_INTEGRITY)
+ time.sleep(1)
+ topology.standalone.plugins.disable(name=PLUGIN_MEMBER_OF)
+ time.sleep(1)
+ topology.standalone.plugins.enable(name=PLUGIN_MEMBER_OF)
+ time.sleep(1)
+ topology.standalone.plugins.enable(name=PLUGIN_REFER_INTEGRITY)
+
+ # Restart idle plugin
+ topology.standalone.plugins.disable(name=PLUGIN_LINKED_ATTRS)
+ topology.standalone.plugins.enable(name=PLUGIN_LINKED_ATTRS)
+
+ # Wait for the 'deleting' threads to complete
+ del_users.join()
+ del_users2.join()
+ del_users3.join()
+
+ # Now make sure both the MO and RI plugins still work
+ plugin_tests.func_tests[8](topology.standalone) # RI plugin
+ plugin_tests.func_tests[5](topology.standalone) # MO plugin
+
+ log.info('#####################################################')
+ log.info('Successfully Stressed Dynamic Plugins.')
+ log.info('#####################################################\n')
+
+ ############################################################################
+ # We made it to the end!
+ ############################################################################
+
+ log.info('#####################################################')
+ log.info('#####################################################')
+ log.info("Dynamic Plugins Testsuite: Completed Successfully!")
+ log.info('#####################################################')
+ log.info('#####################################################')
+
+def test_dynamic_plugins_final(topology):
+ topology.standalone.stop(timeout=10)
+
+
+def run_isolated():
+ '''
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+ To run isolated without py.test, you need to
+ - edit this file and comment '@pytest.fixture' line before 'topology' function.
+ - set the installation prefix
+ - run this program
+ '''
+ global installation_prefix
+ installation_prefix = None
+
+ topo = topology(True)
+ test_dynamic_plugins(topo)
+
+if __name__ == '__main__':
+ run_isolated()
9 years, 4 months
Branch '389-ds-base-1.2.11' - ldap/servers
by Noriko Hosoi
ldap/servers/plugins/acl/acllas.c | 6 +++---
ldap/servers/plugins/acl/aclparse.c | 3 ++-
ldap/servers/plugins/replication/repl5_replica.c | 2 +-
ldap/servers/plugins/replication/repl_extop.c | 4 ++--
ldap/servers/plugins/rootdn_access/rootdn_access.c | 2 +-
ldap/servers/slapd/back-ldbm/ldbm_attr.c | 2 +-
6 files changed, 10 insertions(+), 9 deletions(-)
New commits:
commit 3d69f154192244de2b08b26ea09981cd3f02eecb
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Dec 16 11:26:04 2014 -0800
Ticket 47965 - Fix coverity issues (2014/12/16)
12867 - Uninitialized pointer read
Description:
The third arg for ldap_utf8strtok_r is supposed to be initialized.
https://fedorahosted.org/389/ticket/47965
Reviewed by mreynolds(a)redhat.com (Thank you, Mark!!)
(cherry picked from commit 62072539953d0956e0f2664ef1a3691cf8fbdac0)
(cherry picked from commit a2977b4b1839f4853594a46593ac5e2e27155bed)
(cherry picked from commit 9793fc437a75cca804be7cbec1def59c156f79c1)
Conflicts:
ldap/servers/plugins/acl/aclparse.c
ldap/servers/plugins/replication/windows_connection.c
ldap/servers/plugins/replication/windows_private.c
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index 3fb5d79..fc7f185 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -1212,7 +1212,7 @@ DS_LASUserDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
/* See if we have a parent[2].attr" rule */
if (strstr(attrName, "parent[") != NULL) {
- char *word, *str, *next;
+ char *word, *str, *next = NULL;
numOflevels = 0;
n_currEntryDn = slapi_entry_get_ndn ( lasinfo.resourceEntry );
@@ -1458,7 +1458,7 @@ DS_LASLdapUrlAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
/* See if we have a parent[2].attr" rule */
if (strstr(attrName, "parent[") != NULL) {
- char *word, *str, *next;
+ char *word, *str, *next = NULL;
numOflevels = 0;
n_currEntryDn = slapi_entry_get_ndn ( lasinfo.resourceEntry );
@@ -2626,7 +2626,7 @@ DS_LASGroupDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
/* See if we have a parent[2].attr" rule */
if (strstr(attrName, "parent[") != NULL) {
- char *word, *str, *next;
+ char *word, *str, *next = NULL;
numOflevels = 0;
n_currEntryDn = slapi_entry_get_ndn ( lasinfo.resourceEntry ) ;
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 26d57c4..098b5f7 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -484,6 +484,7 @@ __aclp__sanity_check_acltxt (aci_t *aci_item, char *str)
}
newstr = slapi_ch_strdup (str);
+ next = NULL;
word = ldap_utf8strtok_r(newstr, " ", &next);
if (strcasecmp (word, "version") == 0) {
word = ldap_utf8strtok_r(NULL, " ", &next);
@@ -1189,7 +1190,7 @@ __aclp__get_aci_right (char *str)
{
char *sav_str = slapi_ch_strdup(str);
- char *t, *tt;
+ char *t, *tt = NULL;
int type = 0;
char *delimiter = ",";
char *val = NULL;
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 557921a..b375eb7 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1846,7 +1846,7 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
char *forcing;
char *csnpart;
char *ridstr;
- char *iter;
+ char *iter = NULL;
int i;
for(i = 0; i < CLEANRIDSIZ && clean_vals[i]; i++){
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 92207df..15e9758 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1461,7 +1461,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
char *repl_root;
char *payload = NULL;
char *certify_all;
- char *iter;
+ char *iter = NULL;
int rc = LDAP_SUCCESS;
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
@@ -1589,7 +1589,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
char *force = NULL;
char *extop_oid;
char *repl_root;
- char *iter;
+ char *iter = NULL;
int release_it = 0;
int rid = 0;
int rc = LDAP_OPERATIONS_ERROR;
diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c
index 5323915..d620e68 100644
--- a/ldap/servers/plugins/rootdn_access/rootdn_access.c
+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c
@@ -220,7 +220,7 @@ rootdn_load_config(Slapi_PBlock *pb)
Slapi_Entry *e = NULL;
char *openTime = NULL;
char *closeTime = NULL;
- char *token, *iter, *copy;
+ char *token, *iter = NULL, *copy;
char hour[3], min[3];
int result = 0;
int time;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
index 16ffa42..1992174 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
@@ -509,7 +509,7 @@ attr_index_parse_idlistsize(struct attrinfo *ai, const char *strval, struct inde
int rc = 0; /* assume success */
char *mystr = slapi_ch_strdup(strval); /* copy for strtok */
char *values = NULL;
- char *lasts, *val, *ptr;
+ char *lasts = NULL, *val, *ptr;
int seen_limit = 0, seen_type = 0, seen_flags = 0, seen_values = 0;
Slapi_Attr *attr = &ai->ai_sattr;
9 years, 4 months