From 18ad542ad4ce634f0bbcc97223fa24dcd0559349 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Fri, 24 Feb 2017 12:24:59 -0500 Subject: [PATCH] Issue 49122 - Filtered nsrole that uses nsrole crashes the server Bug Description: When evaluating a fitler role that uses "nsrole" in the filter crashes the server due infinite loop that leads to a stack overflow. Fix Description: Virtual attributes are not allowed to be used in role filters. We were already checking for COS attributes, but not nsrole. Also did some minor code cleanup https://pagure.io/389-ds-base/issue/49122 Reviewed by: ? --- ldap/servers/plugins/roles/roles_cache.c | 116 +++++++++++++++++++------------ 1 file changed, 73 insertions(+), 43 deletions(-) diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c index b7303de..d2472b2 100644 --- a/ldap/servers/plugins/roles/roles_cache.c +++ b/ldap/servers/plugins/roles/roles_cache.c @@ -1072,6 +1072,26 @@ static int roles_cache_create_role_under(roles_cache_def** roles_cache_suffix, S return(rc); } +/* + * Check that we are not using nsrole in the filter + */ +static int roles_check_filter(Slapi_Filter *filter_list) +{ + Slapi_Filter *f; + char *type = NULL; + + for ( f = slapi_filter_list_first( filter_list ); + f != NULL; + f = slapi_filter_list_next( filter_list, f ) ) + { + slapi_filter_get_attribute_type(f, &type); + if (strcasecmp(type, NSROLEATTR) == 0){ + return -1; + } + } + + return 0; +} /* roles_cache_create_object_from_entry ------------------------------------ @@ -1084,10 +1104,10 @@ static int roles_cache_create_role_under(roles_cache_def** roles_cache_suffix, S */ static int roles_cache_create_object_from_entry(Slapi_Entry *role_entry, role_object **result, int hint) { - int rc = 0; - int type = 0; - role_object *this_role = NULL; - char *rolescopeDN = NULL; + int rc = 0; + int type = 0; + role_object *this_role = NULL; + char *rolescopeDN = NULL; slapi_log_err(SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, "--> roles_cache_create_object_from_entry\n"); @@ -1141,52 +1161,50 @@ static int roles_cache_create_object_from_entry(Slapi_Entry *role_entry, role_ob this_role->dn = slapi_sdn_new(); slapi_sdn_copy(slapi_entry_get_sdn(role_entry),this_role->dn); - rolescopeDN = slapi_entry_attr_get_charptr(role_entry, ROLE_SCOPE_DN); - if (rolescopeDN) { - Slapi_DN *rolescopeSDN; - Slapi_DN *top_rolescopeSDN, *top_this_roleSDN; - - /* Before accepting to use this scope, first check if it belongs to the same suffix */ - rolescopeSDN = slapi_sdn_new_dn_byref(rolescopeDN); - if ((strlen((char *) slapi_sdn_get_ndn(rolescopeSDN)) > 0) && - (slapi_dn_syntax_check(NULL, (char *) slapi_sdn_get_ndn(rolescopeSDN), 1) == 0)) { - top_rolescopeSDN = roles_cache_get_top_suffix(rolescopeSDN); - top_this_roleSDN = roles_cache_get_top_suffix(this_role->dn); - if (slapi_sdn_compare(top_rolescopeSDN, top_this_roleSDN) == 0) { - /* rolescopeDN belongs to the same suffix as the role, we can use this scope */ - this_role->rolescopedn = rolescopeSDN; - } else { - slapi_log_err(SLAPI_LOG_ERR, ROLES_PLUGIN_SUBSYSTEM, - "roles_cache_create_object_from_entry - %s: invalid %s - %s not in the same suffix. Scope skipped.\n", - (char*) slapi_sdn_get_dn(this_role->dn), - ROLE_SCOPE_DN, - rolescopeDN); - slapi_sdn_free(&rolescopeSDN); - } - slapi_sdn_free(&top_rolescopeSDN); - slapi_sdn_free(&top_this_roleSDN); - } else { - /* this is an invalid DN, just ignore this parameter*/ - slapi_log_err(SLAPI_LOG_ERR, ROLES_PLUGIN_SUBSYSTEM, - "roles_cache_create_object_from_entry - %s: invalid %s - %s not a valid DN. Scope skipped.\n", - (char*) slapi_sdn_get_dn(this_role->dn), - ROLE_SCOPE_DN, - rolescopeDN); - slapi_sdn_free(&rolescopeSDN); - } - } + rolescopeDN = slapi_entry_attr_get_charptr(role_entry, ROLE_SCOPE_DN); + if (rolescopeDN) { + Slapi_DN *rolescopeSDN; + Slapi_DN *top_rolescopeSDN, *top_this_roleSDN; + + /* Before accepting to use this scope, first check if it belongs to the same suffix */ + rolescopeSDN = slapi_sdn_new_dn_byref(rolescopeDN); + if ((strlen((char *) slapi_sdn_get_ndn(rolescopeSDN)) > 0) && + (slapi_dn_syntax_check(NULL, (char *) slapi_sdn_get_ndn(rolescopeSDN), 1) == 0)) { + top_rolescopeSDN = roles_cache_get_top_suffix(rolescopeSDN); + top_this_roleSDN = roles_cache_get_top_suffix(this_role->dn); + if (slapi_sdn_compare(top_rolescopeSDN, top_this_roleSDN) == 0) { + /* rolescopeDN belongs to the same suffix as the role, we can use this scope */ + this_role->rolescopedn = rolescopeSDN; + } else { + slapi_log_err(SLAPI_LOG_ERR, ROLES_PLUGIN_SUBSYSTEM, + "roles_cache_create_object_from_entry - %s: invalid %s - %s not in the same suffix. Scope skipped.\n", + (char*) slapi_sdn_get_dn(this_role->dn), + ROLE_SCOPE_DN, + rolescopeDN); + slapi_sdn_free(&rolescopeSDN); + } + slapi_sdn_free(&top_rolescopeSDN); + slapi_sdn_free(&top_this_roleSDN); + } else { + /* this is an invalid DN, just ignore this parameter*/ + slapi_log_err(SLAPI_LOG_ERR, ROLES_PLUGIN_SUBSYSTEM, + "roles_cache_create_object_from_entry - %s: invalid %s - %s not a valid DN. Scope skipped.\n", + (char*) slapi_sdn_get_dn(this_role->dn), + ROLE_SCOPE_DN, + rolescopeDN); + slapi_sdn_free(&rolescopeSDN); + } + } /* Depending upon role type, pull out the remaining information we need */ switch (this_role->type) { case ROLE_TYPE_MANAGED: - /* Nothing further needed */ break; case ROLE_TYPE_FILTERED: { - Slapi_Filter *filter = NULL; char *filter_attr_value = NULL; Slapi_PBlock *pb = NULL; @@ -1200,6 +1218,7 @@ static int roles_cache_create_object_from_entry(Slapi_Entry *role_entry, role_ob slapi_ch_free((void**)&this_role); return SLAPI_ROLE_ERROR_NO_FILTER_SPECIFIED; } + /* search (&(objectclass=costemplate)(filter_attr_value))*/ /* if found, reject it (returning SLAPI_ROLE_ERROR_FILTER_BAD) */ pb = slapi_pblock_new(); @@ -1245,16 +1264,27 @@ static int roles_cache_create_object_from_entry(Slapi_Entry *role_entry, role_ob /* Turn it into a slapi filter object */ filter = slapi_str2filter(filter_attr_value); - slapi_ch_free_string(&filter_attr_value); - - if ( filter == NULL ) + if ( filter == NULL ) { /* An error has occured */ slapi_ch_free((void**)&this_role); + slapi_ch_free_string(&filter_attr_value); + return SLAPI_ROLE_ERROR_FILTER_BAD; + } + if (roles_check_filter(filter)) { + slapi_log_err(SLAPI_LOG_ERR, ROLES_PLUGIN_SUBSYSTEM, + "roles_cache_create_object_from_entry - \"%s\": not allowed to use \"nsrole\" " + "in the role filter \"%s\". %s is disabled.\n", + (char*)slapi_sdn_get_ndn(this_role->dn), + filter_attr_value, + ROLE_FILTER_ATTR_NAME); + slapi_ch_free((void**)&this_role); + slapi_ch_free_string(&filter_attr_value); return SLAPI_ROLE_ERROR_FILTER_BAD; } /* Store on the object */ this_role->filter = filter; + slapi_ch_free_string(&filter_attr_value); break; } -- 2.7.4