[389-devel] Please review (revised): Plugin Default Config Entry

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks a lot, Rich!  I revised my proposal based upon your suggestions.  Some comments are in-line...
--noriko

On 08/26/2009 09:13 AM, Rich Megginson wrote:
[...]
About this code:
    if (new_attrs)
    {
-        *attrs = new_attrs;
+        charray_merge_nodup(attrs, new_attrs, 0);
+        slapi_ch_free((void **)&new_attrs);
    }

the 0 flag to charray_merge_nodup() means "do not copy" - so the strings in new_attrs will be moved to attrs, if they are not duplicates.  If they are duplicates, they will not be moved - how will they be freed?  There's no way for the caller of charray_merge_nodup to know which strings were moved and which were not (except by comparing pointers in attrs with new_attrs).
I wanted to avoid malloc/free as much as possible, but it looks I cannot... :(  Changing it as follows:
    if (new_attrs)
    {
        charray_merge_nodup(attrs, new_attrs, 1);
        slapi_ch_array_free(new_attrs);
    }


+            int i;
+            const char *val = slapi_value_get_string(sval);
+            for (i = slapi_attr_first_value(attr, &sval);

I don't think you should be calling slapi_value_get_string() here since sval is not initialized yet.
Thanks for finding it out!  My copy & paste error... :(  Changing it as follows:
            int i;
            const char *val = NULL;
            for (i = slapi_attr_first_value(attr, &sval);

I think slapi_set_plugin_default_config() should always to a modify/add, and just ignore "type or value exists" errors.  Or support single valued attributes only.  Or allow the user to specify to add or replace in the case of a multi-valued attribute.
I was thinking the value is preferably single, but I wanted to support multiple values if set (e.g., by manually adding dse.ldif as you mentioned).  That made the code uglier.  I changed slapi_set_plugin_default_config simply adds the given "attr: value" pair to the plugin default config entry instead of replacing the existing pair(s) with it.
What if the user modifies the list directly over LDAP or by editing dse.ldif?  An internal call to set the value will wipe out their settings. 

Also, there is a reference to frational attr in the slapi_set_plugin_default_config() code.
Thanks!  I removed it... :p

I think slapi_set_plugin_default_config() will leak the pblock used for the initial search if rc != LDAP_SUCCESS or entries is NULL or empty.
I think it's taken care here....  Valgrind shows no leak in slapi_set_plugin_default_config in both cases entries exist or don't exist.
2911     } else { /* cn=plugin default config does not exist. Let's add it. */
2912         LDAPMod *mods[3];
2913         LDAPMod mod[2];
2914         const char *objectclass[3];
2915         char *attrlist[2];
2916   
2917         slapi_free_search_results_internal(&pb);
2918         pblock_done(&pb);



slapi_get_plugin_default_config() - since you are assuming that the values of the requested attribute are all null terminated strings (since you are using slapi_value_get_string()), you could just use slapi_entry_attr_get_charray() to get all of the values as a char **.
Thanks!  This is what I needed...

Why does slapi_set_plugin_default_config() take a char * argument i.e. setting an attribute with a single string value, but slapi_get_plugin_default_config() returns multiple values from a single attribute?

I'm not sure what the code in usn_start() is doing.  Is nsds5ReplicatedAttributeList multi-valued?  If so, each char * in char **old_frac_attrs will be a full attribute list description "(objectclass=*) $ EXCLUDE ...".  Then I'm not sure what the code that adds the entryusn attribute to the default excluded list is doing - will it add entryusn to only the first value of nsds5ReplicatedAttributeList?  And wipe out the other values?  I think that's what will happen, since there is a break in the for loop if token == NULL - it will skip old_frac_attrs[1] etc.  Also the call to charray_add - the token argument is not a malloced string, so that will cause problems when slapi_ch_array_free() is called.

I cleaned up the code.  It just adds the attribute value as follows.
    /* add nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE entryusn
     * to cn=plugin default config,cn=config */
    rc = slapi_set_plugin_default_config("nsds5ReplicatedAttributeList",
                                         "(objectclass=*) $ EXCLUDE entryusn");

Sorry about the previous code I wiped out.  I wanted to do this...
Let's assume we found exisiting nsds5ReplicatedAttributeList lines:
  nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE type0
  nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE type1 type 2
I wanted to convert them in to one line:
  nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE type0 type1 type 2 entryusn

Instead, I changed to just add nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE entryusn to the entry.  So, it'll end up like this:
  nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE type0
  nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE type1 type 2
  nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE entryusn

From 853f4f209b23404a7c9cb82b36b6914eacb01089 Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@xxxxxxxxxx>
Date: Wed, 26 Aug 2009 16:43:49 -0700
Subject: [PATCH] Plugin Default Config Entry

Design doc:
http://directory.fedoraproject.org/wiki/Entry_USN#Plugin_Default_Config_Entr

New slapi APIs in libslapd:
  int slapi_set_plugin_default_config(char *type, char *attr);
  Description: Add given "type: attr" to the plugin default config entry
               (cn=plugin default config,cn=config) unless the same "type:
               attr" pair already exists in the entry.
  Parameters: type - Attribute type to add to the default config entry
              attr - Attribute value to add to the default config entry
  Return Value: 0 if the operation was successful
                non-0 if the operation was not successful

  int slapi_get_plugin_default_config(char *type, char ***attrs);
  Description: Get attribute values of given type from the plugin default
               config entry (cn=plugin default config,cn=config).
  Parameters: type - Attribute type to get from the default config entry
              attrs - Pointer to the string array to store the values of
                      the attribute
  Return Value: 0 if the operation was successful
              non-0 if the operation was not successful
  warning: Caller is responsible to free attrs by slapi_ch_array_free

Changes in the Replication plugin:
1) Functions to set replicated attributes
       agmt_set_replicated_attributes_from_attr and
       agmt_set_replicated_attributes_from_entry
   call _agmt_set_default_fractional_attrs to sets the default excluded
   attribute list from the plugin default config entry before setting
   them from each replication agreement.
   To support it, agmt_parse_excluded_attrs_config_attr is changed to be
   re-entrant.
2) Fixed a minor memory leak in the fractional attributes (ra->frac_attrs).
3) Added a check for the duplicated fractional attributes.

Changes in the USN plugin:
1) usn_start calls slapi_get_plugin_default_config to check if "entryusn" is
   in the EXCLUDE list of the value of nsds5ReplicatedAttributeList in the
   plugin default config entry or not.  If it does not exist, the function
   adds it.  Note: If the nsds5ReplicatedAttributeList value exists and
   "entryusn" is not in the EXCLUDE list, we have to append it to the list
   instead of replacing it.
