From 46daeac581fb71ab66df1603b4d1eee619c6576f Mon Sep 17 00:00:00 2001 From: William Brown Date: Jan 22 2020 00:37:35 +0000 Subject: Ticket 50790 - Add result text when filter is invalid Bug Description: As a result of the change in 50727 we need to communicate to users/admins when queries they issue may be incomplete due to rfc compliance of filter processing. Fix Description: When we use idl_alloc(0) on attributes, we set a result text (if none already set) warning that the result set may be incomplete. https://pagure.io/389-ds-base/issue/50790 Author: William Brown Review by: tbordaz (Thanks!) --- diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c index 348cc6f..cb562e9 100644 --- a/ldap/servers/slapd/pblock.c +++ b/ldap/servers/slapd/pblock.c @@ -4369,6 +4369,15 @@ slapi_pblock_set_flag_operation_notes(Slapi_PBlock *pb, uint32_t opflag) { pb->pb_intop->pb_operation_notes |= opflag; } +/* Set result text if it's NULL */ +void +slapi_pblock_set_result_text_if_empty(Slapi_PBlock *pb, char *text) { + _pblock_assert_pb_intop(pb); + if (pb->pb_intop->pb_result_text == NULL) { + pb->pb_intop->pb_result_text = slapi_ch_strdup(text); + } +} + /* * Clear and then set the bind DN and related credentials for the * connection `conn'. diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c index 6e853fc..a294e67 100644 --- a/ldap/servers/slapd/schema.c +++ b/ldap/servers/slapd/schema.c @@ -760,7 +760,7 @@ slapi_filter_schema_check_inner(Slapi_Filter *f) { * */ Slapi_Filter_Result -slapi_filter_schema_check(Slapi_Filter *f, Slapi_Filter_Policy fp) { +slapi_filter_schema_check(Slapi_PBlock *pb, Slapi_Filter *f, Slapi_Filter_Policy fp) { if (f == NULL) { return FILTER_SCHEMA_FAILURE; } @@ -780,6 +780,9 @@ slapi_filter_schema_check(Slapi_Filter *f, Slapi_Filter_Policy fp) { /* If any warning occured, ensure we fail it. */ if (fp == FILTER_POLICY_STRICT && r != FILTER_SCHEMA_SUCCESS) { r = FILTER_SCHEMA_FAILURE; + } else if (fp == FILTER_POLICY_PROTECT && r == FILTER_SCHEMA_WARNING) { + /* Or, make sure we setup text to warn the user submitting the query */ + slapi_pblock_set_result_text_if_empty(pb, "Invalid attribute in filter - results may not be complete."); } return r; } diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c index 013bece..afcd2a1 100644 --- a/ldap/servers/slapd/search.c +++ b/ldap/servers/slapd/search.c @@ -203,7 +203,7 @@ do_search(Slapi_PBlock *pb) * or reject. A question is the location of this and if we should try to work with * internal searches too ... */ - Slapi_Filter_Result r = slapi_filter_schema_check(filter, config_get_verify_filter_schema()); + Slapi_Filter_Result r = slapi_filter_schema_check(pb, filter, config_get_verify_filter_schema()); if (r == FILTER_SCHEMA_FAILURE) { char *errtxt = "The filter provided contains invalid attributes not found in schema"; err = LDAP_UNWILLING_TO_PERFORM; diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index edf6a9e..56fdfd4 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -1592,7 +1592,7 @@ typedef enum { * WARNING - return SUCCESS, and flag filter elements that are not in schema. * STRICT - return SUCCESS only if all elements are found - else return FAILURE. */ -Slapi_Filter_Result slapi_filter_schema_check(Slapi_Filter *f, Slapi_Filter_Policy fp); +Slapi_Filter_Result slapi_filter_schema_check(Slapi_PBlock *pb, Slapi_Filter *f, Slapi_Filter_Policy fp); /** * Determines if the DN violates the Distinguished Name syntax rules. diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h index 04c0455..4f3b740 100644 --- a/ldap/servers/slapd/slapi-private.h +++ b/ldap/servers/slapd/slapi-private.h @@ -1456,6 +1456,7 @@ void slapi_pblock_set_pw_entry(Slapi_PBlock *pb, struct slapi_entry *entry); uint32_t slapi_pblock_get_operation_notes(Slapi_PBlock *pb); void slapi_pblock_set_operation_notes(Slapi_PBlock *pb, uint32_t opnotes); void slapi_pblock_set_flag_operation_notes(Slapi_PBlock *pb, uint32_t opflag); +void slapi_pblock_set_result_text_if_empty(Slapi_PBlock *pb, char *text); #ifdef __cplusplus } diff --git a/test/libslapd/schema/filter_validate.c b/test/libslapd/schema/filter_validate.c index e93bd6b..d42a98f 100644 --- a/test/libslapd/schema/filter_validate.c +++ b/test/libslapd/schema/filter_validate.c @@ -52,11 +52,13 @@ validate_filter(char *fstr, Slapi_Filter_Policy policy) { char fdup[256] = {0}; strcpy(fdup, fstr); struct slapi_filter *f = slapi_str2filter(fdup); + Slapi_PBlock *pb = slapi_pblock_new(); assert_true(f != NULL); - Slapi_Filter_Result r = slapi_filter_schema_check(f, policy); + Slapi_Filter_Result r = slapi_filter_schema_check(pb, f, policy); // Based on policy, we could assert if flags are set. + slapi_pblock_destroy(pb); slapi_filter_free(f, 1); return r; } @@ -86,7 +88,9 @@ test_libslapd_schema_filter_validate_simple(void **state __attribute__((unused)) /* Did they pass given the policy and expectations? */ /* simple error cases */ - assert_true(slapi_filter_schema_check(NULL, FILTER_POLICY_OFF) == FILTER_SCHEMA_FAILURE); + Slapi_PBlock *pb = slapi_pblock_new(); + assert_true(slapi_filter_schema_check(pb, NULL, FILTER_POLICY_OFF) == FILTER_SCHEMA_FAILURE); + slapi_pblock_destroy(pb); /* policy off, always success no matter what */ assert_true(validate_filter(invalid, FILTER_POLICY_OFF) == FILTER_SCHEMA_SUCCESS);