Forum Discussion

Sheigh_65772's avatar
May 08, 2015

11.5.1 to 11.6.0 HF 4 - APM - Failing Active Directory Query

In moving from 11.5.1 to 11.6.0 HF4 I've come to find that my APM Active Directory query has broken. The SearchFilter I'm creating is based upon the Subject of a client PKI certificate which is then parsed and the AD search filter is then dynamically generated. This was allowing for Active Directory accounts which had certificates mapped to them to be matched up against the certificate that the user supplied and then Kerberos authentication was used.

As background, the client certificate is grabbed on another Authentication VIP where session table entries are created containing the users certificate info. This APM Profile uses those session table entries and so doesn't have direct access to the user's certificate.

For example a user supplies a certificate with the following data when they connect:

Certificate Subject
CN = cn-value1
OU = ou-value1
OU = ou-value2
OU = ou-value3
O = o-value1
C = c-value1

An APM iRule Event is triggered which parses the subject information of the users cert and sets the APM session variable session.custom.ldapsearchuserCert

session.custom.ldapsearchuserCert = (&(userCertificate=*cn-value1*)(userCertificate=*ou-value1*)(userCertificate=*ou-value2*)(userCertificate=*ou-value3*)(userCertificate=*o-value1*)(userCertificate=*c-value1*)(objectClass=user)(objectCategory=person))

APM Active Directory Query:

SearchFilter is set to %{session.custom.ldapsearchuserCert}

I have validated that APM session variable is as expected. Looking in /var/log/apm I see errors indicating an invalid search filter and this is what it logs:

AD module: query with '\28&\28userCertificate=\2acn-value1\2a\29\28userCertificate=\2aou-value1\2a\29\28userCertificate=\2aou-value2\2a\29\28userCertificate=\2aou-value3\2a\29\28userCertificate=\2ao-value1\2a\29\28userCertificate=\2ac-value1\2a\29\28objectClass=user\29\28objectCategory=person\29\29' failed: Bad search filter

So it looks like APM is now doing some conversions on the string before making the query, is there an easy fix to this?

Thanks

8 Replies

  • kunjan's avatar
    kunjan
    Icon for Nimbostratus rankNimbostratus

    Does it work if you hard code the search filter pattern?

     

  • Hey kunjan,

     

    Yes it does work if I hard code the search filter. It matches up to my account and everything is good so it would appear the conversion is taking place during the calling of the variable.

     

  • kunjan's avatar
    kunjan
    Icon for Nimbostratus rankNimbostratus

    Are you able to log as as following and see if there is encoding occurs

    when ACCESS_POLICY_AGENT_EVENT {
      set lcu_ldapsearch_userCert {(&(userCertificate=*cn-value1*)(userCertificate=*ou-value1*)(userCertificate=*ou-value2*)(userCertificate=*ou-value3*)(userCertificate=*o-value1*)(userCertificate=*c-value1*)(objectClass=user)(objectCategory=person)) }
    
      ACCESS::session data set session.custom.ldapsearchuserCert $lcu_ldapsearch_userCert
    
      log local0. "$lcu_ldapsearch_userCert"
    
    }
    
  • Here's my irule:

    if {[ACCESS::policy agent_id] == "ldapsrchstr"} {
    
        set lcu_ldapsearch_userCert "(&"
    
    
        if { [info exists user_key_apm] and [table lookup -subtable $client_table $user_key_apm] != "" } {
            set lcu_list [split [lindex [table lookup -subtable $client_table $user_key_apm] 2] ","]
            foreach lcu_list_item $lcu_list {
                append lcu_ldapsearch_userCert "(userCertificate=*" $lcu_list_item "*)"
            }
            append lcu_ldapsearch_userCert "(objectClass=user)(objectCategory=person))"
            set lcu_ldapsearch_userCert [string map [list *OU= * *C= * *CN= * *O= *] $lcu_ldapsearch_userCert]
    
            ACCESS::session data set session.custom.ldapsearchuserCert $lcu_ldapsearch_userCert
    
    
            log local0. "trimmed newmethod ldapsrchstr apm session lcu_ldapsearch_userCert [ACCESS::session data get session.custom.ldapsearchuserCert]"
    
    }
    

    ltm log

    May 10 11:19:04 bigip info tmm[19795]: Rule /Common/ldap_cert_use : trimmed newmethod ldapsrchstr apm session lcu_ldapsearch_userCert (&(userCertificate=*cn-value1*)(userCertificate=*ou-value1*)(userCertificate=*ou-value2*)(userCertificate=*ou-value3*)(userCertificate=*o-value1*)(userCertificate=*c-value1*)(objectClass=user)(objectCategory=person))
    

    apm log

    May 10 11:19:03 bigip notice tmm3[19796]: 01490544:5: eca9c6fa: Received client info - Type: IE Version: 10 Platform: Win7 CPU: WOW64 UI Mode: Full Javascript Support: 1 ActiveX Support: 1 Plugin Support: 0
    May 10 11:19:03 bigip notice tmm3[19796]: 01490500:5: eca9c6fa: New session from client IP {clientip} (ST=/CC=/C=) at VIP {vip} Listener /Common/citrix_iapp.app/citrix_iapp_webui (Reputation=Unknown)
    May 10 11:19:08 bigip err apd[13568]: 01490107:3: eca9c6fa: AD module: query with '\28&\28userCertificate=\2acn-value1\2a\29\28userCertificate=\2aou-value1\2a\29\28userCertificate=\2aou-value2\2a\29\28userCertificate=\2aou-value3\2a\29\28userCertificate=\2ao-value1\2a\29\28userCertificate=\2ac-value1\2a\29\28objectClass=user\29\28objectCategory=person\29\29' failed: Bad search filter, base: dc=my,dc=domain,dc=com, scope: 2, filter: \28&\28userCertificate=\2acn-value1\2a\29\28userCertificate=\2aou-value1\2a\29\28userCertificate=\2aou-value2\2a\29\28userCertificate=\2aou-value3\2a\29\28userCertificate=\2ao-value1\2a\29\28userCertificate=\2ac-value1\2a\29\28objectClass=user\29\28objectCategory=person\29\29  (-7)
    
  • kunjan's avatar
    kunjan
    Icon for Nimbostratus rankNimbostratus

    APM is treating the control characters as values and escape it as required in RFC-2254.

    One way is to use it directly on the search filter. Save the values in individual session variables and concat this in the searchfilter in the APM.

    (&(userCertificate=*%{session.custom.cn1}*)(userCertificate=*%{session.custom.ou1}*)(userCertificate=*%{session.custom.ou2}*)(userCertificate=*%{session.custom.ou3}*)(userCertificate=*%{session.custom.ov1}*)(userCertificate=*%{session.custom.cv1}*)(objectClass=user)(objectCategory=person))
    
  • kunjan,

     

    Using your suggestion and the RFC you pointed me at (some of our client's certs contain characters listed in that RFC) I was able to come up with a working solution.

     

    Thanks

     

    • kunjan's avatar
      kunjan
      Icon for Nimbostratus rankNimbostratus
      Glad to know you got it worked. Thanks for coming back to update :)