2) fix for the bug 518673 - entryusn: wrong lastusn value; When the entryusn
   is not assigned yet, the next value to be set is 0.  Lastusn is calculate
   as (the next entryusn - 1).  Although the entryusn is 64-bit unsigned
   long, it should be printed as a 64-bit signed integer for lastusn.

Other:
Fixed a compiler error in ldap/servers/slapd/dse.c.
---
 ldap/servers/plugins/replication/repl5_agmt.c |  136 +++++++++++++++++----
 ldap/servers/plugins/usn/usn.c                |   24 +++-
 ldap/servers/plugins/usn/usn.h                |    2 +-
 ldap/servers/slapd/dse.c                      |    7 +-
 ldap/servers/slapd/plugin.c                   |  160 +++++++++++++++++++++++++
 ldap/servers/slapd/proto-slap.h               |    2 +-
 ldap/servers/slapd/slapi-plugin.h             |   23 ++++
 ldap/servers/slapd/slapi-private.h            |    2 +
 8 files changed, 317 insertions(+), 39 deletions(-)

diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 613c222..dc9b3be 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -231,6 +231,7 @@ agmt_new_from_entry(Slapi_Entry *e)
 	Repl_Agmt *ra;
 	char *tmpstr;
 	Slapi_Attr *sattr;
