Browse Source

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!!)
Noriko Hosoi 12 years ago
parent
commit
6602685133

+ 45 - 6
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
@@ -882,15 +902,34 @@ 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';
 

+ 29 - 0
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();

+ 1 - 1
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 );

+ 3 - 0
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();

+ 21 - 8
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 ) {

+ 7 - 0
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;

+ 18 - 0
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
  */