Преглед на файлове

openldap - add support for missing controls, add ldif api, fix NSS usage

Added proxy auth control creation - mozldap has a function to do that but
not openldap
Do not use mozldap filter create function - just create one using
slapi_smprintf
Fix usage of TLS/SSL with new NSS functionality
Created ldif parse wrapper - changed code to use it
Reviewed by: nkinder (Thanks!)
Platforms tested: Fedora 14 (rawhide)
Rich Megginson преди 15 години
родител
ревизия
e30f96f03b

+ 1 - 1
ldap/servers/plugins/chainingdb/cb_controls.c

@@ -281,7 +281,7 @@ int cb_update_controls( Slapi_PBlock * pb,
     if (addauth) {
         slapi_pblock_get( pb, SLAPI_REQUESTOR_DN, &proxyDN );
 
-        if ( ldap_create_proxyauth_control(ld, proxyDN, isabandon?0:1, &ctrls[dCount] )) {
+        if ( slapi_ldap_create_proxyauth_control(ld, proxyDN, isabandon?0:1, 0, &ctrls[dCount] )) {
             ldap_controls_free(ctrls);
                 slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
                 "LDAP_CONTROL_PROXYAUTH control encoding failed.\n");

+ 8 - 7
ldap/servers/plugins/mep/mep.c

@@ -950,8 +950,6 @@ mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
     char **vals = NULL;
     char *type = NULL;
     char *value = NULL;
-    int vlen = 0;
-    struct berval bval;
     Slapi_Value *sval = NULL;
     int found_rdn_map = 0;
     int i = 0;
@@ -982,7 +980,9 @@ mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
      * created managed entry. */
     vals = slapi_entry_attr_get_charray(template, MEP_STATIC_ATTR_TYPE);
     for (i = 0; vals && vals[i]; ++i) {
-        if (ldif_parse_line(vals[i], &type, &value, &vlen) != 0) {
+        struct berval bvtype = {0, NULL}, bvvalue = {0, NULL};
+        int freeval = 0;
+        if (slapi_ldif_parse_line(vals[i], &bvtype, &bvvalue, &freeval) != 0) {
             slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
                         "mep_create_managed_entry: Value for %s config setting  "
                         "is not in the correct format in template \"%s\". "
@@ -992,14 +992,15 @@ mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
             goto done;
         } else {
             /* Create a berval and add the value to the entry. */
-            bval.bv_len = vlen;
-            bval.bv_val = value;
-            sval = slapi_value_new_berval(&bval);
-            slapi_entry_add_value(managed_entry, type, sval);
+            sval = slapi_value_new_berval(&bvvalue);
+            slapi_entry_add_value(managed_entry, bvtype.bv_val, sval);
             slapi_value_free(&sval);
 
             /* Set type and value to NULL so they don't get
              * free'd by mep_parse_mapped_attr(). */
+            if (freeval) {
+                slapi_ch_free_string(&bvvalue.bv_val);
+            }
             type = NULL;
             value = NULL;
         }

+ 5 - 6
ldap/servers/plugins/referint/referint.c

@@ -686,11 +686,10 @@ update_integrity(char **argv, char *origDN,
 
         for(i = 3; argv[i] != NULL; i++)
         {
-            unsigned long filtlen = strlen(argv[i]) + (strlen(origDN) * 3 ) + 5;
-            filter = (char *)slapi_ch_calloc( filtlen, sizeof(char ));  
-            if (( search_result = ldap_create_filter( filter, filtlen, 
-                            "(%a=*%e)", NULL, NULL, argv[i], origDN, NULL ))
-                    == LDAP_SUCCESS ) {
+            char buf[BUFSIZ];
+            size_t len = strlen(origDN);
+            filter = slapi_ch_smprintf("(%s=*%s)", argv[i], escape_filter_value(origDN, len, buf));
+            if ( filter ) {
 
                 /* Need only the current attribute and its subtypes */
                 char *attrs[2];
@@ -778,7 +777,7 @@ update_integrity(char **argv, char *origDN,
                 }
             }
 
-            slapi_ch_free((void**)&filter);
+            slapi_ch_free_string(&filter);
   
             if (search_result_pb) {
                 slapi_free_search_results_internal(search_result_pb);

+ 37 - 32
ldap/servers/plugins/replication/cl5_api.c

@@ -5147,13 +5147,10 @@ static int
 _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op, char **replGen)
 {
 	int rc;
-#if defined(USE_OPENLDAP)
-	ber_len_t vlen;
-#else
-	int vlen;
-#endif
 	char *next, *line;
-	char *type, *value;
+	struct berval type, value;
+	struct berval bv_null = {0, NULL};
+	int freeval = 0;
 	Slapi_Mods *mods;
 	char *rawDN = NULL;
 
@@ -5170,7 +5167,9 @@ _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op, char **repl
 		}
 
 		/* this call modifies ldifEntry */
-		rc = ldif_parse_line(line, &type, &value, &vlen);
+		type = bv_null;
+		value = bv_null;
+		rc = slapi_ldif_parse_line(line, &type, &value, &freeval);
 		if (rc != 0)
 		{
 			slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, 
@@ -5178,55 +5177,55 @@ _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op, char **repl
 			continue;
 		}
 
-		if (strcasecmp (type, T_CHANGETYPESTR) == 0)
+		if (strncasecmp (type.bv_val, T_CHANGETYPESTR, type.bv_len) == 0)
 		{
-			op->operation_type = _cl5Str2OperationType (value);	
+			op->operation_type = _cl5Str2OperationType (value.bv_val);	
 		}
-		else if (strcasecmp (type, T_REPLGEN) == 0)
+		else if (strncasecmp (type.bv_val, T_REPLGEN, type.bv_len) == 0)
         {
-            *replGen = slapi_ch_strdup (value);
+            *replGen = slapi_ch_strdup (value.bv_val);
         }
-		else if (strcasecmp (type, T_CSNSTR) == 0)
+		else if (strncasecmp (type.bv_val, T_CSNSTR, type.bv_len) == 0)
 		{
-			op->csn = csn_new_by_string(value);
+			op->csn = csn_new_by_string(value.bv_val);
 		}
-		else if (strcasecmp (type, T_UNIQUEIDSTR) == 0)
+		else if (strncasecmp (type.bv_val, T_UNIQUEIDSTR, type.bv_len) == 0)
 		{
-			op->target_address.uniqueid = slapi_ch_strdup (value);
+			op->target_address.uniqueid = slapi_ch_strdup (value.bv_val);
 		}
-		else if (strcasecmp (type, T_DNSTR) == 0)
+		else if (strncasecmp (type.bv_val, T_DNSTR, type.bv_len) == 0)
 		{
 			PR_ASSERT (op->operation_type);
 
 			if (op->operation_type == SLAPI_OPERATION_ADD)
 			{
-				rawDN = slapi_ch_strdup (value);
+				rawDN = slapi_ch_strdup (value.bv_val);
 				op->target_address.dn = slapi_ch_strdup(rawDN);
 			}
 			else
-				op->target_address.dn = slapi_ch_strdup (value);
+				op->target_address.dn = slapi_ch_strdup (value.bv_val);
 		}
-		else if (strcasecmp (type, T_PARENTIDSTR) == 0)
+		else if (strncasecmp (type.bv_val, T_PARENTIDSTR, type.bv_len) == 0)
 		{
-			op->p.p_add.parentuniqueid = slapi_ch_strdup (value);	
+			op->p.p_add.parentuniqueid = slapi_ch_strdup (value.bv_val);	
 		}
-		else if (strcasecmp (type, T_NEWRDNSTR) == 0)
+		else if (strncasecmp (type.bv_val, T_NEWRDNSTR, type.bv_len) == 0)
 		{			
-			op->p.p_modrdn.modrdn_newrdn = slapi_ch_strdup (value);
+			op->p.p_modrdn.modrdn_newrdn = slapi_ch_strdup (value.bv_val);
 		}
-		else if (strcasecmp (type, T_DRDNFLAGSTR) == 0)
+		else if (strncasecmp (type.bv_val, T_DRDNFLAGSTR, type.bv_len) == 0)
 		{
-			op->p.p_modrdn.modrdn_deloldrdn = (strcasecmp (value, "true") ? PR_FALSE : PR_TRUE);
+			op->p.p_modrdn.modrdn_deloldrdn = (strncasecmp (value.bv_val, "true", value.bv_len) ? PR_FALSE : PR_TRUE);
 		}
-		else if (strcasecmp (type, T_NEWSUPERIORDNSTR) == 0)
+		else if (strncasecmp (type.bv_val, T_NEWSUPERIORDNSTR, type.bv_len) == 0)
 		{
-			op->p.p_modrdn.modrdn_newsuperior_address.dn = slapi_ch_strdup (value);
+			op->p.p_modrdn.modrdn_newsuperior_address.dn = slapi_ch_strdup (value.bv_val);
 		}		
-		else if (strcasecmp (type, T_NEWSUPERIORIDSTR) == 0)
+		else if (strncasecmp (type.bv_val, T_NEWSUPERIORIDSTR, type.bv_len) == 0)
 		{
-			op->p.p_modrdn.modrdn_newsuperior_address.uniqueid = slapi_ch_strdup (value);
+			op->p.p_modrdn.modrdn_newsuperior_address.uniqueid = slapi_ch_strdup (value.bv_val);
 		}
-		else if (strcasecmp (type, T_CHANGESTR) == 0)
+		else if (strncasecmp (type.bv_val, T_CHANGESTR, type.bv_len) == 0)
 		{
 			PR_ASSERT (op->operation_type);
 
@@ -5245,7 +5244,7 @@ _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op, char **repl
 																 op->operation_type);
 													return CL5_BAD_FORMAT;
 												}
-												mods = parse_changes_string(value);
+												mods = parse_changes_string(value.bv_val);
 												PR_ASSERT (mods);
 												slapi_mods2entry (&(op->p.p_add.target_entry), rawDN, 
 																  slapi_mods_get_ldapmods_byref(mods));
@@ -5253,13 +5252,13 @@ _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op, char **repl
 												slapi_mods_free (&mods);
 												break;
 												
-				case SLAPI_OPERATION_MODIFY:	mods = parse_changes_string(value);
+				case SLAPI_OPERATION_MODIFY:	mods = parse_changes_string(value.bv_val);
 												PR_ASSERT (mods);
 												op->p.p_modify.modify_mods = slapi_mods_get_ldapmods_passout (mods);
 												slapi_mods_free (&mods);
 												break;
 
-				case SLAPI_OPERATION_MODRDN:	mods = parse_changes_string(value);
+				case SLAPI_OPERATION_MODRDN:	mods = parse_changes_string(value.bv_val);
 												PR_ASSERT (mods);
 												op->p.p_modrdn.modrdn_mods = slapi_mods_get_ldapmods_passout (mods);
 												slapi_mods_free (&mods);
@@ -5268,9 +5267,15 @@ _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op, char **repl
 				default:						slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, 
 																"_cl5LDIF2Operation: invalid operation type - %lu\n", 
 																 op->operation_type);
+												if (freeval) {
+													slapi_ch_free_string(&value.bv_val);
+												}
 												return CL5_BAD_FORMAT;
 			}
 		}	
+		if (freeval) {
+			slapi_ch_free_string(&value.bv_val);
+		}
 	}
 
 	if (IsValidOperation (op))

+ 14 - 12
ldap/servers/plugins/replication/replutil.c

@@ -403,9 +403,9 @@ parse_changes_string(char *str)
 	Slapi_Mods *mods;
 	Slapi_Mod  mod;
 	char *line, *next;
-	char *type, *value;
-	int vlen;
-	struct berval bv;
+	struct berval type, value;
+	struct berval bv_null = {0, NULL};
+	int freeval = 0;
 	
 	/* allocate mods array */
 	mods = slapi_mods_new ();
@@ -438,7 +438,9 @@ parse_changes_string(char *str)
 				break;
 			}
 
-			rc = ldif_parse_line(line, &type, &value, &vlen);
+			type = bv_null;
+			value = bv_null;
+			rc = slapi_ldif_parse_line(line, &type, &value, &freeval);
 			if (rc != 0)
 			{
 				/* ONREPL - log warning */
@@ -447,15 +449,15 @@ parse_changes_string(char *str)
 				continue;
 			}
 
-			if (strcasecmp (type, "add") == 0)
+			if (strncasecmp (type.bv_val, "add", type.bv_len) == 0)
 			{
 				slapi_mod_set_operation (&mod, LDAP_MOD_ADD | LDAP_MOD_BVALUES);
 			}
-			else if (strcasecmp (type, "delete") == 0)
+			else if (strncasecmp (type.bv_val, "delete", type.bv_len) == 0)
 			{
 				slapi_mod_set_operation (&mod, LDAP_MOD_DELETE | LDAP_MOD_BVALUES);
 			}
-			else if (strcasecmp (type, "replace") == 0)
+			else if (strncasecmp (type.bv_val, "replace", type.bv_len) == 0)
 			{
 				slapi_mod_set_operation (&mod, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
 			}
@@ -464,15 +466,15 @@ parse_changes_string(char *str)
 				/* adding first value */
 				if (slapi_mod_get_type (&mod) == NULL)
 				{
-					slapi_mod_set_type (&mod, type);
+					slapi_mod_set_type (&mod, type.bv_val);
 				}
 
-				bv.bv_val = value;
-				bv.bv_len = vlen;
-
-				slapi_mod_add_value (&mod, &bv);
+				slapi_mod_add_value (&mod, &value);
 			}
 	
+			if (freeval) {
+				slapi_ch_free_string(&value.bv_val);
+			}
 			line = ldif_getline (&next);
 		}
 	}