+	char **denied_attrs = NULL;
 
 	char *auto_initialize = NULL;
 	char *val_nsds5BeginReplicaRefresh = "start";
@@ -396,27 +397,29 @@ agmt_new_from_entry(Slapi_Entry *e)
 	ra->last_init_status[0] = '\0';
 	
 	/* Fractional attributes */
-	if (slapi_entry_attr_find(e, type_nsds5ReplicatedAttributeList, &sattr) == 0)	
-	{
-			char **denied_attrs = NULL;
-			/* New set of excluded attributes */
-			if (agmt_set_replicated_attributes_from_attr(ra, sattr) != 0)
-            {
-                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_add_callback: " 
-                                "failed to parse replicated attributes for agreement %s\n",
-                                agmt_get_long_name(ra));	
-            }
-			/* Check that there are no verboten attributes in the exclude list */
-			denied_attrs = agmt_validate_replicated_attributes(ra);
-			if (denied_attrs)
-			{
-				/* Report the error to the client */
-				slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "WARNING: "
-						"Attempt to exclude illegal attributes from a fractional agreement\n");
-				/* Free the list */
-				slapi_ch_array_free(denied_attrs);	
-				goto loser;
-			}
+	slapi_entry_attr_find(e, type_nsds5ReplicatedAttributeList, &sattr);
+
+	/* New set of excluded attributes */
+	/* Note: even if sattrs is empty, we have to call this func since there 
+	 * could be a default excluded attr list in cn=plugin default config */
+	if (agmt_set_replicated_attributes_from_attr(ra, sattr) != 0)
+	{
+		slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+						"agmtlist_add_callback: failed to parse "
+						"replicated attributes for agreement %s\n",
+						agmt_get_long_name(ra));
+	}
+	/* Check that there are no verboten attributes in the exclude list */
+	denied_attrs = agmt_validate_replicated_attributes(ra);
+	if (denied_attrs)
+	{
+		/* Report the error to the client */
+		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, 
+						"WARNING: Attempt to exclude illegal attributes "
+						"from a fractional agreement\n");
+		/* Free the list */
+		slapi_ch_array_free(denied_attrs);
+		goto loser;
 	}
 
 	if (!agmt_is_valid(ra))
@@ -488,6 +491,8 @@ agmt_delete(void **rap)
 	slapi_ch_free((void **)&(ra->hostname));
 	slapi_ch_free((void **)&(ra->binddn));
 
