summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2010-04-26 11:03:52 -0700
committerNoriko Hosoi <nhosoi@redhat.com>2010-04-26 11:03:52 -0700
commit78c50664d6421cc5d0836bb03820680dc2cb7acf (patch)
tree20fcfadad9057617daa0b159216f0a92006969f5
parent4754291972668c37559a8f68d75ac6f8c477efb8 (diff)
downloadds-78c50664d6421cc5d0836bb03820680dc2cb7acf.tar.gz
ds-78c50664d6421cc5d0836bb03820680dc2cb7acf.tar.xz
ds-78c50664d6421cc5d0836bb03820680dc2cb7acf.zip
Update to New DN Format
Fix Description: . adding slapi_dn_normalize_ext and its siblings to normalize/validate invalid DNs; deprecating slapi_dn_normalize and its siblings. (dn.c) . replacing slapi_dn_normalize with new corresponding functions. . normalizing hardcoded DNs (e.g., removing spaces around ',') . setting correct DN syntax to nsslapd-suffix, nsslapd-ldapiautodnsuffix, costemplatedn, nsslapd-changelogsuffix, nsBaseDN, nsBindDN . if nsslapd-dn-validate-strict is enabled, incoming DN is examined and rejected if it is invalid. Once approved, the DN is normalized. . fixing compiler warnings and typos. See also: http://directory.fedoraproject.org/wiki/Upgrade_to_New_DN_Format Related bugs: Bug 199923 - subtree search fails to find items under a db containing special characters Bug 567968 - subtree/user level password policy created using 389-ds-console doesn't work. Bug 570107 - The import of LDIFs with base-64 encoded DNs fails, modrdn with non-ASCII new rdn incorrect Bug 570962 - ns-inactivate.pl does not work Bug 572785 - DN syntax: old style of DN <type>="<DN>",<the_rest> is not correctly normalized Bug 573060 - DN normalizer: ESC HEX HEX is not normalized Bug 574167 - An escaped space at the end of the RDN value is not handled correctly
-rw-r--r--ldap/admin/src/scripts/Migration.pm.in2
-rw-r--r--ldap/admin/src/scripts/Setup.pm.in2
-rw-r--r--ldap/schema/01core389.ldif2
-rw-r--r--ldap/schema/02common.ldif3
-rw-r--r--ldap/schema/30ns-common.ldif4
-rw-r--r--ldap/servers/plugins/acl/acl.c56
-rw-r--r--ldap/servers/plugins/acl/acl.h7
-rw-r--r--ldap/servers/plugins/acl/acl_ext.c2
-rw-r--r--ldap/servers/plugins/acl/aclanom.c1
-rw-r--r--ldap/servers/plugins/acl/acleffectiverights.c47
-rw-r--r--ldap/servers/plugins/acl/acllas.c201
-rw-r--r--ldap/servers/plugins/acl/aclparse.c386
-rw-r--r--ldap/servers/plugins/acl/aclproxy.c17
-rw-r--r--ldap/servers/plugins/acl/aclutil.c66
-rw-r--r--ldap/servers/plugins/chainingdb/cb_config.c10
-rw-r--r--ldap/servers/plugins/chainingdb/cb_init.c4
-rw-r--r--ldap/servers/plugins/chainingdb/cb_instance.c8
-rw-r--r--ldap/servers/plugins/cos/cos_cache.c127
-rw-r--r--ldap/servers/plugins/dna/dna.c53
-rw-r--r--ldap/servers/plugins/linkedattrs/fixup_task.c4
-rw-r--r--ldap/servers/plugins/mep/mep.c4
-rw-r--r--ldap/servers/plugins/pwdstorage/smd5_pwd.c4
-rw-r--r--ldap/servers/plugins/referint/referint.c37
-rw-r--r--ldap/servers/plugins/replication/legacy_consumer.c1
-rw-r--r--ldap/servers/plugins/replication/repl5.h2
-rw-r--r--ldap/servers/plugins/replication/repl5_agmt.c19
-rw-r--r--ldap/servers/plugins/replication/repl5_agmtlist.c3
-rw-r--r--ldap/servers/plugins/replication/repl5_protocol.c1
-rw-r--r--ldap/servers/plugins/replication/repl5_replica.c27
-rw-r--r--ldap/servers/plugins/replication/repl5_replica_config.c1
-rw-r--r--ldap/servers/plugins/replication/repl_init.c1
-rw-r--r--ldap/servers/plugins/retrocl/retrocl.c1
-rw-r--r--ldap/servers/plugins/retrocl/retrocl_create.c13
-rw-r--r--ldap/servers/plugins/syntaxes/string.c166
-rw-r--r--ldap/servers/plugins/syntaxes/syntax.h1
-rw-r--r--ldap/servers/plugins/syntaxes/validate.c12
-rw-r--r--ldap/servers/plugins/syntaxes/value.c90
-rw-r--r--ldap/servers/plugins/usn/usn_cleanup.c11
-rw-r--r--ldap/servers/slapd/add.c53
-rw-r--r--ldap/servers/slapd/attrlist.c6
-rw-r--r--ldap/servers/slapd/attrsyntax.c17
-rw-r--r--ldap/servers/slapd/auth.c50
-rw-r--r--ldap/servers/slapd/back-ldbm/import-threads.c1
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c19
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_config.c90
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_index_config.c50
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_instance_config.c167
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_modrdn.c7
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_search.c1
-rw-r--r--ldap/servers/slapd/back-ldbm/ldif2ldbm.c1
-rw-r--r--ldap/servers/slapd/back-ldbm/misc.c4
-rw-r--r--ldap/servers/slapd/back-ldbm/nextid.c2
-rw-r--r--ldap/servers/slapd/back-ldbm/vlv.c78
-rw-r--r--ldap/servers/slapd/backend.c28
-rw-r--r--ldap/servers/slapd/backend_manager.c6
-rw-r--r--ldap/servers/slapd/bind.c34
-rw-r--r--ldap/servers/slapd/compare.c31
-rw-r--r--ldap/servers/slapd/delete.c31
-rw-r--r--ldap/servers/slapd/dn.c791
-rw-r--r--ldap/servers/slapd/entry.c254
-rw-r--r--ldap/servers/slapd/entrywsi.c9
-rw-r--r--ldap/servers/slapd/extendop.c37
-rw-r--r--ldap/servers/slapd/fedse.c1
-rw-r--r--ldap/servers/slapd/libglobs.c11
-rw-r--r--ldap/servers/slapd/main.c4
-rw-r--r--ldap/servers/slapd/mapping_tree.c89
-rw-r--r--ldap/servers/slapd/modify.c35
-rw-r--r--ldap/servers/slapd/modrdn.c108
-rw-r--r--ldap/servers/slapd/modutil.c30
-rw-r--r--ldap/servers/slapd/passwd_extop.c35
-rw-r--r--ldap/servers/slapd/plugin.c26
-rw-r--r--ldap/servers/slapd/plugin_syntax.c2
-rw-r--r--ldap/servers/slapd/search.c35
-rw-r--r--ldap/servers/slapd/slap.h4
-rw-r--r--ldap/servers/slapd/slapi-plugin.h67
-rw-r--r--ldap/servers/slapd/slapi-private.h2
-rw-r--r--ldap/servers/slapd/snmp_collator.c3
-rw-r--r--ldap/servers/slapd/task.c50
-rw-r--r--ldap/servers/slapd/tools/dbscan.c2
-rw-r--r--ldap/servers/slapd/tools/ldclt/ldclt.h1
-rw-r--r--ldap/servers/slapd/util.c98
-rw-r--r--ldap/servers/slapd/value.c26
-rw-r--r--ldap/servers/slapd/valueset.c14
83 files changed, 3023 insertions, 783 deletions
diff --git a/ldap/admin/src/scripts/Migration.pm.in b/ldap/admin/src/scripts/Migration.pm.in
index 44613a80..1942c8b2 100644
--- a/ldap/admin/src/scripts/Migration.pm.in
+++ b/ldap/admin/src/scripts/Migration.pm.in
@@ -125,7 +125,7 @@ You can supply default .inf data in this format:
e.g.
General.FullMachineName=foo.example.com
or
- "slapd.Suffix=dc=example, dc=com"
+ "slapd.Suffix=dc=example,dc=com"
Values passed in this manner will override values in an .inf file
given with the -f argument.
diff --git a/ldap/admin/src/scripts/Setup.pm.in b/ldap/admin/src/scripts/Setup.pm.in
index 021a99c7..52300db0 100644
--- a/ldap/admin/src/scripts/Setup.pm.in
+++ b/ldap/admin/src/scripts/Setup.pm.in
@@ -110,7 +110,7 @@ You can supply default .inf data in this format:
e.g.
General.FullMachineName=foo.example.com
or
- "slapd.Suffix=dc=example, dc=com"
+ "slapd.Suffix=dc=example,dc=com"
Values passed in this manner will override values in an .inf file given with the -f argument.
EOF
}
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index af445e7c..96e70a86 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -122,6 +122,8 @@ attributeTypes: ( nsSSLSupportedCiphers-oid NAME 'nsSSLSupportedCiphers' DESC 'N
attributeTypes: ( nsSSLToken-oid NAME 'nsSSLToken' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSLPersonalitySSL-oid NAME 'nsSSLPersonalitySSL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSLActivation-oid NAME 'nsSSLActivation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2091 NAME 'nsslapd-suffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2092 NAME 'nsslapd-ldapiautodnsuffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
#
# objectclasses
#
diff --git a/ldap/schema/02common.ldif b/ldap/schema/02common.ldif
index 7ea5594d..5269d3bd 100644
--- a/ldap/schema/02common.ldif
+++ b/ldap/schema/02common.ldif
@@ -110,7 +110,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.223 NAME ( 'passwordResetFailureCount' '
attributeTypes: ( 2.16.840.1.113730.3.1.550 NAME 'cosAttribute' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.551 NAME 'cosspecifier' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.552 NAME 'costargettree' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.553 NAME 'costemplatedn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.553 NAME 'costemplatedn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.35 NAME 'changeLog' DESC 'the distinguished name of the entry which contains the set of entries comprising this servers changelog' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Changelog Internet Draft' )
attributeTypes: ( 2.16.840.1.113730.3.1.200 NAME 'changeLogMaximumAge' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.201 NAME 'changeLogMaximumSize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
@@ -144,6 +144,7 @@ attributeTypes: ( 1.3.6.1.1.4 NAME 'vendorName' EQUALITY 1.3.6.1.4.1.1466.109.11
attributeTypes: ( 1.3.6.1.1.5 NAME 'vendorVersion' EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation X-ORIGIN 'RFC 3045' )
attributeTypes: ( 2.16.840.1.113730.3.1.3023 NAME 'nsViewFilter' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2063 NAME 'nsEncryptionAlgorithm' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2093 NAME 'nsslapd-changelogsuffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
#
# objectclasses:
#
diff --git a/ldap/schema/30ns-common.ldif b/ldap/schema/30ns-common.ldif
index a6b109d8..cee5a07b 100644
--- a/ldap/schema/30ns-common.ldif
+++ b/ldap/schema/30ns-common.ldif
@@ -42,8 +42,8 @@
#
dn: cn=schema
attributeTypes: ( nsServerID-oid NAME 'nsServerID' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
-attributeTypes: ( nsBaseDN-oid NAME 'nsBaseDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
-attributeTypes: ( nsBindDN-oid NAME 'nsBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( nsBaseDN-oid NAME 'nsBaseDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
+attributeTypes: ( nsBindDN-oid NAME 'nsBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
attributeTypes: ( nsBindPassword-oid NAME 'nsBindPassword' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsServerPort-oid NAME 'nsServerPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsServerAddress-oid NAME 'nsServerAddress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index aa22d566..715ad1ea 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -358,8 +358,8 @@ acl_access_allowed(
if (oid && ((strcasecmp(oid, DN_SYNTAX_OID) == 0) ||
(strcasecmp(oid, NAMEANDOPTIONALUID_SYNTAX_OID) == 0))) {
/* should use slapi_sdn_compare() but that'a an extra malloc/free */
- char *dn_val_to_write = slapi_dn_normalize(slapi_ch_strdup(val->bv_val));
- if ( aclpb->aclpb_authorization_sdn &&
+ char *dn_val_to_write = slapi_create_dn_string("%s", val->bv_val);
+ if ( dn_val_to_write && aclpb->aclpb_authorization_sdn &&
slapi_utf8casecmp((ACLUCHP)dn_val_to_write, (ACLUCHP)
slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)) == 0) {
access |= SLAPI_ACL_SELF;
@@ -754,9 +754,10 @@ static void print_access_control_summary( char *source, int ret_val, char *clien
if ( aclpb->aclpb_authorization_sdn != NULL ) {
- proxy_user = (char *)(aclpb->aclpb_authorization_sdn->ndn ?
- aclpb->aclpb_authorization_sdn->ndn:
- null_user);
+ proxy_user =
+ (char *)(slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)?
+ slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn):
+ null_user);
slapi_log_error(loglevel, plugin_name,
"conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)"
@@ -1764,8 +1765,7 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
if (parent_DN == NULL) {
new_DN = new_RDN;
} else {
- new_DN = slapi_ch_smprintf("%s,%s", new_RDN, parent_DN);
- slapi_dn_normalize (new_DN);
+ new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
}
/* Change the acls */
@@ -2028,8 +2028,7 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
** We have a single ACI which we need to find if it applies to
** the resource or not.
*/
- if ((aci->aci_type & ACI_TARGET_DN) &&
- (aclpb->aclpb_curr_entry_sdn)) {
+ if ((aci->aci_type & ACI_TARGET_DN) && (aclpb->aclpb_curr_entry_sdn)) {
char *avaType;
struct berval *avaValue;
@@ -2246,10 +2245,10 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
*
*/
- if ((aclpb->aclpb_access & SLAPI_ACL_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS )||
- (aclpb->aclpb_access & SLAPI_ACL_DELETE &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS ) ) {
+ if (((aclpb->aclpb_access & SLAPI_ACL_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) )||
+ ((aclpb->aclpb_access & SLAPI_ACL_DELETE) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS) ) ) {
Targetattrfilter **attrFilterArray;
@@ -2367,10 +2366,10 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
goto acl__resource_match_aci_EXIT;
}
- } else if ( (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) ||
- (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS ) ) {
+ } else if ( ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) ||
+ ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)) ) {
/*
@@ -2381,28 +2380,28 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
* match that filter.
*
*
- */
+ */
Targetattrfilter **attrFilterArray = NULL;
Targetattrfilter *attrFilter;
int found = 0;
- if (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) {
+ if ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) {
- attrFilterArray = aci->targetAttrAddFilters;
+ attrFilterArray = aci->targetAttrAddFilters;
- } else if (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS) {
+ } else if ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)) {
- attrFilterArray = aci->targetAttrDelFilters;
+ attrFilterArray = aci->targetAttrDelFilters;
}
/*
* Scan this filter list for an applicable filter.
- */
+ */
found = 0;
num_attrs = 0;
@@ -2435,7 +2434,7 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
attr_matched= acl__test_filter(aclpb->aclpb_filter_test_entry,
attrFilter->filter,
1 /* Do filter sense evaluation below */
- );
+ );
slapi_entry_free( aclpb->aclpb_filter_test_entry );
}
@@ -2452,8 +2451,6 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
*/
attr_matched_in_targetattrfilters = 1;
-
-
}
} /* targetvaluefilters */
@@ -3233,9 +3230,6 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
realval = tmp;
}
- slapi_dn_normalize (realval);
-
-
/* What we have built is a regular pattaren expression.
** Now we will compile the pattern and compare wth the string to
** see if the input string matches with the patteren or not.
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index 36bdd43c..3f4b4e62 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -119,7 +119,11 @@ static char* const aci_targetattr = "targetattr";
static char* const aci_targetattrfilters = "targattrfilters";
static char* const aci_targetfilter = "targetfilter";
+static char* const LDAP_URL_prefix_core = "ldap://";
+static char* const LDAPS_URL_prefix_core = "ldaps://";
+
static char* const LDAP_URL_prefix = "ldap:///";
+static char* const LDAPS_URL_prefix = "ldaps:///";
static char* const access_str_compare = "compare";
static char* const access_str_search = "search";
@@ -827,7 +831,7 @@ int acl_skip_access_check ( Slapi_PBlock *pb, Slapi_Entry *e );
int aclext_alloc_lockarray ();
-int aclutil_str_appened(char **str1, const char *str2);
+int aclutil_str_append(char **str1, const char *str2);
void aclutil_print_err (int rv , const Slapi_DN *sdn,
const struct berval* val, char **errbuf);
void aclutil_print_aci (aci_t *aci_item, char *type);
@@ -911,6 +915,7 @@ acl_replace_str(char * s, char *substr, char* replace_with);
int acl_strstr(char * s, char *substr);
int aclutil_evaluate_macro( char * rule, lasInfo *lasinfo,
acl_eval_types evalType );
+int aclutil_str_append_ext(char **dest, size_t *dlen, const char *src, size_t slen);
/* acl hash table functions */
void acl_ht_add_and_freeOld(acl_ht_t * acl_ht, PLHashNumber key,char *value);
diff --git a/ldap/servers/plugins/acl/acl_ext.c b/ldap/servers/plugins/acl/acl_ext.c
index 5e1d360b..d9494ec3 100644
--- a/ldap/servers/plugins/acl/acl_ext.c
+++ b/ldap/servers/plugins/acl/acl_ext.c
@@ -791,7 +791,7 @@ acl__done_aclpb ( struct acl_pblock *aclpb )
*/
/* Nothing needs to be cleaned up in this case */
- if ( !aclpb->aclpb_state & ACLPB_INITIALIZED)
+ if (!(aclpb->aclpb_state & ACLPB_INITIALIZED))
return;
/* Check the state */
diff --git a/ldap/servers/plugins/acl/aclanom.c b/ldap/servers/plugins/acl/aclanom.c
index 773dad2f..b1d15ca1 100644
--- a/ldap/servers/plugins/acl/aclanom.c
+++ b/ldap/servers/plugins/acl/aclanom.c
@@ -205,6 +205,7 @@ aclanom_gen_anomProfile (acl_lock_flag_t lock_flag)
/* see if this is a monitor acl */
if (( strcasecmp ( dn, "cn=monitor") == 0 ) ||
+ /* cn=monitor,cn=ldbm: No such object */
( strcasecmp ( dn, "cn=monitor,cn=ldbm") == 0 )) {
aci = acllist_get_next_aci ( NULL, aci, &cookie);
continue;
diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c
index 9afac079..acf856cc 100644
--- a/ldap/servers/plugins/acl/acleffectiverights.c
+++ b/ldap/servers/plugins/acl/acleffectiverights.c
@@ -170,7 +170,7 @@ _ger_g_permission_granted (
goto bailout;
}
- aclutil_str_appened ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
+ aclutil_str_append ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
slapi_log_error (SLAPI_LOG_ACL, plugin_name,
"_ger_g_permission_granted: %s\n", *errbuf);
rc = LDAP_INSUFFICIENT_ACCESS;
@@ -195,7 +195,10 @@ _ger_parse_control (
LDAPControl **requestcontrols;
struct berval *subjectber;
BerElement *ber;
- int subjectndnlen = 0;
+ size_t subjectndnlen = 0;
+ char *orig = NULL;
+ char *normed = NULL;
+ int rc = 0;
if (NULL == subjectndn)
{
@@ -215,7 +218,7 @@ _ger_parse_control (
if ( subjectber == NULL || subjectber->bv_val == NULL ||
subjectber->bv_len == 0 )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: missing subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: missing subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
return LDAP_INVALID_SYNTAX;
}
@@ -227,23 +230,23 @@ _ger_parse_control (
* or base64 encoding string. Hence users using -J option in
* ldapsearch don't have to do BER encoding for the subject.
*/
- *subjectndn = slapi_ch_malloc ( subjectber->bv_len + 1 );
- strncpy ( *subjectndn, subjectber->bv_val, subjectber->bv_len );
- *(*subjectndn + subjectber->bv_len) = '\0';
+ orig = slapi_ch_malloc ( subjectber->bv_len + 1 );
+ strncpy ( orig, subjectber->bv_val, subjectber->bv_len );
+ *(orig + subjectber->bv_len) = '\0';
}
else
{
ber = ber_init (subjectber);
if ( ber == NULL )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: ber_init failed for the subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: ber_init failed for the subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
return LDAP_OPERATIONS_ERROR;
}
/* "a" means to allocate storage as needed for octet string */
- if ( ber_scanf (ber, "a", subjectndn) == LBER_ERROR )
+ if ( ber_scanf (ber, "a", orig) == LBER_ERROR )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
ber_free ( ber, 1 );
return LDAP_INVALID_SYNTAX;
@@ -256,18 +259,32 @@ _ger_parse_control (
* (see section 9 of RFC 2829) only. It also only supports the "dnAuthzId"
* flavor, which looks like "dn:<DN>" where null <DN> is for anonymous.
*/
- subjectndnlen = strlen(*subjectndn);
- if ( NULL == *subjectndn || subjectndnlen < 3 ||
- strncasecmp ( "dn:", *subjectndn, 3 ) != 0 )
+ subjectndnlen = strlen(orig);
+ if ( NULL == orig || subjectndnlen < 3 || strncasecmp ( "dn:", orig, 3 ) != 0 )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
+ aclutil_str_append ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
+ slapi_ch_free_string(&orig);
return LDAP_INVALID_SYNTAX;
}
/* memmove is safe for overlapping copy */
- memmove ( *subjectndn, *subjectndn + 3, subjectndnlen - 2);/* 1 for '\0' */
- slapi_dn_normalize ( *subjectndn );
+ rc = slapi_dn_normalize_ext(orig + 3, 0, &normed, &subjectndnlen);
+ if (rc < 0) {
+ aclutil_str_append ( errbuf, "get-effective-rights: failed to normalize dn: ");
+ aclutil_str_append ( errbuf, orig);
+ slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
+ slapi_ch_free_string(&orig);
+ return LDAP_INVALID_SYNTAX;
+ }
+ if (rc == 0) { /* orig+3 is passed in; not terminated */
+ *(normed + subjectndnlen) = '\0';
+ *subjectndn = slapi_ch_strdup(normed);
+ slapi_ch_free_string(&orig);
+ } else {
+ slapi_ch_free_string(&orig);
+ *subjectndn = normed;
+ }
return LDAP_SUCCESS;
}
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index 9a57d7c8..9fbd25bb 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -480,6 +480,7 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
int rc;
short len;
const size_t LDAP_URL_prefix_len = strlen(LDAP_URL_prefix);
+ const size_t LDAPS_URL_prefix_len = strlen(LDAPS_URL_prefix);
lasInfo lasinfo;
int got_undefined = 0;
@@ -530,15 +531,15 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
** userdn = "ldap:///DN1 || ldap:///DN2"
*/
-
/* The DN is now "ldap:///DN"
** remove the "ldap:///" part
*/
- if (strncasecmp (user, LDAP_URL_prefix,
- LDAP_URL_prefix_len) == 0) {
+ if (strncasecmp (user, LDAP_URL_prefix, LDAP_URL_prefix_len) == 0) {
s_user = user;
user += LDAP_URL_prefix_len;
-
+ } else if (strncasecmp (user, LDAPS_URL_prefix, LDAPS_URL_prefix_len) == 0) {
+ s_user = user;
+ user += LDAPS_URL_prefix_len;
} else {
char ebuf[ BUFSIZ ];
slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
@@ -677,8 +678,19 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
slapi_filter_free(f,1);
} else {
/* Must be a simple dn then */
- if (slapi_utf8casecmp((ACLUCHP)lasinfo.clientDn,
- (ACLUCHP)slapi_dn_normalize(user)) == 0) {
+ char *normed = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(user, 0, &normed, &dnlen);
+ if (rc == 0) { /* user passed in; not terminated */
+ *(normed + dnlen) = '\0';
+ } else if (rc < 0) { /* normalization failed, user the original */
+ normed = user;
+ }
+ rc = slapi_utf8casecmp((ACLUCHP)lasinfo.clientDn, (ACLUCHP)normed);
+ if (normed != user) {
+ slapi_ch_free_string(&normed);
+ }
+ if (0 == rc) {
matched = ACL_TRUE;
break;
}
@@ -1274,8 +1286,14 @@ DS_LASUserDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
while ( j != -1 ) {
attrVal = slapi_value_get_berval ( sval );
/* Here if atleast 1 value matches then we are done.*/
- val = slapi_dn_normalize (
- slapi_ch_strdup( attrVal->bv_val));
+ val = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == val) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASUserDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ slapi_ch_free ( (void**) &s_attrName);
+ return LAS_EVAL_FAIL;
+ }
if (slapi_utf8casecmp((ACLUCHP)val, (ACLUCHP)lasinfo.clientDn ) == 0) {
char ebuf [ BUFSIZ ];
@@ -2380,7 +2398,13 @@ acllas__handle_group_entry (Slapi_Entry* e, void *callback_data)
while ( i != -1 ) {
struct member_info *groupMember = NULL;
attrVal = slapi_value_get_berval ( sval );
- n_dn = slapi_dn_normalize ( slapi_ch_strdup( attrVal->bv_val ));
+ n_dn = slapi_create_dn_string( attrVal->bv_val );
+ if (NULL == n_dn) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__handle_group_entry: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
n = ++info->lu_idx;
if (n < 0) {
slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
@@ -2433,7 +2457,14 @@ acllas__handle_group_entry (Slapi_Entry* e, void *callback_data)
*/
if (strncasecmp( attrVal->bv_val, "ldap://",7) == 0 ||
strncasecmp( attrVal->bv_val, "ldaps://",8) == 0) {
- savURL = memberURL = slapi_ch_strdup ( attrVal->bv_val);
+ savURL = memberURL =
+ slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == savURL) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__handle_group_entry: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
slapi_log_error( SLAPI_LOG_ACL, plugin_name,
"ACL Group Eval:MemberURL:%s\n", memberURL);
info->result = acllas__client_match_URL (
@@ -2656,8 +2687,13 @@ DS_LASGroupDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
attr_i= slapi_attr_first_value ( attr,&sval );
while ( attr_i != -1 ) {
attrVal = slapi_value_get_berval ( sval );
- n_groupdn = slapi_dn_normalize(
- slapi_ch_strdup( attrVal->bv_val));
+ n_groupdn = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_groupdn) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASGroupDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
matched = acllas__user_ismember_of_group (
lasinfo.aclpb, n_groupdn, lasinfo.clientDn,
ACLLAS_CACHE_MEMBER_GROUPS,
@@ -2855,6 +2891,7 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
char *curMemberDn;
int Done = 0;
int ngr, tt;
+ char *normed = NULL;
/* Add the scope to the list of scopes */
if (aclpb->aclpb_numof_bases >= (aclpb->aclpb_grpsearchbase_size-1)) {
@@ -2866,9 +2903,15 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
sizeof (char *));
aclpb->aclpb_grpsearchbase_size += ACLPB_INCR_BASES;
}
- aclpb->aclpb_grpsearchbase[aclpb->aclpb_numof_bases++] =
- slapi_dn_normalize(slapi_ch_strdup(base));
-
+ normed = slapi_create_dn_string("%s", base);
+ if (NULL == normed) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__eval_memberGroupDnAttr: Invalid syntax: %s\n",
+ base );
+ slapi_ch_free ( (void **)&s_str );
+ return ACL_FALSE;
+ }
+ aclpb->aclpb_grpsearchbase[aclpb->aclpb_numof_bases++] = normed;
/* Set up info to do a search */
attrs[0] = type_member;
attrs[1] = type_uniquemember;
@@ -2991,8 +3034,14 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
while ( k != -1 ) {
char *n_attrval;
attrVal = slapi_value_get_berval ( sval );
- n_attrval = slapi_ch_strdup( attrVal->bv_val);
- n_attrval = slapi_dn_normalize (n_attrval);
+ n_attrval = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_attrval) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__eval_memberGroupDnAttr: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ slapi_ch_free ( (void **)&s_str );
+ return ACL_FALSE;
+ }
/* We support: The attribute value can be a USER or a GROUP.
** Let's compare with the client, thi might be just an user. If it is not
@@ -3147,7 +3196,13 @@ acllas__verify_client (Slapi_Entry* e, void *callback_data)
i = slapi_attr_first_value ( attr,&sval );
while ( i != -1 ) {
attrVal = slapi_value_get_berval ( sval );
- val = slapi_dn_normalize(slapi_ch_strdup(attrVal->bv_val));
+ val = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == val) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__verify_client: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
if (slapi_utf8casecmp((ACLUCHP)val, (ACLUCHP)info->clientdn ) == 0) {
info->result = 1;
@@ -3235,7 +3290,12 @@ acllas__get_members (Slapi_Entry* e, void *callback_data)
i = slapi_attr_first_value ( attr,&sval );
while ( i != -1 ) {
attrVal =slapi_value_get_berval ( sval );
- info->member[i] = slapi_dn_normalize ( slapi_ch_strdup(attrVal->bv_val));
+ info->member[i] = slapi_create_dn_string ("%s", attrVal->bv_val);
+ if (NULL == info->member[i]) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__get_members: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ }
i = slapi_attr_next_value ( attr, i, &sval );
}
return 0;
@@ -3426,7 +3486,17 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
LDAPURLDesc *ludp;
int rc;
Slapi_Filter *f = NULL;
-
+ char *rawdn = NULL;
+ char *dn = NULL;
+ size_t dnlen = 0;
+ char *p = NULL;
+ char *normed = NULL;
+ /* ldap(s)://host:port/suffix?attrs?scope?filter */
+ const size_t LDAP_URL_prefix_len = strlen(LDAP_URL_prefix_core);
+ const size_t LDAPS_URL_prefix_len = strlen(LDAPS_URL_prefix_core);
+ size_t prefix_len = 0;
+ char Q = '?';
+ char *hostport = NULL;
/* Get the client's entry if we don't have already */
if ( aclpb && ( NULL == aclpb->aclpb_client_entry )) {
@@ -3459,23 +3529,83 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
}
if ( NULL == aclpb->aclpb_client_entry ) {
- slapi_log_error ( SLAPI_LOG_ACL, plugin_name,
- "DS_LASUserAttrEval: Unable to get client's entry\n");
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: Unable to get client's entry\n");
return ACL_FALSE;
}
- if (( rc = ldap_url_parse( url, &ludp)) != 0 ) {
+ /* DN potion of URL must be normalized before calling ldap_url_parse.
+ * lud_dn is pointing at the middle of lud_string.
+ * lud_dn won't be freed in ldap_free_urldesc.
+ */
+ /* remove the "ldap{s}:///" part */
+ if (strncasecmp (url, LDAP_URL_prefix, LDAP_URL_prefix_len) == 0) {
+ prefix_len = LDAP_URL_prefix_len;
+ } else if (strncasecmp (url, LDAPS_URL_prefix, LDAPS_URL_prefix_len) == 0) {
+ prefix_len = LDAPS_URL_prefix_len;
+ } else {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: url %s does not include ldap prefix: %s\n", url);
+ return ACL_FALSE;
+ }
+ rawdn = url + prefix_len; /* ldap(s)://host:port/... or ldap(s):///... */
+ /* rawdn at ^ or ^ */
+ /* let rawdn point the suffix */
+ if ('/' == *(rawdn+1)) { /* ldap(s):/// */
+ rawdn += 2;
+ hostport = "/";
+ } else {
+ char *tmpp = rawdn;
+ rawdn = strchr(tmpp, '/');
+ size_t hostport_len = 0;
+ if (NULL == rawdn) {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: url %s does not include correct ldap prefix: %s\n", url);
+ return ACL_FALSE;
+ }
+ hostport_len = ++rawdn - tmpp; /* ldap(s)://host:port/... */
+ /* <--------> */
+ hostport = (char *)slapi_ch_malloc(hostport_len + 1);
+ memcpy(hostport, tmpp, hostport_len);
+ *(hostport+hostport_len) = '\0';
+ }
+ p = strchr(rawdn, Q);
+ if (p) {
+ /* url has scope and/or filter: ldap(s):///suffix?attr?scope?filter */
+ *p = '\0';
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__client_match_URL: Invalid syntax: %s\n", url);
+ return ACL_FALSE;
+ } else if (rc == 0) { /* url is passed in and not terminated with NULL*/
+ *(dn + dnlen) = '\0';
+ }
+ if (p) {
+ *p = Q;
+ }
+ normed = slapi_ch_smprintf("%s%s%s%s",
+ (prefix_len==LDAP_URL_prefix_len)?
+ LDAP_URL_prefix_core:LDAPS_URL_prefix_core,
+ hostport, dn, p?p:"");
+ if (rc > 0) {
+ /* dn was allocated in slapi_dn_normalize_ext */
+ slapi_ch_free_string(&dn);
+ }
+ if ('/' != *hostport) {
+ slapi_ch_free_string(&hostport);
+ }
+ rc = ldap_url_parse(normed, &ludp);
+ slapi_ch_free_string(&normed);
+ if (rc) {
return ACL_FALSE;
-
}
if ( ( NULL == ludp->lud_dn) || ( NULL == ludp->lud_filter) ) {
ldap_free_urldesc( ludp );
return ACL_FALSE;
}
- /* Normalize in place the dn */
- slapi_dn_normalize ( ludp->lud_dn );
-
/* Check the scope */
if ( ludp->lud_scope == LDAP_SCOPE_SUBTREE ) {
if (!slapi_dn_issuffix(n_clientdn, ludp->lud_dn)) {
@@ -3777,8 +3907,13 @@ DS_LASRoleDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
Slapi_DN *roleDN;
attrVal = slapi_value_get_berval ( sval );
- n_attrval = slapi_ch_strdup( attrVal->bv_val);
- n_attrval = slapi_dn_normalize (n_attrval);
+ n_attrval = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_attrval) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASRoleDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return LAS_EVAL_FAIL;
+ }
roleDN = slapi_sdn_new_dn_byval(n_attrval);
/* We support: The attribute value can be a USER or a GROUP.
@@ -3831,14 +3966,12 @@ DS_LASRoleDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
* returns: ACL_TRUE for matched,
* ACL_FALSE for matched.
* ACL_DONT_KNOW otherwise.
- *
- *
-*/
+ */
int
aclutil_evaluate_macro( char * rule, lasInfo *lasinfo,
- acl_eval_types evalType ) {
-
+ acl_eval_types evalType )
+{
int matched = 0;
aci_t *aci;
char *matched_val = NULL;
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 8d4a21a0..0c8d0fa3 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -50,7 +50,6 @@ static int __aclp__sanity_check_acltxt(aci_t *aci_item, char *str);
static char * __aclp__normalize_acltxt (aci_t *aci_item, char *str);
static char * __aclp__getNextLASRule(aci_t *aci_item, char *str,
char **endOfCurrRule);
-static char * __aclp__dn_normalize( char *dn , char *end);
static int __aclp__get_aci_right ( char *str);
static int __aclp__init_targetattr (aci_t *aci, char *attr_val);
static int __acl__init_targetattrfilters( aci_t *aci_item, char *str);
@@ -239,10 +238,10 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
/*
- * The targetattrfilters bit looks like this:
- * (targetattrfilters="add= attr1:F1 && attr2:F2 ... && attrn:Fn,
- * del= attr1:F1 && attr2:F2... && attrn:Fn")
- */
+ * The targetattrfilters bit looks like this:
+ * (targetattrfilters="add= attr1:F1 && attr2:F2 ... && attrn:Fn,
+ * del= attr1:F1 && attr2:F2... && attrn:Fn")
+ */
if ( 0 != (rv= __acl__init_targetattrfilters(
aci_item, str))) {
return rv;
@@ -256,15 +255,14 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
}
/* Get individual components of the targetattr.
* (targetattr = "cn || u* || phone ||tel:add:(tel=1234)
- * || sn:del:(gn=5678)")
- * If it contains a value filter, the type will also be
- * ACI_TARGET_VALUE_ATTR.
- */
- if ( 0 != (rv= __aclp__init_targetattr(
- aci_item, str))) {
+ * || sn:del:(gn=5678)")
+ * If it contains a value filter, the type will also be
+ * ACI_TARGET_VALUE_ATTR.
+ */
+ if (0 != (rv = __aclp__init_targetattr(aci_item, str))) {
return rv;
}
- } else if (strncmp(str, aci_targetfilter,tfilterlen ) == 0) {
+ } else if (strncmp(str, aci_targetfilter,tfilterlen ) == 0) {
if ( aci_item->targetFilter)
return ACL_SYNTAX_ERR;
@@ -311,8 +309,8 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
} else if (strncmp(str, aci_targetdn, targetdnlen) == 0) {
char *tstr = NULL;
- const size_t LDAP_URL_prefix_len = strlen (LDAP_URL_prefix);
- char *tt;
+ size_t LDAP_URL_prefix_len = 0;
+ size_t tmplen = 0;
type = ACI_TARGET_DN;
/* Keep a copy of the target attr */
if (aci_item->target) {
@@ -322,30 +320,40 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
type |= ACI_TARGET_NOT;
strncpy(s, " ", 1);
}
-
- /* Convert it to lower as slapi_dn_normalize() does not */
- for (tt = str; *tt; tt++) *tt = TOLOWER ( *tt );
-
if ( (s = strchr( str, '=' )) != NULL ) {
value = s + 1;
- slapi_dn_normalize(value);
+ __acl_strip_leading_space(&value);
len = strlen ( value );
- if (*value == '"' && value[len-1] == '"'){
+ /* strip double quotes */
+ if (*value == '"' && value[len-1] == '"') {
value[len-1] = '\0';
value++;
}
__acl_strip_leading_space(&value);
- } else {
+ } else {
return ( ACL_SYNTAX_ERR );
}
-
- if ( strncasecmp ( value, LDAP_URL_prefix , LDAP_URL_prefix_len) )
+ if (0 ==
+ strncasecmp(value, LDAP_URL_prefix, strlen(LDAP_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAP_URL_prefix);
+ } else if (0 == strncasecmp(value, LDAPS_URL_prefix,
+ strlen(LDAPS_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAPS_URL_prefix);
+ } else {
return ( ACL_SYNTAX_ERR );
+ }
value += LDAP_URL_prefix_len;
- len = strlen ( value );
- tstr = (char *) slapi_ch_malloc ( targetdnlen + len + 4 );
- sprintf ( tstr, "(target=%s)", value);
+ rv = slapi_dn_normalize_case_ext(value, 0, &tmpstr, &tmplen);
+ if (rv < 0) {
+ return ACL_SYNTAX_ERR;
+ } else if (rv == 0) { /* value passed in; not null terminated */
+ *(tmpstr + tmplen) = '\0';
+ }
+ tstr = slapi_ch_smprintf("(target=%s)", tmpstr);
+ if (rv > 0) {
+ slapi_ch_free_string(&tmpstr);
+ }
if ( (rv = acl_check_for_target_macro( aci_item, value)) == -1) {
slapi_ch_free ( (void **) &tstr );
return(ACL_SYNTAX_ERR);
@@ -356,7 +364,7 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
/* it's a normal target with no macros inside */
f = slapi_str2filter ( tstr );
}
- slapi_ch_free ( (void **) &tstr );
+ slapi_ch_free_string ( &tstr );
} else {
/* did start with a 't' but was not a recognsied keyword */
return(ACL_SYNTAX_ERR);
@@ -492,20 +500,86 @@ __aclp__sanity_check_acltxt (aci_t *aci_item, char *str)
slapi_log_error(SLAPI_LOG_ACL, plugin_name, "Normalized String:%s\n", newstr);
/* check for acl syntax error */
- if ((handle = (ACLListHandle_t *) ACL_ParseString(&errp,
- newstr)) == NULL) {
+ if ((handle = (ACLListHandle_t *) ACL_ParseString(&errp, newstr)) == NULL) {
acl_print_acllib_err(&errp, str);
- slapi_ch_free ( (void **) &newstr );
+ slapi_ch_free_string(&newstr);
return ACL_SYNTAX_ERR;
} else {
/* get the rights and the aci type */
aci_item->aci_handle = handle;
nserrDispose(&errp);
- slapi_ch_free ( (void **) &newstr );
+ slapi_ch_free_string(&newstr);
return 0;
}
}
+
+/*
+ * If the src includes "ldap(s):///<dn>", normalize <dn> and copy
+ * the string starting from start to *dest.
+ * If isstrict is non-zero, if ldap(s):/// is not included in the src
+ * string, it returns an error (-1).
+ * If isstrict is zero, the string is copied as is.
+ *
+ * return value: 0 or positive: success
+ * negative: failure
+ */
+int
+__aclp__copy_normalized_str (char *src, char *endsrc, char *start,
+ char **dest, size_t *destlen, int isstrict)
+{
+ char *p = NULL;
+ int rc = -1;
+ char *dn = NULL;
+ size_t dnlen = 0;
+
+ p = PL_strnstr(src, LDAP_URL_prefix, endsrc - src);
+ if (p) {
+ p += strlen(LDAP_URL_prefix);
+ } else {
+ p = PL_strnstr(src, LDAPS_URL_prefix, endsrc - src);
+ if (p) {
+ p += strlen(LDAPS_URL_prefix);
+ }
+ }
+
+ if (isstrict && ((NULL == p) || 0 == strlen(p))) {
+ return rc; /* error */
+ }
+
+ rc = 0;
+ if (p && strlen(p) > 0) {
+ size_t len = 0;
+ /* strip the string starting from ? */
+ char *q = PL_strnchr(p, '?', endsrc - p);
+ if (q) {
+ len = q - p;
+ } else {
+ len = endsrc - p;
+ }
+ /* Normalize the value of userdn and append it to ret_str */
+ rc = slapi_dn_normalize_ext(p, len, &dn, &dnlen);
+ if (rc < 0) {
+ return rc;
+ }
+ /* append up to ldap(s):/// */
+ aclutil_str_append_ext(dest, destlen, start, p - start);
+ /* append the DN part */
+ aclutil_str_append_ext(dest, destlen, dn, dnlen);
+ if (rc > 0) { /* if rc == 0, p is passed in */
+ slapi_ch_free_string(&dn);
+ }
+ if (q) {
+ /* append the rest from '?' */
+ aclutil_str_append_ext(dest, destlen, q, endsrc - q);
+ }
+ } else {
+ aclutil_str_append_ext(dest, destlen, start, endsrc - start);
+ }
+
+ return rc;
+}
+
/******************************************************************************
*
* acl__normalize_acltxt
@@ -534,23 +608,25 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
char *s, *p;
char *end;
char *aclstr, *s_aclstr;
+ char *prevend = NULL;
char *ret_str = NULL;
+ size_t retstr_len = 0;
int len;
- char *ptr, *aclName;
+ char *aclName;
char *nextACE;
char *tmp_str = NULL;
char *acestr = NULL;
char *s_acestr = NULL;
int aci_rights_val = 0; /* bug 389975 */
+ int rc = 0;
/* make a copy first */
s_aclstr = aclstr = slapi_ch_strdup ( str );
/* The rules are like this version 3.0; acl "xyz"; rule1; rule2; */
s = strchr (aclstr, ';');
- if ( NULL == s) {
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (NULL == s) {
+ goto error;
}
aclstr = ++s;
@@ -564,9 +640,8 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
aclName = s+3;
s = strchr (aclstr, ';');
- if ( NULL == s) {
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (NULL == s) {
+ goto error;
}
aclstr = s;
@@ -576,8 +651,10 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
/* Here aclName is the acl description string */
aci_item->aclName = slapi_ch_strdup ( aclName );
- aclutil_str_appened (&ret_str, s_aclstr);
- aclutil_str_appened (&ret_str, ";");
+ retstr_len = strlen(str) * 3;
+ ret_str = (char *)slapi_ch_calloc(sizeof(char), retstr_len);
+ aclutil_str_append_ext (&ret_str, &retstr_len, s_aclstr, strlen(s_aclstr));
+ aclutil_str_append_ext (&ret_str, &retstr_len, ";", 1);
/* start with the string */
acestr = aclstr;
@@ -586,37 +663,34 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
* Here acestr is something like:
*
* " allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP";)"
- *
- *
- */
+ */
normalize_nextACERule:
/* now we are in the rule part */
tmp_str = acestr;
s = strchr (tmp_str, ';');
- if ( s == NULL) {
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (s == NULL) {
+ goto error;
}
+
nextACE = s;
LDAP_UTF8INC(nextACE);
*s = '\0';
- /* acestr now will hold copy of the ACE. Also add
+ /* acestr now will hold copy of the ACE. Also add
** some more space in case we need to add "absolute"
- ** for deny rule. We will never need more 2 times
- ** the len.
+ ** for deny rule. We will never need more 3 times
+ ** the len (even if all the chars are escaped).
*/
__acl_strip_leading_space(&tmp_str);
len = strlen (tmp_str);
- s_acestr = acestr = slapi_ch_calloc ( 1, 2 * len);
+ s_acestr = acestr = slapi_ch_calloc (1, 3 * len);
/*
* Now it's something like:
* allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP";
- */
+ */
if (strncasecmp(tmp_str, "allow", 5) == 0) {
memcpy(acestr, tmp_str, len);
tmp_str += 5;
@@ -624,6 +698,14 @@ normalize_nextACERule:
aci_rights_val = __aclp__get_aci_right (tmp_str);/* bug 389975 */
aci_item->aci_type |= ACI_HAS_ALLOW_RULE;
+ s = strchr(acestr, ')');
+ if (NULL == s) {
+ /* wrong syntax */
+ goto error;
+ }
+ /* add "allow(rights...)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len, acestr, s - acestr + 1);
+ prevend = s + 1;
} else if (strncasecmp(tmp_str, "deny", 4) == 0) {
char *d_rule ="deny absolute";
/* Then we have to add "absolute" to the deny rule
@@ -652,6 +734,15 @@ normalize_nextACERule:
len = strlen ( d_rule );
memcpy (acestr, d_rule, len );
memcpy (acestr+len, tmp_str, strlen (tmp_str) );
+
+ s = strchr(acestr, ')');
+ if (NULL == s) {
+ /* wrong syntax */
+ goto error;
+ }
+ /* add "deny(rights...)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len, acestr, s - acestr + 1);
+ prevend = s + 1;
} else {
/* wrong syntax */
aci_rights_val = -1 ;
@@ -659,32 +750,32 @@ normalize_nextACERule:
if (aci_rights_val == -1 )
{
/* wrong syntax */
- slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_acestr );
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ goto error;
} else
- aci_item->aci_access |= aci_rights_val;
+ aci_item->aci_access |= aci_rights_val;
-
- /* Normalize all the DNs in the userdn rule */
-
+ /* Normalize all the DNs in the userdn, groupdn, roledn rules */
/*
*
* Here acestr starts like this:
- * " allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP"
- */
-
+ * " allow (all) groupdn = "ldap:///cn=Domain Administrators,o=$dn.o,o=ISP"
+ */
s = __aclp__getNextLASRule(aci_item, acestr, &end);
while ( s ) {
- if ( 0 == strncmp ( s, DS_LAS_USERDNATTR, 10) ||
- ( 0 == strncmp ( s, DS_LAS_USERATTR, 8))) {
+ if ( (0 == strncmp(s, DS_LAS_USERDNATTR, 10)) ||
+ (0 == strncmp(s, DS_LAS_USERATTR, 8)) ) {
/*
** For userdnattr/userattr rule, the resources changes and hence
** we cannot cache the result. See above for more comments.
*/
aci_item->aci_elevel = ACI_ELEVEL_USERDNATTR;
- } else if ( 0== strncmp ( s, DS_LAS_USERDN, 6)) {
+
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 0);
+ if (rc < 0) {
+ goto error;
+ }
+ } else if ( 0 == strncmp ( s, DS_LAS_USERDN, 6)) {
p = strstr ( s, "=");
p--;
if ( strncmp (p, "!=", 2) == 0)
@@ -699,22 +790,12 @@ normalize_nextACERule:
* which would ensure that acl info is not cached from
* one resource entry to the next. (bug 558519)
*/
- p = strstr ( p, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8; /* for ldap:/// */
- if( __aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
-
+
/* we have a rule like userdn = "ldap:///blah". s points to blah now.
** let's find if we have a SELF rule like userdn = "ldap:///self".
** Since the resource changes on entry basis, we can't cache the
@@ -750,6 +831,12 @@ normalize_nextACERule:
aci_item->aci_elevel = ACI_ELEVEL_GROUPDNATTR;
}
aci_item->aci_ruleType |= ACI_GROUPDNATTR_RULE;
+
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 0);
+ if (rc < 0) {
+ goto error;
+ }
} else if ( 0 == strncmp ( s, DS_LAS_GROUPDN, 7)) {
p = strstr ( s, "=");
@@ -757,21 +844,12 @@ normalize_nextACERule:
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_GROUPDN;
- p = strstr ( s, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8;
- if (__aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
+
/* check for param rules */
__aclp_chk_paramRules ( aci_item, p, end );
@@ -786,21 +864,12 @@ normalize_nextACERule:
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_ROLEDN;
- p = strstr ( s, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8;
- if (__aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
+
/* check for param rules */
__aclp_chk_paramRules ( aci_item, p, end );
@@ -808,40 +877,47 @@ normalize_nextACERule:
if ( aci_item->aci_elevel > ACI_ELEVEL_GROUPDN )
aci_item->aci_elevel = ACI_ELEVEL_GROUPDN;*/
aci_item->aci_ruleType |= ACI_ROLEDN_RULE;
+ } else {
+ /* adding the string no need to be processed
+ * (e.g., dns="lab.example.com)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len,
+ prevend, end - prevend);
}
+ prevend = end;
s = ++end;
s = __aclp__getNextLASRule(aci_item, s, &end);
- }/* while */
+ if (NULL == s) {
+ /* adding the rest of the string, e.g. '\"' */
+ aclutil_str_append_ext(&ret_str, &retstr_len,
+ prevend, strlen(prevend));
+ }
+ } /* while */
- /* get the head of the string */
- acestr = s_acestr;
- len = strlen( acestr);
- ptr = acestr +len-1;
- while (*ptr && *ptr != '\"' && *ptr != ')' ) *ptr-- = ' ';
- ptr++;
- *ptr = ';';
-
- aclutil_str_appened (&ret_str, acestr);
- if (s_acestr) {
- slapi_ch_free ( (void **) &s_acestr );
- }
- s_acestr = NULL;
+ slapi_ch_free_string (&s_acestr);
+ __acl_strip_trailing_space(ret_str);
+ aclutil_str_append_ext(&ret_str, &retstr_len, ";", 1);
if (nextACE) {
s = strstr (nextACE, "allow");
if (s == NULL) s = strstr (nextACE, "deny");
if (s == NULL) {
if (nextACE && *nextACE != '\0')
- aclutil_str_appened (&ret_str, nextACE);
- slapi_ch_free ( (void **) &s_aclstr );
+ aclutil_str_append (&ret_str, nextACE);
+ slapi_ch_free_string (&s_aclstr);
return (ret_str);
}
acestr = nextACE;
goto normalize_nextACERule;
}
- slapi_ch_free ( (void **) &s_aclstr );
+ slapi_ch_free_string (&s_aclstr);
return (ret_str);
+
+error:
+ slapi_ch_free_string (&ret_str);
+ slapi_ch_free_string (&s_aclstr);
+ slapi_ch_free_string (&s_acestr);
+ return NULL;
}
/*
*
@@ -857,7 +933,7 @@ __aclp__getNextLASRule (aci_t *aci_item, char *original_str , char **endOfCurrRu
{
char *newstr, *word, *next, *start, *end;
char *ruleStart = NULL;
- int len, ruleLen;
+ int len, ruleLen = 0;
int in_dn_expr = 0;
*endOfCurrRule = NULL;
@@ -1029,43 +1105,7 @@ __aclp__getNextLASRule (aci_t *aci_item, char *original_str , char **endOfCurrRu
return ( ruleStart );
}
-/******************************************************************************
-*
-* __aclp__dn_normalize
-*
-* Normalize the DN INPLACE. This routine is similar to slapi_dn_normalize()
-* except various small stuff at the end.
-* Normalize until the "end" and not to the end of string.
-*
-******************************************************************************/
-static char *
-__aclp__dn_normalize( char *dn , char *end)
-{
- char *d;
-
- if ((end - dn) < 0) {
- return(NULL);
- }
- d = slapi_dn_normalize_to_end ( dn, end );
-
- /* Do I have the quotes already */
- if (*d != '\"' ) {
- /*
- ** We are taking care of this situation
- ** " ") ". We need to remove the space
- ** infront and tack it after the quote like this.
- ** "" ) ".
- */
-
- *d = '\"';
- d++;
- while (*d && *d != '\"') *d++ = ' ';
- *d = ' ';
- }
-
- return( dn );
-}
/***************************************************************************
* acl__get_aci_right
*
@@ -1263,6 +1303,7 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
}
while (str != 0 && *str != 0) {
+ int lenstr = 0;
__acl_strip_leading_space(&str);
@@ -1292,23 +1333,28 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
attr = (Targetattr *) slapi_ch_malloc (sizeof (Targetattr));
memset (attr, 0, sizeof(Targetattr));
- if (strchr(str, '*')) {
-
+ /* strip double quotes */
+ lenstr = strlen(str);
+ if (*str == '"' && *(str + lenstr - 1) == '"') {
+ *(str + lenstr - 1) = '\0';
+ str++;
+ }
+ if (strchr(str, '*')) {
+
/* It contains a * so it's something like * or cn* */
if (strcmp(str, "*" ) != 0) {
char line[100];
char *lineptr = &line[0];
char *newline = NULL;
- int lenstr = 0;
struct slapi_filter *f = NULL;
- if ((lenstr = strlen(str)) > 91) { /* 100 - 8 for "(attr =%s)" */
- newline = slapi_ch_malloc(lenstr + 9);
+ if (lenstr > 92) { /* 100 - 8 for "(attr=%s)\0" */
+ newline = slapi_ch_malloc(lenstr + 8);
lineptr = newline;
}
attr->attr_type = ACL_ATTR_FILTER;
- sprintf (lineptr, "(attr =%s)", str);
+ sprintf (lineptr, "(attr=%s)", str);
f = slapi_str2filter (lineptr);
if (f == NULL) {
@@ -1320,7 +1366,7 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
if (newline) slapi_ch_free((void **) &newline);
} else {
- attr->attr_type = ACL_ATTR_STAR;
+ attr->attr_type = ACL_ATTR_STAR;
attr->u.attr_str = slapi_ch_strdup (str);
}
diff --git a/ldap/servers/plugins/acl/aclproxy.c b/ldap/servers/plugins/acl/aclproxy.c
index d40f543f..9b28489a 100644
--- a/ldap/servers/plugins/acl/aclproxy.c
+++ b/ldap/servers/plugins/acl/aclproxy.c
@@ -87,7 +87,9 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
LDAPProxyAuth *spec = NULL;
BerElement *ber = NULL;
char *errstring = "unable to parse proxied authorization control";
-
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
BEGIN
ber_tag_t tag;
@@ -132,11 +134,20 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
errstring = "proxied authorization id must be a DN (dn:...)";
break;
}
- strcpy( spec->auth_dn, spec->auth_dn + 3 );
+ /* memmove is safe for overlapping copy */
+ memmove ( spec->auth_dn, spec->auth_dn + 3, strlen(spec->auth_dn) - 2);/* 1 for '\0' */
}
- slapi_dn_normalize(spec->auth_dn);
lderr = LDAP_SUCCESS; /* got it! */
+ rc = slapi_dn_normalize_ext(spec->auth_dn, 0, &normed, &dnlen);
+ if (rc < 0) {
+ lderr = LDAP_INVALID_SYNTAX;
+ } else if (rc == 0) { /* spec->auth_dn is passed in; not terminated */
+ *(normed + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&spec->auth_dn);
+ spec->auth_dn = normed;
+ }
END
/* Cleanup */
diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c
index 4aebd477..c0b8f579 100644
--- a/ldap/servers/plugins/acl/aclutil.c
+++ b/ldap/servers/plugins/acl/aclutil.c
@@ -65,7 +65,7 @@ static PRIntn acl_ht_display_entry(PLHashEntry *he, PRIntn i, void *arg);
/* UTILITY FUNCTIONS */
/***************************************************************************/
int
-aclutil_str_appened(char **str1, const char *str2)
+aclutil_str_append(char **str1, const char *str2)
{
int new_len;
@@ -87,6 +87,43 @@ aclutil_str_appened(char **str1, const char *str2)
return(0);
}
+/*
+ * dlen: the length of the buffer *dest (not the string length in *dest)
+ */
+int
+aclutil_str_append_ext(char **dest, size_t *dlen, const char *src, size_t slen)
+{
+ char *ptr = NULL;
+ int rc = 0;
+
+ if ( dest == NULL || src == NULL ) {
+ return rc;
+ }
+
+ if (0 == slen) {
+ slen = strlen(src);
+ }
+ if (*dest && dlen > 0) {
+ size_t dest_strlen = strlen(*dest);
+ size_t new_len = dest_strlen + slen + 1;
+ if (new_len > *dlen) {
+ *dest = (char *)slapi_ch_realloc(*dest, new_len);
+ *dlen = new_len;
+ ptr = *dest + dest_strlen;
+ } else {
+ ptr = *dest + dest_strlen;
+ }
+ } else {
+ *dlen = slen + 1;
+ *dest = (char *)slapi_ch_malloc(*dlen);
+ ptr = *dest;
+ }
+ memcpy(ptr, src, slen);
+ *(ptr + slen) = '\0';
+
+ return rc;
+}
+
/***************************************************************************/
/* Print routines */
/***************************************************************************/
@@ -104,9 +141,14 @@ acl_print_acllib_err (NSErr_t *errp , char * str)
aclErrorFmt(errp, msgbuf, ACLUTIL_ACLLIB_MSGBUF_LEN, 1);
msgbuf[ACLUTIL_ACLLIB_MSGBUF_LEN-1] = '\0';
- if (msgbuf)
- slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)(%s)\n",
- msgbuf, str ? str: "NULL");
+ if (strlen(msgbuf) > 0) {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)(%s)\n",
+ msgbuf, str ? str: "NULL");
+ } else {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)\n",
+ str ? str: "NULL");
+ }
+
}
void
aclutil_print_aci (aci_t *aci_item, char *type)
@@ -240,7 +282,7 @@ aclutil_print_err (int rv , const Slapi_DN *sdn, const struct berval* val,
if (errbuf) {
/* If a buffer is provided, then copy the error */
- aclutil_str_appened(errbuf, lineptr );
+ aclutil_str_append(errbuf, lineptr );
}
slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "%s", lineptr);
@@ -436,7 +478,7 @@ acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf)
line = PR_smprintf(
"Insufficient 'delete' privilege to delete the entry '%s'.\n",edn);
}
- aclutil_str_appened(errbuf, line );
+ aclutil_str_append(errbuf, line );
if (line) {
PR_smprintf_free(line);
@@ -540,7 +582,7 @@ aclutil_expand_paramString ( char *str, Slapi_Entry *e )
goto cleanup;
}
*p = '\0';
- aclutil_str_appened ( &buf,a_dns[i]);
+ aclutil_str_append ( &buf,a_dns[i]);
if ( type == 1 ) {
/* xyz = $dn.o */
@@ -573,15 +615,15 @@ aclutil_expand_paramString ( char *str, Slapi_Entry *e )
kk= slapi_attr_next_value( attr, kk, &sval );
if ( kk != -1 ) /* can't handle multiple --error */
goto cleanup;
+ attrValue = slapi_value_get_berval ( t_sval );
+ attrVal = attrValue->bv_val;
}
- attrValue = slapi_value_get_berval ( t_sval );
- attrVal = attrValue->bv_val;
}
} else {
attrVal = a_dns[i];
}
- aclutil_str_appened ( &buf, attrVal);
- aclutil_str_appened ( &buf, ",");
+ aclutil_str_append ( &buf, attrVal);
+ aclutil_str_append ( &buf, ",");
}
rc = 0; /* everything is okay*/
/* remove the last comma */
@@ -607,7 +649,7 @@ __aclutil_extract_dn_component ( char **e_dns, int position, char *attrName )
int i, matched, len;
char *s;
- int matchedPosition;
+ int matchedPosition = 0;
len = strlen ( attrName );
diff --git a/ldap/servers/plugins/chainingdb/cb_config.c b/ldap/servers/plugins/chainingdb/cb_config.c
index 1dab8462..5659353c 100644
--- a/ldap/servers/plugins/chainingdb/cb_config.c
+++ b/ldap/servers/plugins/chainingdb/cb_config.c
@@ -63,24 +63,28 @@ int cb_config_add_dse_entries(cb_backend *cb, char **entries, char *string1, cha
Slapi_PBlock *util_pb = NULL;
int res, rc = 0;
char entry_string[CB_BUFSIZE];
+ char *dn = NULL;
for(x = 0; strlen(entries[x]) > 0; x++) {
util_pb = slapi_pblock_new();
PR_snprintf(entry_string, sizeof(entry_string), entries[x], string1, string2, string3);
e = slapi_str2entry(entry_string, 0);
+ dn = slapi_ch_strdup(slapi_entry_get_dn(e)); /* for err msg */
slapi_add_entry_internal_set_pb(util_pb, e, NULL, cb->identity, 0);
slapi_add_internal_pb(util_pb);
slapi_pblock_get(util_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
if ( LDAP_SUCCESS != res && LDAP_ALREADY_EXISTS != res ) {
char ebuf[ BUFSIZ ];
- slapi_log_error(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
+ slapi_log_error(SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
"Unable to add config entry (%s) to the DSE: %s\n",
- escape_string(slapi_entry_get_dn(e), ebuf),
+ escape_string(dn, ebuf),
ldap_err2string(res));
rc = res;
slapi_pblock_destroy(util_pb);
+ slapi_ch_free_string(&dn);
break;
}
+ slapi_ch_free_string(&dn);
slapi_pblock_destroy(util_pb);
}
return rc;
@@ -161,7 +165,7 @@ int cb_config_load_dse_info(Slapi_PBlock * pb) {
/* Get the default instance value entry if it exists */
/* else create it */
-
+ /* This dn is already normalized */
PR_snprintf(defaultDn,sizeof(defaultDn),"cn=default instance config,%s",cb->pluginDN);
default_pb = slapi_pblock_new();
diff --git a/ldap/servers/plugins/chainingdb/cb_init.c b/ldap/servers/plugins/chainingdb/cb_init.c
index 21a54d54..3b4f7a0b 100644
--- a/ldap/servers/plugins/chainingdb/cb_init.c
+++ b/ldap/servers/plugins/chainingdb/cb_init.c
@@ -82,7 +82,9 @@ chaining_back_init( Slapi_PBlock *pb )
/* Initialize misc. fields */
cb->config.rwl_config_lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "chaining_db");
- rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) cb );
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) cb );
+
+ /* These DNs are already normalized */
cb->pluginDN=slapi_ch_smprintf("cn=%s,%s",CB_PLUGIN_NAME,PLUGIN_BASE_DN);
cb->configDN=slapi_ch_smprintf("cn=config,%s",cb->pluginDN);
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
index 1c08bd9f..73d5e019 100644
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
@@ -153,10 +153,10 @@ cb_dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
static char *cb_skeleton_entries[] =
{
- "dn:cn=monitor, cn=%s, cn=%s, cn=plugins, cn=config\n"
- "objectclass:top\n"
- "objectclass:extensibleObject\n"
- "cn:monitor\n",
+ "dn: cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config\n"
+ "objectclass: top\n"
+ "objectclass: extensibleObject\n"
+ "cn: monitor\n",
""
};
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
index a14e48ce..b5aace63 100644
--- a/ldap/servers/plugins/cos/cos_cache.c
+++ b/ldap/servers/plugins/cos/cos_cache.c
@@ -69,6 +69,8 @@
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
+
#include "portable.h"
#include "slapi-plugin.h"
@@ -324,6 +326,8 @@ static int cos_cache_vattr_compare(vattr_sp_handle *handle, vattr_context *c, Sl
static int cos_cache_vattr_types(vattr_sp_handle *handle,Slapi_Entry *e,vattr_type_list_context *type_context,int flags);
static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Slapi_Entry *e, char *type, Slapi_ValueSet **out_attr, Slapi_Value *test_this, int *result, int *ops);
+static int hexchar2int( char c );
+
/*
compares s2 to s1 starting from end of string until the beginning of either
matches result in the s2 value being clipped from s1 with a NULL char
@@ -904,14 +908,29 @@ static int cos_dn_defs_cb (Slapi_Entry* e, void *callback_data) {
{
/* get the parent of the definition */
- char *parent = slapi_dn_parent(pDn->val);
- slapi_dn_normalize( parent );
+ char *parent = NULL;
+ size_t plen = 0;
+ int rc = 0;
+ char *orig = slapi_dn_parent(pDn->val);
+ rc = slapi_dn_normalize_ext(orig,
+ 0, &parent, &plen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_build_definition_list: failed to normalize parent dn %s. Adding the pre normalized dn.\n", orig, 0, 0);
+ parent = orig;
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(parent + plen) = '\0';
+ }
cos_cache_add_attrval(&pCosTargetTree, parent);
if(!pCosTemplateDn)
cos_cache_add_attrval(&pCosTemplateDn, parent);
- slapi_ch_free((void**)&parent);
+ if (orig != parent) {
+ slapi_ch_free_string(&orig);
+ }
+ slapi_ch_free_string(&parent);
}
slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL);
@@ -1916,16 +1935,33 @@ static int cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAt
theTemp = (cosTemplates*) slapi_ch_malloc(sizeof(cosTemplates));
if(theTemp)
{
- char *grade = (char*)slapi_ch_malloc(strlen(dn->val)+1);
+ char *grade = NULL;
int grade_index = 0;
int index = 0;
+ int lastindex = 0;
int template_default = 0;
-
- slapi_dn_normalize(dn->val);
+ char *dnval = NULL;
+ size_t dnlen = 0;
+ int rc = 0;
+
+ rc = slapi_dn_normalize_ext(dn->val, 0, &dnval, &dnlen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_add_tmpl: failed to normalize dn %s. "
+ "Processing the pre normalized dn.\n", dn->val, 0, 0);
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(dnval + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&dn->val);
+ dn->val = dnval;
+ }
+ grade = (char*)slapi_ch_malloc(strlen(dn->val)+1);
/* extract the cos grade */
while(dn->val[index] != '=' && dn->val[index] != '\0')
index++;
+ lastindex = strlen(dn->val) - 1;
if(dn->val[index] == '=')
{
@@ -1945,7 +1981,29 @@ static int cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAt
}
else
{
- if(dn->val[index] != '\\') /* skip escape chars */
+ if(dn->val[index] == '\\')
+ {
+ if ((index+2 <= lastindex) && isxdigit(dn->val[index+1]) &&
+ isxdigit(dn->val[index+2])) {
+ /* Convert ESC HEX HEX to a real char */
+ int n = hexchar2int(dn->val[index+1]);
+ int n2 = hexchar2int(dn->val[index+2]);
+ n = (n << 4) + n2;
+ if (n == 0) { /* don't change \00 */
+ grade[grade_index] = dn->val[index++]; /* '\\' */
+ grade_index++;
+ grade[grade_index] = dn->val[index++]; /* 0 */
+ grade_index++;
+ grade[grade_index] = dn->val[index]; /* 0 */
+ grade_index++;
+ } else {
+ grade[grade_index] = n;
+ index += 2;
+ grade_index++;
+ }
+ } /* else: skip escape chars */
+ }
+ else
{
grade[grade_index] = dn->val[index];
grade_index++;
@@ -2329,8 +2387,24 @@ static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Sl
/* is this entry a child of the target tree(s)? */
do
{
- if(pTargetTree)
- slapi_dn_normalize( pTargetTree->val );
+ if(pTargetTree) {
+ int rc = 0;
+ char *tval = NULL;
+ size_t tlen = 0;
+ rc = slapi_dn_normalize_ext(pTargetTree->val, 0, &tval, &tlen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_query_attr: failed to normalize dn %s. "
+ "Processing the pre normalized dn.\n",
+ pTargetTree->val, 0, 0);
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(tval + tlen) = '\0';
+ } else {
+ slapi_ch_free_string(&pTargetTree->val);
+ pTargetTree->val = tval;
+ }
+ }
if( pTargetTree->val == 0 ||
slapi_dn_issuffix(pDn, pTargetTree->val) != 0 ||
@@ -2800,7 +2874,23 @@ static int cos_cache_index_all(cosCache *pCache)
while(pAttrVal)
{
- slapi_dn_normalize(pAttrVal->val);
+ int rc = 0;
+ char *dnval = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(pAttrVal->val, 0,
+ &dnval, &dnlen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_index_all: failed to normalize dn %s. "
+ "Processing the pre normalized dn.\n",
+ pAttrVal->val, 0, 0);
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(dnval + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&pAttrVal->val);
+ pAttrVal->val = dnval;
+ }
pCache->ppTemplateList[tmpindex] = pAttrVal->val;
tmpindex++;
@@ -3519,3 +3609,20 @@ static int cos_cache_entry_is_cos_related( Slapi_Entry *e) {
}
return(rc);
}
+
+/* copied from dn.c */
+static int
+hexchar2int( char c )
+{
+ if ( '0' <= c && c <= '9' ) {
+ return( c - '0' );
+ }
+ if ( 'a' <= c && c <= 'f' ) {
+ return( c - 'a' + 10 );
+ }
+ if ( 'A' <= c && c <= 'F' ) {
+ return( c - 'A' + 10 );
+ }
+ return( -1 );
+}
+
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index b8922d9d..94c4ab38 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -680,7 +680,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
}
entry = (struct configEntry *)
- slapi_ch_calloc(1, sizeof(struct configEntry));
+ slapi_ch_calloc(1, sizeof(struct configEntry));
if (NULL == entry) {
ret = DNA_FAILURE;
goto bail;
@@ -787,7 +787,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
if (value) {
/* TODO - Allow multiple scope settings for a single range. This may
* make ordering the scopes tough when we put them in the clist. */
- entry->scope = slapi_dn_normalize(value);
+ entry->scope = value;
} else {
slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
"dna_parse_config_entry: The %s config "
@@ -817,6 +817,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
if (value) {
Slapi_Entry *shared_e = NULL;
Slapi_DN *sdn = NULL;
+ char *normdn = NULL;
sdn = slapi_sdn_new_dn_byref(value);
@@ -840,15 +841,29 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
shared_e = NULL;
}
- entry->shared_cfg_base = slapi_ch_strdup(value);
- slapi_dn_normalize(entry->shared_cfg_base);
+ normdn = slapi_create_dn_string("%s", value);
+ if (NULL == normdn) {
+ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
+ "dna_parse_config_entry: failed to normalize dn: "
+ "%s\n", value);
+ ret = DNA_FAILURE;
+ goto bail;
+ }
+ entry->shared_cfg_base = normdn;
/* We prepend the host & port of this instance as a
* multi-part RDN for the shared config entry. */
- entry->shared_cfg_dn = slapi_ch_smprintf("%s=%s+%s=%s,%s", DNA_HOSTNAME,
- hostname, DNA_PORTNUM, portnum, value);
- slapi_ch_free_string(&value);
- slapi_dn_normalize(entry->shared_cfg_dn);
+ normdn = slapi_create_dn_string("%s=%s+%s=%s,%s", DNA_HOSTNAME,
+ hostname, DNA_PORTNUM, portnum, normdn);
+ if (NULL == normdn) {
+ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
+ "dna_parse_config_entry: failed to create dn: "
+ "%s=%s+%s=%s,%s", DNA_HOSTNAME,
+ hostname, DNA_PORTNUM, portnum, value);
+ ret = DNA_FAILURE;
+ goto bail;
+ }
+ entry->shared_cfg_dn = normdn;
slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM,
"----------> %s [%s]\n", DNA_SHARED_CFG_DN,
@@ -1680,8 +1695,6 @@ static char *dna_get_dn(Slapi_PBlock * pb)
goto bail;
}
-/* slapi_dn_normalize( dn );
-*/
bail:
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"<-- dna_get_dn\n");
@@ -2310,7 +2323,14 @@ static int dna_is_replica_bind_dn(char *range_dn, char *bind_dn)
* the shared config. We need to see what the configured
* replica bind DN is. */
if (be_suffix) {
- replica_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", be_suffix);
+ /* This function converts the old DN style to the new one. */
+ replica_dn = slapi_create_dn_string("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", be_suffix);
+ if (NULL == replica_dn) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
+ "dna_is_replica_bind_dn: failed to create "
+ "replica dn for %s\n", be_suffix);
+ return 1;
+ }
replica_sdn = slapi_sdn_new_dn_passin(replica_dn);
attrs[0] = DNA_REPL_BIND_DN;
@@ -2370,8 +2390,15 @@ static int dna_get_replica_bind_creds(char *range_dn, struct dnaServer *server,
/* Fetch the replication agreement entry */
if (be_suffix) {
- replica_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",cn=mapping tree,cn=config",
- be_suffix);
+ /* This function converts the old DN style to the new one. */
+ replica_dn = slapi_create_dn_string("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", be_suffix);
+ if (NULL == replica_dn) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
+ "dna_get_replica_bind_creds: failed to create "
+ "replica dn for %s\n", be_suffix);
+ ret = LDAP_PARAM_ERROR;
+ goto bail;
+ }
filter = slapi_ch_smprintf("(&(nsds5ReplicaHost=%s)(|(" DNA_REPL_PORT "=%u)"
"(" DNA_REPL_PORT "=%u)))",
diff --git a/ldap/servers/plugins/linkedattrs/fixup_task.c b/ldap/servers/plugins/linkedattrs/fixup_task.c
index 50d35d0e..d5505709 100644
--- a/ldap/servers/plugins/linkedattrs/fixup_task.c
+++ b/ldap/servers/plugins/linkedattrs/fixup_task.c
@@ -80,9 +80,9 @@ linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
goto out;
}
- if (linkdn) {
+ if (linkdn) {
mytaskdata->linkdn = slapi_dn_normalize(slapi_ch_strdup(linkdn));
- }
+ }
/* allocate new task now */
task = slapi_new_task(slapi_entry_get_ndn(e));
diff --git a/ldap/servers/plugins/mep/mep.c b/ldap/servers/plugins/mep/mep.c
index e9d64fe4..ba142033 100644
--- a/ldap/servers/plugins/mep/mep.c
+++ b/ldap/servers/plugins/mep/mep.c
@@ -88,7 +88,6 @@ static int mep_modrdn_pre_op(Slapi_PBlock *pb);
static int mep_load_config();
static void mep_delete_config();
static int mep_parse_config_entry(Slapi_Entry * e, int apply);
-static void mep_insert_config_index(struct configEntry *entry);
static void mep_free_config_entry(struct configEntry ** entry);
/*
@@ -949,7 +948,6 @@ mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
Slapi_Entry *template = NULL;
char *rdn_type = NULL;
char **vals = NULL;
- char *p = NULL;
char *type = NULL;
char *value = NULL;
int vlen = 0;
@@ -1055,7 +1053,7 @@ mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
/* Create the DN using the mapped RDN value
* and the base specified in the config. */
- dn = slapi_ch_smprintf("%s=%s,%s", rdn_type, rdn_val, config->managed_base);
+ dn = slapi_create_dn_string("%s=%s,%s", rdn_type, rdn_val, config->managed_base);
slapi_ch_free_string(&rdn_val);
diff --git a/ldap/servers/plugins/pwdstorage/smd5_pwd.c b/ldap/servers/plugins/pwdstorage/smd5_pwd.c
index 65c6b2a9..cef3ee37 100644
--- a/ldap/servers/plugins/pwdstorage/smd5_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/smd5_pwd.c
@@ -89,7 +89,7 @@ smd5_pw_cmp( const char *userpwd, const char *dbpwd )
memset( quick_dbhash, 0, sizeof(quick_dbhash) );
}
- hashresult = PL_Base64Decode( dbpwd, 0, (char *)dbhash );
+ hashresult = PL_Base64Decode( dbpwd, 0, dbhash );
if (NULL == hashresult) {
slapi_log_error( SLAPI_LOG_PLUGIN, SALTED_MD5_SUBSYSTEM_NAME,
"smd5_pw_cmp: userPassword \"%s\" is the wrong length "
@@ -139,7 +139,7 @@ smd5_pw_enc( const char *pwd )
memset( hash_out, 0, sizeof(hash_out) );
/* generate a new random salt */
- slapi_rand_array( salt, MD5_DEFAULT_SALT_LENGTH );
+ slapi_rand_array( (void *)salt, MD5_DEFAULT_SALT_LENGTH );
saltval.bv_val = (void*)salt;
saltval.bv_len = MD5_DEFAULT_SALT_LENGTH;
diff --git a/ldap/servers/plugins/referint/referint.c b/ldap/servers/plugins/referint/referint.c
index b459a7ac..0f1598db 100644
--- a/ldap/servers/plugins/referint/referint.c
+++ b/ldap/servers/plugins/referint/referint.c
@@ -385,6 +385,7 @@ _update_one_per_mod(const char *entryDN, /* DN of the searched entry */
/* no need to free superior */
superior = slapi_dn_find_parent(origDN);
}
+ /* newRDN and superior are already normalized. */
newDN = slapi_ch_smprintf("%s,%s", newRDN, superior);
/*
* Compare the modified dn with the value of
@@ -409,9 +410,19 @@ _update_one_per_mod(const char *entryDN, /* DN of the searched entry */
nval != -1;
nval = slapi_attr_next_value(attr, nval, &v)) {
char *p = NULL;
+ size_t dnlen = 0;
/* DN syntax, which should be a string */
sval = slapi_ch_strdup(slapi_value_get_string(v));
- slapi_dn_normalize_case(sval);
+ rc = slapi_dn_normalize_case_ext(sval, 0, &p, &dnlen);
+ if (rc == 0) { /* sval is passed in; not terminated */
+ *(p + dnlen) = '\0';
+ sval = p;
+ } else if (rc > 0) {
+ slapi_ch_free_string(&sval);
+ sval = p;
+ }
+ /* else: (rc < 0) Ignore the DN normalization error for now. */
+
p = PL_strstr(sval, norm_origDN);
if (p == sval) {
/* (case 1) */
@@ -448,6 +459,7 @@ _update_one_per_mod(const char *entryDN, /* DN of the searched entry */
bak = *p;
*p = '\0';
+ /* newRDN and superior are already normalized. */
newvalue = slapi_ch_smprintf("%s%s", sval, newDN);
*p = bak;
values_add[0]=newvalue;
@@ -579,9 +591,19 @@ _update_all_per_mod(const char *entryDN, /* DN of the searched entry */
nval != -1;
nval = slapi_attr_next_value(attr, nval, &v)) {
char *p = NULL;
+ size_t dnlen = 0;
/* DN syntax, which should be a string */
sval = slapi_ch_strdup(slapi_value_get_string(v));
- slapi_dn_normalize_case(sval);
+ rc = slapi_dn_normalize_case_ext(sval, 0, &p, &dnlen);
+ if (rc == 0) { /* sval is passed in; not terminated */
+ *(p + dnlen) = '\0';
+ sval = p;
+ } else if (rc > 0) {
+ slapi_ch_free_string(&sval);
+ sval = p;
+ }
+ /* else: (rc < 0) Ignore the DN normalization error for now. */
+
p = PL_strstr(sval, norm_origDN);
if (p == sval) {
/* (case 1) */
@@ -632,6 +654,7 @@ update_integrity(char **argv, char *origDN,
int i, j;
const char *search_base = NULL;
char *norm_origDN = NULL;
+ size_t dnlen = 0;
int rc;
if ( argv == NULL ) {
@@ -644,8 +667,14 @@ update_integrity(char **argv, char *origDN,
/* for now, just putting attributes to keep integrity on in conf file,
until resolve the other timing mode issue */
- norm_origDN = slapi_ch_strdup(origDN);
- slapi_dn_normalize_case(norm_origDN);
+ rc = slapi_dn_normalize_case_ext(origDN, 0, &norm_origDN, &dnlen);
+ if (rc == 0) { /* origDN is passed in; not terminated */
+ *(norm_origDN + dnlen) = '\0';
+ norm_origDN = slapi_ch_strdup(norm_origDN);
+ } else if (rc < 0) {
+ /* Ignore the DN normalization error for now. */
+ norm_origDN = slapi_ch_strdup(origDN);
+ }
search_result_pb = slapi_pblock_new();
diff --git a/ldap/servers/plugins/replication/legacy_consumer.c b/ldap/servers/plugins/replication/legacy_consumer.c
index 97745278..8a47e800 100644
--- a/ldap/servers/plugins/replication/legacy_consumer.c
+++ b/ldap/servers/plugins/replication/legacy_consumer.c
@@ -83,6 +83,7 @@ static void legacy_consumer_encode_pw (Slapi_Entry *e);
static void set_legacy_purl (Slapi_PBlock *pb, const char *purl);
static int get_legacy_referral (Slapi_Entry *e, char **referral, char **state);
+/* LEGACY_CONSUMER_CONFIG_DN is no need to be normalized. */
#define LEGACY_CONSUMER_CONFIG_DN "cn=legacy consumer," REPL_CONFIG_TOP
#define LEGACY_CONSUMER_FILTER "(objectclass=*)"
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index c6859ddb..6be21ceb 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -319,8 +319,8 @@ char **agmt_validate_replicated_attributes(Repl_Agmt *ra);
void* agmt_get_priv (const Repl_Agmt *agmt);
void agmt_set_priv (Repl_Agmt *agmt, void* priv);
-
int get_agmt_agreement_type ( Repl_Agmt *agmt);
+int agmt_has_protocol(Repl_Agmt *agmt);
typedef struct replica Replica;
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 13db1acd..f60da022 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2216,13 +2216,21 @@ agmt_get_consumer_rid ( Repl_Agmt *agmt, void *conn )
{
if ( agmt->consumerRID <= 0 ) {
- char mapping_tree_node[512];
+ char *mapping_tree_node = NULL;
struct berval **bvals = NULL;
- PR_snprintf ( mapping_tree_node,
- sizeof (mapping_tree_node),
- "cn=replica,cn=\"%s\",cn=mapping tree,cn=config",
- slapi_sdn_get_dn (agmt->replarea) );
+
+ /* This function converts the old style DN to the new one. */
+ mapping_tree_node =
+ slapi_create_dn_string("cn=replica,cn=\"%s\",cn=mapping tree,cn=config",
+ slapi_sdn_get_dn (agmt->replarea) );
+ if (NULL == mapping_tree_node) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "agmt_get_consumer_rid: failed to normalize "
+ "replica dn for %s\n",
+ slapi_sdn_get_dn (agmt->replarea));
+ agmt->consumerRID = 0;
+ }
conn_read_entry_attribute ( conn, mapping_tree_node, "nsDS5ReplicaID", &bvals );
if ( NULL != bvals && NULL != bvals[0] ) {
char *ridstr = slapi_ch_malloc( bvals[0]->bv_len + 1 );
@@ -2232,6 +2240,7 @@ agmt_get_consumer_rid ( Repl_Agmt *agmt, void *conn )
slapi_ch_free ( (void**) &ridstr );
ber_bvecfree ( bvals );
}
+ slapi_ch_free_string(&mapping_tree_node);
}
return agmt->consumerRID;
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index 510757b6..f9aa610d 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -50,7 +50,8 @@
#include "repl5.h"
#include <plstr.h>
-#define AGMT_CONFIG_BASE "cn=mapping tree, cn=config"
+/* normalized DN */
+#define AGMT_CONFIG_BASE "cn=mapping tree,cn=config"
#define CONFIG_FILTER "(objectclass=nsds5replicationagreement)"
#define WINDOWS_CONFIG_FILTER "(objectclass=nsdsWindowsreplicationagreement)"
#define GLOBAL_CONFIG_FILTER "(|" CONFIG_FILTER WINDOWS_CONFIG_FILTER " )"
diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c
index 31f6072b..b1ff730d 100644
--- a/ldap/servers/plugins/replication/repl5_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_protocol.c
@@ -173,7 +173,6 @@ void
prot_free(Repl_Protocol **rpp)
{
Repl_Protocol *rp = NULL;
- PRIntervalTime interval;
if (rpp == NULL || *rpp == NULL) return;
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index f669900f..0d2f1956 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1528,6 +1528,12 @@ _replica_get_config_entry (const Slapi_DN *root)
Slapi_PBlock *pb = NULL;
dn = _replica_get_config_dn (root);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "_replica_get_config_entry: failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (root));
+ return NULL;
+ }
pb = slapi_pblock_new ();
slapi_search_internal_set_pb (pb, dn, LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, NULL,
@@ -1839,8 +1845,9 @@ _replica_get_config_dn (const Slapi_DN *root)
PR_ASSERT (root);
- dn = slapi_ch_smprintf("%s,cn=\"%s\",%s", REPLICA_RDN, slapi_sdn_get_dn (root), mp_base);
-
+ /* This function converts the old style DN to the new style. */
+ dn = slapi_create_dn_string("%s,cn=\"%s\",%s",
+ REPLICA_RDN, slapi_sdn_get_dn (root), mp_base);
return dn;
}
@@ -2162,6 +2169,13 @@ _replica_update_state (time_t when, void *arg)
r->repl_csn_assigned = PR_FALSE;
dn = _replica_get_config_dn (r->repl_root);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "_replica_update_state: failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (r->repl_root));
+ PR_Unlock(r->repl_lock);
+ goto done;
+ }
pb = slapi_pblock_new();
mods[0] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod);
@@ -3057,6 +3071,14 @@ replica_replace_ruv_tombstone(Replica *r)
ruv_last_modified_to_smod ((RUV*)object_get_data(r->repl_ruv), &smod_last_modified);
dn = _replica_get_config_dn (r->repl_root);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "replica_replace_ruv_tombstone: "
+ "failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (r->repl_root));
+ PR_Unlock(r->repl_lock);
+ goto bail;
+ }
mods[0] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod);
mods[1] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod_last_modified);
@@ -3090,6 +3112,7 @@ replica_replace_ruv_tombstone(Replica *r)
slapi_ch_free ((void**)&dn);
slapi_pblock_destroy (pb);
+bail:
slapi_mod_done (&smod);
slapi_mod_done (&smod_last_modified);
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index af5b6cd7..80b53616 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -47,6 +47,7 @@
#include "repl5.h"
#include "cl5_api.h"
+/* CONFIG_BASE: no need to optimize */
#define CONFIG_BASE "cn=mapping tree,cn=config"
#define CONFIG_FILTER "(objectclass=nsDS5Replica)"
#define TASK_ATTR "nsds5Task"
diff --git a/ldap/servers/plugins/replication/repl_init.c b/ldap/servers/plugins/replication/repl_init.c
index 5c897595..7a7c32cd 100644
--- a/ldap/servers/plugins/replication/repl_init.c
+++ b/ldap/servers/plugins/replication/repl_init.c
@@ -207,6 +207,7 @@ legacy_entry_init( Slapi_PBlock *pb )
static int
create_config_top()
{
+ /* DN part of this entry_string: no need to be optimized. */
char *entry_string = slapi_ch_strdup("dn: cn=replication,cn=config\nobjectclass: top\nobjectclass: extensibleobject\ncn: replication\n");
Slapi_PBlock *pb = slapi_pblock_new();
Slapi_Entry *e = slapi_str2entry(entry_string, 0);
diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c
index 556dede2..aedd6165 100644
--- a/ldap/servers/plugins/retrocl/retrocl.c
+++ b/ldap/servers/plugins/retrocl/retrocl.c
@@ -266,6 +266,7 @@ char *retrocl_get_config_str(const char *attrt)
int rc = 0;
char *dn;
+ /* RETROCL_PLUGIN_DN is no need to be normalized. */
dn = RETROCL_PLUGIN_DN;
pb = slapi_pblock_new();
diff --git a/ldap/servers/plugins/retrocl/retrocl_create.c b/ldap/servers/plugins/retrocl/retrocl_create.c
index 88974b72..1ffdaae9 100644
--- a/ldap/servers/plugins/retrocl/retrocl_create.c
+++ b/ldap/servers/plugins/retrocl/retrocl_create.c
@@ -77,6 +77,7 @@ static int retrocl_create_be(const char *bedir)
vals[1] = NULL;
e = slapi_entry_alloc();
+ /* RETROCL_LDBM_DN is no need to be normalized. */
slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_LDBM_DN));
/* Set the objectclass attribute */
@@ -142,6 +143,7 @@ static int retrocl_create_be(const char *bedir)
/* we need the changenumber indexed */
e = slapi_entry_alloc();
+ /* RETROCL_INDEX_DN is no need to be normalized. */
slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_INDEX_DN));
/* Set the objectclass attribute */
@@ -210,6 +212,7 @@ int retrocl_create_config(void)
struct berval *vals[2];
struct berval val;
int rc;
+ char *mappingtree_dn = NULL;
vals[0] = &val;
vals[1] = NULL;
@@ -219,7 +222,15 @@ int retrocl_create_config(void)
* in the errors file when the referenced backend does not exist.
*/
e = slapi_entry_alloc();
- slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_MAPPINGTREE_DN));
+ /* This function converts the old DN style to the new one. */
+ mappingtree_dn = slapi_create_dn_string("%s", RETROCL_MAPPINGTREE_DN);
+ if (NULL == mappingtree_dn) {
+ slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
+ "retrocl_create_config: failed to normalize "
+ "mappingtree dn %s\n", RETROCL_MAPPINGTREE_DN);
+ return LDAP_PARAM_ERROR;
+ }
+ slapi_entry_set_dn(e, mappingtree_dn); /* mappingtree_dn is consumed */
/* Set the objectclass attribute */
val.bv_val = "top";
diff --git a/ldap/servers/plugins/syntaxes/string.c b/ldap/servers/plugins/syntaxes/string.c
index 9b338335..21ff5d1b 100644
--- a/ldap/servers/plugins/syntaxes/string.c
+++ b/ldap/servers/plugins/syntaxes/string.c
@@ -63,6 +63,7 @@ string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax,
{
int i, rc;
struct berval bvfilter_norm;
+ char *alt = NULL;
if(retVal) {
*retVal = NULL;
@@ -74,7 +75,12 @@ string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax,
bvfilter_norm.bv_val = slapi_ch_malloc( bvfilter->bv_len + 1 );
SAFEMEMCPY( bvfilter_norm.bv_val, bvfilter->bv_val, bvfilter->bv_len );
bvfilter_norm.bv_val[bvfilter->bv_len] = '\0';
- value_normalize( bvfilter_norm.bv_val, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( bvfilter_norm.bv_val, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&bvfilter_norm.bv_val);
+ bvfilter_norm.bv_val = alt;
+ }
bvfilter_norm.bv_len = strlen(bvfilter_norm.bv_val);
for ( i = 0; (bvals != NULL) && (bvals[i] != NULL); i++ ) {
@@ -211,6 +217,7 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
Operation *op = NULL;
Slapi_Regex *re = NULL;
const char *re_result = NULL;
+ char *alt = NULL;
LDAPDebug( LDAP_DEBUG_FILTER, "=> string_filter_sub\n",
0, 0, 0 );
@@ -260,27 +267,45 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
}
if ( initial != NULL ) {
- value_normalize( initial, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( initial, syntax, 1, &alt );
*p++ = '^';
- filter_strcpy_special_ext( p, initial, FILTER_STRCPY_ESCAPE_RECHARS );
+ if (alt) {
+ filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS );
+ slapi_ch_free_string(&alt);
+ } else {
+ filter_strcpy_special_ext( p, initial, FILTER_STRCPY_ESCAPE_RECHARS );
+ }
p = strchr( p, '\0' );
}
if ( any != NULL ) {
for ( i = 0; any[i] != NULL; i++ ) {
- value_normalize( any[i], syntax, 0 /* DO NOT trim leading blanks */ );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( any[i], syntax, 0, &alt );
/* ".*" + value */
*p++ = '.';
*p++ = '*';
- filter_strcpy_special_ext( p, any[i], FILTER_STRCPY_ESCAPE_RECHARS );
+ if (alt) {
+ filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS );
+ slapi_ch_free_string(&alt);
+ } else {
+ filter_strcpy_special_ext( p, any[i], FILTER_STRCPY_ESCAPE_RECHARS );
+ }
p = strchr( p, '\0' );
}
}
if ( final != NULL ) {
- value_normalize( final, syntax, 0 /* DO NOT trim leading blanks */ );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( final, syntax, 0, &alt );
/* ".*" + value */
*p++ = '.';
*p++ = '*';
- filter_strcpy_special_ext( p, final, FILTER_STRCPY_ESCAPE_RECHARS );
+ if (alt) {
+ filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS );
+ slapi_ch_free_string(&alt);
+ } else {
+ filter_strcpy_special_ext( p, final, FILTER_STRCPY_ESCAPE_RECHARS );
+ }
strcat( p, "$" );
}
@@ -327,9 +352,15 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
strcpy( tmpbuf, bvp->bv_val );
realval = tmpbuf;
}
- value_normalize( realval, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( realval, syntax, 1, &alt );
- tmprc = slapi_re_exec( re, realval, time_up );
+ if (alt) {
+ tmprc = slapi_re_exec( re, alt, time_up );
+ slapi_ch_free_string(&alt);
+ } else {
+ tmprc = slapi_re_exec( re, realval, time_up );
+ }
LDAPDebug( LDAP_DEBUG_TRACE, "re_exec (%s) %i\n",
escape_string( realval, ebuf ), tmprc, 0 );
@@ -359,6 +390,7 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
Slapi_Value **nbvals, **nbvlp;
Slapi_Value **bvlp;
char *w, *c, *p;
+ char *alt = NULL;
if (NULL == ivals) {
return 1;
@@ -380,9 +412,16 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
{
c = slapi_ch_strdup(slapi_value_get_string(*bvlp));
/* if the NORMALIZED flag is set, skip normalizing */
- if (!(slapi_value_get_flags(*bvlp) & SLAPI_ATTR_FLAG_NORMALIZED))
- value_normalize( c, syntax, 1 /* trim leading blanks */ );
- *nbvlp = slapi_value_new_string_passin(c);
+ if (!(slapi_value_get_flags(*bvlp) & SLAPI_ATTR_FLAG_NORMALIZED)) {
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( c, syntax, 1, &alt );
+ }
+ if (alt) {
+ slapi_ch_free_string(&c);
+ *nbvlp = slapi_value_new_string_passin(alt);
+ } else {
+ *nbvlp = slapi_value_new_string_passin(c);
+ }
}
*ivals = nbvals;
break;
@@ -470,14 +509,16 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
for ( bvlp = bvals; bvlp && *bvlp; bvlp++ ) {
/*
* Note: this calculation may err on the high side,
- * because value_normalize(), which is called below
+ * because value_normalize_ext(), which is called below
* before we actually create the substring keys, may
- * reduce the length of the value in some cases. For
- * example, spaces are removed when space insensitive
- * strings are normalized. But it's okay for nsubs to
- * be too big. Since the ivals array is NULL terminated,
- * the only downside is that we allocate more space than
- * we really need.
+ * reduce the length of the value in some cases or
+ * increase the length in other cases. For example,
+ * spaces are removed when space insensitive strings
+ * are normalized. Or if the value includes '\"' (2 bytes),
+ * it's normalized to '\22' (3 bytes). But it's okay
+ * for nsubs to be too big. Since the ivals array is
+ * NULL terminated, the only downside is that we
+ * allocate more space than we really need.
*/
nsubs += slapi_value_get_length(*bvlp) - substrlens[INDEX_SUBSTRMIDDLE] + 3;
}
@@ -489,8 +530,14 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
bvdup= slapi_value_new();
for ( bvlp = bvals; bvlp && *bvlp; bvlp++ ) {
c = slapi_ch_strdup(slapi_value_get_string(*bvlp));
- value_normalize( c, syntax, 1 /* trim leading blanks */ );
- slapi_value_set_string_passin(bvdup, c);
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( c, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&c);
+ slapi_value_set_string_passin(bvdup, alt);
+ } else {
+ slapi_value_set_string_passin(bvdup, c);
+ }
bvp = slapi_value_get_berval(bvdup);
@@ -554,6 +601,7 @@ string_assertion2keys_ava(
size_t len;
char *w, *c;
Slapi_Value *tmpval=NULL;
+ char *alt = NULL;
switch ( ftype ) {
case LDAP_FILTER_EQUALITY_FAST:
@@ -565,13 +613,23 @@ string_assertion2keys_ava(
}
memcpy(tmpval->bv.bv_val,slapi_value_get_string(val),len);
tmpval->bv.bv_val[len]='\0';
- value_normalize(tmpval->bv.bv_val, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext(tmpval->bv.bv_val, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&tmpval->bv.bv_val);
+ tmpval->bv.bv_val = alt;
+ }
tmpval->bv.bv_len=strlen(tmpval->bv.bv_val);
break;
case LDAP_FILTER_EQUALITY:
(*ivals) = (Slapi_Value **) slapi_ch_malloc( 2 * sizeof(Slapi_Value *) );
(*ivals)[0] = slapi_value_dup( val );
- value_normalize( (*ivals)[0]->bv.bv_val, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( (*ivals)[0]->bv.bv_val, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&(*ivals)[0]->bv.bv_val);
+ (*ivals)[0]->bv.bv_val = alt;
+ }
(*ivals)[0]->bv.bv_len = strlen( (*ivals)[0]->bv.bv_val );
(*ivals)[1] = NULL;
break;
@@ -628,6 +686,10 @@ string_assertion2keys_sub(
int localsublens[3] = {SUBBEGIN, SUBMIDDLE, SUBEND};/* default values */
int maxsublen;
char *comp_buf = NULL;
+ char *altinit = NULL;
+ char **altany = NULL;
+ char *altfinal = NULL;
+ int anysize = 0;
slapi_pblock_get(pb, SLAPI_SYNTAX_SUBSTRLENS, &substrlens);
@@ -650,13 +712,17 @@ string_assertion2keys_sub(
* First figure out how many keys we will return. The answer is based
* on the length of each assertion value. Since normalization may
* reduce the length (such as when spaces are removed from space
- * insensitive strings), we call value_normalize() before checking
+ * insensitive strings), we call value_normalize_ext() before checking
* the length.
*/
nsubs = 0;
if ( initial != NULL ) {
- value_normalize( initial, syntax, 0 /* do not trim leading blanks */ );
- initiallen = strlen( initial );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( initial, syntax, 0, &altinit );
+ if (NULL == altinit) {
+ altinit = initial;
+ }
+ initiallen = strlen( altinit );
if ( initiallen > substrlens[INDEX_SUBSTRBEGIN] - 2 ) {
nsubs += 1; /* for the initial begin string key */
/* the rest of the sub keys are "any" keys for this case */
@@ -664,19 +730,31 @@ string_assertion2keys_sub(
nsubs += initiallen - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
} else {
- initial = NULL; /* save some work later */
+ altinit = NULL; /* save some work later */
}
}
for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
- value_normalize( any[i], syntax, 0 /* do not trim leading blanks */ );
- len = strlen( any[i] );
+ anysize++;
+ }
+ altany = (char **)slapi_ch_calloc(anysize + 1, sizeof(char *));
+ for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( any[i], syntax, 0, &altany[i] );
+ if (NULL == altany[i]) {
+ altany[i] = any[i];
+ }
+ len = strlen( altany[i] );
if ( len >= substrlens[INDEX_SUBSTRMIDDLE] ) {
nsubs += len - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
}
if ( final != NULL ) {
- value_normalize( final, syntax, 0 /* do not trim leading blanks */ );
- finallen = strlen( final );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( final, syntax, 0, &altfinal );
+ if (NULL == altfinal) {
+ altfinal = final;
+ }
+ finallen = strlen( altfinal );
if ( finallen > substrlens[INDEX_SUBSTREND] - 2 ) {
nsubs += 1; /* for the final end string key */
/* the rest of the sub keys are "any" keys for this case */
@@ -684,7 +762,7 @@ string_assertion2keys_sub(
nsubs += finallen - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
} else {
- final = NULL; /* save some work later */
+ altfinal = NULL; /* save some work later */
}
}
if ( nsubs == 0 ) { /* no keys to return */
@@ -703,21 +781,31 @@ string_assertion2keys_sub(
nsubs = 0;
comp_buf = (char *)slapi_ch_malloc(maxsublen + 1);
- if ( initial != NULL ) {
- substring_comp_keys( ivals, &nsubs, initial, initiallen, '^', syntax,
+ if ( altinit != NULL ) {
+ substring_comp_keys( ivals, &nsubs, altinit, initiallen, '^', syntax,
comp_buf, substrlens );
+ if (altinit != initial) {
+ slapi_ch_free_string(&altinit);
+ }
}
- for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
- len = strlen( any[i] );
+ for ( i = 0; altany != NULL && altany[i] != NULL; i++ ) {
+ len = strlen( altany[i] );
if ( len < substrlens[INDEX_SUBSTRMIDDLE] ) {
continue;
}
- substring_comp_keys( ivals, &nsubs, any[i], len, 0, syntax,
+ substring_comp_keys( ivals, &nsubs, altany[i], len, 0, syntax,
comp_buf, substrlens );
+ if (altany[i] != any[i]) {
+ slapi_ch_free_string(&altany[i]);
+ }
}
- if ( final != NULL ) {
- substring_comp_keys( ivals, &nsubs, final, finallen, '$', syntax,
+ slapi_ch_free((void **)&altany);
+ if ( altfinal != NULL ) {
+ substring_comp_keys( ivals, &nsubs, altfinal, finallen, '$', syntax,
comp_buf, substrlens );
+ if (altfinal != final) {
+ slapi_ch_free_string(&final);
+ }
}
(*ivals)[nsubs] = NULL;
slapi_ch_free_string(&comp_buf);
diff --git a/ldap/servers/plugins/syntaxes/syntax.h b/ldap/servers/plugins/syntaxes/syntax.h
index ec3d5f03..64942ec7 100644
--- a/ldap/servers/plugins/syntaxes/syntax.h
+++ b/ldap/servers/plugins/syntaxes/syntax.h
@@ -113,6 +113,7 @@ int string_assertion2keys_ava(Slapi_PBlock *pb,Slapi_Value *val,Slapi_Value ***i
int string_assertion2keys_sub(Slapi_PBlock *pb,char *initial,char **any,char *final,Slapi_Value ***ivals,int syntax);
int value_cmp(struct berval *v1,struct berval *v2,int syntax,int normalize);
void value_normalize(char *s,int syntax,int trim_leading_blanks);
+void value_normalize_ext(char *s,int syntax,int trim_leading_blanks, char **alt);
char *first_word( char *s );
char *next_word( char *s );
diff --git a/ldap/servers/plugins/syntaxes/validate.c b/ldap/servers/plugins/syntaxes/validate.c
index aab6d9c2..989137b5 100644
--- a/ldap/servers/plugins/syntaxes/validate.c
+++ b/ldap/servers/plugins/syntaxes/validate.c
@@ -362,7 +362,6 @@ int distinguishedname_validate(
{
int rc = 0; /* Assume value is valid */
char *val_copy = NULL;
- int strict = 0;
const char *p = begin;
const char *last = NULL;
@@ -377,17 +376,6 @@ int distinguishedname_validate(
* attributeValue = string / hexstring
*/
- /* Check if we should be performing strict validation. */
- strict = config_get_dn_validate_strict();
- if (!strict) {
- /* Create a normalized copy of the value to use
- * for validation. The original value will be
- * stored in the backend unmodified. */
- val_copy = PL_strndup(begin, end - begin + 1);
- p = val_copy;
- end = slapi_dn_normalize_to_end(val_copy, NULL) - 1;
- }
-
/* Validate one RDN at a time in a loop. */
while (p <= end) {
if ((rc = rdn_validate(p, end, &last)) != 0) {
diff --git a/ldap/servers/plugins/syntaxes/value.c b/ldap/servers/plugins/syntaxes/value.c
index f127b6b6..9b048f30 100644
--- a/ldap/servers/plugins/syntaxes/value.c
+++ b/ldap/servers/plugins/syntaxes/value.c
@@ -86,23 +86,40 @@ utf8isspace_fast( char* s )
** Also note that this deviates from rfc 4517 INTEGER syntax, but we must
** support legacy clients for the time being
*/
+/*
+ * alt stores the normalized value in case the normalized value is longer
+ * than the original value. It may happen the value is DN.
+ */
void
-value_normalize(
+value_normalize_ext(
char *s,
int syntax,
- int trim_spaces
+ int trim_spaces,
+ char **alt
)
{
char *head = s;
char *d;
int prevspace, curspace;
+ if (NULL == alt) {
+ return;
+ }
+ *alt = NULL;
+
if ( ! (syntax & SYNTAX_CIS) && ! (syntax & SYNTAX_CES) ) {
return;
}
if ( syntax & SYNTAX_DN ) {
- (void) slapi_dn_normalize_case( s );
+ char *dest = NULL;
+ size_t dlen = 0;
+ int rc = slapi_dn_normalize_case_ext(s, 0, &dest, &dlen);
+ if (rc > 0) {
+ *alt = dest;
+ } else if (rc == 0) { /* normalized in line; not terminated */
+ *(dest + dlen) = '\0';
+ }
return;
}
@@ -203,6 +220,16 @@ value_normalize(
}
}
+void
+value_normalize(
+ char *s,
+ int syntax,
+ int trim_spaces
+)
+{
+ /* deprecated */
+}
+
int
value_cmp(
struct berval *v1,
@@ -220,6 +247,7 @@ value_cmp(
int free_v1 = 0;
int free_v2 = 0;
int v1sign = 1, v2sign = 1; /* default to positive */
+ char *alt = NULL;
/* This code used to call malloc up to four times in the copying
* of attributes to be normalized. Now we attempt to keep everything
@@ -233,13 +261,35 @@ value_cmp(
bvcopy1.bv_val = &little_buffer[buffer_offset];
bvcopy1.bv_val[v1->bv_len] = '\0';
v1 = &bvcopy1;
- buffer_space-= v1->bv_len+1;
- buffer_offset+= v1->bv_len+1;
} else {
v1 = ber_bvdup( v1 );
free_v1 = 1;
}
- value_normalize( v1->bv_val, syntax, 1 /* trim leading blanks */ );
+ value_normalize_ext( v1->bv_val, syntax,
+ 1 /* trim leading blanks */, &alt );
+ if (alt) {
+ if (free_v1) {
+ slapi_ch_free_string(&v1->bv_val);
+ v1->bv_val = alt;
+ v1->bv_len = strlen(alt);
+ } else {
+ if (strlen(alt) < buffer_space) {
+ v1->bv_len = strlen(alt);
+ /* Copying to little_buffer */
+ SAFEMEMCPY(v1->bv_val, alt, v1->bv_len);
+ *(v1->bv_val + v1->bv_len) = '\0';
+ } else {
+ free_v1 = 1;
+ v1 = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+ v1->bv_val = alt;
+ v1->bv_len = strlen(alt);
+ }
+ }
+ }
+ if (!free_v1) {
+ buffer_space -= v1->bv_len + 1;
+ buffer_offset += v1->bv_len + 1;
+ }
}
if ( normalize & 2 ) {
/* Do we have space in the little buffer ? */
@@ -249,13 +299,35 @@ value_cmp(
bvcopy2.bv_val = &little_buffer[buffer_offset];
bvcopy2.bv_val[v2->bv_len] = '\0';
v2 = &bvcopy2;
- buffer_space-= v2->bv_len+1;
- buffer_offset+= v2->bv_len+1;
} else {
v2 = ber_bvdup( v2 );
free_v2 = 1;
}
- value_normalize( v2->bv_val, syntax, 1 /* trim leading blanks */ );
+ value_normalize_ext( v2->bv_val, syntax,
+ 1 /* trim leading blanks */, &alt );
+ if (alt) {
+ if (free_v2) {
+ slapi_ch_free_string(&v2->bv_val);
+ v2->bv_val = alt;
+ v2->bv_len = strlen(alt);
+ } else {
+ if (strlen(alt) < buffer_space) {
+ v2->bv_len = strlen(alt);
+ /* Copying to little_buffer */
+ SAFEMEMCPY(v2->bv_val, alt, v2->bv_len);
+ *(v2->bv_val + v2->bv_len) = '\0';
+ } else {
+ free_v2 = 1;
+ v2 = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+ v2->bv_val = alt;
+ v2->bv_len = strlen(alt);
+ }
+ }
+ }
+ if (!free_v2) {
+ buffer_space -= v2->bv_len + 1;
+ buffer_offset += v2->bv_len + 1;
+ }
}
if (syntax & SYNTAX_INT) {
diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c
index bf13073a..1c92a5a1 100644
--- a/ldap/servers/plugins/usn/usn_cleanup.c
+++ b/ldap/servers/plugins/usn/usn_cleanup.c
@@ -194,8 +194,15 @@ _usn_cleanup_is_mmr_enabled(const char *suffix)
char *base_dn = NULL;
int rc = 0; /* disabled, by default */
- base_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",%s",
- suffix, MAPPING_TREE_BASE_DN);
+ /* This function converts the old style DN to the new one */
+ base_dn = slapi_create_dn_string("cn=replica,cn=\"%s\",%s",
+ suffix, MAPPING_TREE_BASE_DN);
+ if (NULL == base_dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
+ "_usn_cleanup_is_mmr_enabled: failed to normalize "
+ "mappingtree dn for %s\n", suffix);
+ return 1;
+ }
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, base_dn, LDAP_SCOPE_ONELEVEL,
"objectclass=nsDS5ReplicationAgreement",
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index 1a1f8673..0e7d5c83 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -115,20 +115,47 @@ do_add( Slapi_PBlock *pb )
*/
/* get the name */
{
- char *dn = NULL;
- if ( ber_scanf( ber, "{a", &dn ) == LBER_ERROR ) {
- slapi_ch_free_string(&dn);
- LDAPDebug( LDAP_DEBUG_ANY,
- "ber_scanf failed (op=Add; params=DN)\n", 0, 0, 0 );
+ char *rawdn = NULL;
+ char *dn = NULL;
+ size_t dnlen = 0;
+ if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR ) {
+ slapi_ch_free_string(&rawdn);
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "ber_scanf failed (op=Add; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "ADD", "???", "decoding error");
- send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
- "decoding error", 0, NULL );
- return;
- }
- e = slapi_entry_alloc();
- slapi_entry_init(e,dn,NULL); /* Responsibility for DN is passed to the Entry. */
- }
- LDAPDebug( LDAP_DEBUG_ARGS, " do_add: dn (%s)\n", slapi_entry_get_dn_const(e), 0, 0 );
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
+ "decoding error", 0, NULL );
+ return;
+ }
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ } else if (rc > 0) {
+ slapi_ch_free_string(&rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
+ e = slapi_entry_alloc();
+ slapi_entry_init(e,dn,NULL); /* Responsibility for DN is passed to the Entry. */
+ }
+ LDAPDebug( LDAP_DEBUG_ARGS, " do_add: dn (%s)\n", slapi_entry_get_dn_const(e), 0, 0 );
/* get the attrs */
for ( tag = ber_first_element( ber, &len, &last );
diff --git a/ldap/servers/slapd/attrlist.c b/ldap/servers/slapd/attrlist.c
index b200472b..9c329902 100644
--- a/ldap/servers/slapd/attrlist.c
+++ b/ldap/servers/slapd/attrlist.c
@@ -289,6 +289,9 @@ int attrlist_replace(Slapi_Attr **alist, const char *type, struct berval **vals)
} else {
attrlist_find_or_create(alist, type, &a);
valuearray_init_bervalarray(vals, &values);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ valuearray_normalize_value(values);
+ }
rc = attr_replace(*a, values);
}
return rc;
@@ -312,6 +315,9 @@ int attrlist_replace_with_flags(Slapi_Attr **alist, const char *type, struct ber
} else {
attrlist_find_or_create(alist, type, &a);
valuearray_init_bervalarray_with_flags(vals, &values, flags);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ valuearray_normalize_value(values);
+ }
rc = attr_replace(*a, values);
}
return rc;
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
index 698c1cd9..65f3bb02 100644
--- a/ldap/servers/slapd/attrsyntax.c
+++ b/ldap/servers/slapd/attrsyntax.c
@@ -819,6 +819,23 @@ slapi_attr_get_syntax_oid_copy( const Slapi_Attr *a, char **oidp )
}
}
+int
+slapi_attr_is_dn_syntax_attr(Slapi_Attr *attr)
+{
+ char *syntaxoid = NULL;
+ int dn_syntax = 0; /* not DN, by default */
+
+ if (attr->a_plugin) { /* If not set, there is no way to get the info */
+ slapi_attr_get_syntax_oid_copy(attr, &syntaxoid);
+ if (syntaxoid) {
+ dn_syntax = ((0 == strcmp(syntaxoid, NAMEANDOPTIONALUID_SYNTAX_OID))
+ || (0 == strcmp(syntaxoid, DN_SYNTAX_OID)));
+ slapi_ch_free_string(&syntaxoid);
+ }
+ }
+ return dn_syntax;
+}
+
#ifdef ATTR_LDAP_DEBUG
PRIntn
diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c
index 3a500eb7..e483f6e9 100644
--- a/ldap/servers/slapd/auth.c
+++ b/ldap/servers/slapd/auth.c
@@ -75,15 +75,33 @@ slapu_msgfree( LDAP* ld, LDAPMessage* msg )
}
static int LDAP_CALL LDAP_CALLBACK
-slapu_search_s( LDAP* ld, const char* baseDN, int scope, const char* filter,
+slapu_search_s( LDAP* ld, const char* rawbaseDN, int scope, const char* filter,
char** attrs, int attrsonly, LDAPMessage** result )
{
int err = LDAP_NO_SUCH_OBJECT;
- Slapi_PBlock* pb;
+ Slapi_PBlock* pb = NULL;
LDAPControl **ctrls;
+ char *baseDN = slapi_ch_strdup(rawbaseDN);
+ char *normDN = NULL;
+ size_t dnlen = 0;
+
+ err = slapi_dn_normalize_ext(baseDN, 0, &normDN, &dnlen);
+ if (err < 0) {
+ err = LDAP_INVALID_DN_SYNTAX;
+ LDAPDebug (LDAP_DEBUG_TRACE, "<= slapu_search_s %i\n", err, 0, 0);
+ return err;
+ } else if (err == 0) { /* baseDN is passed in; not terminated */
+ *(normDN + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&baseDN);
+ baseDN = normDN;
+ }
if (ld != internal_ld) {
- return ldap_search_ext_s (ld, baseDN, scope, filter, attrs, attrsonly, NULL, NULL, NULL, -1, result);
+ err = ldap_search_ext_s(ld, baseDN, scope, filter, attrs, attrsonly,
+ NULL, NULL, NULL, -1, result);
+ slapi_ch_free_string(&baseDN);
+ return err;
}
LDAPDebug (LDAP_DEBUG_TRACE, "=> slapu_search_s (\"%s\", %i, %s)\n",
baseDN, scope, filter);
@@ -120,6 +138,7 @@ slapu_search_s( LDAP* ld, const char* baseDN, int scope, const char* filter,
LDAPDebug (LDAP_DEBUG_ANY, "slapi_search_internal (\"%s\", %i, %s) NULL\n",
escape_string( (char*)baseDN, ebuf ), scope, escape_string( (char*)filter, fbuf ));
}
+ slapi_ch_free_string(&baseDN);
*result = (LDAPMessage*)pb;
LDAPDebug (LDAP_DEBUG_TRACE, "<= slapu_search_s %i\n", err, 0, 0);
return err;
@@ -486,8 +505,8 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
if (err == LDAPU_SUCCESS && chain) {
LDAPMessage* entry = slapu_first_entry (internal_ld, chain);
if (entry) {
+ /* clientDN is duplicated in slapu_get_dn */
clientDN = slapu_get_dn (internal_ld, entry);
- if (clientDN) slapi_dn_normalize (clientDN);
} else {
extraErrorMsg = "no entry";
@@ -507,12 +526,27 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
if (clientDN != NULL) {
char ebuf[ BUFSIZ ];
- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL client bound as %s\n",
- conn->c_connid, escape_string( clientDN, ebuf ));
+ int rc = 0;
+ char *normedDN = NULL;
+ size_t dnlen = 0;
+
+ rc = slapi_dn_normalize_ext(clientDN, 0, &normedDN, &dnlen);
+ if (rc < 0) {
+ /* ignoring the normalization error, use the pre normalized DN */
+ } else if (rc == 0) { /* clientDN is passed in; not terminated */
+ *(normedDN + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&clientDN);
+ clientDN = normedDN;
+ }
+ slapi_log_access (LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " SSL client bound as %s\n",
+ conn->c_connid, escape_string( clientDN, ebuf ));
} else if (clientCert != NULL) {
slapi_log_access (LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL failed to map client certificate to LDAP DN (%s)\n",
- conn->c_connid, extraErrorMsg );
+ "conn=%" NSPRIu64 " SSL failed to map client "
+ "certificate to LDAP DN (%s)\n",
+ conn->c_connid, extraErrorMsg );
}
/*
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index 6cc1b66c..264eb90b 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
@@ -533,6 +533,7 @@ import_producer(void *param)
FREE(estr);
continue;
}
+ /* get_value_from_string decodes base64 if it is encoded. */
rc = get_value_from_string((const char *)estr, "dn", &dn);
if (rc) {
import_log_notice(job, "WARNING: skipping bad LDIF entry (dn "
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
index 67176746..6600f008 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
@@ -142,13 +142,25 @@ attrcrypt_keymgmt_get_key(ldbm_instance *li, attrcrypt_cipher_state *acs, SECKEY
{
int ret = 0;
Slapi_Entry *entry = NULL;
- char *dn_template = "cn=%s,cn=encrypted attribute keys,cn=%s,cn=ldbm database,cn=plugins,cn=config";
+ char *dn_template = "cn=%s,cn=encrypted attribute keys,cn=%s,cn=%s,cn=plugins,cn=config";
char *instance_name = li->inst_name;
- char *dn_string = NULL;
Slapi_Attr *keyattr = NULL;
+ char *dn_string = NULL;
LDAPDebug(LDAP_DEBUG_TRACE,"-> attrcrypt_keymgmt_get_key\n", 0, 0, 0);
- dn_string = slapi_ch_smprintf(dn_template, acs->ace->cipher_display_name, instance_name);
+ dn_string = slapi_create_dn_string(dn_template,
+ acs->ace->cipher_display_name, instance_name,
+ li->inst_li->li_plugin->plg_name);
+ if (NULL == dn_string) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "attrcrypt_keymgmt_get_key: "
+ "failed create attrcrypt key dn for plugin %s, "
+ "instance %s, cypher %s\n",
+ li->inst_li->li_plugin->plg_name,
+ li->inst_name, acs->ace->cipher_display_name);
+ ret = -1;
+ goto bail;
+ }
/* Fetch the entry */
getConfigEntry(dn_string, &entry);
/* Did we find the entry ? */
@@ -170,6 +182,7 @@ attrcrypt_keymgmt_get_key(ldbm_instance *li, attrcrypt_cipher_state *acs, SECKEY
} else {
ret = -2; /* Means: we didn't find the entry (which happens if the key has never been generated) */
}
+bail:
slapi_ch_free_string(&dn_string);
LDAPDebug(LDAP_DEBUG_TRACE,"<- attrcrypt_keymgmt_get_key\n", 0, 0, 0);
return ret;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
index 60c3928b..ecef74bc 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
@@ -1047,7 +1047,7 @@ static int ldbm_config_entryrdn_switch_set(void *arg, void *value,
if (apply) {
entryrdn_set_switch((int)((uintptr_t)value));
}
- return LDAP_SUCCESS;
+ return LDAP_SUCCESS;
}
static void *ldbm_config_entryrdn_noancestorid_get(void *arg)
@@ -1061,7 +1061,7 @@ static int ldbm_config_entryrdn_noancestorid_set(void *arg, void *value,
if (apply) {
entryrdn_set_noancestorid((int)((uintptr_t)value));
}
- return LDAP_SUCCESS;
+ return LDAP_SUCCESS;
}
static void *ldbm_config_legacy_errcode_get(void *arg)
@@ -1296,11 +1296,17 @@ void
ldbm_config_read_instance_entries(struct ldbminfo *li, const char *backend_type)
{
Slapi_PBlock *tmp_pb;
- char basedn[BUFSIZ];
Slapi_Entry **entries = NULL;
+ char *basedn = NULL;
/* Construct the base dn of the subtree that holds the instance entries. */
- PR_snprintf(basedn, BUFSIZ, "cn=%s, cn=plugins, cn=config", backend_type);
+ basedn = slapi_create_dn_string("cn=%s,cn=plugins,cn=config", backend_type);
+ if (NULL == basedn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_read_instance_entries: "
+ "failed create backend dn for %s\n", backend_type);
+ return;
+ }
/* Do a search of the subtree containing the instance entries */
tmp_pb = slapi_pblock_new();
@@ -1327,29 +1333,38 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
{
Slapi_PBlock *search_pb;
Slapi_Entry **entries = NULL;
- int res;
- char dn[BUFSIZ];
+ char *dn = NULL;
+ int rval = 0;
/* We try to read the entry
* cn=config, cn=ldbm database, cn=plugins, cn=config. If the entry is
* there, then we process the config information it stores.
*/
- PR_snprintf(dn, BUFSIZ, "cn=config, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=config,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create config dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, dn, LDAP_SCOPE_BASE,
"objectclass=*", NULL, 0, NULL, NULL, li->li_identity, 0);
slapi_search_internal_pb (search_pb);
- slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rval);
- if (LDAP_NO_SUCH_OBJECT == res) {
+ if (LDAP_NO_SUCH_OBJECT == rval) {
/* Add skeleten dse entries for the ldbm plugin */
ldbm_config_add_dse_entries(li, ldbm_skeleton_entries,
li->li_plugin->plg_name, NULL, NULL, 0);
- } else if (res != LDAP_SUCCESS) {
+ } else if (rval != LDAP_SUCCESS) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the ldbm config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
} else {
/* Need to parse the configuration information for the ldbm
* plugin that is held in the DSE. */
@@ -1358,12 +1373,14 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
if (NULL == entries || entries[0] == NULL) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the ldbm config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
if (0 != parse_ldbm_config_entry(li, entries[0], ldbm_config)) {
LDAPDebug(LDAP_DEBUG_ANY, "Error parsing the ldbm config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
}
@@ -1377,8 +1394,6 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
ldbm_config_read_instance_entries(li, li->li_plugin->plg_name);
/* setup the dse callback functions for the ldbm backend config entry */
- PR_snprintf(dn, BUFSIZ, "cn=config, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_config_search_entry_callback,
(void *) li);
@@ -1388,24 +1403,52 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
slapi_config_register_callback(DSE_OPERATION_WRITE, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_config_search_entry_callback,
(void *) li);
+ slapi_ch_free_string(&dn);
/* setup the dse callback functions for the ldbm backend monitor entry */
- PR_snprintf(dn, BUFSIZ, "cn=monitor, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=monitor,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create monitor dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_monitor_search,
(void *)li);
+ slapi_ch_free_string(&dn);
/* And the ldbm backend database monitor entry */
- PR_snprintf(dn, BUFSIZ, "cn=database, cn=monitor, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=database,cn=monitor,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create monitor database dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_dbmonitor_search,
(void *)li);
+ slapi_ch_free_string(&dn);
/* setup the dse callback functions for the ldbm backend instance
* entries */
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=plugins, cn=config", li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create plugin dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsBackendInstance)",
ldbm_instance_add_instance_entry_callback, (void *) li);
@@ -1418,8 +1461,9 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsBackendInstance)",
ldbm_instance_post_delete_instance_entry_callback, (void *) li);
-
- return 0;
+bail:
+ slapi_ch_free_string(&dn);
+ return rval;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
index 9dc0f98d..503c0fc6 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
@@ -622,6 +622,7 @@ int ldbm_instance_config_add_index_entry(
char tmpIndexesStr[256];
char tmpMatchingRulesStr[1024];
struct ldbminfo *li = inst->inst_li;
+ char *dn = NULL;
if ((argc < 2) || (NULL == argv) || (NULL == argv[0]) ||
(NULL == argv[1])) {
@@ -642,31 +643,42 @@ int ldbm_instance_config_add_index_entry(
{
if('\0' == attrs[i][0]) continue;
basetype = slapi_attr_basetype(attrs[i], NULL, 0);
+ dn = slapi_create_dn_string("cn=%s,cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ basetype, inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_add_index_entry: "
+ "failed create index dn with type %s for plugin %s, "
+ "instance %s\n",
+ basetype, inst->inst_li->li_plugin->plg_name,
+ inst->inst_name);
+ return -1;
+ }
eBuf = PR_smprintf(
- "dn: cn=%s, cn=index, cn=%s, cn=%s, cn=plugins, cn=config\n"
- "objectclass:top\n"
- "objectclass:nsIndex\n"
- "cn:%s\n"
- "nsSystemIndex:%s\n",
- basetype, inst->inst_name, li->li_plugin->plg_name,
- basetype,
+ "dn: %s\n"
+ "objectclass: top\n"
+ "objectclass: nsIndex\n"
+ "cn: %s\n"
+ "nsSystemIndex: %s\n",
+ dn, basetype,
(ldbm_attribute_always_indexed(basetype)?"true":"false"));
+ slapi_ch_free_string(&dn);
for(j=0; indexes[j] != NULL; j++)
{
- eBuf = PR_sprintf_append(eBuf, "nsIndexType:%s\n", indexes[j]);
+ eBuf = PR_sprintf_append(eBuf, "nsIndexType:%s\n", indexes[j]);
}
if((argc>2)&&(argv[2]))
{
for(j=0; matchingRules[j] != NULL; j++)
{
- eBuf = PR_sprintf_append(eBuf, "nsMatchingRule:%s\n", matchingRules[j]);
+ eBuf = PR_sprintf_append(eBuf, "nsMatchingRule:%s\n", matchingRules[j]);
}
}
ldbm_config_add_dse_entry(li, eBuf, flags);
- if (eBuf) {
- PR_smprintf_free(eBuf);
- }
+ if (eBuf) {
+ PR_smprintf_free(eBuf);
+ }
slapi_ch_free((void**)&basetype);
}
@@ -722,10 +734,10 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
Slapi_Value *sval = NULL;
const struct berval *attrValue;
char *argv[ 8 ];
- char basedn[BUFSIZ];
char tmpBuf[MAX_TMPBUF];
char tmpBuf2[MAX_TMPBUF];
int argc;
+ char *basedn = NULL;
struct ldbminfo *li;
@@ -742,8 +754,15 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
strcpy(tmpBuf,"");
/* Construct the base dn of the subtree that holds the default user indexes. */
- PR_snprintf(basedn, BUFSIZ, "cn=default indexes, cn=config, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ basedn = slapi_create_dn_string("cn=default indexes,cn=config,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_instance_create_default_user_indexes: "
+ "failed create default index dn for plugin %s\n",
+ inst->inst_li->li_plugin->plg_name);
+ return -1;
+ }
/* Do a search of the subtree containing the index entries */
aPb = slapi_pblock_new();
@@ -821,5 +840,6 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
slapi_free_search_results_internal(aPb);
slapi_pblock_destroy(aPb);
+ slapi_ch_free_string(&basedn);
return 0;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index f20836b4..a6b11668 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -336,13 +336,20 @@ read_instance_index_entries(ldbm_instance *inst)
{
Slapi_PBlock *tmp_pb;
int scope = LDAP_SCOPE_SUBTREE;
- char basedn[BUFSIZ];
const char *searchfilter = "(objectclass=nsIndex)";
+ char *basedn = NULL;
/* Construct the base dn of the subtree that holds the index entries
* for this instance. */
- PR_snprintf(basedn, BUFSIZ, "cn=index, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ basedn = slapi_create_dn_string("cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "read_instance_index_entries: "
+ "failed create index dn for plugin %s, instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ return 1;
+ }
/* Set up a tmp callback that will handle the init for each index entry */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
@@ -361,6 +368,7 @@ read_instance_index_entries(ldbm_instance *inst)
slapi_free_search_results_internal(tmp_pb);
slapi_pblock_destroy(tmp_pb);
+ slapi_ch_free_string(&basedn);
return 0;
}
@@ -372,13 +380,21 @@ read_instance_attrcrypt_entries(ldbm_instance *inst)
{
Slapi_PBlock *tmp_pb;
int scope = LDAP_SCOPE_SUBTREE;
- char basedn[BUFSIZ];
const char *searchfilter = ldbm_instance_attrcrypt_filter;
+ char *basedn = NULL;
/* Construct the base dn of the subtree that holds the index entries
* for this instance. */
- PR_snprintf(basedn, BUFSIZ, "cn=encrypted attributes, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ basedn = slapi_create_dn_string("cn=encrypted attributes,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "read_instance_attrcrypt_entries: "
+ "failed create encrypted attributes dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ return 1;
+ }
/* Set up a tmp callback that will handle the init for each index entry */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
@@ -397,6 +413,7 @@ read_instance_attrcrypt_entries(ldbm_instance *inst)
slapi_free_search_results_internal(tmp_pb);
slapi_pblock_destroy(tmp_pb);
+ slapi_ch_free_string(&basedn);
return 0;
}
@@ -427,10 +444,11 @@ parse_ldbm_instance_config_entry(ldbm_instance *inst, Slapi_Entry *e, config_inf
Slapi_DN suffix;
slapi_attr_first_value(attr, &sval);
+
bval = (struct berval *) slapi_value_get_berval(sval);
slapi_sdn_init_dn_byref(&suffix, bval->bv_val);
if (!slapi_be_issuffix(inst->inst_be, &suffix)) {
- be_addsuffix(inst->inst_be, &suffix);
+ be_addsuffix(inst->inst_be, &suffix);
}
slapi_sdn_done(&suffix);
continue;
@@ -477,25 +495,34 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
struct ldbminfo *li = inst->inst_li;
Slapi_PBlock *search_pb;
Slapi_Entry **entries = NULL;
- int res;
- char dn[BUFSIZ];
+ char *dn = NULL;
+ int rval = 0;
/* We try to read the entry
* cn=instance_name, cn=ldbm database, cn=plugins, cn=config. If the
* entry is there, then we process the config information it stores.
*/
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create instance dn %s for plugin %s\n",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, dn, LDAP_SCOPE_BASE,
"objectclass=*", NULL, 0, NULL, NULL,
li->li_identity, 0);
slapi_search_internal_pb (search_pb);
- slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rval);
- if (res != LDAP_SUCCESS) {
+ if (rval != LDAP_SUCCESS) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the config DSE\n", 0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
} else {
/* Need to parse the configuration information for the ldbm
* plugin that is held in the DSE. */
@@ -504,13 +531,15 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
if ((!entries) || (!entries[0])) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
if (0 != parse_ldbm_instance_config_entry(inst, entries[0],
ldbm_instance_config)) {
LDAPDebug(LDAP_DEBUG_ANY, "Error parsing the config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
}
@@ -527,8 +556,6 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
inst->inst_name, 0);
/* setup the dse callback functions for the ldbm instance config entry */
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
ldbm_instance_search_config_entry_callback, (void *) inst);
@@ -543,9 +570,20 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
ldbm_instance_deny_config, (void *)inst);
/* delete is handled by a callback set in ldbm_config.c */
+ slapi_ch_free_string(&dn);
+
/* don't forget the monitor! */
- PR_snprintf(dn, BUFSIZ, "cn=monitor, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create monitor instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rval = 1;
+ goto bail;
+ }
/* make callback on search; deny add/modify/delete */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_monitor_instance_search,
@@ -557,10 +595,20 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_instance_deny_config,
(void *)inst);
/* delete is okay */
+ slapi_ch_free_string(&dn);
/* Callbacks to handle indexes */
- PR_snprintf(dn, BUFSIZ, "cn=index, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create index instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_add_callback, (void *) inst);
@@ -570,10 +618,20 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_modify_callback, (void *) inst);
+ slapi_ch_free_string(&dn);
/* Callbacks to handle attribute encryption */
- PR_snprintf(dn, BUFSIZ, "cn=encrypted attributes, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=encrypted attributes,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create encrypted attribute instance dn "
+ "for plugin %s, instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, ldbm_instance_attrcrypt_filter,
ldbm_instance_attrcrypt_config_add_callback, (void *) inst);
@@ -583,8 +641,10 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, ldbm_instance_attrcrypt_filter,
ldbm_instance_attrcrypt_config_modify_callback, (void *) inst);
-
- return 0;
+ rval = 0;
+bail:
+ slapi_ch_free_string(&dn);
+ return rval;
}
/*
@@ -880,11 +940,19 @@ ldbm_instance_add_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBe
static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
{
struct ldbminfo *li = inst->inst_li;
- char dn[BUFSIZ];
+ char *dn = NULL;
/* tear down callbacks for the instance config entry */
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
ldbm_instance_search_config_entry_callback);
@@ -897,20 +965,38 @@ static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
ldbm_instance_deny_config);
+ slapi_ch_free_string(&dn);
/* now the cn=monitor entry */
- PR_snprintf(dn, BUFSIZ, "cn=monitor, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create monitor instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_monitor_instance_search);
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=*)", ldbm_instance_deny_config);
slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_instance_deny_config);
+ slapi_ch_free_string(&dn);
/* now the cn=index entries */
- PR_snprintf(dn, BUFSIZ, "cn=index, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create index dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_add_callback);
@@ -920,10 +1006,19 @@ static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_modify_callback);
+ slapi_ch_free_string(&dn);
/* now the cn=encrypted attributes entries */
- PR_snprintf(dn, BUFSIZ, "cn=encrypted attributes, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=encrypted attributes,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create encrypted attributes dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, ldbm_instance_attrcrypt_filter,
ldbm_instance_attrcrypt_config_add_callback);
@@ -935,6 +1030,8 @@ static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
ldbm_instance_attrcrypt_config_modify_callback);
vlv_remove_callbacks(inst);
+bail:
+ slapi_ch_free_string(&dn);
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 6d0a440b..d30a3b93 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -277,13 +277,6 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
/* find and lock the entry we are about to modify */
done_with_pblock_entry(pb,SLAPI_MODRDN_TARGET_ENTRY); /* Could be through this multiple times */
slapi_pblock_get (pb, SLAPI_TARGET_ADDRESS, &old_addr);
- ldap_result_code = slapi_dn_syntax_check(pb, old_addr->dn, 1);
- if (ldap_result_code)
- {
- ldap_result_code = LDAP_INVALID_DN_SYNTAX;
- slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
- goto error_return;
- }
ldap_result_code= get_copy_of_entry(pb, old_addr, &txn, SLAPI_MODRDN_TARGET_ENTRY, !is_replicated_operation);
if(ldap_result_code==LDAP_OPERATIONS_ERROR ||
ldap_result_code==LDAP_INVALID_DN_SYNTAX)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index 2ca6ad45..db1bd926 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -242,6 +242,7 @@ ldbm_back_search( Slapi_PBlock *pb )
dummyAttrs[0] = dummyAttr;
+ /* This dn is normalized. */
PR_snprintf(dn,sizeof(dn),"dn: oid=%s,cn=features,cn=config",LDAP_CONTROL_VLVREQUEST);
feature= slapi_str2entry(dn,0);
r= plugin_call_acl_plugin (pb, feature, dummyAttrs, NULL, SLAPI_ACL_READ, ACLPLUGIN_ACCESS_DEFAULT, NULL);
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index b913d682..60b72db2 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -619,6 +619,7 @@ int ldbm_back_ldif2ldbm( Slapi_PBlock *pb )
if (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) {
/* initialize UniqueID generator - must be done once backends are started
and event queue is initialized but before plugins are started */
+ /* This dn is normalize. */
Slapi_DN *sdn = slapi_sdn_new_dn_byval ("cn=uniqueid generator,cn=config");
int rc = uniqueIDGenInit (NULL, sdn, 0 /* use single thread mode */);
slapi_sdn_free (&sdn);
diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c
index 802370b9..759e37f3 100644
--- a/ldap/servers/slapd/back-ldbm/misc.c
+++ b/ldap/servers/slapd/back-ldbm/misc.c
@@ -143,7 +143,7 @@ compute_entry_tombstone_dn(const char *entrydn, const char *uniqueid)
PR_ASSERT(NULL != entrydn);
PR_ASSERT(NULL != uniqueid);
- tombstone_dn = slapi_ch_smprintf("%s=%s, %s",
+ tombstone_dn = slapi_ch_smprintf("%s=%s,%s",
SLAPI_ATTR_UNIQUEID,
uniqueid,
entrydn);
@@ -158,7 +158,7 @@ compute_entry_tombstone_rdn(const char *entryrdn, const char *uniqueid)
PR_ASSERT(NULL != entryrdn);
PR_ASSERT(NULL != uniqueid);
- tombstone_rdn = slapi_ch_smprintf("%s=%s, %s",
+ tombstone_rdn = slapi_ch_smprintf("%s=%s,%s",
SLAPI_ATTR_UNIQUEID,
uniqueid,
entryrdn);
diff --git a/ldap/servers/slapd/back-ldbm/nextid.c b/ldap/servers/slapd/back-ldbm/nextid.c
index 6e8f6316..02d381b6 100644
--- a/ldap/servers/slapd/back-ldbm/nextid.c
+++ b/ldap/servers/slapd/back-ldbm/nextid.c
@@ -214,7 +214,7 @@ get_ids_from_disk(backend *be)
void id_internal_to_stored(ID i,char *b)
{
if ( sizeof(ID) > 4 ) {
- memset (b+4, 0, sizeof(ID)-4);
+ (void)memset (b+4, 0, sizeof(ID)-4);
}
b[0] = (char)(i >> 24);
diff --git a/ldap/servers/slapd/back-ldbm/vlv.c b/ldap/servers/slapd/back-ldbm/vlv.c
index 2402017d..2f2cb48e 100644
--- a/ldap/servers/slapd/back-ldbm/vlv.c
+++ b/ldap/servers/slapd/back-ldbm/vlv.c
@@ -339,7 +339,7 @@ vlv_init(ldbm_instance *inst)
/* The FE DSE *must* be initialised before we get here */
int return_value= LDAP_SUCCESS;
int scope= LDAP_SCOPE_SUBTREE;
- char *basedn, buf[512];
+ char *basedn = NULL;
const char *searchfilter = "(objectclass=vlvsearch)";
const char *indexfilter = "(objectclass=vlvindex)";
backend *be= inst->inst_be;
@@ -368,9 +368,15 @@ vlv_init(ldbm_instance *inst)
if (inst == NULL) {
basedn = NULL;
} else {
- PR_snprintf(buf, sizeof(buf), "cn=%s,cn=%s,cn=plugins,cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
- basedn = buf;
+ basedn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "vlv_init: failed to create vlv dn for plugin %s, instance %s\n",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ return_value = LDAP_PARAM_ERROR;
+ return return_value;
+ }
}
/* Find the VLV Search Entries */
@@ -405,6 +411,7 @@ vlv_init(ldbm_instance *inst)
slapi_config_register_callback(SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_DeleteIndexEntry,(void*)inst);
slapi_config_register_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,searchfilter,vlv_ModifyRDNSearchEntry,(void*)inst);
slapi_config_register_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_ModifyRDNIndexEntry,(void*)inst);
+ slapi_ch_free_string(&basedn);
}
return return_value;
@@ -417,16 +424,22 @@ vlv_remove_callbacks(ldbm_instance *inst) {
int return_value= LDAP_SUCCESS;
int scope= LDAP_SCOPE_SUBTREE;
- char *basedn, buf[512];
+ char *basedn = NULL;
const char *searchfilter = "(objectclass=vlvsearch)";
const char *indexfilter = "(objectclass=vlvindex)";
if (inst == NULL) {
basedn = NULL;
} else {
- PR_snprintf(buf, sizeof(buf), "cn=%s,cn=%s,cn=plugins,cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
- basedn = buf;
+ basedn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "vlv_remove_callbacks: failed to create vlv dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ return_value = LDAP_PARAM_ERROR;
+ }
}
if(basedn!=NULL)
{
@@ -439,8 +452,9 @@ vlv_remove_callbacks(ldbm_instance *inst) {
slapi_config_remove_callback(SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_DeleteIndexEntry);
slapi_config_remove_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,searchfilter,vlv_ModifyRDNSearchEntry);
slapi_config_remove_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_ModifyRDNIndexEntry);
+ slapi_ch_free_string(&basedn);
}
- return return_value;
+ return return_value;
}
/* Find an enabled index which matches this description. */
@@ -1980,17 +1994,13 @@ char *create_vlv_search_tag(const char* dn) {
/* Builds strings from Slapi_DN similar console GUI. Uses those dns to
delete vlvsearch's if they match. New write lock.
*/
-
-#define LDBM_PLUGIN_ROOT ", cn=ldbm database, cn=plugins, cn=config"
-#define TAG "cn=by MCC "
-
int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *inst)
{
int rc=0;
Slapi_PBlock *tmppb;
Slapi_DN *newdn;
struct vlvSearch* p=NULL;
- char *buf, *buf2, *tag1, *tag2;
+ char *base1 = NULL, *base2 = NULL, *tag1 = NULL, *tag2 = NULL;
const char *dn= slapi_sdn_get_dn(&e->e_sdn);
backend *be= NULL;
if (NULL == inst) {
@@ -2007,8 +2017,18 @@ int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *ins
return LDAP_OPERATIONS_ERROR;
}
tag1=create_vlv_search_tag(dn);
- buf=slapi_ch_smprintf("%s%s%s%s%s","cn=MCC ",tag1,", cn=",inst->inst_name,LDBM_PLUGIN_ROOT);
- newdn=slapi_sdn_new_dn_byval(buf);
+ base1 = slapi_create_dn_string("cn=MCC %s,cn=%s,cn=%s,cn=plugins,cn=config",
+ tag1, inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == base1) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "vlv_delete_search_entry: "
+ "failed to craete vlv search entry dn (rdn: cn=MCC %s) for "
+ "plugin %s, instance %s\n",
+ tag1, inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rc = LDAP_PARAM_ERROR;
+ goto bail;
+ }
+ newdn = slapi_sdn_new_dn_byval(base1);
/* vlvSearchList is modified; need Wlock */
PR_RWLock_Wlock(be->vlvSearchList_lock);
p = vlvSearch_finddn((struct vlvSearch *)be->vlvSearchList, newdn);
@@ -2016,37 +2036,49 @@ int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *ins
{
LDAPDebug( LDAP_DEBUG_ANY, "Deleted Virtual List View Search (%s).\n", p->vlv_name, 0, 0);
tag2=create_vlv_search_tag(dn);
- buf2=slapi_ch_smprintf("%s%s,%s",TAG,tag2,buf);
+ base2 = slapi_create_dn_string("cn=by MCC %s,%s", tag2, base1);
+ if (NULL == base2) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "vlv_delete_search_entry: failed to create "
+ "vlv search entry dn (rdn: cn=by MCC %s) for "
+ "plugin %s, instance %s\n",
+ tag2, inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rc = LDAP_PARAM_ERROR;
+ slapi_ch_free((void **)&tag2);
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
+ goto bail;
+ }
vlvSearch_removefromlist((struct vlvSearch **)&be->vlvSearchList,p->vlv_dn);
/* This line release lock to prevent recursive deadlock caused by slapi_internal_delete calling vlvDeleteSearchEntry */
PR_RWLock_Unlock(be->vlvSearchList_lock);
vlvSearch_delete(&p);
tmppb = slapi_pblock_new();
- slapi_delete_internal_set_pb(tmppb, buf2, NULL, NULL,
+ slapi_delete_internal_set_pb(tmppb, base2, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
slapi_delete_internal_pb(tmppb);
slapi_pblock_get (tmppb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
if(rc != LDAP_SUCCESS) {
- LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", buf2, 0, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", base2, 0, 0);
}
pblock_done(tmppb);
pblock_init(tmppb);
- slapi_delete_internal_set_pb(tmppb, buf, NULL, NULL,
+ slapi_delete_internal_set_pb(tmppb, base1, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
slapi_delete_internal_pb(tmppb);
slapi_pblock_get (tmppb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
if(rc != LDAP_SUCCESS) {
- LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", buf, 0, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", base1, 0, 0);
}
slapi_pblock_destroy(tmppb);
slapi_ch_free((void **)&tag2);
- slapi_ch_free((void **)&buf2);
+ slapi_ch_free((void **)&base2);
} else {
PR_RWLock_Unlock(be->vlvSearchList_lock);
}
+bail:
instance_set_not_busy(inst);
slapi_ch_free((void **)&tag1);
- slapi_ch_free((void **)&buf);
+ slapi_ch_free((void **)&base1);
slapi_sdn_free(&newdn);
return rc;
}
diff --git a/ldap/servers/slapd/backend.c b/ldap/servers/slapd/backend.c
index 4b2d9283..8784866b 100644
--- a/ldap/servers/slapd/backend.c
+++ b/ldap/servers/slapd/backend.c
@@ -47,18 +47,32 @@
void
be_init( Slapi_Backend *be, const char *type, const char *name, int isprivate, int logchanges, int sizelimit, int timelimit )
{
- char text[128];
slapdFrontendConfig_t *fecfg;
be->be_suffix = NULL;
be->be_suffixlock= PR_NewLock();
be->be_suffixcount= 0;
/* e.g. dn: cn=config,cn=NetscapeRoot,cn=ldbm database,cn=plugins,cn=config */
- PR_snprintf(text, sizeof(text),"cn=%s,cn=%s,cn=plugins,cn=config", name, type);
- be->be_basedn= slapi_ch_strdup(slapi_dn_normalize(text));
- PR_snprintf(text, sizeof(text), "cn=config,cn=%s,cn=%s,cn=plugins,cn=config", name, type);
- be->be_configdn= slapi_ch_strdup(slapi_dn_normalize(text));
- PR_snprintf(text, sizeof(text), "cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config", name, type);
- be->be_monitordn= slapi_ch_strdup(slapi_dn_normalize(text));
+ be->be_basedn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ name, type);
+ if (NULL == be->be_basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "be_init: failed create instance dn for plugin %s, "
+ "instance %s\n", type, name);
+ }
+ be->be_configdn = slapi_create_dn_string("cn=config,cn=%s,cn=%s,cn=plugins,cn=config",
+ name, type);
+ if (NULL == be->be_configdn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "be_init: failed create instance config dn for "
+ "plugin %s, instance %s\n", type, name);
+ }
+ be->be_monitordn = slapi_create_dn_string("cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config",
+ name, type);
+ if (NULL == be->be_configdn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "be_init: failed create instance monitor dn for "
+ "plugin %s, instance %s\n", type, name);
+ }
be->be_sizelimit = sizelimit;
be->be_timelimit = timelimit;
/* maximum group nesting level before giving up */
diff --git a/ldap/servers/slapd/backend_manager.c b/ldap/servers/slapd/backend_manager.c
index 18184376..6456f299 100644
--- a/ldap/servers/slapd/backend_manager.c
+++ b/ldap/servers/slapd/backend_manager.c
@@ -423,12 +423,6 @@ be_nbackends_public()
}
/* backend instance management */
-/* JCM - These are hardcoded for the LDBM database */
-#define LDBM_CLASS_PREFIX "cn=ldbm database,cn=plugins,cn=config"
-#define LDBM_CONFIG_ENTRY "cn=config,cn=ldbm database,cn=plugins,cn=config"
-#define INSTANCE_ATTR "nsslapd-instance"
-#define SUFFIX_ATTR "nsslapd-suffix"
-#define CACHE_ATTR "nsslapd-cachememsize"
void
slapi_be_Rlock(Slapi_Backend * be)
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index f0bdbae4..626494bc 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -123,6 +123,7 @@ do_bind( Slapi_PBlock *pb )
ber_int_t version = -1;
int auth_response_requested = 0;
int pw_response_requested = 0;
+ char *rawdn = NULL;
char *dn = NULL, *saslmech = NULL;
struct berval cred = {0};
Slapi_Backend *be = NULL;
@@ -136,6 +137,7 @@ do_bind( Slapi_PBlock *pb )
int auto_bind = 0;
int minssf = 0;
char *test_bind_dn = NULL;
+ size_t dnlen = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
@@ -159,7 +161,7 @@ do_bind( Slapi_PBlock *pb )
* }
*/
- rc = ber_scanf( ber, "{iat", &version, &dn, &method );
+ rc = ber_scanf( ber, "{iat", &version, &rawdn, &method );
if ( rc == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Bind; params=Version,DN,Method)\n",
@@ -167,11 +169,37 @@ do_bind( Slapi_PBlock *pb )
log_bind_access (pb, "???", method, version, saslmech, "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"decoding error", 0, NULL );
- slapi_ch_free_string(&dn);
+ slapi_ch_free_string(&rawdn);
return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "BIND", rawdn?rawdn:"",
+ "strict: invalid bind dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid bind dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "BIND", rawdn?rawdn:"",
+ "invalid bind dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid bind dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ } else if (rc > 0) { /* if rc == 0, rawdn is passed in */
+ slapi_ch_free_string(&rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
- slapi_sdn_init_dn_passin(&sdn,dn);
+ slapi_sdn_init_dn_passin(&sdn, dn);
LDAPDebug( LDAP_DEBUG_TRACE, "BIND dn=\"%s\" method=%d version=%d\n",
dn, method, version );
diff --git a/ldap/servers/slapd/compare.c b/ldap/servers/slapd/compare.c
index 5a0256ba..578d826a 100644
--- a/ldap/servers/slapd/compare.c
+++ b/ldap/servers/slapd/compare.c
@@ -65,7 +65,9 @@ void
do_compare( Slapi_PBlock *pb )
{
BerElement *ber = pb->pb_op->o_ber;
+ char *rawdn = NULL;
char *dn = NULL;
+ size_t len = 0;
struct ava ava = {0};
Slapi_Backend *be = NULL;
int err;
@@ -94,15 +96,40 @@ do_compare( Slapi_PBlock *pb )
* }
*/
- if ( ber_scanf( ber, "{a{ao}}", &dn, &ava.ava_type,
+ if ( ber_scanf( ber, "{a{ao}}", &rawdn, &ava.ava_type,
&ava.ava_value ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Compare; params=DN,Type,Value)\n",
0, 0, 0 );
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
- NULL );
+ NULL );
goto free_and_return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "CMP",
+ rawdn?rawdn:"", "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawdn, 0, &dn, &len);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "CMP", rawdn?rawdn:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ } else if (err > 0) { /* if rc == 0, rawdn is passed in */
+ slapi_ch_free((void **) &rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + len) = '\0';
+ }
/*
* in LDAPv3 there can be optional control extensions on
* the end of an LDAPMessage. we need to read them in and
diff --git a/ldap/servers/slapd/delete.c b/ldap/servers/slapd/delete.c
index c17b669a..3a80eeba 100644
--- a/ldap/servers/slapd/delete.c
+++ b/ldap/servers/slapd/delete.c
@@ -71,8 +71,10 @@ do_delete( Slapi_PBlock *pb )
{
Slapi_Operation *operation;
BerElement *ber;
+ char *rawdn = NULL;
char *dn = NULL;
- int err;
+ size_t dnlen = 0;
+ int err = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_delete\n", 0, 0, 0 );
@@ -88,7 +90,7 @@ do_delete( Slapi_PBlock *pb )
* DelRequest := DistinguishedName
*/
- if ( ber_scanf( pb->pb_op->o_ber, "a", &dn ) == LBER_ERROR ) {
+ if ( ber_scanf( pb->pb_op->o_ber, "a", &rawdn ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Delete; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "DEL", "???", "decoding error");
@@ -96,6 +98,31 @@ do_delete( Slapi_PBlock *pb )
NULL );
goto free_and_return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "DEL", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ goto free_and_return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "DEL", "???", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ goto free_and_return;
+ } else if (err > 0) { /* if err == 0, rawdn is passed in */
+ slapi_ch_free_string(&rawdn);
+ } else { /* err == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
/*
* in LDAPv3 there can be optional control extensions on
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index f9c22589..743aa361 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -57,9 +57,9 @@
static void add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
struct berval **rdn_avsp, struct berval *avstack );
static void reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp );
-static void sort_rdn_avs( struct berval *avs, int count );
+static void sort_rdn_avs( struct berval *avs, int count, int escape );
static int rdn_av_cmp( struct berval *av1, struct berval *av2 );
-static void rdn_av_swap( struct berval *av1, struct berval *av2 );
+static void rdn_av_swap( struct berval *av1, struct berval *av2, int escape );
int
@@ -77,24 +77,53 @@ hexchar2int( char c )
return( -1 );
}
+#define ISBLANK(c) ((c) == ' ')
+#define ISSPACE(c) (ISBLANK(c) || ((c) == '\n') || ((c) == '\r')) /* XXX 518524 */
+
+#define ISEQUAL(c) ((c) == '=')
+#define ISEQUALSTR(s) \
+ ((*(s) == '3') && ((*((s)+1) == 'd') || (*((s)+1) == 'D')))
+
+#define ISPLUS(c) ((c) == '+')
+#define ISPLUSSTR(s) \
+ ((*(s) == '2') && ((*((s)+1) == 'b') || (*((s)+1) == 'B')))
+
+#define ISESCAPE(c) ((c) == '\\')
+#define ISQUOTE(c) ((c) == '"')
+
#define DNSEPARATOR(c) (((c) == ',') || ((c) == ';'))
-#define SEPARATOR(c) (((c) == ',') || ((c) == ';') || ((c) == '+'))
-#define SPACE(c) (((c) == ' ') || ((c) == '\n')) /* XXX 518524 */
-#define NEEDSESCAPE(c) (((c) == '\\') || ((c) == '"') || ((c) == '+') || \
- ((c) == ',') || ((c) == ';') || ((c) == '<') || ((c) == '>') || ((c) == '='))
-#define LEADNEEDSESCAPE(c) (((c) == ' ') || ((c) == '#') || NEEDSESCAPE(c))
-#if 0 /* not used */
-#define ONLYTRAILNEEDSESCAPE(c) ((c) == ' ')
-#define TRAILNEEDSESCAPE(c) (ONLYTRAILNEEDSESCAPE(c) || NEEDSESCAPE(c))
-#endif
-#define B4TYPE 0
-#define INTYPE 1
-#define B4EQUAL 2
-#define B4VALUE 3
-#define INVALUE 4
-#define INQUOTEDVALUE 5
-#define B4SEPARATOR 6
-#define INVALUE1ST 7
+#define DNSEPARATORSTR(s) \
+ (((*(s) == '2') && ((*((s)+1) == 'c') || (*((s)+1) == 'C'))) || \
+ ((*(s) == '3') && ((*((s)+1) == 'b') || (*((s)+1) == 'B'))))
+
+#define SEPARATOR(c) (DNSEPARATOR(c) || ISPLUS(c))
+#define SEPARATORSTR(s) (DNSEPARATORSTR(s) || ISPLUSSTR(s))
+
+#define NEEDSESCAPE(c) (ISESCAPE(c) || ISQUOTE(c) || SEPARATOR(c) || \
+ ((c) == '<') || ((c) == '>') || ISEQUAL(c))
+#define NEEDSESCAPESTR(s) \
+ (((*(s) == '2') && ((*((s)+1) == '2') || \
+ (*((s)+1) == 'b') || (*((s)+1) == 'B') || \
+ (*((s)+1) == 'c') || (*((s)+1) == 'C'))) || \
+ ((*(s) == '3') && (((*((s)+1) >= 'b') && (*((s)+1) < 'f')) || \
+ ((*((s)+1) >= 'B') && (*((s)+1) < 'F')))) || \
+ ((*(s) == '5') && ((*((s)+1) == 'c') || (*((s)+1) == 'C'))))
+
+#define LEADNEEDSESCAPE(c) (ISBLANK(c) || ((c) == '#') || NEEDSESCAPE(c))
+#define LEADNEEDSESCAPESTR(s) (NEEDSESCAPESTR(s) || \
+ ((*(s) == '2') && (*((s)+1) == '3')))
+
+#define ISCLOSEBRACKET(c) (((c) == ')') || ((c) == ']'))
+
+#define B4TYPE 0
+#define INTYPE 1
+#define B4EQUAL 2
+#define B4VALUE 3
+#define INVALUE 4
+#define INQUOTEDVALUE 5
+#define B4SEPARATOR 6
+#define INVALUE1ST 7
+#define INQUOTEDVALUE1ST 8
#define SLAPI_DNNORM_INITIAL_RDN_AVS 10
#define SLAPI_DNNORM_SMALL_RDN_AV 512
@@ -137,13 +166,13 @@ hexchar2int( char c )
*
* This function does not support UTF-8 multi-byte encoding for attribute
* values, in particular it does not support UTF-8 whitespace. First the
- * SPACE macro above is limited, but also its frequent use of '-1' indexing
+ * ISSPACE macro above is limited, but also its frequent use of '-1' indexing
* into a char[] may hit the middle of a multi-byte UTF-8 whitespace character
* encoding (518524).
*/
char *
-substr_dn_normalize( char *dn, char *end )
+substr_dn_normalize_orig( char *dn, char *end )
{
/* \xx is changed to \c.
* \c is changed to c, unless this would change its meaning.
@@ -166,7 +195,7 @@ substr_dn_normalize( char *dn, char *end )
for ( d = s = dn; s != end; s++ ) {
switch ( state ) {
case B4TYPE:
- if ( ! SPACE( *s ) ) {
+ if ( ! ISSPACE( *s ) ) {
state = INTYPE;
typestart = d;
*d++ = *s;
@@ -176,7 +205,7 @@ substr_dn_normalize( char *dn, char *end )
if ( *s == '=' ) {
state = B4VALUE;
*d++ = *s;
- } else if ( SPACE( *s ) ) {
+ } else if ( ISSPACE( *s ) ) {
state = B4EQUAL;
} else {
*d++ = *s;
@@ -186,13 +215,13 @@ substr_dn_normalize( char *dn, char *end )
if ( *s == '=' ) {
state = B4VALUE;
*d++ = *s;
- } else if ( ! SPACE( *s ) ) {
+ } else if ( ! ISSPACE( *s ) ) {
/* not a valid dn - but what can we do here? */
*d++ = *s;
}
break;
case B4VALUE:
- if ( *s == '"' || ! SPACE( *s ) ) {
+ if ( *s == '"' || ! ISSPACE( *s ) ) {
value_separator = NULL;
value = d;
state = ( *s == '"' ) ? INQUOTEDVALUE : INVALUE1ST;
@@ -223,7 +252,7 @@ substr_dn_normalize( char *dn, char *end )
* be if it does at the end of the RDN value */
/* e.g., ou=ABC \ ,o=XYZ --> ou=ABC \ ,o=XYZ */
if ( lastesc ) {
- while ( SPACE( *(d - 1) ) && d > lastesc ) {
+ while ( ISSPACE( *(d - 1) ) && d > lastesc ) {
d--;
}
if ( d == lastesc ) {
@@ -231,7 +260,7 @@ substr_dn_normalize( char *dn, char *end )
*d++ = ' '; /* escaped trailing space */
}
} else {
- while ( SPACE( *(d - 1) ) ) {
+ while ( ISSPACE( *(d - 1) ) ) {
d--;
}
}
@@ -281,7 +310,7 @@ substr_dn_normalize( char *dn, char *end )
}
if ( *s != '+' ) { /* at end of this RDN */
if ( rdn_av_count > 1 ) {
- sort_rdn_avs( rdn_avs, rdn_av_count );
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
}
if ( rdn_av_count > 0 ) {
reset_rdn_avs( &rdn_avs, &rdn_av_count );
@@ -304,7 +333,7 @@ substr_dn_normalize( char *dn, char *end )
} else if ( *s == '"' ) {
state = B4SEPARATOR;
if ( value_separator == dn /* 2 or more separators */
- || SPACE( value[1] ) || SPACE( d[-1] ) ) {
+ || ISSPACE( value[1] ) || ISSPACE( d[-1] ) ) {
*d++ = *s;
} else {
/* convert to non-quoted value: */
@@ -338,7 +367,7 @@ substr_dn_normalize( char *dn, char *end )
}
if ( *s != '+' ) { /* at end of this RDN */
if ( rdn_av_count > 1 ) {
- sort_rdn_avs( rdn_avs, rdn_av_count );
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
}
if ( rdn_av_count > 0 ) {
reset_rdn_avs( &rdn_avs, &rdn_av_count );
@@ -397,7 +426,7 @@ substr_dn_normalize( char *dn, char *end )
&rdn_avs, initial_rdn_av_stack );
}
if ( rdn_av_count > 1 ) {
- sort_rdn_avs( rdn_avs, rdn_av_count );
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
}
if ( rdn_av_count > 0 ) {
reset_rdn_avs( &rdn_avs, &rdn_av_count );
@@ -408,7 +437,540 @@ substr_dn_normalize( char *dn, char *end )
return( d );
}
+char *
+substr_dn_normalize( char *dn, char *end )
+{
+ /* no op */
+ return end;
+}
+
+/*
+ * 1) Escaped NEEDSESCAPE chars (e.g., ',', '<', '=', etc.) are converted to
+ * ESC HEX HEX (e.g., \2C, \3C, \3D, etc.)
+ * Input could be a string in double quotes
+ * (= old DN format: dn: cn="x=x,y=y",... --> dn: cn=x\3Dx\2Cy\3Dy,...) or
+ * an escaped string
+ * (= new DN format dn: cn=x\=x\,y\=y,... -> dn: cn=x\3Dx\2Cy\3Dy,...)
+ *
+ * 2) All the other ESC HEX HEX are converted to the real characters.
+ *
+ * 3) Spaces around separator ',', ';', and '+' are removed.
+ *
+ * Input:
+ * src: src DN
+ * src_len: length of src; 0 is acceptable if src is NULL terminated.
+ * Output:
+ * dest: address of the converted string; NULL terminated
+ * (could store src address if no need to convert)
+ * dest_len: length of dest
+ *
+ * Return values:
+ * 0: nothing was done; dest is identical to src (src is passed in).
+ * 1: successfully escaped; dest is different from src. src needs to be freed.
+ * -1: failed; dest is NULL; invalid DN
+ */
+int
+slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
+{
+ int rc = -1;
+ int state = B4TYPE;
+ char *s = NULL; /* work pointer for src */
+ char *d = NULL; /* work pointer for dest */
+ char *ends = NULL;
+ char *endd = NULL;
+ char *typestart = NULL;
+ char *subtypestart = NULL; /* used for the nested DN */
+ char *lastesc = NULL;
+ int rdn_av_count = 0;
+ struct berval *rdn_avs = NULL;
+ struct berval initial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
+ int chkblank = 0;
+
+ if (NULL == dest) {
+ goto bail;
+ }
+ if (NULL == src) {
+ *dest = NULL;
+ *dest_len = 0;
+ goto bail;
+ }
+ if (0 == src_len) {
+ src_len = strlen(src);
+ }
+ s = PL_strnchr(src, '\\', src_len);
+ if (s) {
+ *dest_len = src_len * 3;
+ *dest = slapi_ch_malloc(*dest_len); /* max length */
+ rc = 1;
+ } else {
+ s = PL_strnchr(src, '"', src_len);
+ if (s) {
+ *dest_len = src_len * 3;
+ *dest = slapi_ch_malloc(*dest_len); /* max length */
+ rc = 1;
+ } else {
+ *dest_len = src_len;
+ *dest = src; /* just removing spaces around separators */
+ rc = 0;
+ }
+ }
+
+ ends = src + src_len;
+ endd = *dest + *dest_len;
+ for (s = src, d = *dest; s < ends && d < endd; ) {
+ switch (state) {
+ case B4TYPE: /* before type; cn=... */
+ /* ^ */
+ if (ISSPACE(*s)) {
+ s++; /* skip leading spaces */
+ } else {
+ state = INTYPE;
+ typestart = d;
+ *d++ = *s++;
+ }
+ break;
+ case INTYPE: /* in type; cn=... */
+ /* ^ */
+ if (ISEQUAL(*s)) {
+ state = B4VALUE;
+ *d++ = *s++;
+ } else if (ISCLOSEBRACKET(*s)) { /* special care for ACL macro */
+ state = INVALUE; /* skip a trailing space */
+ *d++ = *s++;
+ } else if (ISSPACE(*s)) {
+ state = B4EQUAL; /* skip a trailing space */
+ } else {
+ *d++ = *s++;
+ }
+ break;
+ case B4EQUAL: /* before equal; cn =... */
+ /* ^ */
+ if (ISEQUAL(*s)) {
+ state = B4VALUE;
+ *d++ = *s++;
+ } else if (ISSPACE(*s)) {
+ s++; /* skip trailing spaces */
+ } else {
+ /* type includes spaces; not a valid dn */
+ rc = -1;
+ goto bail;
+ }
+ break;
+ case B4VALUE: /* before value; cn= ABC */
+ /* ^ */
+ if (ISSPACE(*s)) {
+ s++;
+ } else {
+ if (ISQUOTE(*s)) {
+ s++; /* start with the first char in quotes */
+ state = INQUOTEDVALUE1ST;
+ } else {
+ state = INVALUE1ST;
+ }
+ lastesc = NULL;
+ /* process *s in INVALUE or INQUOTEDVALUE */
+ }
+ break;
+ case INVALUE1ST: /* 1st char in value; cn=ABC */
+ /* ^ */
+ if (ISSPACE(*s)) { /* skip leading spaces */
+ s++;
+ continue;
+ } else if (SEPARATOR(*s)) {
+ /* 1st char in value is separator; invalid dn */
+ rc = -1;
+ goto bail;
+ } /* otherwise, go through */
+ case INVALUE: /* in value; cn=ABC */
+ /* ^ */
+ if (ISESCAPE(*s)) {
+ if (s + 1 >= ends) {
+ /* DN ends with '\'; invalid dn */
+ rc = -1;
+ goto bail;
+ }
+ if (((state == INVALUE1ST) && LEADNEEDSESCAPE(*(s+1))) ||
+ ((state == INVALUE) && NEEDSESCAPE(*(s+1)))) {
+ if (d + 2 >= endd) {
+ /* Not enough space for dest; this never happens! */
+ rc = -1;
+ goto bail;
+ } else {
+ if (ISEQUAL(*(s+1))) {
+ if (NULL == subtypestart) {
+ /* e.g., cn=a\=b\,c\=d */
+ /* ^ */
+ *d = '\0';
+ subtypestart = strrchr(*dest, '=');
+ if (subtypestart) {
+ /* pointing 'a' in the above example */
+ subtypestart++;
+ }
+ /* else
+ * No equal for the nested DN looking value.
+ * Just through it.
+ */
+ }
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATOR(*(s+1))) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ if (chkblank && ISESCAPE(*(d-1)) && ISBLANK(*d)) {
+ /* last space is escaped "cn=A\ ,ou=..." */
+ /* ^ */
+ PR_snprintf(d, 3, "%X", *d); /* hexpair */
+ d += 2;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (subtypestart &&
+ (ISPLUS(*(s+1)) || rdn_av_count > 0)) {
+ add_rdn_av(subtypestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*(s+1))) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 1 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ subtypestart = NULL;
+ }
+ }
+ }
+ /* dn: cn=x\=x\,... -> dn: cn=x\3Dx\2C,... */
+ *d++ = *s++; /* '\\' */
+ PR_snprintf(d, 3, "%X", *s); /* hexpair */
+ d += 2;
+ if (ISPLUS(*s) && PL_strnstr(s, "\\=", ends - s)) {
+ /* next type start of multi values */
+ subtypestart = d;
+ }
+ if (SEPARATOR(*s) || ISEQUAL(*s)) {
+ while (ISSPACE(*(s+1)))
+ s++; /* remove leading spaces */
+ s++;
+ } else {
+ s++;
+ }
+ }
+ } else if (((state == INVALUE1ST) && (s+2 < ends) &&
+ LEADNEEDSESCAPESTR(s+1)) ||
+ ((state == INVALUE) && (s+2 < ends) &&
+ NEEDSESCAPESTR(s+1))) {
+ if (ISEQUALSTR(s+1)) {
+ if (NULL == subtypestart) {
+ /* e.g., cn=a\3Db\2Cc\3Dd */
+ /* ^ */
+ *d = '\0';
+ subtypestart = strrchr(*dest, '=');
+ if (subtypestart) {
+ /* pointing 'a' in the above example */
+ subtypestart++;
+ }
+ /* else
+ * No equal for the nested DN looking value.
+ * Just through it.
+ */
+ }
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATORSTR(s+1)) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ if (chkblank && ISESCAPE(*(d-1)) && ISBLANK(*d)) {
+ /* last space is escaped "cn=A\ ,ou=..." */
+ /* ^ */
+ PR_snprintf(d, 3, "%X", *d); /* hexpair */
+ d += 2;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (subtypestart &&
+ (ISPLUSSTR(s+1) || rdn_av_count > 0)) {
+ add_rdn_av(subtypestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUSSTR(s+1)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 1 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ }
+ }
+ *d++ = *s++; /* '\\' */
+ *d++ = *s++; /* HEX */
+ *d++ = *s++; /* HEX */
+ if (ISPLUSSTR(s-2) && PL_strnstr(s, "\\=", ends - s)) {
+ /* next type start of multi values */
+ subtypestart = d;
+ }
+ if (SEPARATORSTR(s-2) || ISEQUALSTR(s-2)) {
+ while (ISSPACE(*s)) /* remove leading spaces */
+ s++;
+ }
+ } else if (s + 2 < ends &&
+ isxdigit(*(s+1)) && isxdigit(*(s+2))) {
+ /* esc hexpair ==> real character */
+ int n = hexchar2int(*(s+1));
+ int n2 = hexchar2int(*(s+2));
+ n = (n << 4) + n2;
+ if (n == 0) { /* don't change \00 */
+ *d++ = *++s;
+ *d++ = *++s;
+ } else {
+ *d++ = n;
+ s += 3;
+ }
+ } else {
+ /* ignore an escape for now */
+ lastesc = d; /* position of the previous escape */
+ s++;
+ }
+ } else if (SEPARATOR(*s)) { /* cn=ABC , ... */
+ /* ^ */
+ /* handling a trailing escaped space */
+ /* assuming a space is the only an extra character which
+ * is not escaped if it appears in the middle, but should
+ * be if it does at the end of the RDN value */
+ /* e.g., ou=ABC \ ,o=XYZ --> ou=ABC \ ,o=XYZ */
+ if (lastesc) {
+ while (ISSPACE(*(d-1)) && d > lastesc ) {
+ d--;
+ }
+ if (d == lastesc) {
+ /* esc hexpair of space: \20 */
+ *d++ = '\\';
+ *d++ = '2';
+ *d++ = '0';
+ }
+ } else {
+ while (ISSPACE(*(d-1))) {
+ d--;
+ }
+ }
+ state = B4SEPARATOR;
+ break;
+ } else { /* else if (SEPARATOR(*s)) */
+ *d++ = *s++;
+ }
+ if (state == INVALUE1ST) {
+ state = INVALUE;
+ }
+ break;
+ case INQUOTEDVALUE1ST:
+ if (ISSPACE(*s) && (s+1 < ends && ISSPACE(*(s+1)))) {
+ /* skip leading spaces but need to leave one */
+ s++;
+ continue;
+ }
+ subtypestart = d; /* prepare for '+' in the quoted value, if any */
+ case INQUOTEDVALUE:
+ if (ISQUOTE(*s)) {
+ if (ISESCAPE(*(d-1))) { /* the quote is escaped */
+ PR_snprintf(d, 3, "%X", *(s++)); /* hexpair */
+ } else { /* end of INQUOTEVALUE */
+ while (ISSPACE(*(d-1))) { /* eliminate trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ /* We have to keep the last ' ' of a value in quotes.
+ * The same idea as the escaped last space:
+ * "cn=A,ou=B " */
+ /* ^ */
+ if (chkblank && ISBLANK(*d)) {
+ PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
+ d += 3;
+ chkblank = 0;
+ }
+ state = B4SEPARATOR;
+ s++;
+ }
+ } else if (((state == INQUOTEDVALUE1ST) && LEADNEEDSESCAPE(*s)) ||
+ (state == INQUOTEDVALUE && NEEDSESCAPE(*s))) {
+ if (d + 2 >= endd) {
+ /* Not enough space for dest; this never happens! */
+ rc = -1;
+ goto bail;
+ } else {
+ if (ISEQUAL(*s)) {
+ while (ISSPACE(*(d-1))) { /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATOR(*s)) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) { /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ /* We have to keep the last ' ' of a value in quotes.
+ * The same idea as the escaped last space:
+ * "cn=A\ ,ou=..." */
+ /* ^ */
+ if (chkblank && ISBLANK(*d)) {
+ PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
+ d += 3;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (ISPLUS(*s) || rdn_av_count > 0) {
+ add_rdn_av(subtypestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*s)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 1 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ subtypestart = NULL;
+ }
+ }
+ }
+
+ /* dn: cn="x=x,..",... -> dn: cn=x\3Dx\2C,... */
+ *d++ = '\\';
+ PR_snprintf(d, 3, "%X", *s); /* hexpair */
+ d += 2;
+ if (ISPLUS(*s++)) {
+ subtypestart = d; /* next type start of multi values */
+ }
+ if (SEPARATOR(*(s-1)) || ISEQUAL(*(s-1))) {
+ while (ISSPACE(*s)) /* remove leading spaces */
+ s++;
+ }
+ }
+ } else {
+ *d++ = *s++;
+ }
+ if (state == INQUOTEDVALUE1ST) {
+ state = INQUOTEDVALUE;
+ }
+ break;
+ case B4SEPARATOR:
+ if (SEPARATOR(*s)) {
+ state = B4TYPE;
+
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (ISPLUS(*s) || rdn_av_count > 0) {
+ add_rdn_av(typestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*s)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ }
+
+ *d++ = (ISPLUS(*s++)) ? '+' : ',';
+ } else {
+ s++;
+ }
+ break;
+ default:
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "slapi_dn_normalize - unknown state %d\n", state, 0, 0 );
+ break;
+ }
+ }
+
+ /*
+ * Track and sort attribute values within multivalued RDNs.
+ */
+ /* We may still be in an unexpected state, such as B4TYPE if
+ * we encountered something odd like a '+' at the end of the
+ * rdn. If this is the case, we don't want to add this bogus
+ * rdn to our list to sort. We should only be in the INVALUE
+ * or B4SEPARATOR state if we have a valid rdn component to
+ * be added. */
+ if ((rdn_av_count > 0) && ((state == INVALUE1ST) ||
+ (state == INVALUE) || (state == B4SEPARATOR))) {
+ add_rdn_av(typestart, d, &rdn_av_count, &rdn_avs, initial_rdn_av_stack);
+ }
+ if ( rdn_av_count > 1 ) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
+ }
+ if ( rdn_av_count > 0 ) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ /* Trim trailing spaces */
+ while (d > *dest && ISBLANK(*(d-1))) {
+ --d; /* XXX 518524 */
+ }
+ *dest_len = d - *dest;
+bail:
+ if (rc < 0) {
+ if (*dest != src) {
+ slapi_ch_free_string(dest);
+ } else {
+ *dest = NULL;
+ }
+ *dest_len = 0;
+ } else if (rc > 0) {
+ /* We terminate the str with NULL only when we allocate the str */
+ *d = '\0';
+ }
+ return rc;
+}
+
+char *
+slapi_create_dn_string(const char *fmt, ...)
+{
+ char *src = NULL;
+ char *dest = NULL;
+ size_t dest_len = 0;
+ va_list ap;
+ int rc = 0;
+
+ if (NULL == fmt) {
+ return NULL;
+ }
+
+ va_start(ap, fmt);
+ src = PR_vsmprintf(fmt, ap);
+ va_end(ap);
+ rc = slapi_dn_normalize_ext(src, strlen(src), &dest, &dest_len);
+ if (rc < 0) {
+ slapi_ch_free_string(&src);
+ return NULL;
+ } else if (rc == 0) { /* src is passed in. */
+ *(dest + dest_len) = '\0';
+ } else {
+ slapi_ch_free_string(&src);
+ }
+ return dest;
+}
/*
* Append previous AV to the attribute value array if multivalued RDN.
@@ -418,21 +980,22 @@ substr_dn_normalize( char *dn, char *end )
*/
static void
add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
- struct berval **rdn_avsp, struct berval *avstack )
+ struct berval **rdn_avsp, struct berval *avstack )
{
if ( *rdn_av_countp == 0 ) {
- *rdn_avsp = avstack;
+ *rdn_avsp = avstack;
} else if ( *rdn_av_countp == SLAPI_DNNORM_INITIAL_RDN_AVS ) {
- struct berval *tmpavs;
+ struct berval *tmpavs;
- tmpavs = (struct berval *)slapi_ch_calloc(
- SLAPI_DNNORM_INITIAL_RDN_AVS * 2, sizeof( struct berval ));
- memcpy( tmpavs, *rdn_avsp,
- SLAPI_DNNORM_INITIAL_RDN_AVS * sizeof( struct berval ));
- *rdn_avsp = tmpavs;
+ tmpavs = (struct berval *)slapi_ch_calloc(
+ SLAPI_DNNORM_INITIAL_RDN_AVS * 2, sizeof( struct berval ));
+ memcpy( tmpavs, *rdn_avsp,
+ SLAPI_DNNORM_INITIAL_RDN_AVS * sizeof( struct berval ));
+ *rdn_avsp = tmpavs;
} else if (( *rdn_av_countp % SLAPI_DNNORM_INITIAL_RDN_AVS ) == 0 ) {
- *rdn_avsp = (struct berval *)slapi_ch_realloc( (char *)*rdn_avsp,
- (*rdn_av_countp + SLAPI_DNNORM_INITIAL_RDN_AVS)*sizeof(struct berval) );
+ *rdn_avsp = (struct berval *)slapi_ch_realloc( (char *)*rdn_avsp,
+ (*rdn_av_countp +
+ SLAPI_DNNORM_INITIAL_RDN_AVS)*sizeof(struct berval) );
}
/*
@@ -453,7 +1016,7 @@ static void
reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp )
{
if ( *rdn_av_countp > SLAPI_DNNORM_INITIAL_RDN_AVS ) {
- slapi_ch_free( (void **)rdn_avsp );
+ slapi_ch_free( (void **)rdn_avsp );
}
*rdn_avsp = NULL;
*rdn_av_countp = 0;
@@ -471,9 +1034,9 @@ reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp )
* Also note that the bv_val's in the "avas" array are not zero-terminated.
*/
static void
-sort_rdn_avs( struct berval *avs, int count )
+sort_rdn_avs( struct berval *avs, int count, int escape )
{
- int i, j, swaps;
+ int i, j, swaps;
/*
* Since we expect there to be a small number of AVs, we use a
@@ -481,16 +1044,16 @@ sort_rdn_avs( struct berval *avs, int count )
* adjacent values anyway.
*/
for ( i = 0; i < count - 1; ++i ) {
- swaps = 0;
- for ( j = 0; j < count - 1; ++j ) {
- if ( rdn_av_cmp( &avs[j], &avs[j+1] ) > 0 ) {
- rdn_av_swap( &avs[j], &avs[j+1] );
- ++swaps;
- }
- }
- if ( swaps == 0 ) {
- break; /* stop early if no swaps made during the last pass */
- }
+ swaps = 0;
+ for ( j = 0; j < count - 1; ++j ) {
+ if ( rdn_av_cmp( &avs[j], &avs[j+1] ) > 0 ) {
+ rdn_av_swap( &avs[j], &avs[j+1], escape );
+ ++swaps;
+ }
+ }
+ if ( swaps == 0 ) {
+ break; /* stop early if no swaps made during the last pass */
+ }
}
}
@@ -501,15 +1064,15 @@ sort_rdn_avs( struct berval *avs, int count )
static int
rdn_av_cmp( struct berval *av1, struct berval *av2 )
{
- int rc;
+ int rc;
rc = strncasecmp( av1->bv_val, av2->bv_val,
- ( av1->bv_len < av2->bv_len ) ? av1->bv_len : av2->bv_len );
+ ( av1->bv_len < av2->bv_len ) ? av1->bv_len : av2->bv_len );
if ( rc == 0 ) {
- return( av1->bv_len - av2->bv_len ); /* longer is greater */
+ return( av1->bv_len - av2->bv_len ); /* longer is greater */
} else {
- return( rc );
+ return( rc );
}
}
@@ -519,12 +1082,12 @@ rdn_av_cmp( struct berval *av1, struct berval *av2 )
* Avoid allocating any heap memory for reasonably small AVs.
*/
static void
-rdn_av_swap( struct berval *av1, struct berval *av2 )
+rdn_av_swap( struct berval *av1, struct berval *av2, int escape )
{
- char *buf1, *buf2;
- char stackbuf1[ SLAPI_DNNORM_SMALL_RDN_AV ];
- char stackbuf2[ SLAPI_DNNORM_SMALL_RDN_AV ];
- int len1, len2;
+ char *buf1, *buf2;
+ char stackbuf1[ SLAPI_DNNORM_SMALL_RDN_AV ];
+ char stackbuf2[ SLAPI_DNNORM_SMALL_RDN_AV ];
+ int len1, len2;
/*
* Copy the two avs into temporary buffers. We use stack-based buffers
@@ -532,16 +1095,16 @@ rdn_av_swap( struct berval *av1, struct berval *av2 )
* large values.
*/
if (( len1 = av1->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
- buf1 = stackbuf1;
+ buf1 = stackbuf1;
} else {
- buf1 = slapi_ch_malloc( len1 );
+ buf1 = slapi_ch_malloc( len1 );
}
memcpy( buf1, av1->bv_val, len1 );
if (( len2 = av2->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
- buf2 = stackbuf2;
+ buf2 = stackbuf2;
} else {
- buf2 = slapi_ch_malloc( len2 );
+ buf2 = slapi_ch_malloc( len2 );
}
memcpy( buf2, av2->bv_val, len2 );
@@ -556,7 +1119,13 @@ rdn_av_swap( struct berval *av1, struct berval *av2 )
* Also reset av2 pointer and length.
*/
av2->bv_val = av1->bv_val + len2;
- *(av2->bv_val)++ = '+';
+ if (escape) {
+ *(av2->bv_val)++ = '\\';
+ PR_snprintf(av2->bv_val, 3, "%X", '+'); /* hexpair */
+ av2->bv_val += 2;
+ } else {
+ *(av2->bv_val)++ = '+';
+ }
memcpy( av2->bv_val, buf1, len1 );
av2->bv_len = len1;
@@ -564,19 +1133,19 @@ rdn_av_swap( struct berval *av1, struct berval *av2 )
* Clean up.
*/
if ( len1 > SLAPI_DNNORM_SMALL_RDN_AV ) {
- slapi_ch_free( (void **)&buf1 );
+ slapi_ch_free( (void **)&buf1 );
}
if ( len2 > SLAPI_DNNORM_SMALL_RDN_AV ) {
- slapi_ch_free( (void **)&buf2 );
+ slapi_ch_free( (void **)&buf2 );
}
}
/*
+ * DEPRECATED: this function does nothing.
* slapi_dn_normalize - put dn into a canonical format. the dn is
* normalized in place, as well as returned.
*/
-
char *
slapi_dn_normalize( char *dn )
{
@@ -586,7 +1155,10 @@ slapi_dn_normalize( char *dn )
return dn;
}
-/* Note that this routine normalizes to the end and doesn't null terminate */
+/*
+ * DEPRECATED: this function does nothing.
+ * Note that this routine normalizes to the end and doesn't null terminate
+ */
char *
slapi_dn_normalize_to_end( char *dn , char *end)
{
@@ -600,13 +1172,28 @@ slapi_dn_normalize_to_end( char *dn , char *end)
char *
slapi_dn_ignore_case( char *dn )
{
- unsigned char *s, *d;
+ unsigned char *s = NULL, *d = NULL;
+ int ssz, dsz;
+ /* normalize case (including UTF-8 multi-byte chars) */
+ for ( s = d = (unsigned char *)dn; s && *s; s += ssz, d += dsz ) {
+ slapi_utf8ToLower( s, d, &ssz, &dsz );
+ }
+ if (d) {
+ *d = '\0'; /* utf8ToLower result may be shorter than the original */
+ }
+ return( dn );
+}
+
+char *
+dn_ignore_case_to_end( char *dn, char *end )
+{
+ unsigned char *s = NULL, *d = NULL;
int ssz, dsz;
/* normalize case (including UTF-8 multi-byte chars) */
- for ( s = d = (unsigned char *)dn; *s; s += ssz, d += dsz ) {
- slapi_utf8ToLower( s, d, &ssz, &dsz );
+ for (s = d = (unsigned char *)dn; s && s < (unsigned char *)end && *s;
+ s += ssz, d += dsz) {
+ slapi_utf8ToLower( s, d, &ssz, &dsz );
}
- *d = '\0'; /* utf8ToLower result may be shorter than the original */
return( dn );
}
@@ -626,6 +1213,47 @@ slapi_dn_normalize_case( char *dn )
return( slapi_dn_ignore_case( dn ));
}
+int
+slapi_dn_normalize_case_ext(char *src, size_t src_len,
+ char **dest, size_t *dest_len)
+{
+ int rc = slapi_dn_normalize_ext(src, src_len, dest, dest_len);
+
+ if (rc >= 0) {
+ dn_ignore_case_to_end(*dest, *dest + *dest_len);
+ }
+ return rc;
+}
+
+char *
+slapi_create_dn_string_case(const char *fmt, ...)
+{
+ char *src = NULL;
+ char *dest = NULL;
+ size_t dest_len = 0;
+ va_list ap;
+ int rc = 0;
+
+ if (NULL == fmt) {
+ return NULL;
+ }
+
+ va_start(ap, fmt);
+ src = PR_vsmprintf(fmt, ap);
+ va_end(ap);
+
+ rc = slapi_dn_normalize_ext(src, strlen(src), &dest, &dest_len);
+ if (rc < 0) {
+ slapi_ch_free_string(&src);
+ } else if (rc == 0) { /* src is passed in. */
+ *(dest + dest_len) = '\0';
+ } else {
+ slapi_ch_free_string(&src);
+ }
+
+ return slapi_dn_ignore_case(dest);
+}
+
/*
* slapi_dn_beparent - return a copy of the dn of dn's parent,
* NULL if the DN is a suffix of the backend.
@@ -1129,10 +1757,7 @@ slapi_sdn_set_rdn(Slapi_DN *sdn, const Slapi_RDN *rdn)
{
/* NewDN= NewRDN + OldParent */
char *parentdn= slapi_dn_parent(sdn->dn);
- char *newdn= slapi_ch_malloc(strlen(rawrdn)+1+strlen(parentdn)+1);
- strcpy( newdn, rawrdn );
- strcat( newdn, "," );
- strcat( newdn, parentdn );
+ char *newdn = slapi_ch_smprintf("%s,%s", rawrdn, parentdn);
slapi_ch_free((void**)&parentdn);
slapi_sdn_set_dn_passin(sdn,newdn);
}
@@ -1264,10 +1889,10 @@ slapi_sdn_get_ndn(const Slapi_DN *sdn)
if(sdn->dn!=NULL)
{
char *p= slapi_ch_strdup(sdn->dn);
- Slapi_DN *ncsdn= (Slapi_DN*)sdn; /* non-const Slapi_DN */
- slapi_dn_normalize_case(p);
+ Slapi_DN *ncsdn= (Slapi_DN*)sdn; /* non-const Slapi_DN */
+ slapi_dn_ignore_case(p); /* dn is normalized; just ignore case */
ncsdn->ndn= p;
- ncsdn->ndn_len=strlen(p);
+ ncsdn->ndn_len=strlen(p);
ncsdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_NDN);
PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_created);
PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index 3816d42a..0a8c40d5 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -150,9 +150,9 @@ str2entry_state_information_from_type(char *s,CSNSet **csnset,CSN **attributedel
}
}
-/* dn is not consumed. Caller needs to free it. */
+/* rawdn is not consumed. Caller needs to free it. */
static Slapi_Entry *
-str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
+str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
{
Slapi_Entry *e;
char *next, *ptype=NULL;
@@ -163,6 +163,11 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
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 */
CSN *maxcsn = NULL;
+ char *normdn = NULL;
+ int strict = 0;
+
+ /* Check if we should be performing strict validation. */
+ strict = config_get_dn_validate_strict();
/*
* In string format, an entry looks like either of these:
@@ -267,13 +272,41 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
a = NULL;
}
- if ( dn ) {
- if ( NULL == slapi_entry_get_dn_const( e )) {
- slapi_entry_set_dn( e, slapi_ch_strdup( dn ));
+ if ( rawdn ) {
+ if ( NULL == slapi_entry_get_dn_const( e )) {
+ normdn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == normdn) {
+ 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);
+ return NULL;
+ }
+ /* normdn is consumed in e */
+ slapi_entry_set_dn(e, normdn);
}
- if ( NULL == slapi_entry_get_rdn_const( e )) {
- slapi_entry_set_rdn( e, (char *)dn );
+ if ( NULL == slapi_entry_get_rdn_const( e )) {
+ if (normdn) {
+ /* normdn is just referred in slapi_entry_set_rdn. */
+ slapi_entry_set_rdn(e, normdn);
+ } else {
+ normdn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == normdn) {
+ 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);
+ return NULL;
+ }
+ /* normdn is just referred in slapi_entry_set_rdn. */
+ slapi_entry_set_rdn(e, normdn);
+ slapi_ch_free_string(&normdn);
+ }
}
+ rawdn = NULL; /* Set once in the loop.
+ This won't affect the caller's passed address. */
}
if ( strcasecmp( type, "dn" ) == 0 ) {
if ( slapi_entry_get_dn_const(e)!=NULL ) {
@@ -288,11 +321,22 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
if (freetype) slapi_ch_free_string(&type);
continue;
}
- slapi_entry_set_dn(e,slapi_ch_strdup( valuecharptr ));
+ normdn = slapi_create_dn_string("%s", valuecharptr);
+ if (NULL == normdn) {
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
+ "str2entry_fast: Invalid DN: %s\n", valuecharptr);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ /* 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);
- continue;
+ continue;
}
if ( strcasecmp( type, "rdn" ) == 0 ) {
@@ -302,7 +346,7 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
/* 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);
- continue;
+ continue;
}
@@ -310,8 +354,9 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
if (e->e_uniqueid != NULL){
- LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: entry has multiple "
- "uniqueids %s and %s (second ignored)\n",
+ LDAPDebug (LDAP_DEBUG_TRACE,
+ "str2entry_fast: entry has multiple uniqueids %s "
+ "and %s (second ignored)\n",
e->e_uniqueid, valuecharptr, 0);
}else{
/* name2asi will be locked in slapi_entry_set_uniqueid */
@@ -333,12 +378,7 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
}
{
- Slapi_Value *value= value_new(NULL,CSN_TYPE_NONE,NULL);
- slapi_value_set( value, valuecharptr, valuelen );
- /* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free_string(&valuecharptr);
- value->v_csnset= valuecsnset;
- valuecsnset= NULL;
+ Slapi_Value *value = NULL;
if(a==NULL)
{
switch(attr_state)
@@ -368,9 +408,51 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
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);
+ 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);
+ if (rc) { /* syntax check failed */
+ LDAPDebug2Args(LDAP_DEBUG_TRACE,
+ "str2entry_fast: strict: Invalid DN value: %s: %s\n",
+ type, valuecharptr);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ }
+ rc = slapi_dn_normalize_ext(valuecharptr, 0, &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);
+ } else if (rc == 0) { /* rc == 0; valuecharptr is passed in;
+ not null terminated */
+ *(dn_aval + dnlen) = '\0';
+ }
+ } else {
+ slapi_value_set(value, valuecharptr, valuelen);
}
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;
+ valuecsnset = NULL;
{
const CSN *distinguishedcsn= csnset_get_csn_of_type(value->v_csnset,CSN_TYPE_VALUE_DISTINGUISHED);
if(distinguishedcsn!=NULL)
@@ -601,7 +683,7 @@ entry_attrs_find(entry_attrs *ea,char *type)
/* dn is not consumed. Caller needs to free it. */
static Slapi_Entry *
-str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
+str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
{
Slapi_Entry *e;
str2entry_attr stack_attrs[STR2ENTRY_SMALL_BUFFER_SIZE];
@@ -625,6 +707,11 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
( 0 != ( flags & SLAPI_STR2ENTRY_REMOVEDUPVALS ));
Slapi_Value *value = 0;
CSN *maxcsn= NULL;
+ char *normdn = NULL;
+ int strict = 0;
+
+ /* Check if we should be performing strict validation. */
+ strict = config_get_dn_validate_strict();
LDAPDebug( LDAP_DEBUG_TRACE, "=> str2entry_dupcheck\n", 0, 0, 0 );
@@ -688,16 +775,44 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
csnset_free(&valuecsnset);
}
- if ( dn ) {
- if ( NULL == slapi_entry_get_dn_const(e) ) {
- slapi_entry_set_dn( e, slapi_ch_strdup( dn ));
+ if ( rawdn ) {
+ if ( NULL == slapi_entry_get_dn_const(e) ) {
+ normdn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == normdn) {
+ 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);
+ return NULL;
+ }
+ /* normdn is consumed in e */
+ slapi_entry_set_dn(e, normdn);
}
- if ( NULL == slapi_entry_get_rdn_const(e) ) {
- slapi_entry_set_rdn( e, (char *)dn );
+ if ( NULL == slapi_entry_get_rdn_const(e) ) {
+ if (normdn) {
+ /* normdn is just referred in slapi_entry_set_rdn. */
+ slapi_entry_set_rdn(e, normdn);
+ } else {
+ normdn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == normdn) {
+ 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);
+ return NULL;
+ }
+ /* normdn is just referred in slapi_entry_set_rdn. */
+ slapi_entry_set_rdn(e, normdn);
+ slapi_ch_free_string(&normdn);
+ }
}
+ rawdn = NULL; /* Set once in the loop.
+ This won't affect the caller's passed address. */
}
if ( strcasecmp( type, "dn" ) == 0 ) {
- if ( slapi_entry_get_dn_const(e)!=NULL ) {
+ if ( slapi_entry_get_dn_const(e)!=NULL ) {
char ebuf[ BUFSIZ ];
LDAPDebug( LDAP_DEBUG_TRACE,
"str2entry_dupcheck: entry has multiple dns \"%s\" "
@@ -708,8 +823,18 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
if (retmalloc) slapi_ch_free_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
continue;
- }
- slapi_entry_set_dn(e,slapi_ch_strdup( valuecharptr ));
+ }
+ normdn = slapi_create_dn_string("%s", valuecharptr);
+ if (NULL == normdn) {
+ 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);
+ 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);
@@ -730,8 +855,9 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
if (e->e_uniqueid != NULL){
- LDAPDebug (LDAP_DEBUG_ANY, "str2entry_dupcheck: entry has multiple "
- "uniqueids %s and %s (second ignored)\n",
+ LDAPDebug (LDAP_DEBUG_TRACE,
+ "str2entry_dupcheck: entry has multiple uniqueids %s "
+ "and %s (second ignored)\n",
e->e_uniqueid, valuecharptr, 0);
}else{
slapi_entry_set_uniqueid (e, slapi_ch_strdup(valuecharptr));
@@ -853,10 +979,44 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
nattrs++;
}
- if (freetype) slapi_ch_free_string(&type);
sa = prev_attr; /* For readability */
- value= value_new(NULL,CSN_TYPE_NONE,NULL);
- slapi_value_set( value, valuecharptr, valuelen );
+ value= value_new(NULL, CSN_TYPE_NONE, NULL);
+ if (slapi_attr_is_dn_syntax_attr(&(sa->sa_attr))) {
+ 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);
+ if (rc) { /* syntax check failed */
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "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);
+ goto free_and_return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(valuecharptr, 0, &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;
+ }
+ slapi_value_set(value, dn_aval, dnlen);
+ if (rc > 0) { /* if rc == 0, valuecharptr is passed in */
+ slapi_ch_free_string(&dn_aval);
+ } else if (rc == 0) { /* rc == 0; valuecharptr is passed in;
+ not null terminated */
+ *(dn_aval + dnlen) = '\0';
+ }
+ } else {
+ slapi_value_set(value, valuecharptr, valuelen);
+ }
+ 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);
value->v_csnset= valuecsnset;
@@ -1166,6 +1326,7 @@ slapi_str2entry( char *s, int flags )
/*
* string s does not include dn.
+ * NOTE: the first arg "dn" should have been normalized before passing.
*/
Slapi_Entry *
slapi_str2entry_ext( const char *dn, char *s, int flags )
@@ -1190,15 +1351,15 @@ slapi_str2entry_ext( const char *dn, char *s, int flags )
*/
if ( 0 != ( flags & SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF ) ||
0 != ( flags & ~SLAPI_STRENTRY_FLAGS_HANDLED_BY_STR2ENTRY_FAST ))
- {
+ {
e= str2entry_dupcheck( dn, s, flags, read_stateinfo );
- }
- else
- {
+ }
+ else
+ {
e= str2entry_fast( dn, s, flags, read_stateinfo );
- }
- if (!e)
- return e; /* e == NULL */
+ }
+ if (!e)
+ return e; /* e == NULL */
if ( flags & SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES )
{
@@ -1770,8 +1931,12 @@ static size_t slapi_dn_size(Slapi_DN *sdn)
if (sdn == NULL) return 0;
- if (sdn->dn) size += strlen(sdn->dn) + 1;
- if (sdn->ndn) size *= 2;
+ if (slapi_sdn_get_dn(sdn)) {
+ size += strlen(slapi_sdn_get_dn(sdn)) + 1;
+ }
+ if (slapi_sdn_get_ndn(sdn)) {
+ size += strlen(slapi_sdn_get_ndn(sdn)) + 1;
+ }
return size;
}
@@ -2922,7 +3087,7 @@ entry_apply_mod( Slapi_Entry *e, const LDAPMod *mod )
case LDAP_MOD_ADD:
LDAPDebug( LDAP_DEBUG_ARGS, " add: %s\n", mod->mod_type, 0, 0 );
if(sawsubentry) e->e_flags |= SLAPI_ENTRY_LDAPSUBENTRY;
- err = slapi_entry_add_values( e, mod->mod_type, mod->mod_bvalues );
+ err = slapi_entry_add_values( e, mod->mod_type, mod->mod_bvalues );
break;
case LDAP_MOD_DELETE:
@@ -2980,6 +3145,9 @@ slapi_entry_add_values_sv(Slapi_Entry *e,
Slapi_Attr **a= NULL;
Slapi_Attr **alist= &e->e_attrs;
attrlist_find_or_create(alist, type, &a);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ valuearray_normalize_value(vals);
+ }
rc= attr_add_valuearray(*a,vals,slapi_entry_get_dn_const(e));
}
return( rc );
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 6b51ef1c..01c160c2 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -450,6 +450,10 @@ entry_add_present_values_wsi(Slapi_Entry *e, const char *type, struct berval **b
}
a_flags_orig = a->a_flags;
a->a_flags |= flags;
+ /* Check if the type of the to-be-added values has DN syntax or not. */
+ if (slapi_attr_is_dn_syntax_attr(a)) {
+ valuearray_normalize_value(valuestoadd);
+ }
if(urp)
{
/*
@@ -566,6 +570,11 @@ entry_delete_present_values_wsi(Slapi_Entry *e, const char *type, struct berval
/* delete some specific values */
Slapi_Value **valuestodelete= NULL;
valuearray_init_bervalarray(vals,&valuestodelete); /* JCM SLOW FUNCTION */
+ /* Check if the type of the to-be-deleted values has DN syntax
+ * or not. */
+ if (slapi_attr_is_dn_syntax_attr(a)) {
+ valuearray_normalize_value(valuestodelete);
+ }
if(urp)
{
Slapi_Value **valuesupdated= NULL;
diff --git a/ldap/servers/slapd/extendop.c b/ldap/servers/slapd/extendop.c
index 003c2ab8..a521cb7b 100644
--- a/ldap/servers/slapd/extendop.c
+++ b/ldap/servers/slapd/extendop.c
@@ -53,7 +53,9 @@ static const char *extended_op_oid2string( const char *oid );
static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid,
struct berval *extval)
{
- char *suffix;
+ char *orig = NULL;
+ char *suffix = NULL;
+ size_t dnlen = 0;
Slapi_DN *sdn = NULL;
Slapi_Backend *be = NULL;
struct berval bv;
@@ -66,10 +68,34 @@ static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid,
"no data supplied", 0, NULL);
return;
}
- suffix = slapi_ch_malloc(extval->bv_len+1);
- strncpy(suffix, extval->bv_val, extval->bv_len);
- suffix[extval->bv_len] = 0;
-
+ orig = slapi_ch_malloc(extval->bv_len+1);
+ strncpy(orig, extval->bv_val, extval->bv_len);
+ orig[extval->bv_len] = 0;
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ ret = slapi_dn_syntax_check(pb, orig, 1);
+ if (ret) { /* syntax check failed */
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "extop_handle_import_start: strict: invalid suffix\n",
+ orig);
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "invalid suffix", 0, NULL);
+ return;
+ }
+ }
+ ret = slapi_dn_normalize_ext(orig, 0, &suffix, &dnlen);
+ if (ret < 0) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "extop_handle_import_start: invalid suffix\n", orig);
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "invalid suffix", 0, NULL);
+ return;
+ } else if (ret > 0) {
+ slapi_ch_free_string(&orig);
+ } else { /* ret == 0; orig is passed in; not null terminated */
+ *(suffix + dnlen) = '\0';
+ }
sdn = slapi_sdn_new_dn_byval(suffix);
if (!sdn) {
LDAPDebug(LDAP_DEBUG_ANY,
@@ -109,6 +135,7 @@ static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid,
/* slapi_str2entry modify its dn parameter so we must copy
* this string each time we call it !
*/
+ /* This dn is no need to be normalized. */
PR_snprintf(dn, sizeof(dn), "dn: oid=%s,cn=features,cn=config",
EXTOP_BULK_IMPORT_START_OID);
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index 0439007b..642b6af9 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -76,6 +76,7 @@
extern char ** getSupportedCiphers();
+/* Note: These DNs are no need to be normalized */
static const char *internal_entries[] =
{
"dn:\n"
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index dbeae654..b8e26d1c 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -870,7 +870,8 @@ FrontendConfig_init () {
cfg->ldapi_map_entries = LDAP_OFF;
cfg->ldapi_uidnumber_type = slapi_ch_strdup("uidNumber");
cfg->ldapi_gidnumber_type = slapi_ch_strdup("gidNumber");
- cfg->ldapi_search_base_dn = slapi_ch_strdup("dc=example, dc=com");
+ /* These DNs are no need to be normalized. */
+ cfg->ldapi_search_base_dn = slapi_ch_strdup("dc=example,dc=com");
#if defined(ENABLE_AUTO_DN_SUFFIX)
cfg->ldapi_auto_dn_suffix = slapi_ch_strdup("cn=peercred,cn=external,cn=auth");
#endif
@@ -4884,18 +4885,18 @@ config_set_instancedir(const char *attrname, char *value, char *errorbuf, int ap
{
int retVal = LDAP_SUCCESS;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
-
+
if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
return LDAP_OPERATIONS_ERROR;
}
-
+
if (!apply) {
return retVal;
}
-
+
CFG_LOCK_WRITE(slapdFrontendConfig);
/* We don't want to allow users to modify instance dir.
- * Set it once when the server starts. */
+ * Set it once when the server starts. */
if (NULL == slapdFrontendConfig->instancedir) {
slapdFrontendConfig->instancedir = slapi_ch_strdup(value);
}
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index 5023dcd2..3772a757 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -1107,6 +1107,7 @@ main( int argc, char **argv)
/* initialize UniqueID generator - must be done once backends are started
and event queue is initialized but before plugins are started */
+ /* Note: This DN is no need to be normalized. */
sdn = slapi_sdn_new_dn_byval ("cn=uniqueid generator,cn=config");
rc = uniqueIDGenInit (NULL, sdn, slapd_exemode == SLAPD_EXEMODE_SLAPD);
slapi_sdn_free (&sdn);
@@ -1908,6 +1909,7 @@ lookup_instance_name_by_suffix(char *suffix,
if (query == NULL)
goto done;
+ /* Note: This DN is no need to be normalized. */
slapi_search_internal_set_pb(pb, "cn=mapping tree,cn=config",
LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
@@ -1928,6 +1930,7 @@ lookup_instance_name_by_suffix(char *suffix,
query = slapi_ch_smprintf("(&(objectclass=nsmappingtree)(|(cn=*%s\")(cn=*%s)))", suffixp, suffixp);
if (query == NULL)
goto done;
+ /* Note: This DN is no need to be normalized. */
slapi_search_internal_set_pb(pb, "cn=mapping tree,cn=config",
LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
@@ -2015,6 +2018,7 @@ static struct slapdplugin *lookup_plugin_by_instance_name(const char *name)
return NULL;
}
+ /* Note: This DN is no need to be normalized. */
slapi_search_internal_set_pb(pb, "cn=plugins,cn=config",
LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index 645618c2..7503929d 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -133,6 +133,7 @@ static int extension_type = -1; /* type returned from the factory */
/* Need to add a modifier flag to the state - such as round robin */
+/* Note: This DN is no need to be normalized. */
#define MAPPING_TREE_BASE_DN "cn=mapping tree,cn=config"
#define MAPPING_TREE_PARENT_ATTRIBUTE "nsslapd-parent-suffix"
@@ -365,24 +366,30 @@ static Slapi_DN *
get_parent_from_entry(Slapi_Entry * entry)
{
Slapi_Attr *attr = NULL;
- char * parent;
+ char *origparent = NULL;
+ char *parent = NULL;
Slapi_Value *val = NULL;
- Slapi_DN *parent_sdn;
+ Slapi_DN *parent_sdn = NULL;
if (slapi_entry_attr_find(entry, MAPPING_TREE_PARENT_ATTRIBUTE, &attr))
return NULL;
slapi_attr_first_value(attr, &val);
- parent = slapi_ch_strdup(slapi_value_get_string(val));
- if(parent[0]=='\"')
- {
- parent[strlen(parent) - 1] = '\0';
- parent_sdn = slapi_sdn_new_dn_byval(parent+1);
+ origparent = parent = slapi_ch_strdup(slapi_value_get_string(val));
+ if (parent) {
+ if(*parent == '"') {
+ char *ptr = NULL;
+ parent++; /* skipping the starting '"' */
+ ptr = PL_strnrchr(parent, '"', strlen(parent));
+ if (ptr) {
+ *ptr = '\0';
+ }
+ }
+ parent_sdn =
+ slapi_sdn_new_dn_passin(slapi_create_dn_string("%s", parent));
+ slapi_ch_free_string(&origparent);
}
- else
- parent_sdn = slapi_sdn_new_dn_byval(parent);
- slapi_ch_free((void **) &parent);
return parent_sdn;
}
@@ -393,9 +400,10 @@ static Slapi_DN *
get_subtree_from_entry(Slapi_Entry * entry)
{
Slapi_Attr *attr = NULL;
- char * cn;
+ char *origcn = NULL;
+ char *cn = NULL;
Slapi_Value *val = NULL;
- Slapi_DN *subtree;
+ Slapi_DN *subtree = NULL;
if (slapi_entry_attr_find(entry, "cn", &attr))
return NULL;
@@ -415,15 +423,19 @@ get_subtree_from_entry(Slapi_Entry * entry)
/* GB : I think removing the first and last " in the cn value
* is the right stuff to do
*/
- cn = slapi_ch_strdup(slapi_value_get_string(val));
- if(cn[0]=='\"')
- {
- cn[strlen(cn) - 1] = '\0';
- subtree = slapi_sdn_new_dn_byval(cn+1);
+ origcn = cn = slapi_ch_strdup(slapi_value_get_string(val));
+ if (cn) {
+ if(*cn == '"') {
+ char *ptr = NULL;
+ cn++; /* skipping the starting '"' */
+ ptr = PL_strnrchr(cn, '"', strlen(cn));
+ if (ptr) {
+ *ptr = '\0';
+ }
+ }
+ subtree = slapi_sdn_new_dn_passin(slapi_create_dn_string("%s", cn));
+ slapi_ch_free_string(&origcn);
}
- else
- subtree = slapi_sdn_new_dn_byval(cn);
- slapi_ch_free((void **) &cn);
return subtree;
}
@@ -2790,7 +2802,7 @@ get_mapping_tree_node_by_name(mapping_tree_node * node, char * be_name)
char*
slapi_get_mapping_tree_node_configdn (const Slapi_DN *root)
{
- char *dn;
+ char *dn = NULL;
if(mapping_tree_freed){
/* shutdown detected */
@@ -2799,7 +2811,16 @@ slapi_get_mapping_tree_node_configdn (const Slapi_DN *root)
if (root == NULL)
return NULL;
- dn = slapi_ch_smprintf("cn=\"%s\",%s", slapi_sdn_get_dn(root), MAPPING_TREE_BASE_DN);
+ /* This function converts the old DN style to the new one. */
+ dn = slapi_create_dn_string("cn=\"%s\",%s",
+ slapi_sdn_get_dn(root), MAPPING_TREE_BASE_DN);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "slapi_get_mapping_tree_node_configdn: "
+ "failed to crate mapping tree dn for %s\n",
+ slapi_sdn_get_dn(root));
+ return NULL;
+ }
return dn;
}
@@ -3114,7 +3135,7 @@ slapi_mtn_set_referral(const Slapi_DN *sdn, char ** referral)
}
slapi_mods_done(&smods);
- slapi_ch_free((void **) &node_dn);
+ slapi_ch_free_string(&node_dn);
return rc;
}
@@ -3135,13 +3156,13 @@ slapi_mtn_set_state(const Slapi_DN *sdn, char *state)
char * node_dn;
char * value;
- node_dn = slapi_get_mapping_tree_node_configdn(sdn);
- if(!node_dn){
- /* shutdown has been detected */
+ if (NULL == state) {
return LDAP_OPERATIONS_ERROR;
}
- if (NULL == state) {
+ node_dn = slapi_get_mapping_tree_node_configdn(sdn);
+ if(!node_dn){
+ /* shutdown has been detected */
return LDAP_OPERATIONS_ERROR;
}
@@ -3150,9 +3171,7 @@ slapi_mtn_set_state(const Slapi_DN *sdn, char *state)
if ( strcasecmp(value, state) == 0 )
{
/* Same state, don't change anything */
- slapi_ch_free((void **) &value);
- slapi_ch_free((void **) &node_dn);
- return rc;
+ goto bail;
}
}
@@ -3168,10 +3187,10 @@ slapi_mtn_set_state(const Slapi_DN *sdn, char *state)
slapi_pblock_get (&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
slapi_mods_done(&smods);
- slapi_ch_free((void **) &node_dn);
pblock_done(&pb);
- slapi_ch_free((void **) &value);
-
+bail:
+ slapi_ch_free_string(&value);
+ slapi_ch_free_string(&node_dn);
return rc;
}
@@ -3265,7 +3284,7 @@ slapi_mtn_get_referral(const Slapi_DN *sdn)
slapi_attr_free(&attr);
}
- slapi_ch_free((void **) &node_dn);
+ slapi_ch_free_string(&node_dn);
return referral;
}
@@ -3301,7 +3320,7 @@ slapi_mtn_get_state(const Slapi_DN *sdn)
slapi_attr_free(&attr);
}
- slapi_ch_free((void **) &node_dn);
+ slapi_ch_free_string(&node_dn);
return state;
}
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index 40646b2b..027bbefb 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -166,16 +166,43 @@ do_modify( Slapi_PBlock *pb )
*/
{
- if ( ber_scanf( ber, "{a", &dn ) == LBER_ERROR )
+ char *rawdn = NULL;
+ size_t dnlen = 0;
+ int rc = 0;
+ if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR )
{
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Modify; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "MOD", "???", "decoding error");
- send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
- NULL );
- slapi_ch_free_string(&dn);
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL );
+ slapi_ch_free_string(&rawdn);
return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "MOD", "???", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ } else if (rc > 0) { /* if rc == 0, rawdn is passed in */
+ slapi_ch_free_string(&rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
}
LDAPDebug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", dn, 0, 0 );
diff --git a/ldap/servers/slapd/modrdn.c b/ldap/servers/slapd/modrdn.c
index b70377a9..6951fb05 100644
--- a/ldap/servers/slapd/modrdn.c
+++ b/ldap/servers/slapd/modrdn.c
@@ -72,10 +72,13 @@ do_modrdn( Slapi_PBlock *pb )
{
Slapi_Operation *operation;
BerElement *ber;
+ char *rawdn = NULL, *rawnewsuperior = NULL;
char *dn = NULL, *newsuperior = NULL;
+ char *rawnewrdn = NULL;
char *newrdn = NULL;
int err = 0, deloldrdn = 0;
ber_len_t len = 0;
+ size_t dnlen = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 );
@@ -96,7 +99,7 @@ do_modrdn( Slapi_PBlock *pb )
* }
*/
- if ( ber_scanf( ber, "{aab", &dn, &newrdn, &deloldrdn )
+ if ( ber_scanf( ber, "{aab", &rawdn, &rawnewrdn, &deloldrdn )
== LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=ModRDN; params=DN,newRDN,deleteOldRDN)\n",
@@ -109,25 +112,116 @@ do_modrdn( Slapi_PBlock *pb )
}
if ( ber_peek_tag( ber, &len ) == LDAP_TAG_NEWSUPERIOR ) {
+ /* This "len" is not used... */
if ( pb->pb_conn->c_ldapversion < LDAP_VERSION3 ) {
LDAPDebug( LDAP_DEBUG_ANY,
"got newSuperior in LDAPv2 modrdn op\n", 0, 0, 0 );
- op_shared_log_error_access (pb, "MODRDN", dn, "decoding error");
+ op_shared_log_error_access (pb, "MODRDN",
+ rawdn?rawdn:"", "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"received newSuperior in LDAPv2 modrdn", 0, NULL );
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
goto free_and_return;
}
- if ( ber_scanf( ber, "a", &newsuperior ) == LBER_ERROR ) {
+ if ( ber_scanf( ber, "a", &rawnewsuperior ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=ModRDN; params=newSuperior)\n",
0, 0, 0 );
- op_shared_log_error_access (pb, "MODRDN", dn, "decoding error");
+ op_shared_log_error_access (pb, "MODRDN", rawdn, "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"unable to decode newSuperior parameter", 0, NULL );
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
goto free_and_return;
}
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MODRDN", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ }
+ /* check that the new rdn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawnewrdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MODRDN", rawnewrdn?rawnewrdn:"",
+ "strict: invalid new rdn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new rdn", 0, NULL);
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "MODRDN", rawdn?rawdn:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ } else if (err > 0) {
+ slapi_ch_free((void **) &rawdn);
+ } else { /* err == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
+ err = slapi_dn_normalize_ext(rawnewrdn, 0, &newrdn, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "MODRDN", rawnewrdn?rawnewrdn:"",
+ "invalid new rdn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new rdn", 0, NULL);
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ } else if (err > 0) {
+ slapi_ch_free((void **) &rawnewrdn);
+ } else { /* err == 0; rawnewdn is passed in; not null terminated */
+ *(newrdn + dnlen) = '\0';
+ }
+ if (rawnewsuperior) {
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawnewsuperior, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MODRDN",
+ rawnewsuperior?rawnewsuperior:"",
+ "strict: invalid new superior");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new superior", 0, NULL);
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawnewsuperior, 0, &newsuperior, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "MODRDN",
+ rawnewsuperior?rawnewsuperior:"",
+ "invalid new superior");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new superior", 0, NULL);
+ slapi_ch_free_string( &rawnewsuperior);
+ goto free_and_return;
+ } else if (err > 0) {
+ slapi_ch_free((void **) &rawnewsuperior);
+ } else { /* err == 0; rawnewsuperior is passed in; not terminated */
+ *(newsuperior + dnlen) = '\0';
+ }
+ }
+
/*
* in LDAPv3 there can be optional control extensions on
* the end of an LDAPMessage. we need to read them in and
@@ -153,9 +247,9 @@ do_modrdn( Slapi_PBlock *pb )
return;
free_and_return:
- slapi_ch_free((void **) &dn );
- slapi_ch_free((void **) &newrdn );
- slapi_ch_free((void **) &newsuperior );
+ slapi_ch_free_string( &dn );
+ slapi_ch_free_string( &newrdn );
+ slapi_ch_free_string( &newsuperior );
return;
}
diff --git a/ldap/servers/slapd/modutil.c b/ldap/servers/slapd/modutil.c
index 9c5949d5..82147c69 100644
--- a/ldap/servers/slapd/modutil.c
+++ b/ldap/servers/slapd/modutil.c
@@ -188,11 +188,37 @@ void
slapi_mods_insert_at(Slapi_Mods *smods, LDAPMod *mod, int pos)
{
int i;
- slapi_mods_add_one_element(smods);
- for( i=smods->num_mods-1; i>=pos; i--)
+ Slapi_Attr a = {0};
+
+ if (NULL == mod) {
+ return;
+ }
+ slapi_mods_add_one_element(smods);
+ for( i=smods->num_mods-1; i>=pos; i--)
{
smods->mods[i+1]= smods->mods[i];
}
+ slapi_attr_init(&a, mod->mod_type);
+ /* Check if the type of the to-be-added values has DN syntax or not. */
+ if (slapi_attr_is_dn_syntax_attr(&a)) {
+ int rc = 0;
+ struct berval **mbvp = NULL;
+ char *normed = NULL;
+ size_t len = 0;
+ for (mbvp = mod->mod_bvalues; mbvp && *mbvp; mbvp++) {
+ rc = slapi_dn_normalize_ext((*mbvp)->bv_val, (*mbvp)->bv_len,
+ &normed, &len);
+ if (rc > 0) {
+ slapi_ch_free((void **)&((*mbvp)->bv_val));
+ } else if (rc == 0) {
+ /* original is passed in; not null terminated */
+ *(normed + len) = '\0';
+ }
+ (*mbvp)->bv_val = normed;
+ (*mbvp)->bv_len = len;
+ }
+ }
+ attr_done(&a);
smods->mods[pos]= mod;
smods->num_mods++;
smods->mods[smods->num_mods]= NULL;
diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c
index 14341f94..ff2e19f3 100644
--- a/ldap/servers/slapd/passwd_extop.c
+++ b/ldap/servers/slapd/passwd_extop.c
@@ -455,7 +455,9 @@ passwd_modify_extop( Slapi_PBlock *pb )
char *oid = NULL;
char *bindDN = NULL;
char *authmethod = NULL;
+ char *rawdn = NULL;
char *dn = NULL;
+ size_t dnlen = 0;
char *otdn = NULL;
char *oldPasswd = NULL;
char *newPasswd = NULL;
@@ -561,16 +563,43 @@ passwd_modify_extop( Slapi_PBlock *pb )
/* identify userID field by tags */
if (tag == LDAP_EXTOP_PASSMOD_TAG_USERID )
{
- if ( ber_scanf( ber, "a", &dn) == LBER_ERROR )
+ int rc = 0;
+ if ( ber_scanf( ber, "a", &rawdn) == LBER_ERROR )
{
- slapi_ch_free_string(&dn);
+ slapi_ch_free_string(&rawdn);
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed :{\n", 0, 0, 0 );
errMesg = "ber_scanf failed at userID parse.\n";
rc = LDAP_PROTOCOL_ERROR;
goto free_and_return;
}
-
+
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "EXT", rawdn?rawdn:"",
+ "strict: invalid target dn");
+ errMesg = "invalid target dn.\n";
+ slapi_ch_free_string(&rawdn);
+ rc = LDAP_INVALID_SYNTAX;
+ goto free_and_return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "EXT", rawdn?rawdn:"",
+ "invalid target dn");
+ slapi_ch_free_string(&rawdn);
+ errMesg = "invalid target dn.\n";
+ rc = LDAP_INVALID_SYNTAX;
+ goto free_and_return;
+ } else if (rc == 0) { /* rawdn is passed in, not terminated */
+ *(dn + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&rawdn);
+ }
tag = ber_peek_tag( ber, &len);
}
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 133f60e3..84dbcfe5 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -268,8 +268,15 @@ slapi_register_plugin_ext(
{
int ii = 0;
int rc = 0;
- Slapi_Entry *e = slapi_entry_alloc();
- char *dn = slapi_ch_smprintf("cn=%s, %s", name, PLUGIN_BASE_DN);
+ Slapi_Entry *e = NULL;
+ char *dn = slapi_create_dn_string("cn=%s,%s", name, PLUGIN_BASE_DN);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, NULL,
+ "slapi_register_plugin_ext: "
+ "failed to create plugin dn (plugin name: %s)\n", name);
+ return 1;
+ }
+ e = slapi_entry_alloc();
/* this function consumes dn */
slapi_entry_init(e, dn, NULL);
@@ -2461,7 +2468,7 @@ plugin_invoke_plugin_sdn (struct slapdplugin *plugin, int operation, Slapi_PBloc
*/
char* plugin_get_dn (const struct slapdplugin *plugin)
{
- char *plugindn;
+ char *plugindn = NULL;
char *pattern = "cn=%s," PLUGIN_BASE_DN;
if (plugin == NULL) /* old plugin that does not pass identity - use default */
@@ -2470,8 +2477,13 @@ char* plugin_get_dn (const struct slapdplugin *plugin)
if (plugin->plg_name == NULL)
return NULL;
- plugindn = slapi_ch_smprintf(pattern, plugin->plg_name);
-
+ plugindn = slapi_create_dn_string(pattern, plugin->plg_name);
+ if (NULL == plugindn) {
+ slapi_log_error(SLAPI_LOG_FATAL, NULL,
+ "plugin_get_dn: failed to create plugin dn "
+ "(plugin name: %s)\n", plugin->plg_name);
+ return NULL;
+ }
return plugindn;
}
@@ -2965,7 +2977,7 @@ slapi_set_plugin_default_config(const char *type, Slapi_Value *value)
/* cn=plugin default config,cn=config */
pblock_init(&pb);
slapi_search_internal_set_pb(&pb,
- SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */
+ SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN (normalized) */
LDAP_SCOPE_BASE,
"(objectclass=*)",
search_attrs, /* Attrs */
@@ -3069,7 +3081,7 @@ slapi_get_plugin_default_config(char *type, Slapi_ValueSet **valueset)
/* cn=plugin default config,cn=config */
pblock_init(&pb);
slapi_search_internal_set_pb(&pb,
- SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */
+ SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN (normalized) */
LDAP_SCOPE_BASE,
"(objectclass=*)",
search_attrs, /* Attrs */
diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c
index 384692db..5018326e 100644
--- a/ldap/servers/slapd/plugin_syntax.c
+++ b/ldap/servers/slapd/plugin_syntax.c
@@ -334,7 +334,7 @@ slapi_dn_syntax_check(
}
/* See if we need to set the error text in the pblock. */
- if (errp != &errtext[0]) {
+ if (pb && errp != &errtext[0]) {
/* SLAPI_PB_RESULT_TEXT duplicates the text in slapi_pblock_set */
slapi_pblock_set( pb, SLAPI_PB_RESULT_TEXT, errtext );
}
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
index fc3000cf..2909a170 100644
--- a/ldap/servers/slapd/search.c
+++ b/ldap/servers/slapd/search.c
@@ -68,6 +68,7 @@ do_search( Slapi_PBlock *pb )
BerElement *ber;
int i, err, attrsonly;
ber_int_t scope, deref, sizelimit, timelimit;
+ char *rawbase = NULL;
char *base = NULL, *fstr = NULL;
struct slapi_filter *filter = NULL;
char **attrs = NULL;
@@ -80,6 +81,8 @@ do_search( Slapi_PBlock *pb )
int rc = -1;
char *original_base = 0;
char *new_base = 0;
+ size_t baselen = 0;
+ int strict = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 );
@@ -114,13 +117,41 @@ do_search( Slapi_PBlock *pb )
*/
/* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */
- if ( ber_scanf( ber, "{aiiiib", &base, &scope, &deref, &sizelimit, &timelimit, &attrsonly ) == LBER_ERROR ){
- slapi_ch_free((void**)&base );
+ if ( ber_scanf( ber, "{aiiiib", &rawbase, &scope, &deref, &sizelimit, &timelimit, &attrsonly ) == LBER_ERROR ){
+ slapi_ch_free((void**)&rawbase );
log_search_access (pb, "???", -1, "???", "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL );
return;
}
+ /* Check if we should be performing strict validation. */
+ strict = config_get_dn_validate_strict();
+ if (strict) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawbase, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "SRCH",
+ rawbase?rawbase:"", "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawbase);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawbase, 0, &base, &baselen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "SRCH",
+ rawbase?rawbase:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawbase);
+ return;
+ } else if (rc > 0) { /* if rc == 0, rawbase is passed in */
+ slapi_ch_free((void **) &rawbase);
+ } else { /* rc == 0; rawbase is passed in; not null terminated */
+ *(base + baselen) = '\0';
+ }
+
/*
* ignore negative time and size limits since they make no sense
*/
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 140158a2..aa5a88b4 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -575,9 +575,9 @@ typedef int (*SyntaxEnumFunc)(char **names, Slapi_PluginDesc *plugindesc,
struct slapi_dn
{
unsigned char flag;
- const char *dn; /* DN */
+ const char *dn; /* DN [normalized] */
const char *ndn; /* Case Normalised DN */
- int ndn_len; /* normalize dn len */
+ int ndn_len; /* normalized dn length */
};
/*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index f7683b5e..2922a527 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -3025,28 +3025,74 @@ int slapi_rdn_partial_dup(Slapi_RDN *from, Slapi_RDN **to, int idx);
* utility routines for dealing with DNs
*/
/**
- * Normalizes a DN.
+ * Does nothing. (DEPRECATED)
*
* \param dn The DN to normalize.
* \return The normalized DN.
- * \deprecated Use slapi_sdn_get_ndn() instead.
+ * \deprecated Use slapi_dn_normalized_ext.
*/
char *slapi_dn_normalize( char *dn );
/**
- * Normalizes a portion of a DN value.
+ * Does nothing. (DEPRECATED)
*
* \param dn The DN value to normalize.
* \param end Pointer to the end of what will be normalized from the DN
* value in \c dn. If this parameter is \c NULL, the DN value
* will be wholly normalized.
- * \return A pointer to the end of the DN that has been normalized.
- * \warning This function does not null-terminate the string. Use this
- * function only if you know what you are doing.
+ * \return The normalized DN.
+ * \deprecated Use slapi_dn_normalized_ext.
*/
char *slapi_dn_normalize_to_end( char *dn, char *end );
/**
+ * Normalizes a DN.
+ *
+ * \param src The DN to normalize.
+ * \param src_len The length of src DN to normalize. If 0 is given, strlen(src) is used.
+ * \param dest The normalized DN.
+ * \param dest The length of the normalized DN dest.
+ * \return \c 0 if successful. The dest DN is normalized in line. Caller must not free dest.
+ * \return \c 1 if successful. The dest DN is allocated. Caller must free dest.
+ * \return \c -1 if an error occurs (for example, if the src DN cannot be normalized)
+ */
+int slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len);
+
+/**
+ * Normalizes a DN (in lower-case characters).
+ *
+ * \param src The DN to normalize.
+ * \param src_len The length of src DN to normalize. If 0 is given, strlen(src) is used internally.
+ * \param dest The normalized DN with the cases lowered.
+ * \param dest_len The length of the normalized DN dest.
+ * \return \c 0 if successful. The dest DN is normalized in line. Caller must not free dest. The string is NOT NULL terminated.
+ * \return \c 1 if successful. The dest DN is allocated. Caller must free dest.
+ * \return \c -1 if an error occurs (for example, if src DN cannot be normalized)
+ */
+int slapi_dn_normalize_case_ext(char *src, size_t src_len, char **dest, size_t *dest_len);
+
+/**
+ * Generate a valid DN string.
+ *
+ * \param fmt The format used to generate a DN string.
+ * \param ... The arguments to generate a DN string.
+ * \return A pointer to the generated DN. The
+ * \return NULL if failed.
+ * \note When a DN needs to be internally created, this function is supposed to be called. This function allocates the enough memory for the normalized DN and returns it filled with the normalized DN.
+ */
+char *slapi_create_dn_string(const char *fmt, ...);
+
+/**
+ * Generates a valid DN string (in lower-case characters).
+ *
+ * \param fmt The format used to generate a DN string.
+ * \param ... The arguments to generate a DN string.
+ * \return A pointer to the generated DN.
+ * \return NULL if failed.
+ */
+char *slapi_create_dn_string_case(const char *fmt, ...);
+
+/**
* Converts a DN to lowercase.
*
* \param dn The DN to convert.
@@ -3332,6 +3378,15 @@ int slapi_attr_get_oid_copy( const Slapi_Attr *attr, char **oidp );
int slapi_attr_get_syntax_oid_copy( const Slapi_Attr *a, char **oidp );
/**
+ * Checks if the attribute uses a DN syntax or not.
+ *
+ * \param attr The attribute to be checked.
+ * \return \c non 0 if the attribute uses a DN syntax.
+ * \return \c 0 if the attribute does not use a DN syntax.
+ */
+int slapi_attr_is_dn_syntax_attr(Slapi_Attr *attr);
+
+/**
* Get the flags associated with a particular attribute.
*
* Valid flags are:
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 84c3eb14..382cded0 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -364,6 +364,7 @@ const CSN *value_get_csn( const Slapi_Value *value, CSNType t );
const CSNSet *value_get_csnset ( const Slapi_Value *value);
Slapi_Value *value_remove_csn( Slapi_Value *value, CSNType t);
int value_contains_csn( const Slapi_Value *value, CSN *csn);
+int value_normalize_value(Slapi_Value *value);
/* dn.c */
/* this functions should only be used for dns allocated on the stack */
@@ -820,6 +821,7 @@ void valuearray_add_value_fast(Slapi_Value ***vals, Slapi_Value *addval, int nva
void valuearray_add_valuearray( Slapi_Value ***vals, Slapi_Value **addvals, PRUint32 flags );
void valuearray_add_valuearray_fast( Slapi_Value ***vals, Slapi_Value **addvals, int nvals, int naddvals, int *maxvals, int exact, int passin );
int valuearray_find(const Slapi_Attr *a, Slapi_Value **va, const Slapi_Value *v);
+int valuearray_normalize_value(Slapi_Value **vals);
/******************************************************************************
diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c
index 9beb878a..9c485de4 100644
--- a/ldap/servers/slapd/snmp_collator.c
+++ b/ldap/servers/slapd/snmp_collator.c
@@ -873,7 +873,8 @@ loadConfigStats() {
static Slapi_Entry *
getConfigEntry( Slapi_Entry **e ) {
Slapi_DN sdn;
-
+
+ /* SNMP_CONFIG_DN: no need to be normalized */
slapi_sdn_init_dn_byref( &sdn, SNMP_CONFIG_DN );
slapi_search_internal_get_entry( &sdn, NULL, e,
plugin_get_default_component_id());
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 733618f2..a7fe7892 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -60,13 +60,13 @@ static int shutting_down = 0;
/***********************************
* Private Defines
***********************************/
-#define TASK_BASE_DN "cn=tasks, cn=config"
-#define TASK_IMPORT_DN "cn=import, cn=tasks, cn=config"
-#define TASK_EXPORT_DN "cn=export, cn=tasks, cn=config"
-#define TASK_BACKUP_DN "cn=backup, cn=tasks, cn=config"
-#define TASK_RESTORE_DN "cn=restore, cn=tasks, cn=config"
-#define TASK_INDEX_DN "cn=index, cn=tasks, cn=config"
-#define TASK_UPGRADEDB_DN "cn=upgradedb, cn=tasks, cn=config"
+#define TASK_BASE_DN "cn=tasks,cn=config"
+#define TASK_IMPORT_DN "cn=import,cn=tasks,cn=config"
+#define TASK_EXPORT_DN "cn=export,cn=tasks,cn=config"
+#define TASK_BACKUP_DN "cn=backup,cn=tasks,cn=config"
+#define TASK_RESTORE_DN "cn=restore,cn=tasks,cn=config"
+#define TASK_INDEX_DN "cn=index,cn=tasks,cn=config"
+#define TASK_UPGRADEDB_DN "cn=upgradedb,cn=tasks,cn=config"
#define TASK_LOG_NAME "nsTaskLog"
#define TASK_STATUS_NAME "nsTaskStatus"
@@ -403,9 +403,12 @@ int slapi_task_register_handler(const char *name, dseCallbackFn func)
int ret = -1;
int x;
- dn = slapi_ch_smprintf("cn=%s, %s", name, TASK_BASE_DN);
- if (dn == NULL) {
- goto out;
+ dn = slapi_create_dn_string("cn=%s,%s", name, TASK_BASE_DN);
+ if (NULL == dn) {
+ LDAPDebug1Arg( LDAP_DEBUG_ANY,
+ "slapi_task_register_handler: "
+ "failed to create task dn for %s\n", name);
+ return ret;
}
pb = slapi_pblock_new();
@@ -458,9 +461,7 @@ int slapi_task_register_handler(const char *name, dseCallbackFn func)
ret = 0;
out:
- if (dn) {
- slapi_ch_free((void **)&dn);
- }
+ slapi_ch_free_string(&dn);
if (pb) {
slapi_pblock_destroy(pb);
}
@@ -487,18 +488,27 @@ void slapi_task_set_cancel_fn(Slapi_Task *task, TaskCallbackFn func)
***********************************/
/* create a new task, fill in DN, and setup modify callback */
static Slapi_Task *
-new_task(const char *dn)
+new_task(const char *rawdn)
{
- Slapi_Task *task = (Slapi_Task *)slapi_ch_calloc(1, sizeof(Slapi_Task));
+ Slapi_Task *task = NULL;
+ char *dn = NULL;
+
+ if (rawdn == NULL) {
+ return NULL;
+ }
- if (task == NULL)
+ dn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "new_task failed: invalid task dn: %s\n", rawdn);
return NULL;
+ }
+ task = (Slapi_Task *)slapi_ch_calloc(1, sizeof(Slapi_Task));
PR_Lock(global_task_lock);
task->next = global_task_list;
global_task_list = task;
PR_Unlock(global_task_lock);
-
- task->task_dn = slapi_ch_strdup(dn);
+ task->task_dn = dn;
task->task_state = SLAPI_TASK_SETUP;
task->task_flags = SLAPI_TASK_RUNNING_AS_TASK;
task->destructor = NULL;
@@ -511,8 +521,8 @@ new_task(const char *dn)
/* don't add entries under this one */
#if 0
/* don't know why, but this doesn't work. it makes the current add
- * * operation fail. :(
- * */
+ * operation fail. :(
+ */
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=*)", task_deny, NULL);
#endif
diff --git a/ldap/servers/slapd/tools/dbscan.c b/ldap/servers/slapd/tools/dbscan.c
index ad22b424..320f5eda 100644
--- a/ldap/servers/slapd/tools/dbscan.c
+++ b/ldap/servers/slapd/tools/dbscan.c
@@ -434,7 +434,7 @@ static ID id_stored_to_internal(char* b)
static void id_internal_to_stored(ID i,char *b)
{
if ( sizeof(ID) > 4 ) {
- memset (b+4, 0, sizeof(ID)-4);
+ (void)memset (b+4, 0, sizeof(ID)-4);
}
b[0] = (char)(i >> 24);
diff --git a/ldap/servers/slapd/tools/ldclt/ldclt.h b/ldap/servers/slapd/tools/ldclt/ldclt.h
index c8ead2c5..48c398be 100644
--- a/ldap/servers/slapd/tools/ldclt/ldclt.h
+++ b/ldap/servers/slapd/tools/ldclt/ldclt.h
@@ -741,6 +741,7 @@ extern char *dnFromMessage (thread_context *tttctx, LDAPMessage *res);
extern int doAddEntry (thread_context *tttctx);
extern int doAttrReplace (thread_context *tttctx); /*JLS 21-11-00*/
extern int doAttrFileReplace (thread_context *tttctx);
+
extern int doBindOnly (thread_context *tttctx); /*JLS 04-05-01*/
extern int doDeleteEntry (thread_context *tttctx);
extern int doExactSearch (thread_context *tttctx);
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
index d26b0b98..8987e634 100644
--- a/ldap/servers/slapd/util.c
+++ b/ldap/servers/slapd/util.c
@@ -335,8 +335,9 @@ int slapi_entry2mods (const Slapi_Entry *e, char **dn, LDAPMod ***attrs)
*
* normalize_mods2bvals
*
-*
-*
+* Return value: normalized mods
+* The values/bvals are all duplicated in this function since
+* the normalized mods are freed with ldap_mods_free by the caller.
*
*******************************************************************************/
@@ -360,6 +361,18 @@ normalize_mods2bvals(const LDAPMod **mods)
for (w = 0; mods[w] != NULL; w++)
{
+ Slapi_Attr a = {0};
+ slapi_attr_init(&a, mods[w]->mod_type);
+ int is_dn_syntax = 0;
+ struct berval **normmbvp = NULL;
+
+ /* Check if the type of the to-be-added values has DN syntax
+ * or not. */
+ if (slapi_attr_is_dn_syntax_attr(&a)) {
+ is_dn_syntax = 1;
+ }
+ attr_done(&a);
+
/* copy each mod into a normalized modbvalue */
normalized_mods[w] = (LDAPMod *) slapi_ch_calloc(1, sizeof(LDAPMod));
normalized_mods[w]->mod_op = mods[w]->mod_op | LDAP_MOD_BVALUES;
@@ -397,32 +410,79 @@ normalize_mods2bvals(const LDAPMod **mods)
if (mods[w]->mod_op & LDAP_MOD_BVALUES)
{
- for (x = 0; mods[w]->mod_bvalues != NULL &&
- mods[w]->mod_bvalues[x] != NULL; x++)
+ struct berval **mbvp = NULL;
+
+ for (mbvp = mods[w]->mod_bvalues,
+ normmbvp = normalized_mods[w]->mod_bvalues;
+ mbvp && *mbvp; mbvp++, normmbvp++)
{
- normalized_mods[w]->mod_bvalues[x] = ber_bvdup(mods[w]->mod_bvalues[x]);
+ if (is_dn_syntax) {
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
+
+ rc = slapi_dn_normalize_ext((*mbvp)->bv_val,
+ (*mbvp)->bv_len,
+ &normed, &dnlen);
+ if (rc < 0) { /* normalization failed; use the original */
+ *normmbvp = ber_bvdup(*mbvp);
+ } else if (rc == 0) { /* if rc == 0, value is passed in */
+ *(normed + dnlen) = '\0';
+ *normmbvp = ber_bvdup(*mbvp);
+ } else {
+ (*normmbvp)->bv_val = normed;
+ (*normmbvp)->bv_len = dnlen;
+ }
+ } else {
+ *normmbvp = ber_bvdup(*mbvp);
+ }
}
} else {
- for (x = 0; mods[w]->mod_values != NULL &&
- mods[w]->mod_values[x] != NULL; x++)
+ char **mvp = NULL;
+
+ for (mvp = mods[w]->mod_values,
+ normmbvp = normalized_mods[w]->mod_bvalues;
+ mvp && *mvp; mvp++, normmbvp++)
{
- normalized_mods[w]->mod_bvalues[ x ] = (struct berval *)
- slapi_ch_calloc(1, sizeof(struct berval));
-
- vlen = strlen(mods[w]->mod_values[x]);
- normalized_mods[w]->mod_bvalues[ x ]->bv_val =
- slapi_ch_calloc(vlen + 1, sizeof(char));
- memcpy(normalized_mods[w]->mod_bvalues[ x ]->bv_val,
- mods[w]->mod_values[x], vlen);
- normalized_mods[w]->mod_bvalues[ x ]->bv_val[vlen] = '\0';
- normalized_mods[w]->mod_bvalues[ x ]->bv_len = vlen;
+ *normmbvp =
+ (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+
+ vlen = strlen(*mvp);
+
+ if (is_dn_syntax) {
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(*mvp, vlen,
+ &normed, &dnlen);
+ if (rc < 0) { /* normalization failed; use the original */
+ (*normmbvp)->bv_val = slapi_ch_malloc(vlen + 1);
+ memcpy((*normmbvp)->bv_val, *mvp, vlen);
+ (*normmbvp)->bv_val[vlen] = '\0';
+ (*normmbvp)->bv_len = vlen;
+ } else if (rc == 0) { /* if rc == 0, value is passed in */
+ *(normed + dnlen) = '\0';
+ (*normmbvp)->bv_val = slapi_ch_strdup(normed);
+ (*normmbvp)->bv_len = dnlen;
+ } else {
+ (*normmbvp)->bv_val = normed;
+ (*normmbvp)->bv_len = dnlen;
+ }
+ } else {
+ (*normmbvp)->bv_val = slapi_ch_malloc(vlen + 1);
+ memcpy((*normmbvp)->bv_val, *mvp, vlen);
+ (*normmbvp)->bv_val[vlen] = '\0';
+ (*normmbvp)->bv_len = vlen;
+ }
}
}
+ PR_ASSERT(normmbvp - normalized_mods[w]->mod_bvalues <= num_values);
+
/* don't forget to null terminate it */
- if (num_values > 0)
+ if (num_values > 0)
{
- normalized_mods[w]->mod_bvalues[ x ] = NULL;
+ *normmbvp = NULL;
}
}
diff --git a/ldap/servers/slapd/value.c b/ldap/servers/slapd/value.c
index 72f94b93..c0cf66e9 100644
--- a/ldap/servers/slapd/value.c
+++ b/ldap/servers/slapd/value.c
@@ -551,3 +551,29 @@ value_dump( const Slapi_Value *value, const char *text)
}
#endif
+int
+value_normalize_value(Slapi_Value *value)
+{
+ char *normval = NULL;
+ size_t len = 0;
+ int rc = 0;
+
+ if (NULL == value) {
+ return 0;
+ }
+
+ rc = slapi_dn_normalize_ext(value->bv.bv_val, value->bv.bv_len,
+ &normval, &len);
+ if (rc < 0) {
+ return 1;
+ } else if (rc > 0) { /* if rc == 0, the original value is passed in */
+ slapi_ch_free_string(&value->bv.bv_val);
+ } else { /* rc == 0; original is passed in; not null terminated */
+ /* since bvalue, no need to terminate with null, tho */
+ *(normval + len) = '\0';
+ }
+ value->bv.bv_val = normval;
+ value->bv.bv_len = len;
+
+ return 0;
+}
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
index d6909ac8..22ffb4aa 100644
--- a/ldap/servers/slapd/valueset.c
+++ b/ldap/servers/slapd/valueset.c
@@ -1437,3 +1437,17 @@ valueset_update_csn_for_valuearray(Slapi_ValueSet *vs, const Slapi_Attr *a, Slap
*valuesupdated= vaf_valuesupdated.va;
}
}
+
+int
+valuearray_normalize_value(Slapi_Value **vals)
+{
+ int rc = 0;
+ Slapi_Value **vp = NULL;
+
+ for (vp = vals; vp && *vp; vp++) {
+ rc |= value_normalize_value(*vp);
+ }
+
+ return rc;
+}
+