diff options
author | Nathan Kinder <nkinder@redhat.com> | 2009-05-13 11:12:11 -0700 |
---|---|---|
committer | Nathan Kinder <nkinder@redhat.com> | 2009-05-13 11:12:11 -0700 |
commit | 0410819d48795fca4faf986cf8658c34c4d929e3 (patch) | |
tree | 0adaff658324a4b1ea7809fddad9da075be41517 | |
parent | 5381a78daee870cff14684fa9c7845ff363a6e7c (diff) | |
download | ds-0410819d48795fca4faf986cf8658c34c4d929e3.tar.gz ds-0410819d48795fca4faf986cf8658c34c4d929e3.tar.xz ds-0410819d48795fca4faf986cf8658c34c4d929e3.zip |
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
-rw-r--r-- | ldap/ldif/template-dse.ldif.in | 1 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/dn.c | 16 | ||||
-rw-r--r-- | ldap/servers/slapd/config.c | 16 | ||||
-rw-r--r-- | ldap/servers/slapd/libglobs.c | 30 | ||||
-rw-r--r-- | ldap/servers/slapd/proto-slap.h | 2 | ||||
-rw-r--r-- | 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 232d9f2e..54a9c4f4 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 a6dcceda..80a3f8bf 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 1af1b77b..62757572 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 30ad5f3a..8c13a9b6 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 c561196d..2041a997 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 cec186f9..724bef93 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; |