]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 3345: Support %un (any available user name) format code for external ACLs.
authorAmos Jeffries <squid3@treenet.co.nz>
Sat, 25 Jul 2015 16:25:42 +0000 (09:25 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Sat, 25 Jul 2015 16:25:42 +0000 (09:25 -0700)
The same %un code, with the same meaning is already supported in access.log.
In an external ACL request, it expands to the first available user name
from the following list of information sources:

  - authenticated user name, like %ul or %LOGIN
  - user name supplied by an external ACL to Squid via the "user=..."
    key=value pair, like %ue or %EXT_USER
  - SSL client name, like %us
  - ident user name, like %ui

Based on Amos Jeffries 2011 patch and "arronax28" design:
http://www.squid-cache.org/mail-archive/squid-dev/201112/0080.html
with TODO completion by Measurement Factory

src/cf.data.pre
src/external_acl.cc

index 5308ee5d97f770fe4a3bf1411680ed8df28aa2e6..cd775bd68d7ca7d03fc3a1d3b0e9d4f6fdfc3839 100644 (file)
@@ -699,6 +699,12 @@ DOC_START
        FORMAT specifications
 
          %LOGIN        Authenticated user login name
+         %un           A user name. Expands to the first available name
+                       from the following list of information sources:
+                       - authenticated user name, like %ul or %LOGIN
+                       - user name sent by an external ACL, like %EXT_USER
+                       - SSL client name, like %us in logformat
+                       - ident user name, like %ui in logformat
          %EXT_USER     Username from previous external acl
          %EXT_LOG      Log details from previous external acl
          %EXT_TAG      Tag from previous external acl
@@ -4033,6 +4039,12 @@ DOC_START
                ue      User name from external acl helper
                ui      User name from ident
                us      User name from SSL
+               un      A user name. Expands to the first available name
+                       from the following list of information sources:
+                       - authenticated user name, like %ul
+                       - user name supplied by an external ACL, like %ue
+                       - SSL client name, like %us
+                       - ident user name, like %ui
                credentials Client credentials. The exact meaning depends on
                        the authentication scheme: For Basic authentication,
                        it is the password; for Digest, the realm sent by the
index 9892dcd33e2176b7bccf1e1cdb6ed268839205ed..53ebe05aeb2426ab5b80b05e7e5074ce4f7a8e21 100644 (file)
@@ -402,6 +402,10 @@ parse_externalAclHelper(external_acl ** list)
 #if USE_AUTH
         else if (strcmp(token, "%EXT_USER") == 0 || strcmp(token, "%ue") == 0)
             format->type = Format::LFT_USER_EXTERNAL;
+#endif
+#if USE_AUTH || defined(USE_OPENSSL) || defined(USE_IDENT)
+        else if (strcmp(token, "%un") == 0)
+            format->type = Format::LFT_USER_NAME;
 #endif
         else if (strcmp(token, "%EXT_LOG") == 0 || strcmp(token, "%ea") == 0)
             format->type = Format::LFT_EXT_LOG;
@@ -508,6 +512,7 @@ dump_externalAclHelper(StoreEntry * sentry, const char *name, const external_acl
                 break
 #if USE_AUTH
                 DUMP_EXT_ACL_TYPE_FMT(USER_LOGIN," %%ul");
+                DUMP_EXT_ACL_TYPE_FMT(USER_NAME," %%un");
 #endif
 #if USE_IDENT
 
@@ -875,6 +880,18 @@ external_acl_cache_touch(external_acl * def, const ExternalACLEntryPointer &entr
     dlinkAdd(e, &entry->lru, &def->lru_list);
 }
 
+#if USE_OPENSSL
+static const char *
+external_acl_ssl_get_user_attribute(const ACLFilledChecklist &ch, const char *attr)
+{
+    if (ch.conn() != NULL && Comm::IsConnOpen(ch.conn()->clientConnection)) {
+        if (SSL *ssl = fd_table[ch.conn()->clientConnection->fd].ssl)
+            return sslGetUserAttribute(ssl, attr);
+    }
+    return NULL;
+}
+#endif
+
 static char *
 makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data)
 {
@@ -1038,14 +1055,7 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data)
             break;
 
         case Format::LFT_EXT_ACL_USER_CERT:
-
-            if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConnection)) {
-                SSL *ssl = fd_table[ch->conn()->clientConnection->fd].ssl;
-
-                if (ssl)
-                    str = sslGetUserAttribute(ssl, format->header);
-            }
-
+            str = external_acl_ssl_get_user_attribute(*ch, format->header);
             break;
 
         case Format::LFT_EXT_ACL_USER_CA_CERT:
@@ -1091,6 +1101,24 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data)
             str = request->extacl_user.termedBuf();
             break;
 #endif
+        case Format::LFT_USER_NAME:
+            /* find the first available name from various sources */
+#if USE_AUTH
+            if (ch->auth_user_request != NULL)
+                str = ch->auth_user_request->username();
+            if ((!str || !*str) &&
+                    (request->extacl_user.size() > 0 && request->extacl_user[0] != '-'))
+                str = request->extacl_user.termedBuf();
+#endif
+#if USE_OPENSSL
+            if (!str || !*str)
+                str = external_acl_ssl_get_user_attribute(*ch, "CN");
+#endif
+#if USE_IDENT
+            if (!str || !*str)
+                str = ch->rfc931;
+#endif
+            break;
         case Format::LFT_EXT_LOG:
             str = request->extacl_log.termedBuf();
             break;