@@ -322,7 +322,7 @@ int fr_ldap_map_expand(TALLOC_CTX *ctx, fr_ldap_map_exp_t *expanded, request_t *
322322 * - Number of maps successfully applied.
323323 * - -1 on failure.
324324 */
325- int fr_ldap_map_do (request_t * request ,
325+ int fr_ldap_map_do (request_t * request , char const * check_attr ,
326326 char const * valuepair_attr , fr_ldap_map_exp_t const * expanded , LDAPMessage * entry )
327327{
328328 map_t const * map = NULL ;
@@ -333,6 +333,62 @@ int fr_ldap_map_do(request_t *request,
333333 char const * name ;
334334 LDAP * handle = fr_ldap_handle_thread_local ();
335335
336+ if (check_attr ) {
337+ struct berval * * values ;
338+ int count , i ;
339+ tmpl_rules_t const parse_rules = {
340+ .attr = {
341+ .dict_def = request -> dict ,
342+ .list_def = request_attr_request ,
343+ .prefix = TMPL_ATTR_REF_PREFIX_AUTO
344+ },
345+ .xlat = {
346+ .runtime_el = unlang_interpret_event_list (request ),
347+ },
348+ .at_runtime = true,
349+ };
350+
351+ values = ldap_get_values_len (handle , entry , check_attr );
352+ count = ldap_count_values_len (values );
353+
354+ for (i = 0 ; i < count ; i ++ ) {
355+ map_t * check = NULL ;
356+ char * value = fr_ldap_berval_to_string (request , values [i ]);
357+
358+ RDEBUG3 ("Parsing condition %s" , value );
359+ if (map_afrom_attr_str (request , & check , value , & parse_rules , & parse_rules ) < 0 ) {
360+ RPEDEBUG ("Failed parsing '%s' value \"%s\"" , check_attr , value );
361+ fail :
362+ applied = -1 ;
363+ free :
364+ talloc_free (check );
365+ talloc_free (value );
366+ ldap_value_free_len (values );
367+ return applied ;
368+ }
369+
370+ if (!fr_comparison_op [check -> op ]) {
371+ REDEBUG ("Invalid operator '%s'" , fr_tokens [check -> op ]);
372+ goto fail ;
373+ }
374+
375+ if (fr_type_is_structural (tmpl_attr_tail_da (check -> lhs )-> type ) &&
376+ (check -> op != T_OP_CMP_TRUE ) && (check -> op != T_OP_CMP_FALSE )) {
377+ REDEBUG ("Invalid comparison for structural type" );
378+ goto fail ;
379+ }
380+
381+ RDEBUG2 ("Checking condition %s %s %s" , check -> lhs -> name , fr_tokens [check -> op ], check -> rhs -> name );
382+ if (radius_legacy_map_cmp (request , check ) != 1 ) {
383+ RDEBUG2 ("Failed match: skipping this profile" );
384+ goto free ;
385+ }
386+ talloc_free (value );
387+ talloc_free (check );
388+ }
389+ ldap_value_free_len (values );
390+ }
391+
336392 while ((map = map_list_next (expanded -> maps , map ))) {
337393 int ret ;
338394
0 commit comments