From 7579c6992e07b3f4e1357d73d6bdccf9d0260c55 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Fri, 31 Jul 2009 17:06:21 +0000 Subject: 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 --- plugin/suffix.c | 186 ++++++++++++++++++-------------------------------------- 1 file 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; -- cgit v1.2.3