+ 7 - 13
ldap/servers/slapd/back-ldbm/import-threads.c

@@ -271,17 +271,9 @@ static int
 import_get_version(char *str)
 {
     char *s;
-    char *type;
-    char *valuecharptr;
     char *mystr, *ms;
     int offset;
-#if defined(USE_OPENLDAP)
-    ber_len_t valuelen;
-#else
-    int valuelen;
-#endif
     int my_version = 0;
-    int retmalloc = 0;
 
     if ((s = strstr(str, "version:")) == NULL)
         return 0;
@@ -289,17 +281,19 @@ import_get_version(char *str)
     offset = s - str;
     mystr = ms = slapi_ch_strdup(str);
     while ( (s = ldif_getline( &ms )) != NULL ) {
-        if ( (retmalloc = ldif_parse_line( s, &type, &valuecharptr, &valuelen )) >= 0 ) {
-            if (!strcasecmp(type, "version")) {
-                my_version = atoi(valuecharptr);
+        struct berval type = {0, NULL}, value = {0, NULL};
+        int freeval = 0;
+        if ( slapi_ldif_parse_line( s, &type, &value, &freeval ) >= 0 ) {
+            if (!PL_strncasecmp(type.bv_val, "version", type.bv_len)) {
+                my_version = atoi(value.bv_val);
                 *(str + offset) = '#';
                 /* the memory below was not allocated by the slapi_ch_ functions */
-                if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+                if (freeval) slapi_ch_free_string(&value.bv_val);
                 break;
             } 
         }
         /* the memory below was not allocated by the slapi_ch_ functions */
-        if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+        if (freeval) slapi_ch_free_string(&value.bv_val);
     }
 
     slapi_ch_free((void **)&mystr);

+ 90 - 59
ldap/servers/slapd/back-ldbm/misc.c

@@ -405,6 +405,39 @@ is_fullpath(char *path)
     return 0;
 }
 
+/* the problem with getline is that it inserts \0 for every
+   newline \n or \r - this is a problem when you just want
+   to grab some value from the ldif string but do not
+   want to change the ldif string because it will be
+   parsed again in the future
+   openldap ldif_getline() is more of a problem because
+   it does this for every comment line too, whereas mozldap
+   ldif_getline() just skips comment lines
+*/
+static void
+ldif_getline_fixline(char *start, char *end)
+{
+    while (start && (start < end)) {
+        if (*start == '\0') {
+            /* the original ldif string will usually end with \n \0
+               ldif_getline will turn this into \0 \0
+               in this case, we don't want to turn it into
+               \r \n we want \n \0
+            */
+            if ((start < (end - 1)) && (*(start + 1) == '\0')) {
+                *start = '\r';
+                start++;
+            }
+            *start = '\n';
+            start++;
+        } else {
+            start++;
+        }
+    }
+
+    return;
+}
+
 /* 
  * Get value of type from string.
  * Note: this function is very primitive.  It does not support multi values.
@@ -420,13 +453,10 @@ get_value_from_string(const char *string, char *type, char **value)
     char *ptr = NULL;
     char *copy = NULL;
     char *tmpptr = NULL;
-    char *tmptype = NULL;
-    char *valueptr = NULL;
-#if defined (USE_OPENLDAP)
-    ber_len_t valuelen;
-#else
-    int valuelen;
-#endif
+    char *startptr = NULL;
+    struct berval tmptype;
+    struct berval bvvalue;
+    int freeval = 0;
 
     if (NULL == string || NULL == type || NULL == value) {
         return rc;
@@ -439,43 +469,46 @@ get_value_from_string(const char *string, char *type, char **value)
     }
 
     typelen = strlen(type);
+    startptr = tmpptr;
     while (NULL != (ptr = ldif_getline(&tmpptr))) {
         if ((0 != PL_strncasecmp(ptr, type, typelen)) ||
             (*(ptr + typelen) != ';' && *(ptr + typelen) != ':')) {
             /* did not match */
-            /* ldif_getline replaces '\n' and '\r' with '\0' */
-            if ('\0' == *(tmpptr - 1)) {
-                *(tmpptr - 1) = '\n';
-            }
-            if ('\0' == *(tmpptr - 2)) {
-                *(tmpptr - 2) = '\r';
-            }
+            ldif_getline_fixline(startptr, tmpptr);
+            startptr = tmpptr;
             continue;
         }
         /* matched */
         copy = slapi_ch_strdup(ptr);
-        /* ldif_getline replaces '\n' and '\r' with '\0' */
-        if ('\0' == *(tmpptr - 1)) {
-            *(tmpptr - 1) = '\n';
-        }
-        if ('\0' == *(tmpptr - 2)) {
-            *(tmpptr - 2) = '\r';
-        }
-        rc = ldif_parse_line(copy, &tmptype, &valueptr, &valuelen);
-        if (0 > rc || NULL == valueptr || 0 >= valuelen) {
+        ldif_getline_fixline(startptr, tmpptr);
+        startptr = tmpptr;
+        rc = slapi_ldif_parse_line(copy, &tmptype, &bvvalue, &freeval);
+        if (0 > rc || NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) {
             slapi_log_error(SLAPI_LOG_FATAL, "get_value_from_string", "parse "
                                              "failed: %d\n", rc);
+            if (freeval) {
+                slapi_ch_free_string(&bvvalue.bv_val);
+            }
             goto bail;
         }
-        if (0 != strcasecmp(type, tmptype)) {
+        if (0 != PL_strncasecmp(type, tmptype.bv_val, tmptype.bv_len)) {
             slapi_log_error(SLAPI_LOG_FATAL, "get_value_from_string", "type "
                                              "does not match: %s != %s\n", 
-                                             type, tmptype);
+                                             type, tmptype.bv_val);
+            if (freeval) {
+                slapi_ch_free_string(&bvvalue.bv_val);
+            }
             goto bail;
         }
-        *value = (char *)slapi_ch_malloc(valuelen + 1);
-        memcpy(*value, valueptr, valuelen);
-        *(*value + valuelen) = '\0';
+        if (freeval) {
+            *value = bvvalue.bv_val; /* just hand off the memory */
+            bvvalue.bv_val = NULL;
+        } else { /* make a copy */
+            *value = (char *)slapi_ch_malloc(bvvalue.bv_len + 1);
+            memcpy(*value, bvvalue.bv_val, bvvalue.bv_len);
+            *(*value + bvvalue.bv_len) = '\0';
+        }
+        slapi_ch_free_string(&copy);
     }
 bail:
     slapi_ch_free_string(&copy);
@@ -495,13 +528,9 @@ get_values_from_string(const char *string, char *type, char ***valuearray)
     char *ptr = NULL;
     char *copy = NULL;
     char *tmpptr = NULL;
-    char *tmptype = NULL;
-    char *valueptr = NULL;
-#if defined (USE_OPENLDAP)
-    ber_len_t valuelen;
-#else
-    int valuelen;
-#endif
+    char *startptr = NULL;
+    struct berval tmptype, bvvalue;
+    int freeval = 0;
     char *value = NULL;
     int idx = 0;
 #define get_values_INITIALMAXCNT 1
@@ -518,51 +547,53 @@ get_values_from_string(const char *string, char *type, char ***valuearray)
     }
 
     typelen = strlen(type);
