*/
#include "squid.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "ExternalACL.h"
#include "ExternalACLEntry.h"
#include "auth/UserRequest.h"
#if USE_IDENT
#include "ident/AclIdent.h"
#endif
+#include "ip/tools.h"
#include "client_side.h"
+#include "comm/Connection.h"
#include "HttpRequest.h"
#include "HttpReply.h"
#include "auth/Acl.h"
#include "auth/Gadgets.h"
#include "helper.h"
#include "MemBuf.h"
+#include "rfc1738.h"
#include "URLScheme.h"
#include "wordlist.h"
wordlist *cmdline;
- int children;
-
- int concurrency;
+ HelperChildConfig children;
helper *theHelper;
dlink_list queue;
+ /**
+ * Configuration flag. May only be altered by the configuration parser.
+ *
+ * Indicates that all uses of this external_acl_type helper require authentication
+ * details to be processed. If none are available its a fail match.
+ */
bool require_auth;
enum {
QUOTE_METHOD_URL
} quote;
- IpAddress local_addr;
+ Ip::Address local_addr;
};
struct _external_acl_format {
if (p->theHelper) {
helperShutdown(p->theHelper);
- helperFree(p->theHelper);
+ delete p->theHelper;
p->theHelper = NULL;
}
/* set defaults */
a->ttl = DEFAULT_EXTERNAL_ACL_TTL;
a->negative_ttl = -1;
- a->children = DEFAULT_EXTERNAL_ACL_CHILDREN;
+ a->cache_size = 256*1024;
+ a->children.n_max = DEFAULT_EXTERNAL_ACL_CHILDREN;
+ a->children.n_startup = a->children.n_max;
+ a->children.n_idle = 1;
a->local_addr.SetLocalhost();
a->quote = external_acl::QUOTE_METHOD_URL;
-
token = strtok(NULL, w_space);
if (!token)
} else if (strncmp(token, "negative_ttl=", 13) == 0) {
a->negative_ttl = atoi(token + 13);
} else if (strncmp(token, "children=", 9) == 0) {
- a->children = atoi(token + 9);
+ a->children.n_max = atoi(token + 9);
+ debugs(0, 0, "WARNING: external_acl_type option children=N has been deprecated in favor of children-max=N and children-startup=N");
+ } else if (strncmp(token, "children-max=", 13) == 0) {
+ a->children.n_max = atoi(token + 13);
+ } else if (strncmp(token, "children-startup=", 17) == 0) {
+ a->children.n_startup = atoi(token + 17);
+ } else if (strncmp(token, "children-idle=", 14) == 0) {
+ a->children.n_idle = atoi(token + 14);
} else if (strncmp(token, "concurrency=", 12) == 0) {
- a->concurrency = atoi(token + 12);
+ a->children.concurrency = atoi(token + 12);
} else if (strncmp(token, "cache=", 6) == 0) {
a->cache_size = atoi(token + 6);
} else if (strncmp(token, "grace=", 6) == 0) {
debugs(3, 0, "WARNING: Error converting " << a->local_addr << " to IPv4 in " << a->name );
}
} else if (strcmp(token, "ipv6") == 0) {
-#if !USE_IPV6
- debugs(3, 0, "WARNING: --enable-ipv6 required for external ACL helpers to use IPv6: " << a->name );
-#else
- (void)0;
-#endif
+ if (!Ip::EnableIpv6)
+ debugs(3, 0, "WARNING: --enable-ipv6 required for external ACL helpers to use IPv6: " << a->name );
+ // else nothing to do.
} else {
break;
}
token = strtok(NULL, w_space);
}
+ /* check that child startup value is sane. */
+ if (a->children.n_startup > a->children.n_max)
+ a->children.n_startup = a->children.n_max;
+
+ /* check that child idle value is sane. */
+ if (a->children.n_idle > a->children.n_max)
+ a->children.n_idle = a->children.n_max;
+ if (a->children.n_idle < 1)
+ a->children.n_idle = 1;
+
if (a->negative_ttl == -1)
a->negative_ttl = a->ttl;
format->type = _external_acl_format::EXT_ACL_METHOD;
#if USE_SSL
-
else if (strcmp(token, "%USER_CERT") == 0)
format->type = _external_acl_format::EXT_ACL_USER_CERT_RAW;
else if (strcmp(token, "%USER_CERTCHAIN") == 0)
format->type = _external_acl_format::EXT_ACL_USER_CERT;
format->header = xstrdup(token + 11);
}
-
#endif
else if (strcmp(token, "%EXT_USER") == 0)
format->type = _external_acl_format::EXT_ACL_EXT_USER;
if (node->grace)
storeAppendPrintf(sentry, " grace=%d", node->grace);
- if (node->children != DEFAULT_EXTERNAL_ACL_CHILDREN)
- storeAppendPrintf(sentry, " children=%d", node->children);
+ if (node->children.n_max != DEFAULT_EXTERNAL_ACL_CHILDREN)
+ storeAppendPrintf(sentry, " children-max=%d", node->children.n_max);
+
+ if (node->children.n_startup != 1)
+ storeAppendPrintf(sentry, " children-startup=%d", node->children.n_startup);
+
+ if (node->children.n_idle != (node->children.n_max + node->children.n_startup) )
+ storeAppendPrintf(sentry, " children-idle=%d", node->children.n_idle);
- if (node->concurrency)
- storeAppendPrintf(sentry, " concurrency=%d", node->concurrency);
+ if (node->children.concurrency)
+ storeAppendPrintf(sentry, " concurrency=%d", node->children.concurrency);
if (node->cache)
storeAppendPrintf(sentry, " cache=%d", node->cache_size);
if (acl->def->require_auth) {
int ti;
/* Make sure the user is authenticated */
+ debugs(82, 3, "aclMatchExternal: " << acl->def->name << " check user authenticated.");
if ((ti = AuthenticateAcl(ch)) != 1) {
debugs(82, 2, "aclMatchExternal: " << acl->def->name << " user not authenticated (" << ti << ")");
return ti;
}
+ debugs(82, 3, "aclMatchExternal: " << acl->def->name << " user is authenticated.");
}
key = makeExternalAclKey(ch, acl);
- if (acl->def->require_auth)
- AUTHUSERREQUESTUNLOCK(ch->auth_user_request, "ACLChecklist via aclMatchExternal");
-
if (!key) {
/* Not sufficient data to process */
return -1;
debugs(82, 2, "aclMatchExternal: \"" << key << "\": entry=@" <<
entry << ", age=" << (entry ? (long int) squid_curtime - entry->date : 0));
- if (acl->def->theHelper->stats.queue_size <= acl->def->theHelper->n_running) {
+ if (acl->def->theHelper->stats.queue_size <= (int)acl->def->theHelper->childs.n_active) {
debugs(82, 2, "aclMatchExternal: \"" << key << "\": queueing a call.");
ch->changeState (ExternalACLLookup::Instance());
if (entry->log.size())
ch->request->extacl_log = entry->log;
+
+ if (entry->message.size())
+ ch->request->extacl_message = entry->message;
}
return result;
switch (format->type) {
case _external_acl_format::EXT_ACL_LOGIN:
- assert (ch->auth_user_request);
+ assert (ch->auth_user_request != NULL);
str = ch->auth_user_request->username();
break;
#if USE_IDENT
case _external_acl_format::EXT_ACL_USER_CERT_RAW:
- if (ch->conn() != NULL) {
- SSL *ssl = fd_table[ch->conn()->fd].ssl;
+ if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConn)) {
+ SSL *ssl = fd_table[ch->conn()->clientConn->fd].ssl;
if (ssl)
str = sslGetUserCertificatePEM(ssl);
case _external_acl_format::EXT_ACL_USER_CERTCHAIN_RAW:
- if (ch->conn() != NULL) {
- SSL *ssl = fd_table[ch->conn()->fd].ssl;
+ if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConn)) {
+ SSL *ssl = fd_table[ch->conn()->clientConn->fd].ssl;
if (ssl)
str = sslGetUserCertificateChainPEM(ssl);
case _external_acl_format::EXT_ACL_USER_CERT:
- if (ch->conn() != NULL) {
- SSL *ssl = fd_table[ch->conn()->fd].ssl;
+ if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConn)) {
+ SSL *ssl = fd_table[ch->conn()->clientConn->fd].ssl;
if (ssl)
str = sslGetUserAttribute(ssl, format->header);
case _external_acl_format::EXT_ACL_CA_CERT:
- if (ch->conn() != NULL) {
- SSL *ssl = fd_table[ch->conn()->fd].ssl;
+ if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConn)) {
+ SSL *ssl = fd_table[ch->conn()->clientConn->fd].ssl;
if (ssl)
str = sslGetCAAttribute(ssl, format->header);
if (acl->def->require_auth) {
int ti;
/* Make sure the user is authenticated */
+ debugs(82, 3, "aclMatchExternal: " << acl->def->name << " check user authenticated.");
if ((ti = AuthenticateAcl(ch)) != 1) {
debugs(82, 1, "externalAclLookup: " << acl->def->name <<
callback(callback_data, NULL);
return;
}
+ debugs(82, 3, "aclMatchExternal: " << acl->def->name << " user is authenticated.");
}
const char *key = makeExternalAclKey(ch, acl);
} else {
/* Check for queue overload */
- if (def->theHelper->stats.queue_size >= def->theHelper->n_running) {
+ if (def->theHelper->stats.queue_size >= (int)def->theHelper->childs.n_running) {
debugs(82, 1, "externalAclLookup: '" << def->name << "' queue overload (ch=" << ch << ")");
cbdataFree(state);
callback(callback_data, entry);
static void
externalAclRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("external_acl",
- "External ACL stats",
- externalAclStats, 0, 1);
+ Mgr::RegisterAction("external_acl",
+ "External ACL stats",
+ externalAclStats, 0, 1);
}
void
p->cache = hash_create((HASHCMP *) strcmp, hashPrime(1024), hash4);
if (!p->theHelper)
- p->theHelper = helperCreate(p->name);
+ p->theHelper = new helper(p->name);
p->theHelper->cmdline = p->cmdline;
- p->theHelper->n_to_start = p->children;
-
- p->theHelper->concurrency = p->concurrency;
+ p->theHelper->childs = p->children;
p->theHelper->ipc_type = IPC_TCP_SOCKET;