/*
Authors:
Pavel Březina <pbrezina@redhat.com>
Copyright (C) 2016 Red Hat
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <ldb.h>
#include <talloc.h>
#include <tevent.h>
#include "responder/common/cache_req/cache_req_private.h"
#include "responder/common/cache_req/cache_req_plugin.h"
{
"This request type does not support negative cache\n");
return EOK;
}
"Checking negative cache for [%s]\n",
"[%s] does not exist (negative cache)\n",
return ENOENT;
"Unable to check negative cache [%d]: %s\n",
return ret;
}
"[%s] is not present in negative cache\n",
return EOK;
}
struct sss_domain_info *domain)
{
"This request type does not support negative cache\n");
return;
}
"Cannot set negative cache for [%s] [%d]: %s\n",
/* not fatal */
}
return;
}
{
}
struct ldb_result **_result)
{
const char *name;
return ENOMEM;
}
"This request type does not support filtering "
"result by negative cache\n");
goto done;
}
"Filtering out results by negative cache\n");
msg_count = 0;
"sss_get_name_from_msg() returned NULL, which should never "
"happen in this scenario!\n");
ret = ERR_INTERNAL;
goto done;
}
"[%s] filtered out! (negative cache)\n",
name);
continue;
"Unable to check negative cache [%d]: %s\n",
goto done;
}
msg_count++;
}
if (msg_count == 0) {
goto done;
}
if (filtered_result == NULL) {
goto done;
}
done:
return ret;
}
struct ldb_result **_result)
{
"Bug: No cache lookup function specified\n");
return ERR_INTERNAL;
}
"Looking up [%s] in cache\n",
}
switch (ret) {
case EOK:
"Multiple objects were found when "
"only one was expected!\n");
ret = ERR_INTERNAL;
goto done;
}
break;
case ERR_ID_OUTSIDE_RANGE:
"ID [%s] was filtered out\n",
break;
case ENOENT:
"Object [%s] was not found in cache\n",
break;
default:
"Unable to lookup [%s] in cache [%d]: %s\n",
break;
}
done:
}
return ret;
}
static enum cache_object_status
struct ldb_result *result)
{
return CACHE_OBJECT_MISSING;
}
return CACHE_OBJECT_VALID;
return CACHE_OBJECT_MIDPOINT;
}
return CACHE_OBJECT_EXPIRED;
}
struct cache_req_search_state {
/* input data */
/* output data */
bool dp_success;
};
enum cache_object_status status);
struct tevent_req *
struct tevent_context *ev,
bool bypass_cache,
bool bypass_dp)
{
return NULL;
}
goto done;
}
/* If bypass_cache is enabled we always contact data provider before
* searching the cache. Thus we set expiration status to missing,
* which will trigger data provider request later.
*
* If disabled, we want to search the cache here to see if the
* object is already cached and valid or if data provider needs
* to be contacted.
*/
if (!bypass_cache) {
goto done;
}
if (status == CACHE_OBJECT_VALID) {
goto done;
}
/* If bypass_dp is true but we found the object in this domain,
* we will contact the data provider anyway to refresh it so
* we can return it without searching the rest of the domains.
*/
if (status != CACHE_OBJECT_MISSING) {
"Object found, but needs to be refreshed.\n");
bypass_dp = false;
} else {
}
}
if (!bypass_dp) {
}
goto done;
}
return req;
done:
}
} else {
}
return req;
}
enum cache_object_status status)
{
switch (status) {
case CACHE_OBJECT_MIDPOINT:
/* Out of band update. The calling function will return the cached
* entry immediately. We need to use rctx so the request is not
* removed when state is freed. */
"Performing midpoint cache update of [%s]\n",
"data provider request\n");
/* This is non-fatal, so we'll continue here */
} else {
}
break;
case CACHE_OBJECT_EXPIRED:
case CACHE_OBJECT_MISSING:
"Looking up [%s] in data provider\n",
"Out of memory sending data provider request\n");
break;
}
break;
default:
/* error */
"Unexpected status [%d]\n", status);
ret = ERR_INTERNAL;
break;
}
return ret;
}
{
return;
}
{
/* Get result from cache again. */
/* Only store entry in negative cache if DP request succeeded
* because only then we know that the entry does not exist. */
if (state->dp_success) {
}
}
goto done;
}
/* ret == EOK */
goto done;
}
done:
return;
}
return;
}
struct tevent_req *req,
struct ldb_result **_result,
bool *_dp_success)
{
return EOK;
}
struct cache_req_locate_domain_state {
char *found_domain;
};
struct tevent_context *ev,
{
bool should_run;
return NULL;
}
if (should_run == false) {
/* The request was tried too recently, don't issue a new one
* as its results are still valid
*/
goto immediate;
}
goto immediate;
}
return req;
} else {
}
return req;
}
{
&state->found_domain);
return;
}
}
struct tevent_req *req,
char **_found_domain)
{
return EOK;
}