+    startptr = tmpptr;
     while (NULL != (ptr = ldif_getline(&tmpptr))) {
         if ((0 != PL_strncasecmp(ptr, type, typelen)) ||
             (*(ptr + typelen) != ';' && *(ptr + typelen) != ':')) {
             /* did not match */
-            /* ldif_getline replaces '\n' and '\r' with '\0' */
-            if ('\0' == *(tmpptr - 1)) {
-                *(tmpptr - 1) = '\n';
-            }
-            if ('\0' == *(tmpptr - 2)) {
-                *(tmpptr - 2) = '\r';
-            }
+            ldif_getline_fixline(startptr, tmpptr);
+            startptr = tmpptr;
             continue;
         }
         /* matched */
         copy = slapi_ch_strdup(ptr);
-        /* ldif_getline replaces '\n' and '\r' with '\0' */
-        if ('\0' == *(tmpptr - 1)) {
-            *(tmpptr - 1) = '\n';
-        }
-        if ('\0' == *(tmpptr - 2)) {
-            *(tmpptr - 2) = '\r';
-        }
-        rc = ldif_parse_line(copy, &tmptype, &valueptr, &valuelen);
-        if (0 > rc || NULL == valueptr || 0 >= valuelen) {
+        ldif_getline_fixline(startptr, tmpptr);
+        startptr = tmpptr;
+        rc = slapi_ldif_parse_line(copy, &tmptype, &bvvalue, &freeval);
+        if (0 > rc || NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) {
             continue;
         }
-        if (0 != strcasecmp(type, tmptype)) {
-            char *p = PL_strchr(tmptype, ';'); /* subtype ? */
+        if (0 != PL_strncasecmp(type, tmptype.bv_val, tmptype.bv_len)) {
+            char *p = PL_strchr(tmptype.bv_val, ';'); /* subtype ? */
             if (p) {
-                if (0 != strncasecmp(type, tmptype, p - tmptype)) {
+                if (0 != strncasecmp(type, tmptype.bv_val, p - tmptype.bv_val)) {
                     slapi_log_error(SLAPI_LOG_FATAL, "get_values_from_string", 
                                     "type does not match: %s != %s\n", 
-                                    type, tmptype);
+                                    type, tmptype.bv_val);
+                    if (freeval) {
+                        slapi_ch_free_string(&bvvalue.bv_val);
+                    }
                     goto bail;
                 }
             } else {
                 slapi_log_error(SLAPI_LOG_FATAL, "get_values_from_string", 
                                 "type does not match: %s != %s\n", 
-                                type, tmptype);
+                                type, tmptype.bv_val);
+                if (freeval) {
+                    slapi_ch_free_string(&bvvalue.bv_val);
+                }
                 goto bail;
             }
         }
-        value = (char *)slapi_ch_malloc(valuelen + 1);
-        memcpy(value, valueptr, valuelen);
-        *(value + valuelen) = '\0';
+        if (freeval) {
+            value = bvvalue.bv_val; /* just hand off memory */
+            bvvalue.bv_val = NULL;
+        } else { /* copy */
+            value = (char *)slapi_ch_malloc(bvvalue.bv_len + 1);
+            memcpy(value, bvvalue.bv_val, bvvalue.bv_len);
+            *(value + bvvalue.bv_len) = '\0';
+        }
         if ((get_values_INITIALMAXCNT == maxcnt) || !valuearray || 
             (idx + 1 >= maxcnt)) {
             maxcnt *= 2;

+ 83 - 119
ldap/servers/slapd/entry.c

@@ -158,7 +158,6 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 	char		*next, *ptype=NULL;
 	int nvals= 0;
 	int del_nvals= 0;
-	int retmalloc = 0;
 	unsigned long attr_val_cnt = 0;
 	CSN *attributedeletioncsn= NULL; /* Moved to this level so that the JCM csn_free call below gets useful */
 	CSNSet *valuecsnset= NULL; /* Moved to this level so that the JCM csn_free call below gets useful */
@@ -207,33 +206,23 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 	while ( (s = ldif_getline( &next )) != NULL &&
 	         attr_val_cnt < ENTRY_MAX_ATTRIBUTE_VALUE_COUNT )
 	{
-		char *valuecharptr=NULL;
-#if defined(USE_OPENLDAP)
-		ber_len_t valuelen;
-#else
-		int	valuelen;
-#endif
+		struct berval type = {0, NULL};
+		struct berval value = {0, NULL};
+		int freeval = 0;
 		int value_state= VALUE_NOTFOUND;
 		int attr_state= ATTRIBUTE_NOTFOUND;
 		int maxvals;
 		int del_maxvals;
-		char *type;
-		int freetype = 0;
 
 		if ( *s == '\n' || *s == '\0' ) {
 			break;
 		}
 
-		if ( (retmalloc = ldif_parse_line( s, &type, &valuecharptr, &valuelen )) < 0 ) {
+		if ( slapi_ldif_parse_line( s, &type, &value, &freeval ) < 0 ) {
 			LDAPDebug( LDAP_DEBUG_TRACE,
 			    "<= str2entry_fast NULL (parse_line)\n", 0, 0, 0 );
 			continue;
 		}
-#if defined(USE_OPENLDAP)
-		/* openldap always mallocs the type and value arguments to ldap_parse_line */
-		retmalloc = 1;
-		freetype = 1;
-#endif
 
 		/*
 		 * Extract the attribute and value CSNs from the attribute type.
@@ -242,7 +231,7 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 		csnset_free(&valuecsnset);
 		value_state= VALUE_NOTFOUND;
 		attr_state= ATTRIBUTE_NOTFOUND;
-		str2entry_state_information_from_type(type,&valuecsnset,&attributedeletioncsn,&maxcsn,&value_state,&attr_state);
+		str2entry_state_information_from_type(type.bv_val,&valuecsnset,&attributedeletioncsn,&maxcsn,&value_state,&attr_state);
 		if(!read_stateinfo)
 		{
 			/* We are not maintaining state information */
@@ -250,8 +239,7 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 			{
 				/* ignore deleted values and attributes */
 				/* the memory below was not allocated by the slapi_ch_ functions */
-				if (retmalloc) slapi_ch_free_string(&valuecharptr);
-				if (freetype) slapi_ch_free_string(&type);
+				if (freeval) slapi_ch_free_string(&value.bv_val);
 				continue;
 			}
 			/* Ignore CSNs */
@@ -261,10 +249,10 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 		/*
 		 * We cache some stuff as we go around the loop.
 		 */
-		if((ptype==NULL)||(strcasecmp(type,ptype) != 0))
+		if((ptype==NULL)||(PL_strncasecmp(type.bv_val,ptype,type.bv_len) != 0))
 		{
 			slapi_ch_free_string(&ptype);
-			ptype=slapi_ch_strdup(type);
+			ptype=PL_strndup(type.bv_val, type.bv_len);
 			nvals = 0;
 			maxvals = 0;
 			del_nvals = 0;
@@ -283,8 +271,7 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 						LDAPDebug1Arg(LDAP_DEBUG_TRACE,
 							  		"str2entry_fast: Invalid DN: %s\n", rawdn);
 						slapi_entry_free( e );
-						if (retmalloc) slapi_ch_free_string(&valuecharptr);
-						if (freetype) slapi_ch_free_string(&type);
+						if (freeval) slapi_ch_free_string(&value.bv_val);
 						e = NULL;
 						goto done;
 					}
@@ -306,8 +293,7 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 							LDAPDebug1Arg(LDAP_DEBUG_TRACE,
 							  		"str2entry_fast: Invalid DN: %s\n", rawdn);
 							slapi_entry_free( e );
-							if (retmalloc) slapi_ch_free_string(&valuecharptr);
-							if (freetype) slapi_ch_free_string(&type);
+							if (freeval) slapi_ch_free_string(&value.bv_val);
 							e = NULL;
 							goto done;
 						}
@@ -320,31 +306,31 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 			rawdn = NULL; /* Set once in the loop. 
 							 This won't affect the caller's passed address. */
 		}
-		if ( strcasecmp( type, "dn" ) == 0 ) {
+		if ( PL_strncasecmp( type.bv_val, "dn", type.bv_len ) == 0 ) {
 			if ( slapi_entry_get_dn_const(e)!=NULL ) {
-				char ebuf[ BUFSIZ ];
+				char ebuf[ BUFSIZ ], ebuf2[ BUFSIZ ];
 				LDAPDebug( LDAP_DEBUG_TRACE,
 					"str2entry_fast: entry has multiple dns \"%s\" and "
 					"\"%s\" (second ignored)\n",
 					escape_string( slapi_entry_get_dn_const(e), ebuf ),
-					escape_string( valuecharptr, ebuf ), 0 );
+					escape_string( value.bv_val, ebuf2 ), 0 );
 				/* the memory below was not allocated by the slapi_ch_ functions */
-				if (retmalloc) slapi_ch_free_string(&valuecharptr);
-				if (freetype) slapi_ch_free_string(&type);
+				if (freeval) slapi_ch_free_string(&value.bv_val);
 				continue;
 			}
 			if (flags & SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT) {
 				normdn = 
-					slapi_ch_strdup(slapi_dn_normalize_original(valuecharptr));
+					slapi_ch_strdup(slapi_dn_normalize_original(value.bv_val));
 			} else {
-				normdn = slapi_create_dn_string("%s", valuecharptr);
+				normdn = slapi_create_dn_string("%s", value.bv_val);
 			}
 			if (NULL == normdn) {
+				char ebuf[ BUFSIZ ];
 				LDAPDebug1Arg(LDAP_DEBUG_TRACE,
-							  "str2entry_fast: Invalid DN: %s\n", valuecharptr);
+							  "str2entry_fast: Invalid DN: %s\n",
+                              escape_string( value.bv_val, ebuf ));
 				slapi_entry_free( e );
-				if (retmalloc) slapi_ch_free_string(&valuecharptr);
-				if (freetype) slapi_ch_free_string(&type);
+				if (freeval) slapi_ch_free_string(&value.bv_val);
 				e = NULL;
 				goto done;
 			}
@@ -352,134 +338,126 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 			slapi_entry_set_dn(e, normdn);
 
 			/* the memory below was not allocated by the slapi_ch_ functions */
-			if (retmalloc) slapi_ch_free_string(&valuecharptr);
-			if (freetype) slapi_ch_free_string(&type);
+			if (freeval) slapi_ch_free_string(&value.bv_val);
 			continue;
 		}
 
-		if ( strcasecmp( type, "rdn" ) == 0 ) {
+		if ( PL_strncasecmp( type.bv_val, "rdn", type.bv_len ) == 0 ) {
 			if ( NULL == slapi_entry_get_rdn_const( e )) {
-				slapi_entry_set_rdn( e, valuecharptr );
+				slapi_entry_set_rdn( e, value.bv_val );
 			}
 			/* the memory below was not allocated by the slapi_ch_ functions */
-			if (retmalloc) slapi_ch_free_string(&valuecharptr);
-			if (freetype) slapi_ch_free_string(&type);
+			if (freeval) slapi_ch_free_string(&value.bv_val);
 			continue;
 		}
 
 
 		/* retrieve uniqueid */
-		if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
+		if ( PL_strncasecmp (type.bv_val, SLAPI_ATTR_UNIQUEID, type.bv_len) == 0 ){
 
 			if (e->e_uniqueid != NULL){
 				LDAPDebug (LDAP_DEBUG_TRACE, 
 						   "str2entry_fast: entry has multiple uniqueids %s "
 						   "and %s (second ignored)\n",
-						   e->e_uniqueid, valuecharptr, 0);
+						   e->e_uniqueid, value.bv_val, 0);
 			}else{
 				/* name2asi will be locked in slapi_entry_set_uniqueid */
 				attr_syntax_unlock_read(); 
-				slapi_entry_set_uniqueid (e, slapi_ch_strdup(valuecharptr));
+				slapi_entry_set_uniqueid (e, PL_strndup(value.bv_val, value.bv_len));
 				attr_syntax_read_lock();
 			}
 			/* the memory below was not allocated by the slapi_ch_ functions */
-			if (retmalloc) slapi_ch_free_string(&valuecharptr);
-			if (freetype) slapi_ch_free_string(&type);
+			if (freeval) slapi_ch_free_string(&value.bv_val);
 			continue;
 		}
 		
-		if (strcasecmp(type,"objectclass") == 0) {
-			if (strcasecmp(valuecharptr,"ldapsubentry") == 0)
+		if (PL_strncasecmp(type.bv_val,"objectclass",type.bv_len) == 0) {
+			if (PL_strncasecmp(value.bv_val,"ldapsubentry",value.bv_len) == 0)
 				e->e_flags |= SLAPI_ENTRY_LDAPSUBENTRY;
-			if (strcasecmp(valuecharptr, SLAPI_ATTR_VALUE_TOMBSTONE) == 0)
+			if (PL_strncasecmp(value.bv_val, SLAPI_ATTR_VALUE_TOMBSTONE,value.bv_len) == 0)
 				e->e_flags |= SLAPI_ENTRY_FLAG_TOMBSTONE;
 		}
 		
 		{
-			Slapi_Value	*value = NULL;
+			Slapi_Value	*svalue = NULL;
 			if(a==NULL)
 			{
 				switch(attr_state)
 				{
 				case ATTRIBUTE_PRESENT:
-					if(attrlist_find_or_create_locking_optional(&e->e_attrs, type, &a, PR_FALSE)==0 /* Found */)
+					if(attrlist_find_or_create_locking_optional(&e->e_attrs, type.bv_val, &a, PR_FALSE)==0 /* Found */)
 					{
-						LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous attribute values for %s\n", type, 0, 0);
+						LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous attribute values for %s\n", type.bv_val, 0, 0);
 						PR_ASSERT(0);
-						if (freetype) slapi_ch_free_string(&type);
 						continue;
 					}
 					break;
 				case ATTRIBUTE_DELETED:
-					if(attrlist_find_or_create_locking_optional(&e->e_deleted_attrs, type, &a, PR_FALSE)==0 /* Found */)
+					if(attrlist_find_or_create_locking_optional(&e->e_deleted_attrs, type.bv_val, &a, PR_FALSE)==0 /* Found */)
 					{
-						LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous deleted attribute values for %s\n", type, 0, 0);
+						LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous deleted attribute values for %s\n", type.bv_val, 0, 0);
 						PR_ASSERT(0);
-						if (freetype) slapi_ch_free_string(&type);
 						continue;
 					}
 					break;
 				case ATTRIBUTE_NOTFOUND:
-					LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous deleted attribute values for %s\n", type, 0, 0);
+					LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous deleted attribute values for %s\n", type.bv_val, 0, 0);
 					PR_ASSERT(0);
-					if (freetype) slapi_ch_free_string(&type);
 					continue;
 					/* break; ??? */
 				}
 			}
 			/* moved the value setting code here to check Slapi_Attr 'a'
 			 * to retrieve the attribute syntax info */
-			value = value_new(NULL, CSN_TYPE_NONE, NULL);
+			svalue = value_new(NULL, CSN_TYPE_NONE, NULL);
 			if (slapi_attr_is_dn_syntax_attr(*a)) {
 				int rc = 0;
 				char *dn_aval = NULL;
 				size_t dnlen = 0;
 				if (strict) {
 					/* check that the dn is formatted correctly */
-					rc = slapi_dn_syntax_check(NULL, valuecharptr, 1);
+					rc = slapi_dn_syntax_check(NULL, value.bv_val, 1);
 					if (rc) { /* syntax check failed */
 						LDAPDebug2Args(LDAP_DEBUG_TRACE, 
 							"str2entry_fast: strict: Invalid DN value: %s: %s\n",
-							type, valuecharptr);
+							type.bv_val, value.bv_val);
 						slapi_entry_free( e );
-						if (retmalloc) slapi_ch_free_string(&valuecharptr);
-						if (freetype) slapi_ch_free_string(&type);
+						if (freeval) slapi_ch_free_string(&value.bv_val);
 						e = NULL;
 						goto done;
 					}
 				}
 				if (flags & SLAPI_STR2ENTRY_USE_OBSOLETE_DNFORMAT) {
-					dn_aval = slapi_dn_normalize_original(valuecharptr);
-					slapi_value_set(value, dn_aval, strlen(dn_aval));
+					dn_aval = slapi_dn_normalize_original(value.bv_val);
+					slapi_value_set(svalue, dn_aval, strlen(dn_aval));
 				} else {
-					rc = slapi_dn_normalize_ext(valuecharptr, 
-												0, &dn_aval, &dnlen);
+					rc = slapi_dn_normalize_ext(value.bv_val, 
+												value.bv_len, &dn_aval, &dnlen);
 					if 	(rc < 0) {
 						/* Give up normalizing the attribute value */
 						LDAPDebug2Args(LDAP_DEBUG_TRACE,
 							       "str2entry_fast: Invalid DN value: %s: %s\n",
 							       type, valuecharptr);
-						dn_aval = valuecharptr;
-						dnlen = valuelen;
-					}
-					slapi_value_set(value, dn_aval, dnlen);
-					if (rc > 0) { /* if rc == 0, valuecharptr is passed in */
-						slapi_ch_free_string(&dn_aval);
+						dn_aval = value.bv_val;
+						dnlen = value.bv_len;
 					} else if (rc == 0) { /* rc == 0; valuecharptr is passed in;
 											 not null terminated */
 						*(dn_aval + dnlen) = '\0';
 					}
+					slapi_value_set(svalue, dn_aval, dnlen);
+					if (rc > 0) { /* if rc == 0, valuecharptr is passed in */
+						slapi_ch_free_string(&dn_aval);
+					}
 				}
 			} else {
-				slapi_value_set(value, valuecharptr, valuelen);
+				slapi_value_set_berval(svalue, &value);
 			}
-			if (freetype) slapi_ch_free_string(&type); /* don't need type anymore */
 			/* the memory below was not allocated by the slapi_ch_ functions */	
-			if (retmalloc) slapi_ch_free_string(&valuecharptr);
-			value->v_csnset = valuecsnset;
+			if (freeval) slapi_ch_free_string(&value.bv_val);
+			svalue->v_csnset = valuecsnset;
 			valuecsnset = NULL;
 			{
-				const CSN *distinguishedcsn= csnset_get_csn_of_type(value->v_csnset,CSN_TYPE_VALUE_DISTINGUISHED);
+				const CSN *distinguishedcsn= csnset_get_csn_of_type(svalue->v_csnset,CSN_TYPE_VALUE_DISTINGUISHED);
 				if(distinguishedcsn!=NULL)
 				{
 					entry_add_dncsn_ext(e,distinguishedcsn, ENTRY_DNCSN_INCREASING);
@@ -490,7 +468,7 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 				/* consumes the value */
 				valuearray_add_value_fast(
 					&(*a)->a_deleted_values.va, /* JCM .va is private */
-					value,
+					svalue,
 					del_nvals,
 					&del_maxvals,
 					0/*!Exact*/,
@@ -502,7 +480,7 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
 				/* consumes the value */
 				valuearray_add_value_fast(
 					&(*a)->a_present_values.va, /* JCM .va is private */
-					value, 
+					svalue, 
 					nvals,
 					&maxvals, 
 					0 /*!Exact*/, 
@@ -722,11 +700,12 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
     int nattrs;
     int maxattrs = STR2ENTRY_SMALL_BUFFER_SIZE;
     char *type;
+    struct berval bvtype;
     str2entry_attr *sa;
     int i, j;
     char *next=NULL;
     char *valuecharptr=NULL;
-    int retmalloc = 0;
+    struct berval bvvalue;
     int rc;
 	int fast_dup_check = 0;
 	entry_attrs *ea = NULL;
@@ -759,27 +738,23 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 		CSNSet *valuecsnset= NULL;
 		int value_state= VALUE_NOTFOUND;
 		int attr_state= VALUE_NOTFOUND;
-		int freetype = 0;
-#if defined(USE_OPENLDAP)
-		ber_len_t valuelen;
-#else
-		int	valuelen;
-#endif
+		int freeval = 0;
+		struct berval bv_null = {0, NULL};
 
 		if ( *s == '\n' || *s == '\0' ) {
 		    break;
 		}
 
-		if ( (retmalloc = ldif_parse_line( s, &type, &valuecharptr, &valuelen )) < 0 ) {
+		bvtype = bv_null;
+		bvvalue = bv_null;
+		if ( slapi_ldif_parse_line( s, &bvtype, &bvvalue, &freeval ) < 0 ) {
 		    LDAPDebug( LDAP_DEBUG_TRACE,
 			    "<= str2entry_dupcheck NULL (parse_line)\n", 0, 0, 0 );
 		    continue;
 		}
-#if defined(USE_OPENLDAP)
-		/* openldap always mallocs type and value */
-		retmalloc = 1;
-		freetype = 1;
-#endif
+		type = bvtype.bv_val;
+		valuecharptr = bvvalue.bv_val;
+
 		/*
 		 * Extract the attribute and value CSNs from the attribute type.
 		 */		
@@ -795,8 +770,7 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 			{
 				/* ignore deleted values and attributes */
 				/* the memory below was not allocated by the slapi_ch_ functions */
-				if (retmalloc) slapi_ch_free_string(&valuecharptr);
-				if (freetype) slapi_ch_free_string(&type);
+				if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 				csn_free(&attributedeletioncsn);
 				continue;
 			}
@@ -812,8 +786,7 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 					LDAPDebug1Arg(LDAP_DEBUG_TRACE,
 							  "str2entry_dupcheck: Invalid DN: %s\n", rawdn);
 					slapi_entry_free( e );
-					if (retmalloc) slapi_ch_free_string(&valuecharptr);
-					if (freetype) slapi_ch_free_string(&type);
+					if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 					csn_free(&attributedeletioncsn);
 					return NULL;
 				}
@@ -830,8 +803,7 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 						LDAPDebug1Arg(LDAP_DEBUG_TRACE,
 							  	"str2entry_fast: Invalid DN: %s\n", rawdn);
 						slapi_entry_free( e );
-						if (retmalloc) slapi_ch_free_string(&valuecharptr);
-						if (freetype) slapi_ch_free_string(&type);
+						if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 						csn_free(&attributedeletioncsn);
 						return NULL;
 					}
@@ -845,15 +817,14 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 		}
 		if ( strcasecmp( type, "dn" ) == 0 ) {
 			if ( slapi_entry_get_dn_const(e)!=NULL ) {
-				char ebuf[ BUFSIZ ];
+				char ebuf[ BUFSIZ ], ebuf2[ BUFSIZ ];
 				LDAPDebug( LDAP_DEBUG_TRACE,
 					"str2entry_dupcheck: entry has multiple dns \"%s\" "
 					"and \"%s\" (second ignored)\n",
 					escape_string( slapi_entry_get_dn_const(e), ebuf ),
-					escape_string( valuecharptr, ebuf ), 0 );
+					escape_string( valuecharptr, ebuf2 ), 0 );
 				/* the memory below was not allocated by the slapi_ch_ functions */
-				if (retmalloc) slapi_ch_free_string(&valuecharptr);
-				if (freetype) slapi_ch_free_string(&type);
+				if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 				csn_free(&attributedeletioncsn);
 				continue;
 			}
@@ -862,15 +833,13 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 				LDAPDebug1Arg(LDAP_DEBUG_TRACE,
 						"str2entry_dupcheck: Invalid DN: %s\n", valuecharptr);
 				slapi_entry_free( e ); e = NULL;
-				if (retmalloc) slapi_ch_free_string(&valuecharptr);
-				if (freetype) slapi_ch_free_string(&type);
+				if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 				goto free_and_return;
 			}
 			/* normdn is consumed in e */
 			slapi_entry_set_dn(e, normdn);
 			/* the memory below was not allocated by the slapi_ch_ functions */
-			if (retmalloc) slapi_ch_free_string(&valuecharptr);
-			if (freetype) slapi_ch_free_string(&type);
+			if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 			csn_free(&attributedeletioncsn);
 		    continue;
 		}
@@ -880,8 +849,7 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 				slapi_entry_set_rdn( e, valuecharptr );
 			}
 			/* the memory below was not allocated by the slapi_ch_ functions */
-			if (retmalloc) slapi_ch_free_string(&valuecharptr);
-			if (freetype) slapi_ch_free_string(&type);
+			if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 			csn_free(&attributedeletioncsn);
 		    continue;
 		}
@@ -898,8 +866,7 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 				slapi_entry_set_uniqueid (e, slapi_ch_strdup(valuecharptr));
 			}
 			/* the memory below was not allocated by the slapi_ch_ functions */