+	slapi_ch_array_free(ra->frac_attrs);
+
 	if (NULL != ra->creds)
 	{
 		/* XXX free berval */
@@ -1060,7 +1065,14 @@ agmt_parse_excluded_attrs_next(const char *attr_string, size_t *offset, char***
 		tmpstr = slapi_ch_malloc(stringlen + 1);
 		strncpy(tmpstr,beginstr,stringlen);
 		tmpstr[stringlen] = '\0';
-		charray_add(attrs,tmpstr);
+		if (charray_inlist(*attrs, tmpstr)) /* tmpstr is already in attrs */
+		{
+			slapi_ch_free_string(&tmpstr);
+		}
+		else
+		{
+			charray_add(attrs,tmpstr);
+		}
 		(*offset) += stringlen;
 		/* Skip a delimiting space */
 		if (c == ' ')
@@ -1073,17 +1085,22 @@ agmt_parse_excluded_attrs_next(const char *attr_string, size_t *offset, char***
 	}
 	return retval;
 }
- /* It looks like this:
- nsDS5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE jpegPhoto telephoneNumber
+
+/* It looks like this:
+ * nsDS5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE jpegPhoto telephoneNumber
+ * This function could be called multiple times: to set excluded attrs in the
+ * plugin default config and to set the ones in the replica agreement. 
+ * The excluded attrs from replica agreement are added to the ones from 
+ * default config.  (Therefore, *attrs should not be initialized in this 
+ * function.)
  */
 static int 
-agmt_parse_excluded_attrs_config_attr(const char *attr_string, char*** attrs)
+agmt_parse_excluded_attrs_config_attr(const char *attr_string, char ***attrs)
 {
 	int retval = 0;
 	size_t offset = 0;
 	char **new_attrs = NULL;
 
-	*attrs = NULL;
 	/* First parse and skip the filter */
 	retval = agmt_parse_excluded_attrs_filter(attr_string, &offset);
 	if (retval) 
@@ -1105,13 +1122,78 @@ agmt_parse_excluded_attrs_config_attr(const char *attr_string, char*** attrs)
 	retval = 0;
 	if (new_attrs) 
 	{
-		*attrs = new_attrs;
+		charray_merge_nodup(attrs, new_attrs, 1);
+		slapi_ch_array_free(new_attrs);
 	}
 error:
 	return retval;
 }
 
 /*
+ * _agmt_set_default_fractional_attrs
+ *   helper function to set nsds5ReplicatedAttributeList value (from cn=plugin
+ *   default config,cn=config) to frac_attrs in Repl_Agmt.  
+ *   nsds5ReplicatedAttributeList set in each agreement is added to the
+ *   default list set in this function.
+ */
+static int
+_agmt_set_default_fractional_attrs(Repl_Agmt *ra)
+{
+	Slapi_PBlock *newpb = NULL;
+	Slapi_Entry **entries = NULL;
+	int rc = LDAP_SUCCESS;
+	char *attrs[2];
+
+	attrs[0] = (char *)type_nsds5ReplicatedAttributeList;
+	attrs[1] = NULL;
+
+	newpb = slapi_pblock_new();
+	slapi_search_internal_set_pb(newpb,
+					SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */
+					LDAP_SCOPE_BASE,
+					"(objectclass=*)",
+					attrs, /* Attrs */
+					0, /* AttrOnly */
+					NULL, /* Controls */
+					NULL, /* UniqueID */
+					repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
+					0);
+	slapi_search_internal_pb(newpb);
+	slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+	slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+	ra->frac_attrs = NULL;
+	if (LDAP_SUCCESS == rc && entries && *entries) /* default config entry exists */
+	{
+		Slapi_Attr *attr;
+		Slapi_Value *sval = NULL;
+		if (0 == slapi_entry_attr_find(*entries,
+								      type_nsds5ReplicatedAttributeList, &attr))
+		{
+			int i;
+			const char *val = NULL;
+			for (i = slapi_attr_first_value(attr, &sval);
+				 i >= 0; i = slapi_attr_next_value(attr, i, &sval)) {
+				val = slapi_value_get_string(sval);
+				rc = agmt_parse_excluded_attrs_config_attr(val,
+														   &(ra->frac_attrs));
+				if (0 != rc) {
+					slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+							"_agmt_set_default_fractional_attrs: failed to "
+							"parse default config (%s) attribute value: %s\n",
+							SLAPI_PLUGIN_DEFAULT_CONFIG,
+							type_nsds5ReplicatedAttributeList, val);
+				}
+			}
+		}
+	}
+
+	slapi_free_search_results_internal(newpb);
+	slapi_pblock_destroy(newpb);
+
+	return rc;
+}
+
+/*
  * Set or reset the set of replicated attributes.
  *
  * Returns 0 if DN set, or -1 if an error occurred.
@@ -1130,6 +1212,7 @@ agmt_set_replicated_attributes_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
 		slapi_ch_array_free(ra->frac_attrs);
 		ra->frac_attrs = NULL;
 	}
+	_agmt_set_default_fractional_attrs(ra);
 	if (NULL != sattr)
 	{
 		Slapi_Value *sval = NULL;
@@ -1162,6 +1245,7 @@ agmt_set_replicated_attributes_from_attr(Repl_Agmt *ra, Slapi_Attr *sattr)
 		slapi_ch_array_free(ra->frac_attrs);
 		ra->frac_attrs = NULL;
 	}
+	_agmt_set_default_fractional_attrs(ra);
 	if (NULL != sattr)
 	{
 		Slapi_Value *sval = NULL;
diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c
index 7f46436..485ae9d 100644
--- a/ldap/servers/plugins/usn/usn.c
+++ b/ldap/servers/plugins/usn/usn.c
@@ -112,13 +112,13 @@ usn_init(Slapi_PBlock *pb)
     rc = slapi_register_plugin("preoperation", 1 /* Enabled */,
                                "usn_preop_init", usn_preop_init,
                                "USN preoperation plugin", NULL, identity);
