summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2009-07-31 17:06:21 +0000
committerStef Walter <stef@memberwebs.com>2009-07-31 17:06:21 +0000
commit7579c6992e07b3f4e1357d73d6bdccf9d0260c55 (patch)
treea7843e43d0751827d6411f5db7afc776b3c691b0
parent5fd6cf69da7ff8d512dfc0edd9d1996c4f6e3e87 (diff)
Switch to using bervals and minimizing memory allocation
git-svn-id: http://internal-svn-server/svn/network/slapi-suffix@1514 96c7dce7-e4ff-0310-afa0-05b99c2e9643
-rw-r--r--plugin/suffix.c186
1 files changed, 60 insertions, 126 deletions
diff --git a/plugin/suffix.c b/plugin/suffix.c
index 6327994..e8aeeca 100644
--- a/plugin/suffix.c
+++ b/plugin/suffix.c
@@ -48,19 +48,18 @@
*/
static const char *suffix_attribute = NULL;
-static const char *suffix_delimiter = NULL;
+static struct berval suffix_delimiter = { 0, NULL };
/* ---------------------------------------------------------------------------------
* LDAP OPERATIONS
*/
-static char**
+static struct berval**
entry_values (Slapi_Entry *entry, const char *name)
{
- struct berval **values, **bv;
- char **results, *result, **r;
+ struct berval **values;
Slapi_Attr *attr;
- int rc, num;
+ int rc;
/* The attribute we're after */
rc = slapi_entry_attr_find (entry, (char*)name, &attr);
@@ -72,42 +71,21 @@ entry_values (Slapi_Entry *entry, const char *name)
rc = slapi_attr_get_values (attr, &values);
return_val_if_fail (rc == 0, NULL);
- /* How many values? */
- for (bv = values, num = 0; values && *bv; ++bv)
- ++num;
-
- /* Allocate memory and copy over all values found */
- r = results = (char**)slapi_ch_calloc (num + 1, sizeof (char*));
- for (bv = values; values && *bv; ++bv) {
-
- /* Allocate a string for this value */
- result = slapi_ch_calloc ((*bv)->bv_len + 1, sizeof (char));
- if ((*bv)->bv_len)
- memcpy (result, (*bv)->bv_val, (*bv)->bv_len);
- result[(*bv)->bv_len] = 0;
-
- /* Add into array */
- *(r++) = result;
- }
-
- /* Null terminate */
- *r = NULL;
-
- return results;
+ return values;
}
-static char**
-lookup_values (const char *dn, const char *attr)
+static struct berval**
+lookup_values (const char *dn, const char *attr, Slapi_PBlock **pb)
{
Slapi_Entry **entries, *entry;
- Slapi_PBlock *pb;
LDAPControl *ctrl;
char *attrs[2];
- char **results;
+ struct berval **results;
int rc, code;
assert (dn && dn[0]);
-
+ assert (pb);
+
ctrl = NULL; /* No controls */
attrs[0] = (char*)attr;
attrs[1] = NULL;
@@ -115,23 +93,22 @@ lookup_values (const char *dn, const char *attr)
trace ("performing internal lookup");
/* Do the actual search */
- pb = slapi_search_internal ((char*)dn, LDAP_SCOPE_BASE, "(objectClass=*)", &ctrl, attrs, 0);
- return_val_if_fail (pb, NULL);
+ *pb = slapi_search_internal ((char*)dn, LDAP_SCOPE_BASE, "(objectClass=*)", &ctrl, attrs, 0);
+ return_val_if_fail (*pb, NULL);
/* Was it successful? */
code = -1;
- rc = slapi_pblock_get (pb, SLAPI_PLUGIN_INTOP_RESULT, &code);
+ rc = slapi_pblock_get (*pb, SLAPI_PLUGIN_INTOP_RESULT, &code);
return_val_if_fail (rc >= 0, NULL);
if (code != LDAP_SUCCESS) {
log_plugin ("error loading attribute %s from %s (code %d)", attr, dn, code);
- slapi_pblock_destroy (pb);
trace ("failure");
return NULL;
}
/* Dig out all the entries */
entries = NULL;
- slapi_pblock_get (pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+ slapi_pblock_get (*pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
return_val_if_fail (entries, NULL);
/* The first entry is what we're after */
@@ -139,110 +116,72 @@ lookup_values (const char *dn, const char *attr)
return_val_if_fail (entry, NULL);
results = entry_values (entry, attr);
- slapi_pblock_destroy (pb);
trace ("success");
return results;
}
-static char**
-mods_values (LDAPMod **mods, const char *name)
-{
- char **results, *result, **r;
- struct berval **bv;
- LDAPMod *mod;
- int num;
-
- assert (name);
-
- /* Count the number of values */
- for (mod = *mods; mod; mod = *(++mods)) {
- if (mod->mod_op & LDAP_MOD_DELETE ||
- strcmp (mod->mod_type, name) != 0)
- continue;
- for (bv = mod->mod_bvalues; *bv; ++bv)
- ++num;
- }
-
- /* Allocate memory and copy over all values found */
- r = results = (char**)slapi_ch_calloc (num + 1, sizeof (char*));
- for (mod = *mods; mod; mod = *(++mods)) {
- if (mod->mod_op & LDAP_MOD_DELETE ||
- strcmp (mod->mod_type, name) != 0)
- continue;
- for (bv = mod->mod_bvalues; *bv; ++bv) {
-
- /* Allocate a string for this value */
- result = slapi_ch_calloc ((*bv)->bv_len + 1, sizeof (char));
- if ((*bv)->bv_len)
- memcpy (result, (*bv)->bv_val, (*bv)->bv_len);
- result[(*bv)->bv_len] = 0;
-
- /* Add into array */
- *(r++) = result;
-
- }
- }
-
- /* Null terminate */
- *r = NULL;
-
- return results;
-}
-
static int
-has_suffix (const char *value, const char *suffix, const char *delim)
+has_suffix (struct berval *value, struct berval *suffix, struct berval *delim)
{
- size_t n_value, n_suffix, n_delim;
+ char *ptr;
assert (value);
assert (suffix);
assert (delim);
- n_value = strlen (value);
- n_suffix = strlen (suffix);
- n_delim =strlen (delim);
-
/* Must be long enough */
- if (n_value < n_suffix + n_delim)
+ if (value->bv_len < suffix->bv_len + delim->bv_len)
return 0;
+
+ ptr = value->bv_val;
/* The delim must be in the right place */
- if (memcmp (value + (n_value - (n_suffix + n_delim)), delim, n_delim) != 0)
+ if (memcmp (ptr + (value->bv_len - (suffix->bv_len + delim->bv_len)),
+ delim, delim->bv_len) != 0)
return 0;
/* And the suffix must be in the right place */
- if (memcmp (value + (n_value - n_suffix), suffix, n_suffix) != 0)
+ if (memcmp (ptr + (value->bv_len - suffix->bv_len),
+ suffix, suffix->bv_len) != 0)
return 0;
return 1;
}
static int
-check_suffix_constraints (Slapi_PBlock *pb, char **suffixes, char **values)
+check_suffix_constraints (Slapi_PBlock *pb, struct berval **suffixes, struct berval **values)
{
- char **val, **suffix;
+ struct berval *value, *suffix;
+ char string[128];
char msg[512];
int found;
assert (pb);
+ /* When parent has no suffixes, then any are allowed */
if (!values || !suffixes)
return 0;
- for (val = values; *val; ++val) {
+ for (value = *values; value; value = *(++values)) {
found = 0;
- for (suffix = suffixes; *suffix; ++suffix) {
- if (has_suffix (*val, *suffix, suffix_delimiter)) {
+ for (suffix = *suffixes; suffix; suffix = *(++suffixes)) {
+ if (has_suffix (value, suffix, &suffix_delimiter)) {
found = 1;
break;
}
}
if (!found) {
+ /* Null terminate the value for the message below */
+ strncpy (string, value->bv_val,
+ value->bv_len >= sizeof (string) ? sizeof (string) : value->bv_len);
+ string[sizeof(string) - 1] = 0;
+
+ /* Build and return our error message */
snprintf (msg, sizeof (msg),
"The value '%s' for the %s attribute does not have a valid suffix",
- *val, suffix_attribute);
+ string, suffix_attribute);
slapi_send_ldap_result (pb, LDAP_CONSTRAINT_VIOLATION, NULL, msg, 0, NULL);
return -1;
}
@@ -254,9 +193,10 @@ check_suffix_constraints (Slapi_PBlock *pb, char **suffixes, char **values)
int
suffix_pre_add (Slapi_PBlock *pb, const char *dn)
{
+ struct berval **suffixes;
+ struct berval **values;
+ Slapi_PBlock *ipb = NULL;
Slapi_Entry *entry;
- char **suffixes;
- char **values;
char *parent;
int rc = 0;
@@ -266,15 +206,9 @@ suffix_pre_add (Slapi_PBlock *pb, const char *dn)
parent = slapi_dn_parent (dn);
return_val_if_fail (parent, -1);
- suffixes = lookup_values (parent, suffix_attribute);
+ suffixes = lookup_values (parent, suffix_attribute, &ipb);
slapi_ch_free_string (&parent);
-
- /* When parent has no suffixes, then any are allowed */
- if (!suffixes || !suffixes[0]) {
- slapi_ch_array_free (suffixes);
- return 0;
- }
-
+
/* The entry itself */
rc = slapi_pblock_get (pb, SLAPI_ADD_ENTRY, &entry);
return_val_if_fail (rc >= 0 && entry, -1);
@@ -283,8 +217,8 @@ suffix_pre_add (Slapi_PBlock *pb, const char *dn)
values = entry_values (entry, suffix_attribute);
rc = check_suffix_constraints (pb, suffixes, values);
- slapi_ch_array_free (suffixes);
- slapi_ch_array_free (values);
+ return_val_if_fail (ipb, -1);
+ slapi_pblock_destroy (ipb);
return rc;
}
@@ -292,9 +226,9 @@ suffix_pre_add (Slapi_PBlock *pb, const char *dn)
int
suffix_pre_modify (Slapi_PBlock *pb, const char *dn)
{
- char **suffixes;
- LDAPMod **mods;
- char **values;
+ struct berval **suffixes;
+ Slapi_PBlock *ipb = NULL;
+ LDAPMod **mods, *mod;
char *parent;
int rc = 0;
@@ -304,25 +238,22 @@ suffix_pre_modify (Slapi_PBlock *pb, const char *dn)
parent = slapi_dn_parent (dn);
return_val_if_fail (parent, -1);
- suffixes = lookup_values (parent, suffix_attribute);
+ suffixes = lookup_values (parent, suffix_attribute, &ipb);
slapi_ch_free_string (&parent);
- /* When parent has no suffixes, then any are allowed */
- if (!suffixes || !suffixes[0]) {
- slapi_ch_array_free (suffixes);
- return 0;
- }
-
/* The modifications being made */
rc = slapi_pblock_get (pb, SLAPI_MODIFY_MODS, &mods);
return_val_if_fail (rc >= 0 && mods, -1);
-
- /* Extract the various values from the entry */
- values = mods_values (mods, suffix_attribute);
- rc = check_suffix_constraints (pb, suffixes, values);
- slapi_ch_array_free (suffixes);
- slapi_ch_array_free (values);
+ /* Validate the values */
+ for (mod = *mods; rc == 0 && mod; mod = *(++mods)) {
+ if (!(mod->mod_op & LDAP_MOD_DELETE) &&
+ strcmp (mod->mod_type, suffix_attribute) == 0)
+ rc = check_suffix_constraints (pb, suffixes, mod->mod_bvalues);
+ }
+
+ return_val_if_fail (ipb, -1);
+ slapi_pblock_destroy (ipb);
return rc;
}
@@ -336,6 +267,9 @@ suffix_config (const char *name, const char *value)
suffix_attribute = value;
return 1;
+ } else if (strcmp ("suffix-delimiter", name) == 0 && value) {
+ suffix_delimiter.bv_val = (void*)value;
+ suffix_delimiter.bv_len = strlen (value);
}
return 0;