-			if (retmalloc) slapi_ch_free_string(&valuecharptr);
-			if (freetype) slapi_ch_free_string(&type);
+			if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 			csn_free(&attributedeletioncsn);
 			continue;
 		}
@@ -942,8 +909,7 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 					if (0 != entry_attrs_new(&ea))
 					{
 						/* Something very bad happened */
-						if (retmalloc) slapi_ch_free_string(&valuecharptr);
-						if (freetype) slapi_ch_free_string(&type);
+						if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 						csn_free(&attributedeletioncsn);
 						return NULL;
 					}
@@ -1029,20 +995,19 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 						"str2entry_dupcheck: strict: Invalid DN value: %s: %s\n",
 						type, valuecharptr);
 					slapi_entry_free( e ); e = NULL;
-					if (retmalloc) slapi_ch_free_string(&valuecharptr);
-					if (freetype) slapi_ch_free_string(&type);
+					if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 					csn_free(&attributedeletioncsn);
 					goto free_and_return;
 				}
 			}
-			rc = slapi_dn_normalize_ext(valuecharptr, 0, &dn_aval, &dnlen);
+			rc = slapi_dn_normalize_ext(bvvalue.bv_val, bvvalue.bv_len, &dn_aval, &dnlen);
 			if (rc < 0) {
 				/* Give up normalizing the attribute value */
 				LDAPDebug2Args(LDAP_DEBUG_TRACE,
 							   "str2entry_dupcheck: Invalid DN value: %s: %s\n",
 							   type, valuecharptr);
 				dn_aval = valuecharptr;
-				dnlen = valuelen;
+				dnlen = bvvalue.bv_len;
 			}
 			slapi_value_set(value, dn_aval, dnlen);
 			if (rc > 0) { /* if rc == 0, valuecharptr is passed in */
@@ -1052,11 +1017,10 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
 				*(dn_aval + dnlen) = '\0';
 			}
 		} else {
-			slapi_value_set(value, valuecharptr, valuelen);
+			slapi_value_set_berval(value, &bvvalue);
 		}
