[389-devel] Please Review: Add strict DN syntax enforcement option

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

 




>From 0410819d48795fca4faf986cf8658c34c4d929e3 Mon Sep 17 00:00:00 2001
From: Nathan Kinder <nkinder@xxxxxxxxxx>
Date: Wed, 13 May 2009 11:12:11 -0700
Subject: [PATCH] Add strict DN syntax enforcement option.

The DN syntax has become more restrictive over time, and the
current rules are quite strict. Strict adherence to the rules
defined in RFC 4514, section 3, would likely cause some pain to
client applications. Things such as spaces between the RDN
components are not allowed, yet many people use them still since
they were allowed in the previous specification outlined in RFC
1779.

To deal with the special circumstances around validation of the DN
syntax, a configuration attribute is provided named
nsslapd-dn-validate-strict. This configuration attribute will
ensure that the value strictly adheres to the rules defined in RFC
4514, section 3 if it is set to on. If it is set to off, the server
will normalize the value before checking it for syntax violations.
Our current normalization function was designed to handle DN values
adhering to RFC 1779 or RFC 2253
---
 ldap/ldif/template-dse.ldif.in     |    1 +
 ldap/servers/plugins/syntaxes/dn.c |   16 ++++++++++++++++
 ldap/servers/slapd/config.c        |   16 ++++++++++++++++
 ldap/servers/slapd/libglobs.c      |   30 ++++++++++++++++++++++++++++++
 ldap/servers/slapd/proto-slap.h    |    2 ++
 ldap/servers/slapd/slap.h          |    4 +++-
 6 files changed, 68 insertions(+), 1 deletions(-)

diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in
index 232d9f2..54a9c4f 100644
--- a/ldap/ldif/template-dse.ldif.in
+++ b/ldap/ldif/template-dse.ldif.in
@@ -25,6 +25,7 @@ nsslapd-enquote-sup-oc: off
 nsslapd-localhost: %fqdn%
 nsslapd-schemacheck: on
 nsslapd-syntaxcheck: on
+nsslapd-dn-validate-strict: off
 nsslapd-rewrite-rfc1274: off
 nsslapd-return-exact-case: on
 nsslapd-ssl-check-hostname: on
