]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Support %un (any available user name) format code for external ACLs.
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 20 Jul 2015 18:09:23 +0000 (11:09 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 20 Jul 2015 18:09:23 +0000 (11:09 -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 ecb9b735aa2311537e98ea3b32ef87b0703cf9a4..12fb8ebb53d5bde7af90127aa96a0b726c3f77d8 100644 (file)
@@ -764,6 +764,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
@@ -4149,6 +4155,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 fe480cf88c777bd3baac93a61ec45f1280ebe349..3d418cc66925076f69709d045c2324e2d17aa279 100644 (file)
@@ -418,6 +418,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;
@@ -524,6 +528,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
 
@@ -887,6 +892,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)
 {
@@ -1050,11 +1067,7 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data)
 
         case Format::LFT_EXT_ACL_USER_CERT:
 
-            if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConnection)) {
-                if (auto ssl = fd_table[ch->conn()->clientConnection->fd].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:
@@ -1098,6 +1111,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;