-		if (freetype) slapi_ch_free_string(&type);
 		/* the memory below was not allocated by the slapi_ch_ functions */
-		if (retmalloc) slapi_ch_free_string(&valuecharptr);
+		if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
 		value->v_csnset= valuecsnset;
 		valuecsnset= NULL;
 		{

+ 5 - 11
ldap/servers/slapd/fedse.c

@@ -1721,20 +1721,16 @@ int
 search_easter_egg( Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg)
 {
     char *fstr= NULL;
-    int retmalloc= 0;
 	char eggfilter[64];
 	PR_snprintf(eggfilter,sizeof(eggfilter),"(objectclass=%s)",EGG_OBJECT_CLASS);
     slapi_pblock_get( pb, SLAPI_SEARCH_STRFILTER, &fstr );
     if(fstr!=NULL && strcasecmp(fstr,eggfilter)==0)
     {
 		static int twiddle= -1;
-		char *type, *value, *copy;
-#if defined(USE_OPENLDAP)
-		ber_len_t vlen;
-#else
-		int vlen;
-#endif
+		char *copy;
+		struct berval bvtype;
 		struct berval bv;
+		int freeval = 0;
 		struct berval *bvals[2];
 		if (twiddle < 0) {
 			twiddle = slapi_rand();
@@ -1742,17 +1738,15 @@ search_easter_egg( Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr
 		bvals[0] = &bv;
 		bvals[1] = NULL;
 		copy= slapi_ch_strdup(easter_egg_photos[twiddle%NUM_EASTER_EGG_PHOTOS]);
-		if ( (retmalloc = ldif_parse_line(copy, &type, &value, &vlen)) < 0 ) {
+		if ( slapi_ldif_parse_line(copy, &bvtype, &bv, &freeval) < 0 ) {
 		    return SLAPI_DSE_CALLBACK_ERROR;
 		}
-		bv.bv_val = value;
-		bv.bv_len = vlen;
 	    slapi_entry_attr_delete(entryBefore, "jpegphoto");
     	slapi_entry_attr_merge(entryBefore, "jpegphoto", bvals);
 		slapi_ch_free((void**)&copy);
 		twiddle++;
 		/* the memory below was not allocated by the slapi_ch_ functions */
-		if (retmalloc) slapi_ch_free( (void**)&value );
+		if (freeval) slapi_ch_free_string(&bv.bv_val);
         return SLAPI_DSE_CALLBACK_OK;
     }
     return SLAPI_DSE_CALLBACK_ERROR;

+ 109 - 13
ldap/servers/slapd/ldaputil.c

@@ -252,6 +252,91 @@ slapi_ldap_count_values( char **vals )
 #endif
 }
 
+int
+slapi_ldap_create_proxyauth_control (
+    LDAP *ld, /* only used to get current ber options */
+    const char *dn, /* proxy dn */
+    const char ctl_iscritical,
+    int usev2, /* use the v2 (.18) control instead */
+    LDAPControl **ctrlp /* value to return */
+)
+{
+    BerElement *ber = NULL;
+    int rc = 0;
+    int beropts = 0;
+    char *berfmtstr = NULL;
+    char *ctrloid = NULL;
+    struct berval *bv = NULL;
+
+    /* note - there is currently no way to get the beroptions from the ld*,
+       so we just hard code it here */
+#if defined(USE_OPENLDAP)
+    beropts = LBER_USE_DER; /* openldap seems to use DER by default */
+#endif
+    if (ctrlp == NULL) {
+	return LDAP_PARAM_ERROR;
+    }
+    if (NULL == dn) {
+	dn = "";
+    }
+
+    if (NULL == (ber = ber_alloc_t(beropts))) {
+	return LDAP_NO_MEMORY;
+    }
+
+    if (usev2) {
+	berfmtstr = "s";
+	ctrloid = LDAP_CONTROL_PROXIEDAUTH;
+    } else {
+	berfmtstr = "{s}";
+	ctrloid = LDAP_CONTROL_PROXYAUTH;
+    }
+
+    if (LBER_ERROR == ber_printf(ber, berfmtstr, dn)) {
+	ber_free(ber, 1);
+	return LDAP_ENCODING_ERROR;
+    }
+
+    if (LBER_ERROR == ber_flatten(ber, &bv)) {
+        ber_bvfree(bv);
+        ber_free(ber, 1);
+	return LDAP_ENCODING_ERROR;
+    }
+	
+    if (NULL == bv) {
+        ber_free(ber, 1);
+        return LDAP_NO_MEMORY;
+    }
+
+    rc = ldap_control_create(ctrloid, ctl_iscritical, bv, 1, ctrlp);
+    ber_bvfree(bv);
+    ber_free(ber, 1);
+
+    return rc;
+}
+
+int
+slapi_ldif_parse_line(
+    char *line,
+    struct berval *type,
+    struct berval *value,
+    int *freeval
+)
+{
+    int rc;
+#if defined(USE_OPENLDAP)
+    rc = ldif_parse_line2(line, type, value, freeval);
+    /* check that type and value are null terminated */
+#else
+    int vlen;
+    rc = ldif_parse_line(line, &type->bv_val, &value->bv_val, &vlen);
+    type->bv_len = type->bv_val ? strlen(type->bv_val) : 0;
+    value->bv_len = vlen;
+    *freeval = 0; /* always returns in place */
+#endif
+    return rc;
+}
+
 /*
   Perform LDAP init and return an LDAP* handle.  If ldapurl is given,
   that is used as the basis for the protocol, host, port, and whether
@@ -462,9 +547,11 @@ slapi_ldap_init_ext(
 	 * Set SSL strength (server certificate validity checking).
 	 */
 	if (secure > 0) {
-#if !defined(USE_OPENLDAP)
+#if defined(USE_OPENLDAP)
+	    char *certdir = config_get_certdir();
+	    int optval = 0;
+#endif /* !USE_OPENLDAP */
 	    int ssl_strength = 0;
-#endif
 	    LDAP *myld = NULL;
 
 	    /* we can only use the set functions below with a real
@@ -477,30 +564,39 @@ slapi_ldap_init_ext(
 	    if (config_get_ssl_check_hostname()) {
 		/* check hostname against name in certificate */
 #if defined(USE_OPENLDAP)
-		if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, "hard"))) {
-		    slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
-				    "failed: unable to set REQUIRE_CERT option to hard\n");
-		}
+		ssl_strength = LDAP_OPT_X_TLS_HARD;
 #else /* !USE_OPENLDAP */
 		ssl_strength = LDAPSSL_AUTH_CNCHECK;
 #endif /* !USE_OPENLDAP */
 	    } else {
 		/* verify certificate only */
 #if defined(USE_OPENLDAP)
-		if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, "allow"))) {
-		    slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
-				    "failed: unable to set REQUIRE_CERT option to allow\n");
-		}
+		ssl_strength = LDAP_OPT_X_TLS_ALLOW;
 #else /* !USE_OPENLDAP */
 		ssl_strength = LDAPSSL_AUTH_CERT;
 #endif /* !USE_OPENLDAP */
 	    }
 
 #if defined(USE_OPENLDAP)