diff --git a/ldap/servers/plugins/syntaxes/dn.c b/ldap/servers/plugins/syntaxes/dn.c
index a6dcced..80a3f8b 100644
--- a/ldap/servers/plugins/syntaxes/dn.c
+++ b/ldap/servers/plugins/syntaxes/dn.c
@@ -141,6 +141,7 @@ dn_assertion2keys_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
 static int dn_validate( struct berval *val )
 {
 	int rc = 0; /* Assume value is valid */
+	char *val_copy = NULL;
 
 	if (val != NULL) {
 		/* Per RFC 4514:
@@ -154,10 +155,22 @@ static int dn_validate( struct berval *val )
 		 * attributeValue = string / hexstring
 		 */
 		if (val->bv_len > 0) {
+			int strict = 0;
 			char *p = val->bv_val;
 			char *end = &(val->bv_val[val->bv_len - 1]);
 			char *last = NULL;
 
+			/* 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(val->bv_val, val->bv_len);
+				p = val_copy;
+				end = slapi_dn_normalize_to_end(p, NULL) - 1;
+			}
+
 			/* Validate one RDN at a time in a loop. */
 			while (p <= end) {
 				if ((rc = rdn_validate(p, end, &last)) != 0) {
@@ -186,6 +199,9 @@ static int dn_validate( struct berval *val )
 		goto exit;
 	}
 exit:
+	if (val_copy) {
+		slapi_ch_free_string(&val_copy);
+	}
 	return rc;
 }
 
diff --git a/ldap/servers/slapd/config.c b/ldap/servers/slapd/config.c
index 1af1b77..6275757 100644
--- a/ldap/servers/slapd/config.c
+++ b/ldap/servers/slapd/config.c
@@ -241,11 +241,13 @@ slapd_bootstrap_config(const char *configdir)
 			char schemacheck[BUFSIZ];
 			char syntaxcheck[BUFSIZ];
 			char syntaxlogging[BUFSIZ];
+			char dn_validate_strict[BUFSIZ];
 			Slapi_DN plug_dn;
 
 			workpath[0] = loglevel[0] = maxdescriptors[0] = '\0';
 			val[0] = logenabled[0] = schemacheck[0] = syntaxcheck[0] = '\0';
 			syntaxlogging[0] = _localuser[0] = '\0';
+			dn_validate_strict[0] = '\0';
 
 			/* Convert LDIF to entry structures */
 			slapi_sdn_init_dn_byref(&plug_dn, PLUGIN_BASE_DN);
@@ -490,6 +492,20 @@ slapd_bootstrap_config(const char *configdir)
 					}
 				}
 
+				/* see if we need to enable strict dn validation */
+				if (!dn_validate_strict[0] &&
+				    entry_has_attr_and_value(e, CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE,
+				    dn_validate_strict, sizeof(dn_validate_strict)))
+				{
+					if (config_set_dn_validate_strict(CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE,
+					                           dn_validate_strict, errorbuf, CONFIG_APPLY)
+					                           != LDAP_SUCCESS)
+					{
+						LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
+						          CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE, errorbuf);
+					}
+				}
+
 				/* see if we need to expect quoted schema values */
 				if (entry_has_attr_and_value(e, CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE,
 											 val, sizeof(val)))
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 30ad5f3..8c13a9b 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -327,6 +327,9 @@ static struct config_get_and_set {
 	{CONFIG_SYNTAXLOGGING_ATTRIBUTE, config_set_syntaxlogging,
 		NULL, 0,
 		(void**)&global_slapdFrontendConfig.syntaxlogging, CONFIG_ON_OFF, NULL},
+	{CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE, config_set_dn_validate_strict,
+		NULL, 0,
+		(void**)&global_slapdFrontendConfig.dn_validate_strict, CONFIG_ON_OFF, NULL},
 	{CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE, config_set_ds4_compatible_schema,
 		NULL, 0,
 		(void**)&global_slapdFrontendConfig.ds4_compatible_schema,
@@ -899,6 +902,7 @@ FrontendConfig_init () {
   cfg->schemacheck = LDAP_ON;
   cfg->syntaxcheck = LDAP_OFF;
   cfg->syntaxlogging = LDAP_OFF;
+  cfg->dn_validate_strict = LDAP_OFF;
   cfg->ds4_compatible_schema = LDAP_OFF;
   cfg->enquote_sup_oc = LDAP_OFF;
   cfg->lastmod = LDAP_ON;
@@ -2459,6 +2463,20 @@ config_set_syntaxlogging( const char *attrname, char *value, char *errorbuf, int
 }
 
 int
+config_set_dn_validate_strict( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  retVal = config_set_onoff ( attrname,
+                              value,
+                              &(slapdFrontendConfig->dn_validate_strict),
+                              errorbuf,
+                              apply);
+
+  return retVal;
+}
+
+int
 config_set_ds4_compatible_schema( const char *attrname, char *value, char *errorbuf, int apply ) {
   int retVal = LDAP_SUCCESS;
   slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -4093,6 +4111,18 @@ config_get_syntaxlogging() {
 }
 
 int
+config_get_dn_validate_strict() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->dn_validate_strict;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
+int
 config_get_ds4_compatible_schema() {
   slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
   int retVal;
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index c561196..2041a99 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -266,6 +266,7 @@ int config_set_readonly( const char *attrname, char *value, 	char *errorbuf, int
 int config_set_schemacheck( const char *attrname, char *value, char *errorbuf, int apply );
 int config_set_syntaxcheck( const char *attrname, char *value, char *errorbuf, int apply );
 int config_set_syntaxlogging( const char *attrname, char *value, char *errorbuf, int apply );
+int config_set_dn_validate_strict( const char *attrname, char *value, char *errorbuf, int apply );
 int config_set_ds4_compatible_schema( const char *attrname, char *value, char *errorbuf, int apply );
 int config_set_schema_ignore_trailing_spaces( const char *attrname, char *value, char *errorbuf, int apply );
 int config_set_rootdn( const char *attrname, char *value, char *errorbuf, int apply );
@@ -410,6 +411,7 @@ int config_get_security();
 int config_get_schemacheck();
 int config_get_syntaxcheck();
 int config_get_syntaxlogging();
+int config_get_dn_validate_strict();
 int config_get_ds4_compatible_schema();
 int config_get_schema_ignore_trailing_spaces();
 char *config_get_rootdn();
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index cec186f..724bef9 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1639,7 +1639,8 @@ typedef struct _slapdEntryPoints {
 #define CONFIG_SCHEMACHECK_ATTRIBUTE    "nsslapd-schemacheck"
 #define CONFIG_SYNTAXCHECK_ATTRIBUTE	"nsslapd-syntaxcheck"
 #define CONFIG_SYNTAXLOGGING_ATTRIBUTE	"nsslapd-syntaxlogging"
-#define CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE    "nsslapd-ds4-compatible-schema"
+#define CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE     "nsslapd-dn-validate-strict"
+#define CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE  "nsslapd-ds4-compatible-schema"
 #define CONFIG_SCHEMA_IGNORE_TRAILING_SPACES    "nsslapd-schema-ignore-trailing-spaces"
 #define CONFIG_SCHEMAREPLACE_ATTRIBUTE	"nsslapd-schemareplace"
 #define CONFIG_LOGLEVEL_ATTRIBUTE       "nsslapd-errorlog-level"
@@ -1856,6 +1857,7 @@ typedef struct _slapdFrontendConfig {
   int schemacheck;
   int syntaxcheck;
   int syntaxlogging;
+  int dn_validate_strict;
   int ds4_compatible_schema;
   int schema_ignore_trailing_spaces;
   int secureport;
-- 
1.6.0.6

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

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

  Powered by Linux