-    rc = slapi_register_plugin("bepreoperation", 1 /* Enabled */,
+    rc |= slapi_register_plugin("bepreoperation", 1 /* Enabled */,
                                "usn_bepreop_init", usn_bepreop_init,
                                "USN bepreoperation plugin", NULL, identity);
-    rc = slapi_register_plugin("bepostoperation", 1 /* Enabled */,
+    rc |= slapi_register_plugin("bepostoperation", 1 /* Enabled */,
                                "usn_bepostop_init", usn_bepostop_init,
                                "USN bepostoperation plugin", NULL, identity);
-   usn_set_identity(identity);
+    usn_set_identity(identity);
 bail:
     slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
                     "<-- usn_init\n");
@@ -212,14 +212,24 @@ static int
 usn_start(Slapi_PBlock *pb)
 {
     int rc = 0;
+    char **old_frac_attrs = NULL;
+    char **ofap = NULL;
+    int notfound = 1;
 
     slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "--> usn_start\n");
 
     rc = usn_rootdse_init();
     rc |= usn_cleanup_start(pb);
-
-    slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "<-- usn_start\n");
-
+    if (rc) {
+        goto bail;
+    }
+    /* add nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE entryusn 
+     * to cn=plugin default config,cn=config */
+    rc = slapi_set_plugin_default_config("nsds5ReplicatedAttributeList", 
+                                         "(objectclass=*) $ EXCLUDE entryusn");
+bail:
+    slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
+                    "<-- usn_start (rc: %d)\n", rc);
     return rc;
 }
 
@@ -547,7 +557,7 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
             continue;
         }
         /* get a next USN counter from be_usn_counter; then minus 1 from it */
-        PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, 
+        PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRI64 "d", 
                                  slapi_counter_get_value(be->be_usn_counter)-1);
         usn_berval.bv_len = strlen(usn_berval.bv_val);
 
diff --git a/ldap/servers/plugins/usn/usn.h b/ldap/servers/plugins/usn/usn.h
index cf0cd18..ac9f86b 100644
--- a/ldap/servers/plugins/usn/usn.h
+++ b/ldap/servers/plugins/usn/usn.h
@@ -46,7 +46,7 @@
 #define USN_LAST_USN               "lastusn"
 #define USN_LAST_USN_ATTR_CORE_LEN 8 /* lastusn; */
 
-#define USN_COUNTER_BUF_LEN        32 /* enough size for 64 bit inteters */
+#define USN_COUNTER_BUF_LEN        64 /* enough size for 64 bit integers */
 
 /* usn.c */
 void usn_set_identity(void *identity);
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
index 4a0312b..f0d124c 100644
--- a/ldap/servers/slapd/dse.c
+++ b/ldap/servers/slapd/dse.c
@@ -2323,15 +2323,14 @@ dse_search_set_release (void **ss)
 }
 
 void 
-dse_prev_search_results (Slapi_PBlock *pb)
+dse_prev_search_results (void *vp)
 {
+	Slapi_PBlock *pb = (Slapi_PBlock *)vp;
 	dse_search_set *ss;
-	slapi_pblock_get( pb, SLAPI_SEARCH_RESULT_SET, &ss );
+	slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &ss);
 	if (ss) {
 		dl_get_prev (&ss->dl, &ss->current_entry);
 	}
-	return;
-
 }
 
 static void 
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index e5e016d..c2e7a05 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -2837,3 +2837,163 @@ bail:
 
 	return rc;
 }