+	    if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &optval))) {
+		slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+				"failed: unable to create new TLS context\n");
+	    }
+	    if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &ssl_strength))) {
+		slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+				"failed: unable to set REQUIRE_CERT option to %d\n", ssl_strength);
+	    }
+	    /* tell it where our cert db is */
+	    if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTDIR, certdir))) {
+		slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+				"failed: unable to set CACERTDIR option to %s\n", certdir);
+	    }
+	    slapi_ch_free_string(&certdir);
 #if defined(LDAP_OPT_X_TLS_PROTOCOL_MIN)
-	    if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, LDAP_OPT_X_TLS_PROTOCOL_SSL3))) {
+	    optval = LDAP_OPT_X_TLS_PROTOCOL_SSL3;
+	    if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, &optval))) {
 		slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
-				"failed: unable to set minimum TLS protocol level to SSL3n");
+				"failed: unable to set minimum TLS protocol level to SSL3\n");
 	    }
 #endif /* LDAP_OPT_X_TLS_PROTOCOL_MIN */
 #else  /* !USE_OPENLDAP */
@@ -512,7 +608,7 @@ slapi_ldap_init_ext(
 
 		slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
 				"failed: unable to set SSL options ("
-				SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+				SLAPI_COMPONENT_NAME_NSPR " error %d - %s)\n",
 				prerr, slapd_pr_strerror(prerr));
 
 	    }

