ldap/servers/slapd/attrsyntax.c | 51 +++++++++++++++++++++++++++++++++-----
ldap/servers/slapd/libglobs.c | 29 +++++++++++++++++++++
ldap/servers/slapd/operation.c | 2 -
ldap/servers/slapd/proto-slap.h | 3 ++
ldap/servers/slapd/search.c | 29 +++++++++++++++------
ldap/servers/slapd/slap.h | 7 +++++
ldap/servers/slapd/slapi-plugin.h | 18 +++++++++++++
7 files changed, 124 insertions(+), 15 deletions(-)
New commits:
commit 6602685133997e93aedba1c473d3afeb24a855a6
Author: Noriko Hosoi <nhosoi(a)totoro.usersys.redhat.com>
Date: Fri Mar 1 17:36:05 2013 -0800
Ticket #604 - Required attribute not checked during search operation
Bug description: If attribute list passed from the ldapsearch
contains a string with a space and following characters, the
same string is returned to the client. E.g.,
ldapsearch -b <basedn> "(filter)" "sn garbage"
returns
dn: <matched dn>
sn garbage: <sn>
Fix description: This patch introduces a config parameter
nsslapd-search-return-original-type-switch. It takes on | off.
By default, it is off. When it is off, search returns the
attribute from which a space and following characters are
chopped.
dn: <matched dn>
sn: <sn>
If it is on, it respects the current behaviour and returns
the original attribute string.
https://fedorahosted.org/389/ticket/604
Reviewed by Rich (Thank you!!)
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
index 26e09db..227369c 100644
--- a/ldap/servers/slapd/attrsyntax.c
+++ b/ldap/servers/slapd/attrsyntax.c
@@ -450,9 +450,6 @@ attr_syntax_delete_no_lock( struct asyntaxinfo *asi,
*
* Warning: The caller must free the returned string.
*/
-
-
-
char *
slapi_attr_syntax_normalize( const char *s )
{
@@ -470,6 +467,29 @@ slapi_attr_syntax_normalize( const char *s )
return r;
}
+/*
+ * flags:
+ * 0 -- same as slapi_attr_syntax_normalize
+ * ATTR_SYNTAX_NORM_ORIG_ATTR -- In addition to slapi_attr_syntax_normalize,
+ * a space and following characters are removed
+ * from the given string 's'.
+ */
+char *
+slapi_attr_syntax_normalize_ext( char *s, int flags )
+{
+ struct asyntaxinfo *asi = NULL;
+ char *r = NULL;
+
+ if((asi=attr_syntax_get_by_name(s)) != NULL ) {
+ r = slapi_ch_strdup(asi->asi_name);
+ attr_syntax_return( asi );
+ }
+ if ( NULL == asi ) {
+ slapi_ch_free_string( &r );
+ r = attr_syntax_normalize_no_lookup_ext( s, flags );
+ }
+ return r;
+}
/*
* attr_syntax_exists: return 1 if attr_name exists, 0 otherwise
@@ -883,14 +903,33 @@ attr_syntax_print()
/* lowercase the attr name and chop trailing spaces */
/* note that s may contain options also, e.g., userCertificate;binary */
char *
+attr_syntax_normalize_no_lookup_ext( char *s, int flags )
+{
+ char *save, *tmps;
+
+ tmps = slapi_ch_strdup(s);
+ for ( save = tmps; (*tmps != '\0') && (*tmps != ' '); tmps++ )
+ {
+ *tmps = TOLOWER( *tmps );
+ }
+ *tmps = '\0';
+ if (flags & ATTR_SYNTAX_NORM_ORIG_ATTR) {
+ /* Chop trailing spaces + following strings */
+ *(s + (tmps - save)) = '\0';
+ }
+
+ return save;
+}
+
+char *
attr_syntax_normalize_no_lookup( const char *s )
{
char *save, *tmps;
- tmps = slapi_ch_strdup(s);
- for ( save = tmps; (*tmps != '\0') && (*tmps != ' '); tmps++
)
+ tmps = slapi_ch_strdup(s);
+ for ( save = tmps; (*tmps != '\0') && (*tmps != ' '); tmps++ )
{
- *tmps = TOLOWER( *tmps );
+ *tmps = TOLOWER( *tmps );
}
*tmps = '\0';
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 17ac377..59790bc 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -253,6 +253,7 @@ slapi_onoff_t init_disk_logging_critical;
slapi_onoff_t init_disk_preserve_logging;
slapi_onoff_t init_ndn_cache_enabled;
slapi_onoff_t init_sasl_mapping_fallback;
+slapi_onoff_t init_return_orig_type;
#ifdef MEMPOOL_EXPERIMENTAL
slapi_onoff_t init_mempool_switch;
#endif
@@ -1028,6 +1029,10 @@ static struct config_get_and_set {
CONFIG_SPECIAL_UNHASHED_PW_SWITCH,
(ConfigGetFunc)config_get_unhashed_pw_switch,
DEFAULT_UNHASHED_PW_SWITCH},
+ {CONFIG_SEARCH_RETURN_ORIGINAL_TYPE, config_set_return_orig_type_switch,
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.return_orig_type,
+ CONFIG_ON_OFF, (ConfigGetFunc)config_get_return_orig_type_switch,
&init_return_orig_type}
#ifdef MEMPOOL_EXPERIMENTAL
,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch,
NULL, 0,
@@ -1458,6 +1463,7 @@ FrontendConfig_init () {
cfg->sasl_mapping_fallback = slapi_counter_new();
init_sasl_mapping_fallback = LDAP_OFF;
cfg->unhashed_pw_switch = SLAPD_UNHASHED_PW_ON;
+ init_return_orig_type = cfg->return_orig_type = LDAP_OFF;
#ifdef MEMPOOL_EXPERIMENTAL
init_mempool_switch = cfg->mempool_switch = LDAP_ON;
@@ -1740,6 +1746,17 @@ config_set_ndn_cache_max_size(const char *attrname, char *value,
char *errorbuf,
return retVal;
}
+int
+config_set_return_orig_type_switch(const char *attrname, char *value, char *errorbuf, int
apply)
+{
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ int retVal;
+
+ retVal = config_set_onoff(attrname, value,
&(slapdFrontendConfig->return_orig_type), errorbuf, apply);
+
+ return retVal;
+}
+
int
config_set_port( const char *attrname, char *port, char *errorbuf, int apply ) {
long nPort;
@@ -5738,6 +5755,18 @@ config_get_ndn_cache_enabled(){
return retVal;
}
+int
+config_get_return_orig_type_switch()
+{
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ int retVal;
+
+ CFG_ONOFF_LOCK_READ(slapdFrontendConfig);
+ retVal = (int)slapdFrontendConfig->return_orig_type;
+ CFG_ONOFF_UNLOCK_READ(slapdFrontendConfig);
+ return retVal;
+}
+
char *
config_get_basedn() {
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
index 13e05c1..743b9ce 100644
--- a/ldap/servers/slapd/operation.c
+++ b/ldap/servers/slapd/operation.c
@@ -220,7 +220,7 @@ operation_free( Slapi_Operation **op, Connection *conn )
slapi_sdn_free(&(*op)->o_target_spec);
slapi_ch_free_string( &(*op)->o_authtype );
if ( (*op)->o_searchattrs != NULL ) {
- cool_charray_free( (*op)->o_searchattrs );
+ charray_free( (*op)->o_searchattrs );
}
if ( NULL != (*op)->o_params.request_controls ) {
ldap_controls_free( (*op)->o_params.request_controls );
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 0a07a29..acea92f 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -127,6 +127,7 @@ int attr_syntax_create( const char *attr_oid, char *const*attr_names,
void attr_syntax_free( struct asyntaxinfo *a );
int attr_syntax_add( struct asyntaxinfo *asip );
char *attr_syntax_normalize_no_lookup( const char *s );
+char *attr_syntax_normalize_no_lookup_ext( char *s, int flags );
void attr_syntax_enumerate_attrs(AttrEnumFunc aef, void *arg, PRBool writelock);
void attr_syntax_all_clear_flag( unsigned long flag );
void attr_syntax_delete_all_not_flagged( unsigned long flag );
@@ -394,6 +395,7 @@ int config_set_auditlog_unhashed_pw(const char *attrname, char *value,
char *err
int config_set_ndn_cache_enabled(const char *attrname, char *value, char *errorbuf, int
apply);
int config_set_ndn_cache_max_size(const char *attrname, char *value, char *errorbuf, int
apply);
int config_set_unhashed_pw_switch(const char *attrname, char *value, char *errorbuf, int
apply);
+int config_set_return_orig_type_switch(const char *attrname, char *value, char *errorbuf,
int apply);
#if !defined(_WIN32) && !defined(AIX)
int config_set_maxdescriptors( const char *attrname, char *value, char *errorbuf, int
apply );
@@ -552,6 +554,7 @@ int config_get_disk_logging_critical();
int config_get_ndn_cache_count();
size_t config_get_ndn_cache_size();
int config_get_ndn_cache_enabled();
+int config_get_return_orig_type_switch();
char *config_get_allowed_sasl_mechs();
int config_set_allowed_sasl_mechs(const char *attrname, char *value, char *errorbuf, int
apply);
int config_get_schemamod();
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
index c3d51d6..974cb6a 100644
--- a/ldap/servers/slapd/search.c
+++ b/ldap/servers/slapd/search.c
@@ -329,16 +329,29 @@ do_search( Slapi_PBlock *pb )
gerattrs[gerattridx] = NULL;
}
- operation->o_searchattrs = cool_charray_dup( attrs );
- for ( i = 0; attrs[i] != NULL; i++ ) {
- char *type;
-
- type = slapi_attr_syntax_normalize(attrs[i]);
- slapi_ch_free( (void**)&(attrs[i]) );
- attrs[i] = type;
+ if (config_get_return_orig_type_switch()) {
+ /* return the original type, e.g., "sn (surname)" */
+ operation->o_searchattrs = charray_dup( attrs );
+ for ( i = 0; attrs[i] != NULL; i++ ) {
+ char *type;
+ type = slapi_attr_syntax_normalize(attrs[i]);
+ slapi_ch_free( (void**)&(attrs[i]) );
+ attrs[i] = type;
+ }
+ } else {
+ /* return the chopped type, e.g., "sn" */
+ operation->o_searchattrs = NULL;
+ for ( i = 0; attrs[i] != NULL; i++ ) {
+ char *type;
+ type = slapi_attr_syntax_normalize_ext(attrs[i],
+ ATTR_SYNTAX_NORM_ORIG_ATTR);
+ /* attrs[i] is consumed */
+ charray_add(&operation->o_searchattrs, attrs[i]);
+ attrs[i] = type;
+ }
}
}
- if ( slapd_ldap_debug & LDAP_DEBUG_ARGS ) {
+ if ( slapd_ldap_debug & LDAP_DEBUG_ARGS ) {
char abuf[ 1024 ], *astr;
if ( NULL == attrs ) {
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index a44bced..02cb121 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -530,6 +530,10 @@ typedef int (*AttrEnumFunc)(struct asyntaxinfo *asi, void *arg);
#define ATTR_SYNTAX_ENUM_STOP 1 /* halt the enumeration */
#define ATTR_SYNTAX_ENUM_REMOVE 2 /* unhash current node and continue */
+/* flags for slapi_attr_syntax_normalize_ext */
+#define ATTR_SYNTAX_NORM_ORIG_ATTR 0x1 /* a space and following characters are
+ removed from the given string */
+
/* This is the type of the function passed into plugin_syntax_enumerate */
typedef int (*SyntaxEnumFunc)(char **names, Slapi_PluginDesc *plugindesc,
void *arg);
@@ -2066,6 +2070,7 @@ typedef struct _slapdEntryPoints {
#define CONFIG_ALLOWED_SASL_MECHS "nsslapd-allowed-sasl-mechanisms"
#define CONFIG_IGNORE_VATTRS "nsslapd-ignore-virtual-attrs"
#define CONFIG_SASL_MAPPING_FALLBACK "nsslapd-sasl-mapping-fallback"
+#define CONFIG_SEARCH_RETURN_ORIGINAL_TYPE
"nsslapd-search-return-original-type-switch"
#ifdef MEMPOOL_EXPERIMENTAL
#define CONFIG_MEMPOOL_SWITCH_ATTRIBUTE "nsslapd-mempool"
@@ -2301,6 +2306,8 @@ typedef struct _slapdFrontendConfig {
slapi_onoff_t ndn_cache_enabled;
size_t ndn_cache_max_size;
+ slapi_onoff_t return_orig_type; /* if on, search returns original type set in attr list
*/
+
/* atomic settings */
Slapi_Counter *ignore_vattrs;
Slapi_Counter *sasl_mapping_fallback;
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 127cbcd..8979c18 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -4037,6 +4037,24 @@ int slapi_attr_get_bervals_copy( Slapi_Attr *a, struct berval
***vals );
*/
char * slapi_attr_syntax_normalize( const char *s );
+/**
+ * Normalize an attribute type.
+ *
+ * The attribute type will be looked up in the defined syntaxes to
+ * get the normalized form. If it is not found, the passed in type
+ * will be normalized. If ATTR_SYNTAX_NORM_ORIG_ATTR is set to flags,
+ * the upper and lower cases are kept but trailing spaces are chopped
+ * from the original attribute type.
+ *
+ * \param s The attribute type that you want to normalize.
+ * \param flags 0 or ATTR_SYNTAX_NORM_ORIG_ATTR
+ * \return A normalized copy of the passed in attribute type.
+ * \warning You should free the returned string using slapi_ch_free_string().
+ * \see slapi_ch_free_string()
+ */
+char * slapi_attr_syntax_normalize_ext( char *s, int flags );
+
+
/*
* value routines
*/