+
+/*
+ * Set given "type: attr" to the plugin default config entry
+ * (cn=plugin default config,cn=config) unless the same "type: attr" pair
+ * already exists in the entry.
+ */ 
+int
+slapi_set_plugin_default_config(char *type, char *attr)
+{
+    Slapi_PBlock pb;
+    Slapi_Entry **entries = NULL;
+    int rc = LDAP_SUCCESS;
+    char **search_attrs = NULL; /* used by search */
+
+    if (NULL == type || '\0' == *type ||
+        NULL == attr || '\0' == *attr) { /* nothing to do */
+        return rc;
+    }
+
+    charray_add(&search_attrs, slapi_ch_strdup(type));
+
+    /* cn=plugin default config,cn=config */
+    pblock_init(&pb);
+    slapi_search_internal_set_pb(&pb,
+                    SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */
+                    LDAP_SCOPE_BASE,
+                    "(objectclass=*)",
+                    search_attrs, /* Attrs */
+                    0, /* AttrOnly */
+                    NULL, /* Controls */
+                    NULL, /* UniqueID */
+                    (void *)plugin_get_default_component_id(),
+                    0);
+    slapi_search_internal_pb(&pb);
+    slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+    slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+    if (LDAP_SUCCESS == rc && entries && *entries) {
+        /* plugin default config entry exists */
+        char **old_values = NULL;
+
+        old_values = slapi_entry_attr_get_charray(*entries, (const char *)type);
+        
+        slapi_free_search_results_internal(&pb);
+        pblock_done(&pb);
+
+        if (!charray_inlist(old_values, attr)) {
+            /* The argument attr is not in the plugin default config.
+             * Let's add it. */
+            char *attrlist[2];
+            LDAPMod *mods[2];
+            LDAPMod mod[1];
+            attrlist[0] = attr;
+            attrlist[1] = NULL;
+    
+            mod[0].mod_op = LDAP_MOD_ADD;
+            mod[0].mod_type = type;
+            mod[0].mod_values = attrlist;
+    
+            mods[0] = &mod[0];
+            mods[1] = NULL;
+    
+            pblock_init(&pb);
+            slapi_modify_internal_set_pb(&pb, SLAPI_PLUGIN_DEFAULT_CONFIG,
+                                     mods, NULL, NULL, /* UniqueID */
+                                    (void *)plugin_get_default_component_id(),
+                                    0 /* Flags */ );
+
+            slapi_modify_internal_pb(&pb);
+            slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+
+            pblock_done(&pb);
+        }
+        slapi_ch_array_free(old_values);
+    } else { /* cn=plugin default config does not exist. Let's add it. */
+        LDAPMod *mods[3];
+        LDAPMod mod[2];
+        const char *objectclass[3];
+        char *attrlist[2];
+
+        slapi_free_search_results_internal(&pb);
+        pblock_done(&pb);
+
+        attrlist[0] = attr;
+        attrlist[1] = NULL;
+
+        objectclass[0] = "top";
+        objectclass[1] = "extensibleObject";
+        objectclass[2] = NULL;
+
+        mod[0].mod_op = LDAP_MOD_ADD;
+        mod[0].mod_type = "objectClass";
+        mod[0].mod_values = (char **)objectclass;
+
+        mod[1].mod_op = LDAP_MOD_ADD;
+        mod[1].mod_type = type;
+        mod[1].mod_values = attrlist;
+
+        mods[0] = &mod[0];
+        mods[1] = &mod[1];
+        mods[2] = NULL;
+
+        pblock_init(&pb);
+        slapi_add_internal_set_pb(&pb, SLAPI_PLUGIN_DEFAULT_CONFIG, mods, NULL, 
+                                  (void *)plugin_get_default_component_id(),
+                                  0 /* Flags */ );
+        slapi_add_internal_pb(&pb);
+        slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+        pblock_done(&pb);
+    }
+    charray_free(search_attrs);
+
+    return rc;
+}
+
+/*
+ * Get attribute values of given type from the plugin default config entry
+ * (cn=plugin default config,cn=config).
+ *
+ * Caller is responsible to free attrs by slapi_ch_array_free.
+ */
+int
+slapi_get_plugin_default_config(char *type, char ***attrs)
+{
+    Slapi_PBlock pb;
+    Slapi_Entry **entries = NULL;
+    int rc = LDAP_NO_SUCH_ATTRIBUTE;
+    char **search_attrs = NULL; /* used by search */
+
+    if (NULL == type || '\0' == *type || NULL == attrs) { /* nothing to do */
+        return rc;
+    }
+
+    charray_add(&search_attrs, slapi_ch_strdup(type));
+
+    /* cn=plugin default config,cn=config */
+    pblock_init(&pb);
+    slapi_search_internal_set_pb(&pb,
+                    SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */
+                    LDAP_SCOPE_BASE,
+                    "(objectclass=*)",
+                    search_attrs, /* Attrs */
+                    0, /* AttrOnly */
+                    NULL, /* Controls */
+                    NULL, /* UniqueID */
+                    (void *)plugin_get_default_component_id(),
+                    0);
+    slapi_search_internal_pb(&pb);
+    slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+    slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+    if (LDAP_SUCCESS == rc && entries && *entries) {
+        /* default config entry exists */
+        /* retrieve attribute values from the entry */
+        *attrs = slapi_entry_attr_get_charray(*entries, (const char *)type);
+    }
+    slapi_free_search_results_internal(&pb);
+    pblock_done(&pb);
+    charray_free(search_attrs);
+
+    return rc;
+}
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 9c6c16e..4b1bbdf 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -604,7 +604,7 @@ void dse_unset_dont_ever_write_dse_files(void);
 int dse_next_search_entry (Slapi_PBlock *pb);
 char *dse_read_next_entry( char *buf, char **lastp );
 void dse_search_set_release (void **ss);