+ 16 - 0
ldap/servers/slapd/slapi-plugin.h

@@ -5062,6 +5062,22 @@ slapi_ldap_bind(
     int *msgidp /* pass in non-NULL for async handling */
 );
 
+int
+slapi_ldap_create_proxyauth_control (
+    LDAP *ld, /* only used to get current ber options */
+    const char *dn, /* proxy dn */
+    const char ctl_iscritical,
+    int usev2, /* use the v2 (.18) control instead */
+    LDAPControl **ctrlp /* value to return */
+);
+
+int
+slapi_ldif_parse_line(
+    char *line, /* line to parse */
+    struct berval *type, /* attribute type to return */
+    struct berval *value, /* attribute value to return */
+    int *freeval /* values will usually be returned in place as pointers into line - if the value is a url, the value will be malloced and must be freed by the caller */
+);
 
 /*
  * computed attributes

+ 26 - 10
ldap/servers/slapd/tools/ldclt/ldapfct.c

@@ -267,8 +267,9 @@ int ldclt_create_deref_control( LDAP *ld, char *derefAttr, char **attrs, LDAPCon
 
 #if !defined(USE_OPENLDAP)
 int ldclt_build_control( char *oid, BerElement *ber, int freeber, char iscritical, LDAPControl **ctrlp );
-int ldclt_alloc_ber( LDAP *ld, BerElement **berp );
 #endif
+int ldclt_alloc_ber( LDAP *ld, BerElement **berp );
+
 
 /* ****************************************************************************
 	FUNCTION :	my_ldap_err2string
@@ -4233,6 +4234,9 @@ ldclt_create_deref_control(
 {
     BerElement *ber;
     int rc;
+#if defined(USE_OPENLDAP)
+    struct berval *bv = NULL;
+#endif
     
     if (ld == 0) {
         return( LDAP_PARAM_ERROR );
@@ -4243,12 +4247,7 @@ ldclt_create_deref_control(
         return ( LDAP_PARAM_ERROR );
     }
 
-    /* create a ber package to hold the controlValue */
-#if defined(USE_OPENLDAP)
-    if ( NULL == ( ber = ldap_alloc_ber_with_options( ld ) ) )
-#else
     if ( LDAP_SUCCESS != ldclt_alloc_ber( ld, &ber )  ) 
