if (strchr(buf, '\n') != NULL)
break;
}
- SEND_ERR("Invalid Request. Too Long.");
+ SEND_BH(HLP_MSG("Invalid Request. Too Long."));
continue;
}
if ((p = strchr(buf, '\n')) != NULL)
debug("Got '%s' from Squid (length: %d).\n", buf, strlen(buf));
if (buf[0] == '\0') {
- SEND_ERR("Invalid Request. No Input.");
+ SEND_BH(HLP_MSG("Invalid Request. No Input."));
continue;
}
username = strtok(buf, " ");
numberofgroups = n;
if (NULL == username) {
- SEND_ERR("Invalid Request. No Username.");
+ SEND_BH(HLP_MSG("Invalid Request. No Username."));
continue;
}
rfc1738_unescape(username);
if (strchr(buf, '\n') != NULL)
break;
}
- SEND_ERR("");
+ SEND_BH(HLP_MSG("Input too large"));
continue;
}
user = strtok(buf, " \n");
if (!user) {
debug("%s: Invalid request: No Username given\n", argv[0]);
- SEND_ERR("Invalid request. No Username");
+ SEND_BH(HLP_MSG("Invalid request. No Username"));
continue;
}
rfc1738_unescape(user);
extension_dn = strtok(NULL, " \n");
if (!extension_dn) {
debug("%s: Invalid request: Extension DN configured, but none sent.\n", argv[0]);
- SEND_ERR("Invalid Request. Extension DN required.");
+ SEND_BH(HLP_MSG("Invalid Request. Extension DN required"));
continue;
}
rfc1738_unescape(extension_dn);
}
+ const char *broken = nullptr;
while (!found && user && (group = strtok(NULL, " \n")) != NULL) {
rfc1738_unescape(group);
if (strstr(ldapServer, "://") != NULL) {
rc = ldap_initialize(&ld, ldapServer);
if (rc != LDAP_SUCCESS) {
+ broken = HLP_MSG("Unable to connect to LDAP server");
fprintf(stderr, "%s: ERROR: Unable to connect to LDAPURI:%s\n", argv[0], ldapServer);
break;
}
} else
#endif
if ((ld = ldap_init(ldapServer, port)) == NULL) {
- fprintf(stderr, "ERROR: Unable to connect to LDAP server:%s port:%d\n", ldapServer, port);
+ broken = HLP_MSG("Unable to connect to LDAP server");
+ fprintf(stderr, "ERROR: %s:%s port:%d\n", broken, ldapServer, port);
break;
}
if (connect_timeout)
version = LDAP_VERSION3;
}
if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) {
- fprintf(stderr, "ERROR: Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
- version);
+ broken = HLP_MSG("Could not set LDAP_OPT_PROTOCOL_VERSION");
+ fprintf(stderr, "ERROR: %s %d\n", broken, version);
ldap_unbind(ld);
ld = NULL;
break;
fprintf(stderr, "FATAL: TLS requires LDAP version 3\n");
exit(1);
} else if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) {
- fprintf(stderr, "ERROR: Could not Activate TLS connection\n");
+ broken = HLP_MSG("Could not Activate TLS connection");
+ fprintf(stderr, "ERROR: %s\n", broken);
ldap_unbind(ld);
ld = NULL;
break;
if (binddn && bindpasswd && *binddn && *bindpasswd) {
rc = ldap_simple_bind_s(ld, binddn, bindpasswd);
if (rc != LDAP_SUCCESS) {
- fprintf(stderr, PROGRAM_NAME ": WARNING: could not bind to binddn '%s'\n", ldap_err2string(rc));
+ broken = HLP_MSG("could not bind");
+ fprintf(stderr, PROGRAM_NAME ": WARNING: %s to binddn '%s'\n", broken, ldap_err2string(rc));
ldap_unbind(ld);
ld = NULL;
break;
}
debug("Connected OK\n");
}
- if (searchLDAP(ld, group, user, extension_dn) == 0) {
+ int searchResult = searchLDAP(ld, group, user, extension_dn);
+ if (searchResult == 0) {
found = 1;
break;
- } else {
+ } else if (searchResult < 0){
if (tryagain) {
tryagain = 0;
ldap_unbind(ld);
ld = NULL;
goto recover;
}
+ broken = HLP_MSG("LDAP search error");
}
}
if (found)
SEND_OK("");
+ else if (broken)
+ SEND_BH(broken);
else {
SEND_ERR("");
}
if (!build_filter(filter, searchfilter, member, group)) {
std::cerr << PROGRAM_NAME << ": ERROR: Failed to construct LDAP search filter. filter=\"" <<
filter.c_str() << "\", user=\"" << member << "\", group=\"" << group << "\"" << std::endl;
- return 1;
+ return -1;
}
debug("group filter '%s', searchbase '%s'\n", filter.c_str(), searchbase.c_str());
rc = ldap_search_s(ld, searchbase.c_str(), searchscope, filter.c_str(), searchattr, 1, &res);
LdapResult ldapRes(res, ldap_msgfree);
if (!ldap_search_ok(rc))
- return 1;
+ return -1;
return ldap_first_entry(ld, ldapRes.get()) ? 0 : 1;
}
rc = ldap_search_s(ld, searchbase.c_str(), searchscope, filter.c_str(), searchattr, 1, &res);
LdapResult ldapRes(res, ldap_msgfree);
if (!ldap_search_ok(rc))
- return 1;
+ return -1;
entry = ldap_first_entry(ld, ldapRes.get());
if (!entry) {
std::cerr << PROGRAM_NAME << ": WARNING: User '" << login <<
if (strchr(buf, '\n') != NULL)
break;
}
- SEND_ERR("Input Too Long.");
+ SEND_BH(HLP_MSG("Input Too Long."));
continue;
}
if ((p = strchr(buf, '\n')) != NULL)
debug("Got '%s' from Squid (length: %d).\n", buf, strlen(buf));
if (buf[0] == '\0') {
- SEND_ERR("Invalid Request.");
+ SEND_BH(HLP_MSG("Invalid Request."));
continue;
}
username = strtok(buf, " ");
groups[n] = NULL;
if (NULL == username) {
- SEND_ERR("Invalid Request. No Username.");
+ SEND_BH(HLP_MSG("Invalid Request. No Username."));
continue;
}
rfc1738_unescape(username);
print(stderr "Received: Channel=".$cid.", UID='".$uid."'\n") if ($debug);
- $status = $cid . " ERR message=\"database error\"";
+ $status = $cid . " BH message=\"database error\"";
my $sth = query_db($uid) || next;
print(stderr "Rows: ". $sth->rows()."\n") if ($debug);
$status = $cid . " ERR message=\"unknown UID '".$uid."'\"";
/* No space given, but group string is required --> ERR */
if ((edui_conf.mode & EDUI_MODE_GROUP) && (p == NULL)) {
debug("while() -> Search group is missing. (required)\n");
- local_printfx("ERR message=\"(Search Group Required)\"\n");
+ local_printfx("BH message=\"(Search Group Required)\"\n");
continue;
}
x = 0;
if (x != LDAP_ERR_SUCCESS) {
/* Unable to bind */
debug("BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
- local_printfx("ERR message=\"(BindLDAP: %s - %s)\"\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
+ local_printfx("BH message=\"(BindLDAP: %s - %s)\"\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
continue;
} else
debug("BindLDAP(-, %s, %s, (LDAP_AUTH_TLS)) -> %s\n", edui_conf.dn, edui_conf.passwd, ErrLDAP(x));
if (x != LDAP_ERR_SUCCESS) {
/* Unable to bind */
debug("BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
- local_printfx("ERR message=\"(BindLDAP: %s - %s)\"\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
+ local_printfx("BH message=\"(BindLDAP: %s - %s)\"\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
continue;
} else
debug("BindLDAP(-, %s, %s, (LDAP_AUTH_SIMPLE)) -> %s\n", edui_conf.dn, edui_conf.passwd, ErrLDAP(x));
if (x != LDAP_ERR_SUCCESS) {
/* Unable to bind */
debug("BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
- local_printfx("ERR message=\"(BindLDAP: %s - %s)\"\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
+ local_printfx("BH message=\"(BindLDAP: %s - %s)\"\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
continue;
} else
debug("BindLDAP(-, -, -, (LDAP_AUTH_NONE)) -> %s\n", ErrLDAP(x));
/* Everything failed --> ERR */
debug("while() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
CloseLDAP(&edui_ldap);
- local_printfx("ERR message=\"(General Failure: %s)\"\n", ErrLDAP(x));
+ local_printfx("BH message=\"(General Failure: %s)\"\n", ErrLDAP(x));
continue;
}
edui_ldap.err = -1;
x = ConvertIP(&edui_ldap, bufb);
if (x < 0) {
debug("ConvertIP() -> %s\n", ErrLDAP(x));
- local_printfx("ERR message=\"(ConvertIP: %s)\"\n", ErrLDAP(x));
+ local_printfx("BH message=\"(ConvertIP: %s)\"\n", ErrLDAP(x));
} else {
edui_ldap.err = -1;
debug("ConvertIP(-, %s) -> Result[%d]: %s\n", bufb, x, edui_ldap.search_ip);
x = SearchFilterLDAP(&edui_ldap, bufa);
if (x < 0) {
debug("SearchFilterLDAP() -> %s\n", ErrLDAP(x));
- local_printfx("ERR message=\"(SearchFilterLDAP: %s)\"\n", ErrLDAP(x));
+ local_printfx("BH message=\"(SearchFilterLDAP: %s)\"\n", ErrLDAP(x));
} else {
/* Do Search */
edui_ldap.err = -1;
x = SearchLDAP(&edui_ldap, edui_ldap.scope, edui_ldap.search_filter, (char **) &search_attrib);
if (x != LDAP_ERR_SUCCESS) {
debug("SearchLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
- local_printfx("ERR message=\"(SearchLDAP: %s)\"\n", ErrLDAP(x));
+ local_printfx("BH message=\"(SearchLDAP: %s)\"\n", ErrLDAP(x));
} else {
edui_ldap.err = -1;
debug("SearchLDAP(-, %d, %s, -) -> %s\n", edui_conf.scope, edui_ldap.search_filter, ErrLDAP(x));
x = SearchIPLDAP(&edui_ldap);
- if (x != LDAP_ERR_SUCCESS) {
- debug("SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
+ if (x == LDAP_ERR_NOTFOUND) {
+ debug("SearchIPLDAP() -> %s\n", ErrLDAP(x));
local_printfx("ERR message=\"(SearchIPLDAP: %s)\"\n", ErrLDAP(x));
- } else {
+ } else if (x == LDAP_ERR_SUCCESS) {
debug("SearchIPLDAP(-, %s) -> %s\n", edui_ldap.userid, ErrLDAP(x));
local_printfx("OK user=%s\n", edui_ldap.userid); /* Got userid --> OK user=<userid> */
+ } else {
+ debug("SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
+ local_printfx("BH message=\"(SearchIPLDAP: %s)\"\n", ErrLDAP(x));
}
}
/* Clear for next query */
}
} else {
debug("StringSplit() -> Error: %" PRIuSIZE "\n", i);
- local_printfx("ERR message=\"(StringSplit Error %" PRIuSIZE ")\"\n", i);
+ local_printfx("BH message=\"(StringSplit Error %" PRIuSIZE ")\"\n", i);
}
} else {
/* No group to match against, only an IP */
x = ConvertIP(&edui_ldap, bufa);
if (x < 0) {
debug("ConvertIP() -> %s\n", ErrLDAP(x));
- local_printfx("ERR message=\"(ConvertIP: %s)\"\n", ErrLDAP(x));
+ local_printfx("BH message=\"(ConvertIP: %s)\"\n", ErrLDAP(x));
} else {
debug("ConvertIP(-, %s) -> Result[%d]: %s\n", bufa, x, edui_ldap.search_ip);
/* Do search */
x = SearchFilterLDAP(&edui_ldap, NULL);
if (x < 0) {
debug("SearchFilterLDAP() -> %s\n", ErrLDAP(x));
- local_printfx("ERR message=\"(SearchFilterLDAP: %s)\"\n", ErrLDAP(x));
+ local_printfx("BH message=\"(SearchFilterLDAP: %s)\"\n", ErrLDAP(x));
} else {
edui_ldap.err = -1;
debug("SearchFilterLDAP(-, NULL) -> Length: %u\n", x);
x = SearchLDAP(&edui_ldap, edui_ldap.scope, edui_ldap.search_filter, (char **) &search_attrib);
if (x != LDAP_ERR_SUCCESS) {
debug("SearchLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(x));
- local_printfx("ERR message=\"(SearchLDAP: %s)\"\n", ErrLDAP(x));
+ local_printfx("BH message=\"(SearchLDAP: %s)\"\n", ErrLDAP(x));
} else {
edui_ldap.err = -1;
debug("SearchLDAP(-, %d, %s, -) -> %s\n", edui_conf.scope, edui_ldap.search_filter, ErrLDAP(x));
x = SearchIPLDAP(&edui_ldap);
- if (x != LDAP_ERR_SUCCESS) {
- debug("SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
+ if (x == LDAP_ERR_NOTFOUND) {
+ debug("SearchIPLDAP() -> %s\n", ErrLDAP(x));
local_printfx("ERR message=\"(SearchIPLDAP: %s)\"\n", ErrLDAP(x));
- } else {
+ } else if (x == LDAP_ERR_SUCCESS) {
debug("SearchIPLDAP(-, %s) -> %s\n", edui_ldap.userid, ErrLDAP(x));
local_printfx("OK user=%s\n", edui_ldap.userid); /* Got a userid --> OK user=<userid> */
+ } else if (x != LDAP_ERR_SUCCESS) {
+ debug("SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
+ local_printfx("BH message=\"(SearchIPLDAP: %s)\"\n", ErrLDAP(x));
}
}
}
if (strchr(line, '\n') != NULL)
break;
}
- SEND_ERR("Input Too Large.");
+ SEND_BH(HLP_MSG("Input Too Large."));
continue;
}
*cp = '\0';
username = strtok(NULL, " \t");
if (!address || !username) {
debug("%s: unable to read tokens\n", program_name);
- SEND_ERR("Invalid Input.");
+ SEND_BH(HLP_MSG("Invalid Input."));
continue;
}
rfc1738_unescape(address);
// we expect the following line syntax: %LOGIN
const char *user_key = strtok(request, " \n");
if (!user_key) {
- SEND_BH("message=\"User name missing\"");
+ SEND_BH(HLP_MSG("User name missing"));
continue;
}
processActivity(user_key);
if (strchr(buf, '\n') != NULL)
break;
}
- SEND_ERR("Username Input too large.");
+ SEND_BH(HLP_MSG("Username Input too large."));
continue;
}
*p = '\0';
if ((p = strtok(buf, " ")) == NULL) {
- SEND_ERR("No username given.");
+ SEND_BH(HLP_MSG("No username given."));
continue;
} else {
user = p;
void trimCache();
+ bool maybeCacheable(const allow_t &) const;
+
int ttl;
int negative_ttl;
}
}
+bool
+external_acl::maybeCacheable(const allow_t &result) const
+{
+ if (cache_size <= 0)
+ return false; // cache is disabled
+
+ if (result == ACCESS_DUNNO)
+ return false; // non-cacheable response
+
+ if ((result == ACCESS_ALLOWED ? ttl : negative_ttl) <= 0)
+ return false; // not caching this type of response
+
+ return true;
+}
+
/******************************************************************
* external acl type
*/
external_acl_cache_touch(external_acl * def, const ExternalACLEntryPointer &entry)
{
// this must not be done when nothing is being cached.
- if (def->cache_size <= 0 || (def->ttl <= 0 && entry->result == 1) || (def->negative_ttl <= 0 && entry->result != 1))
+ if (!def->maybeCacheable(entry->result))
return;
dlinkDelete(&entry->lru, &def->lru_list);
static int
external_acl_entry_expired(external_acl * def, const ExternalACLEntryPointer &entry)
{
- if (def->cache_size <= 0)
+ if (def->cache_size <= 0 || entry->result == ACCESS_DUNNO)
return 1;
- if (entry->date + (entry->result == 1 ? def->ttl : def->negative_ttl) < squid_curtime)
+ if (entry->date + (entry->result == ACCESS_ALLOWED ? def->ttl : def->negative_ttl) < squid_curtime)
return 1;
else
return 0;
static int
external_acl_grace_expired(external_acl * def, const ExternalACLEntryPointer &entry)
{
- if (def->cache_size <= 0)
+ if (def->cache_size <= 0 || entry->result == ACCESS_DUNNO)
return 1;
int ttl;
- ttl = entry->result == 1 ? def->ttl : def->negative_ttl;
+ ttl = entry->result == ACCESS_ALLOWED ? def->ttl : def->negative_ttl;
ttl = (ttl * (100 - def->grace)) / 100;
if (entry->date + ttl <= squid_curtime)
{
ExternalACLEntryPointer entry;
- // do not bother caching this result if TTL is going to expire it immediately
- if (def->cache_size <= 0 || (def->ttl <= 0 && data.result == 1) || (def->negative_ttl <= 0 && data.result != 1)) {
+ if (!def->maybeCacheable(data.result)) {
debugs(82,6, HERE);
+
+ if (data.result == ACCESS_DUNNO) {
+ if (const ExternalACLEntryPointer oldentry = static_cast<ExternalACLEntry *>(hash_lookup(def->cache, key)))
+ external_acl_cache_delete(def, oldentry);
+ }
entry = new ExternalACLEntry;
entry->key = xstrdup(key);
entry->update(data);
externalAclState *state = static_cast<externalAclState *>(data);
externalAclState *next;
ExternalACLEntryData entryData;
- entryData.result = ACCESS_DENIED;
debugs(82, 2, HERE << "reply=" << reply);
if (reply.result == Helper::Okay)
entryData.result = ACCESS_ALLOWED;
- // XXX: handle other non-DENIED results better
+ else if (reply.result == Helper::Error)
+ entryData.result = ACCESS_DENIED;
+ else //BrokenHelper,TimedOut or Unknown. Should not cached.
+ entryData.result = ACCESS_DUNNO;
// XXX: make entryData store a proper Helper::Reply object instead of copying.
dlinkDelete(&state->list, &state->def->queue);
ExternalACLEntryPointer entry;
- if (cbdataReferenceValid(state->def)) {
- // only cache OK and ERR results.
- if (reply.result == Helper::Okay || reply.result == Helper::Error)
- entry = external_acl_cache_add(state->def, state->key, entryData);
- else {
- const ExternalACLEntryPointer oldentry = static_cast<ExternalACLEntry *>(hash_lookup(state->def->cache, state->key));
-
- if (oldentry != NULL)
- external_acl_cache_delete(state->def, oldentry);
- }
- }
+ if (cbdataReferenceValid(state->def))
+ entry = external_acl_cache_add(state->def, state->key, entryData);
do {
void *cbdata;
if (!msgEnd)
return; // We are waiting for more data.
- HLPCB *callback = r->request.callback;
- r->request.callback = nullptr;
-
bool retry = false;
- void *cbdata = nullptr;
- if (cbdataReferenceValidDone(r->request.data, &cbdata)) {
+ if (cbdataReferenceValid(r->request.data)) {
r->reply.finalize();
if (r->reply.result == Helper::BrokenHelper && r->request.retries < MAX_RETRIES) {
debugs(84, DBG_IMPORTANT, "ERROR: helper: " << r->reply << ", attempt #" << (r->request.retries + 1) << " of 2");
retry = true;
- } else
+ } else {
+ HLPCB *callback = r->request.callback;
+ r->request.callback = nullptr;
+ void *cbdata = nullptr;
+ cbdataReferenceValidDone(r->request.data, &cbdata);
callback(cbdata, r->reply);
+ }
}
-- srv->stats.pending;
/* send ERR result to Squid with a string parameter. */
#define SEND_ERR(x) std::cout << "ERR " << x << std::endl
-/* send ERR result to Squid with a string parameter. */
+/* send BH result to Squid with a string parameter. */
#define SEND_BH(x) std::cout << "BH " << x << std::endl
+/* constructs a message to Squid. */
+#define HLP_MSG(text) "message=\"" text "\""
+
/* send TT result to Squid with a string parameter. */
#define SEND_TT(x) std::cout << "TT " << x << std::endl