-void dse_prev_search_results (Slapi_PBlock *pb);
+void dse_prev_search_results (void *pb);
 
 
 /*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index e59df68..352862b 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -3637,6 +3637,29 @@ char **slapi_str2charray_ext( char *str, char *brkstr, int allow_dups );
 #endif
 #endif
 
+/**
+ * Set given "type: attr" to the plugin default config entry
+ * (cn=plugin default config,cn=config) unless the same "type: attr" pair
+ * already exists in the entry.
+ *
+ * \param type Attribute type to add to the default config entry
+ * \param attr Attribute value to add to the default config entry
+ * \return 0 if the operation was successful
+ * \return non-0 if the operation was not successful
+ */
+int slapi_set_plugin_default_config(char *type, char *attr);
+
+/**
+ * Get attribute values of given type from the plugin default config entry
+ * (cn=plugin default config,cn=config).
+ *
+ * \param type Attribute type to get from the default config entry
+ * \param attrs Pointer to the string array to store the values of the attribute
+ * \return 0 if the operation was successful
+ * \return non-0 if the operation was not successful
+ * \warning Caller is responsible to free attrs by slapi_ch_array_free
+ *     */
+int slapi_get_plugin_default_config(char *type, char ***attrs);
 
 #ifdef __cplusplus
 }
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index c09e975..0f32f00 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -1177,6 +1177,8 @@ void bervalarray_add_berval_fast(struct berval ***vals, const struct berval *add
    configuration entries will be found */
 #define PLUGIN_BASE_DN "cn=plugins,cn=config"
 
+#define SLAPI_PLUGIN_DEFAULT_CONFIG   "cn=plugin default config,cn=config"
+
 /***** End of items added for the replication plugin. ***********************/
 
 void    DS_Sleep(PRIntervalTime ticks);
-- 
1.6.2.5

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

--
389-devel mailing list
389-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/fedora-directory-devel

[Index of Archives]     [Fedora Directory Announce]     [Fedora Users]     [Older Fedora Users Mail]     [Fedora Advisory Board]     [Fedora Security]     [Fedora Devel Java]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Mentors]     [Fedora Package Review]     [Fedora Art]     [Fedora Music]     [Fedora Packaging]     [CentOS]     [Fedora SELinux]     [Big List of Linux Books]     [KDE Users]     [Fedora Art]     [Fedora Docs]

  Powered by Linux