-#endif
     {
         return( LDAP_NO_MEMORY );
     }
@@ -4260,9 +4259,21 @@ ldclt_create_deref_control(
     }
 
 #if defined(USE_OPENLDAP)
-    rc = ldap_create_control( LDAP_CONTROL_X_DEREF, ber, 1, ctrlp );
+    if ( LBER_ERROR == ber_flatten(ber, &bv) ) {
+        ber_bvfree( bv );
+        ber_free( ber, 1 );
+        return( LDAP_ENCODING_ERROR );
+    }
+    if ( NULL == bv ) {
+        ber_free( ber, 1 );
+        return( LDAP_NO_MEMORY );
+    }
+    rc = ldap_control_create( LDAP_CONTROL_X_DEREF, 1, bv, 1, ctrlp );
+    ber_bvfree( bv );
+    ber_free( ber, 1 );
 #else
     rc = ldclt_build_control( LDAP_CONTROL_X_DEREF, ber, 1, 1, ctrlp );
+    ber_free( ber, 1 );
 #endif
 
     return( rc );
@@ -4323,6 +4334,7 @@ ldclt_build_control( char *oid, BerElement *ber, int freeber, char iscritical,
 
     return( LDAP_SUCCESS );
 }
+#endif
 
 /*
  * Duplicated nsldapi_build_control from 
@@ -4334,9 +4346,14 @@ int
 ldclt_alloc_ber( LDAP *ld, BerElement **berp )
 {
     int    err;
-
+    int beropt;
+#if defined(USE_OPENLDAP)
+    beropt = LBER_USE_DER;
+#else
+    beropt = LBER_OPT_USE_DER;
+#endif
     /* We use default lberoptions since the value is not public in mozldap. */
-     if (( *berp = ber_alloc_t( LBER_OPT_USE_DER )) == (BerElement *)NULL ) {
+     if (( *berp = ber_alloc_t( beropt )) == (BerElement *)NULL ) {
         err = LDAP_NO_MEMORY;
     } else {
         err = LDAP_SUCCESS;
@@ -4344,6 +4361,5 @@ ldclt_alloc_ber( LDAP *ld, BerElement **berp )
 
     return( err );
 }
-#endif
 
 /* End of file */