On 22/08/2016 10:54 a.m., Diogenes S. Jesus wrote: > Hi everyone. > > I've the following use case to be accomplished using ACL: > > - Allow any authenticated user who is member of a group named after the URI > > To construct this I've built the following squid.conf (snippet): > > --------- > auth_param negotiate program /usr/lib/squid3/negotiate_kerberos_auth -d -r > auth_param negotiate children 10 > auth_param negotiate keep_alive on > > external_acl_type ldap_HTTP %LOGIN %URI > /usr/lib/squid/ext_ldap_group_acl -D "cn=admin,dc=example,dc=com" -w > test -R -b "ou=authorization,dc=example,dc=com" -B > "ou=people,dc=example,dc=com" -f > '(&(objectclass=groupOfNames)(cn=%g)(member=uid=%u,ou=people,dc=example,dc=com))' > -h ldap01.example.com -d Please be aware that the %URI format does not perform any type of shell or LDAP escaping to protect this helper lookup against shell-injection attacks. It is possible that a remote client can end a URL with ')' followed by any LDAP commands they like and have that executed by your helper. If you want to do things like this safely please upgrade to Squid-4 where the logformat codes are available. Those codes provide customizable escaping and quoting styles so you can set one that protects LDAP against these attacks to be ued on the URI field value sent by Squid. > > acl allow_HTTP_ACL external ldap_HTTP "" > > http_access deny !allow_HTTP_ACL all > http_access allow allow_HTTP_ACL > http_access deny all > --------- > > I call it a "dynamic" acl, because the value of the group is the > actual URI Whereas everyone else calls it dynamic because the ACL test is highly variable (aka dynamic) based on whatever the custom helper logic is. > (the search filter will expand like: > cn=<URI>,ou=authorization,dc=example,dc=com). For that > "allow_HTTP_ACL" passes "" to ldap_HTTP. > > This is working, however that's not documented. I was wondering how > this works, so I debugged. > > I found out the %<template filter var> expands as following for the > following search filter: > -f '(&(objectclass=groupOfNames)(<template_filter_reference>=%<template_filter>)(member=uid=%u,ou=people,dc=example,dc=com))' > ... > > 4) '(&(objectclass=groupOfNames)(test=%test)(member=uid=%u,ou=people,dc=example,dc=com))': > ERROR: Unknown filter template string %t > ext_ldap_group_acl: ERROR: Failed to construct LDAP search filter. > filter="(&(objectclass=groupOfNames)(test=?,?U", user="john_doe", > group="http://web.example.com/" > ERROR: Unknown filter template string %t > ext_ldap_group_acl: ERROR: Failed to construct LDAP search filter. > filter="(&(objectclass=groupOfNames)(test=?,?U", user="john_doe", > group="GET" > ERROR: Unknown filter template string %t > ext_ldap_group_acl: ERROR: Failed to construct LDAP search filter. > filter="(&(objectclass=groupOfNames)(test=?,?U", user="john_doe", > group="80" > > 5) '(&(objectclass=groupOfNames)(v=%v)(member=uid=%u,ou=people,dc=example,dc=com))': > ext_ldap_group_acl.cc(718): pid=26314 :group filter > '(&(objectclass=groupOfNames)(v=john_doe)(member=uid=john_doe,ou=people,dc=example,dc=com))', > searchbase 'ou=authorization,dc=example,dc=com' > ext_ldap_group_acl.cc(718): pid=26314 :group filter > '(&(objectclass=groupOfNames)(v=john_doe)(member=uid=john_doe,ou=people,dc=example,dc=com))', > searchbase 'ou=authorization,dc=example,dc=com' > ext_ldap_group_acl.cc(718): pid=26314 :group filter > '(&(objectclass=groupOfNames)(v=john_doe)(member=uid=john_doe,ou=people,dc=example,dc=com))', > searchbase 'ou=authorization,dc=example,dc=com' > I dont think you quite grok which part of these outputs is the garbage (uninitialized memory dump), and which part is the incomplete prefix of the filter string. Notice the above 'garbage' outputs start with: filter="(&(objectclass=groupOfNames)(test= then obvious garbage: ?,?U", user="john_doe", group="GET" Its not always obvious. As in case #6: > > 6) '(&(objectclass=groupOfNames)(g=%g)(member=uid=%u,ou=people,dc=example,dc=com))': > ext_ldap_group_acl.cc(718): pid=26408 :group filter > '(&(objectclass=groupOfNames)(g=http://web.example.com/)(member=uid=john_doe,ou=people,dc=example,dc=com))', > searchbase 'ou=authorization,dc=example,dc=com' > ext_ldap_group_acl.cc(718): pid=26408 :group filter > '(&(objectclass=groupOfNames)(g=GET)(member=uid=john_doe,ou=people,dc=example,dc=com))', > searchbase 'ou=authorization,dc=example,dc=com' > ext_ldap_group_acl.cc(718): pid=26408 :group filter > '(&(objectclass=groupOfNames)(g=80)(member=uid=john_doe,ou=people,dc=example,dc=com))', > searchbase 'ou=authorization,dc=example,dc=com' What is happening is that the helper expects the %LOGIN field to be followed by a list of space-separated 'words'. Each 'word' is a group name to be checked against the users account memberships. So the list of words is looked up individually until one matches or none left to check. So somehow the HTTP request URL/URI is the whole string: "GET http://web.example.com/ 80" -> very odd. It is not even a valid HTTP request-line. Looks more like some outdated Squid-1.1 URL re-write helper is mangling the URL. But the order is slightly wrong even for that (GET would be after the actual URL). Anyhow, that resuls in the ACL group helper receiving: john_does GET http://web.example.com/ 80 Meaning, username: "john_doe" group #1: "GET" group #2: "http://web.example.com/" group #3: "80" > > This is all pretty much happening here > [https://github.com/squid-cache/squid/blob/master/helpers/external_acl/LDAP_group/ext_ldap_group_acl.cc#L638] > > So conclusions: > - %v and %u both map to "user", which is expected (historical reasons > & compatibility) As documented. > - %g and %a both map to "group", which is expected (historical reasons > & compatibility) As documented. > - any other template filter (%b, %c, %test, etc) is trash (only %a, > %u, %g, %v won't yield error) Nod. The helper autor(s) reserve other %-code to be defined with any arbitrary meaning at any time. So there is simply no documented behaviour for them. A you found v and a have old meanings that are still supported, though deprecated so removed from the documentation intentionally to prevent future use. > - when "" is passed to the acl ("acl <ACL_name> external ldap_HTTP > ""), the helper will attempt all FORMAT values, mapping then to > "group" (%a or %g) It should mean Squid loads a file with undefined name (\0) and sends that files content as the list of group names. Each line in the file being a group name. > > Although I can move on with this for now, I would be actually more > relieved if I could use: > acl allow_HTTP_ACL external ldap_HTTP > <a_var_which_is_available_here_representing_URI> > instead of > acl allow_HTTP_ACL external ldap_HTTP "" + non-documented behavior of > ext_ldap_group_acl Dont specify anything at all in that position. The %URI field you defined to be sent to the helper should be formatted in the place it expects to find a group name "word" as mentioned above. Just use: acl allow_HTTP_ACL external ldap_HTTP Amos _______________________________________________ squid-users mailing list squid-users@xxxxxxxxxxxxxxxxxxxxx http://lists.squid-cache.org/listinfo/squid-users