cache_req.c revision 9286d0d4143bcb4e36b91022107e307998122bbb
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/*
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen Authors:
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen Pavel Březina <pbrezina@redhat.com>
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen Copyright (C) 2016 Red Hat
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen This program is free software; you can redistribute it and/or modify
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen it under the terms of the GNU General Public License as published by
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen the Free Software Foundation; either version 3 of the License, or
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen (at your option) any later version.
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen This program is distributed in the hope that it will be useful,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen GNU General Public License for more details.
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen You should have received a copy of the GNU General Public License
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen*/
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen#include <ldb.h>
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen#include <talloc.h>
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen#include <tevent.h>
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen#include <errno.h>
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen#include "util/util.h"
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen#include "responder/common/cache_req/cache_req_private.h"
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen#include "responder/common/cache_req/cache_req_plugin.h"
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenstatic const struct cache_req_plugin *
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainencache_req_get_plugin(enum cache_req_type type)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen{
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen static const struct cache_req_plugin *plugins[CACHE_REQ_SENTINEL] = {
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_user_by_name,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_user_by_upn,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_user_by_id,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_user_by_cert,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_user_by_filter,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_group_by_name,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_group_by_id,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_group_by_filter,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_initgroups_by_name,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_initgroups_by_upn,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_object_by_sid,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_object_by_name,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen &cache_req_object_by_id,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen &cache_req_enum_users,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen &cache_req_enum_groups,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen &cache_req_enum_svc,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen &cache_req_svc_by_name,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen &cache_req_svc_by_port,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen &cache_req_netgroup_by_name,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen &cache_req_host_by_name,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen };
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (type >= CACHE_REQ_SENTINEL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen DEBUG(SSSDBG_FATAL_FAILURE, "Bug: invalid plugin type!");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return NULL;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return plugins[type];
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen}
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic errno_t cache_req_set_plugin(struct cache_req *cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen enum cache_req_type type)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen const struct cache_req_plugin *plugin;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen plugin = cache_req_get_plugin(type);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (plugin == NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen DEBUG(SSSDBG_FATAL_FAILURE, "Bug: unset plugin!");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return EINVAL;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->reqname = plugin->name;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->plugin = plugin;
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_INTERNAL, cr, "Setting \"%s\" plugin\n",
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen plugin->name);
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen return EOK;
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen}
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainenstatic struct cache_req *
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainencache_req_create(TALLOC_CTX *mem_ctx,
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen struct resp_ctx *rctx,
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen struct cache_req_data *data,
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen struct sss_nc_ctx *ncache,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen int midpoint)
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen{
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen struct cache_req *cr;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen errno_t ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr = talloc_zero(mem_ctx, struct cache_req);
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen if (cr == NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return NULL;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->rctx = rctx;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->data = data;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->ncache = ncache;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->midpoint = midpoint;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->req_start = time(NULL);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* It is perfectly fine to just overflow here. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->reqid = rctx->cache_req_num++;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cache_req_set_plugin(cr, data->type);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ret != EOK) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen talloc_free(cr);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return NULL;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return cr;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen}
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic errno_t
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainencache_req_set_name(struct cache_req *cr, const char *name)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen const char *dup_name;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
b8864211b88ed7521e9af514590639344af38910Timo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Setting name [%s]\n", name);
b8864211b88ed7521e9af514590639344af38910Timo Sirainen
c3cb859d93a77d52d6af054d358b55d45b4a5188Timo Sirainen dup_name = talloc_strdup(cr->data, name);
b8864211b88ed7521e9af514590639344af38910Timo Sirainen if (dup_name == NULL) {
c3cb859d93a77d52d6af054d358b55d45b4a5188Timo Sirainen CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr, "Unable to set name!\n");
c3cb859d93a77d52d6af054d358b55d45b4a5188Timo Sirainen return ENOMEM;
c3cb859d93a77d52d6af054d358b55d45b4a5188Timo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen talloc_zfree(cr->data->name.name);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->data->name.name = dup_name;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return EOK;
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen}
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainenstatic bool
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainencache_req_validate_domain(struct cache_req *cr,
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen struct sss_domain_info *domain)
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen{
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen if (!cr->plugin->require_enumeration) {
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen return true;
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen }
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen if (domain->enumerate == false) {
930d6db2ee2bbafd3c7cdaa39855ddccb999522fTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Domain %s does not support "
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "enumeration, skipping...\n", domain->name);
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen return false;
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen }
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Domain %s supports enumeration\n",
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen domain->name);
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen return true;
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen}
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainenstatic errno_t
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainencache_req_is_well_known_object(TALLOC_CTX *mem_ctx,
aa938aea66562ca3f3c5965a79b3b27ebcbe04efTimo Sirainen struct cache_req *cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct cache_req_result **_result)
01e29d9d23a1844b4582592a473a3b3eac56b36bTimo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen errno_t ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (cr->plugin->is_well_known_fn == NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return ENOENT;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cr->plugin->is_well_known_fn(mem_ctx, cr, cr->data, _result);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ret == EOK) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Object is well known!\n");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen (*_result)->well_known_object = true;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen } else if (ret != ENOENT) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "Unable to prepare data [%d]: %s\n",
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret, sss_strerror(ret));
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen}
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic errno_t
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainencache_req_prepare_domain_data(struct cache_req *cr,
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen struct sss_domain_info *domain)
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen errno_t ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (cr->plugin->prepare_domain_data_fn == NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return EOK;
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen }
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "Preparing input data for domain [%s] rules\n",
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen domain->name);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen ret = cr->plugin->prepare_domain_data_fn(cr, cr->data, domain);
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen if (ret != EOK) {
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "Unable to prepare data [%d]: %s\n",
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret, sss_strerror(ret));
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen return ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return EOK;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen}
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic errno_t
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainencache_req_create_debug_name(struct cache_req *cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct sss_domain_info *domain)
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (cr->plugin->create_debug_name_fn == NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "Bug: no create debug name function specified!\n");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return ERR_INTERNAL;
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen }
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen talloc_zfree(cr->debugobj);
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen cr->debugobj = cr->plugin->create_debug_name_fn(cr, cr->data, domain);
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen if (cr->debugobj == NULL) {
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen "Unable to create debug name!\n");
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen return ENOMEM;
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return EOK;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen}
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic errno_t
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainencache_req_set_domain(struct cache_req *cr,
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen struct sss_domain_info *domain)
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen errno_t ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Using domain [%s]\n", domain->name);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cache_req_prepare_domain_data(cr, domain);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ret != EOK) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cache_req_create_debug_name(cr, domain);
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen if (ret != EOK) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen cr->domain = domain;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return EOK;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen}
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic void cache_req_global_ncache_add(struct cache_req *cr)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen errno_t ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (cr->plugin->global_ncache_add_fn == NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_INTERNAL, cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "This request type does not support "
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "global negative cache\n");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Adding [%s] to global "
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "negative cache\n", cr->debugobj);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cr->plugin->global_ncache_add_fn(cr->ncache, cr->data);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ret != EOK) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_MINOR_FAILURE, cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen "Cannot set negative cache for [%s] [%d]: %s\n",
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->debugobj, ret, sss_strerror(ret));
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* not fatal */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen}
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic bool
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainencache_req_assume_upn(struct cache_req *cr)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen errno_t ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (cr->plugin->allow_switch_to_upn == false
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen || cr->data->name.input == NULL
3281669db44d09a087a203201248abbc81b3cc1aTimo Sirainen || strchr(cr->data->name.input, '@') == NULL) {
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen return false;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cache_req_set_plugin(cr, cr->plugin->upn_equivalent);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ret != EOK) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return false;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cache_req_set_name(cr, cr->data->name.input);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ret != EOK) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "cache_req_set_name() failed\n");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return false;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Assuming UPN [%s]\n",
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr->data->name.input);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return true;
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen}
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainenstruct cache_req_search_domains_state {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* input data */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct tevent_context *ev;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct cache_req *cr;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen /* work data */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct sss_domain_info *domain;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct sss_domain_info *selected_domain;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct cache_req_result **results;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen size_t num_results;
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen bool check_next;
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen bool dp_success;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen};
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic struct tevent_req *
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainencache_req_search_domains_send(TALLOC_CTX *mem_ctx,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct tevent_context *ev,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct cache_req *cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct sss_domain_info *domain,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen bool check_next);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic errno_t cache_req_search_domains_next(struct tevent_req *req);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic errno_t cache_req_select_domains(struct tevent_req *req,
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen const char *domain_name);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstatic void cache_req_search_domains_done(struct tevent_req *subreq);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstruct tevent_req *cache_req_search_domains_send(TALLOC_CTX *mem_ctx,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct tevent_context *ev,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct cache_req *cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct sss_domain_info *domain,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen bool check_next)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct tevent_req *req;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct cache_req_search_domains_state *state = NULL;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen errno_t ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen req = tevent_req_create(mem_ctx, &state,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct cache_req_search_domains_state);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (req == NULL) {
3b8a19184c37851d9794178dd7a612ed8ed1c4f8Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return NULL;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state->ev = ev;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state->cr = cr;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state->domain = domain;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen state->check_next = check_next;
fad068d459cc7b04fedade4e0bb343be62e6d310Timo Sirainen state->dp_success = true;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cache_req_search_domains_next(req);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ret == EAGAIN) {
fad068d459cc7b04fedade4e0bb343be62e6d310Timo Sirainen return req;
fad068d459cc7b04fedade4e0bb343be62e6d310Timo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ret == EOK) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen tevent_req_done(req);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen } else {
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen tevent_req_error(req, ret);
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen }
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen tevent_req_post(req, ev);
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen return req;
fad068d459cc7b04fedade4e0bb343be62e6d310Timo Sirainen}
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainenstatic errno_t cache_req_search_domains_next(struct tevent_req *req)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen{
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct cache_req_search_domains_state *state;
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen struct tevent_req *subreq;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct cache_req *cr;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen uint32_t next_domain_flag;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen bool is_domain_valid;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen bool allow_no_fqn;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen errno_t ret;
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state = tevent_req_data(req, struct cache_req_search_domains_state);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen cr = state->cr;
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen next_domain_flag = cr->plugin->get_next_domain_flags;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen allow_no_fqn = cr->plugin->allow_missing_fqn;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen while (state->domain != NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* Check if this domain is valid for this request. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen is_domain_valid = cache_req_validate_domain(cr, state->domain);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (!is_domain_valid) {
fad068d459cc7b04fedade4e0bb343be62e6d310Timo Sirainen state->domain = get_next_domain(state->domain, next_domain_flag);
fad068d459cc7b04fedade4e0bb343be62e6d310Timo Sirainen continue;
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen }
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* If not specified otherwise, we skip domains that require fully
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen * qualified names on domain less search. We do not descend into
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen * subdomains here since those are implicitly qualified.
fad068d459cc7b04fedade4e0bb343be62e6d310Timo Sirainen */
fad068d459cc7b04fedade4e0bb343be62e6d310Timo Sirainen if (state->check_next && !allow_no_fqn && state->domain->fqnames) {
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen state->domain = get_next_domain(state->domain, 0);
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen continue;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state->selected_domain = state->domain;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (state->domain == NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen break;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cache_req_set_domain(cr, state->domain);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (ret != EOK) {
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen return ret;
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen subreq = cache_req_search_send(state, state->ev, cr);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (subreq == NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return ENOMEM;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen tevent_req_set_callback(subreq, cache_req_search_domains_done, req);
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen /* we will continue with the following domain the next time */
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen if (state->check_next) {
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen state->domain = get_next_domain(state->domain,
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen cr->plugin->get_next_domain_flags);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen return EAGAIN;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen /* If we've got some result from previous searches we want to return
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen * EOK here so the whole cache request is successfully finished. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (state->num_results > 0) {
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen return EOK;
35e4905f732e1d25c71c47be3dbd747bc28cf642Timo Sirainen }
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen /* We have searched all available domains and no result was found.
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen *
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen * If the plug-in uses a negative cache which is shared among all domains
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen * (e.g. unique identifiers such as user or group id or sid), we add it
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen * here and return object not found error.
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen *
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen * However, we can only set the negative cache if all data provider
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen * requests succeeded because only then we can be sure that it does
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen * not exist-
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen */
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen if (state->dp_success) {
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen cache_req_global_ncache_add(cr);
de9d79337eca11a7f9c1cd476c74dfe4f09a4bd7Timo Sirainen }
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen
de9d79337eca11a7f9c1cd476c74dfe4f09a4bd7Timo Sirainen return ENOENT;
de9d79337eca11a7f9c1cd476c74dfe4f09a4bd7Timo Sirainen}
de9d79337eca11a7f9c1cd476c74dfe4f09a4bd7Timo Sirainen
d1baa8c6f97cdb1b3c2c44a73cc21f9dfc7a963fTimo Sirainenstatic void cache_req_search_domains_done(struct tevent_req *subreq)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen{
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen struct cache_req_search_domains_state *state;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen struct ldb_result *result;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct tevent_req *req;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct tevent_req *req_send;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen bool dp_success;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen errno_t ret;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen req = tevent_req_callback_data(subreq, struct tevent_req);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state = tevent_req_data(req, struct cache_req_search_domains_state);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = cache_req_search_recv(state, subreq, &result, &dp_success);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen talloc_zfree(subreq);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* Remember if any DP request fails. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state->dp_success = !dp_success ? false : state->dp_success;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen switch (ret) {
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen case EOK:
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen /* We got some data from this search. Save it. */
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen ret = cache_req_create_and_add_result(state,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state->cr,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state->selected_domain,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen result,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen state->cr->data->name.lookup,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen &state->results,
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen &state->num_results);
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen if (ret != EOK) {
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen /* We were unable to save data. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen goto done;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen }
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (!state->check_next || !state->cr->plugin->search_all_domains) {
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen /* We are not interested in more results. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen ret = EOK;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen goto done;
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen }
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen break;
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen case ENOENT:
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen if (state->check_next == false) {
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen /* Lookup domain was specified as input.
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen * We don't want to try the next domain,
082e82792b8ac33ad42beac510441b37a3c50737Timo Sirainen * but we may want to try UPN search. */
082e82792b8ac33ad42beac510441b37a3c50737Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (cache_req_assume_upn(state->cr)) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen /* Here we need to access the request created by cache_req_send()
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen * in order to pass it down to cache_req_select_domains() */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen req_send = tevent_req_callback_data(req, struct tevent_req);
/* Try UPN now. */
ret = cache_req_select_domains(req_send, NULL);
goto done;
}
/* Not found. */
ret = ENOENT;
goto done;
}
break;
default:
/* Some serious error has happened. Finish. */
goto done;
}
/* This is a domain less search, continue with the next domain. */
ret = cache_req_search_domains_next(req);
done:
if (ret == ENOENT && state->results != NULL) {
/* We have at least one result. */
ret = EOK;
}
switch (ret) {
case EOK:
tevent_req_done(req);
break;
case EAGAIN:
break;
default:
tevent_req_error(req, ret);
break;
}
return;
}
static errno_t
cache_req_search_domains_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
struct cache_req_result ***_results)
{
struct cache_req_search_domains_state *state;
state = tevent_req_data(req, struct cache_req_search_domains_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
if (_results != NULL) {
*_results = talloc_steal(mem_ctx, state->results);
}
return EOK;
}
struct cache_req_state {
/* input data */
struct tevent_context *ev;
struct cache_req *cr;
/* work data */
struct cache_req_result **results;
size_t num_results;
};
static errno_t cache_req_process_input(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
struct cache_req *cr,
const char *domain);
static void cache_req_input_parsed(struct tevent_req *subreq);
static errno_t cache_req_search_domains(struct tevent_req *req,
struct sss_domain_info *domain,
bool check_next);
static void cache_req_done(struct tevent_req *subreq);
struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct resp_ctx *rctx,
struct sss_nc_ctx *ncache,
int midpoint,
const char *domain,
struct cache_req_data *data)
{
struct cache_req_state *state;
struct cache_req_result *result;
struct cache_req *cr;
struct tevent_req *req;
errno_t ret;
req = tevent_req_create(mem_ctx, &state, struct cache_req_state);
if (req == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
return NULL;
}
state->ev = ev;
state->cr = cr = cache_req_create(state, rctx, data, ncache, midpoint);
if (state->cr == NULL) {
ret = ENOMEM;
goto done;
}
CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "New request '%s'\n", cr->reqname);
ret = cache_req_is_well_known_object(state, cr, &result);
if (ret == EOK) {
ret = cache_req_add_result(state, result, &state->results,
&state->num_results);
goto done;
} else if (ret != ENOENT) {
goto done;
}
ret = cache_req_process_input(state, req, cr, domain);
if (ret != EOK) {
goto done;
}
ret = cache_req_select_domains(req, domain);
done:
if (ret == EOK) {
tevent_req_done(req);
tevent_req_post(req, ev);
} else if (ret != EAGAIN) {
tevent_req_error(req, ret);
tevent_req_post(req, ev);
}
return req;
}
static errno_t cache_req_process_input(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
struct cache_req *cr,
const char *domain)
{
struct tevent_req *subreq;
const char *default_domain;
if (cr->data->name.input == NULL) {
/* Input was not name, there is no need to process it further. */
return EOK;
}
if (cr->plugin->parse_name == false || domain != NULL) {
/* We do not want to parse the name. */
return cache_req_set_name(cr, cr->data->name.input);
}
default_domain = NULL;
if (!cr->plugin->ignore_default_domain) {
default_domain = cr->rctx->default_domain;
}
/* Parse name since it may contain a domain name. */
CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
"Parsing input name [%s]\n", cr->data->name.input);
subreq = sss_parse_inp_send(mem_ctx, cr->rctx, default_domain,
cr->data->name.input);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n");
return ENOMEM;
}
tevent_req_set_callback(subreq, cache_req_input_parsed, req);
return EAGAIN;
}
static void cache_req_input_parsed(struct tevent_req *subreq)
{
struct tevent_req *req;
struct cache_req_state *state;
char *name;
char *domain;
bool maybe_upn;
errno_t ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct cache_req_state);
ret = sss_parse_inp_recv(subreq, state, &name, &domain);
switch (ret) {
case EOK:
ret = cache_req_set_name(state->cr, name);
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
break;
case ERR_DOMAIN_NOT_FOUND:
maybe_upn = cache_req_assume_upn(state->cr);
if (!maybe_upn) {
tevent_req_error(req, ret);
return;
}
domain = NULL;
break;
default:
tevent_req_error(req, ret);
return;
}
ret = cache_req_select_domains(req, domain);
if (ret != EAGAIN) {
tevent_req_error(req, ret);
return;
}
}
static errno_t cache_req_select_domains(struct tevent_req *req,
const char *domain_name)
{
struct cache_req_state *state = NULL;
struct sss_domain_info *domain;
bool check_next;
state = tevent_req_data(req, struct cache_req_state);
if (domain_name != NULL) {
CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
"Performing a single domain search\n");
domain = responder_get_domain(state->cr->rctx, domain_name);
if (domain == NULL) {
return ERR_DOMAIN_NOT_FOUND;
}
check_next = false;
} else {
CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
"Performing a multi-domain search\n");
domain = state->cr->rctx->domains;
check_next = true;
}
return cache_req_search_domains(req, domain, check_next);
}
static errno_t cache_req_search_domains(struct tevent_req *req,
struct sss_domain_info *domain,
bool check_next)
{
struct tevent_req *subreq;
struct cache_req_state *state = NULL;
state = tevent_req_data(req, struct cache_req_state);
subreq = cache_req_search_domains_send(state, state->ev, state->cr, domain,
check_next);
if (subreq == NULL) {
return ENOMEM;
}
tevent_req_set_callback(subreq, cache_req_done, req);
return EAGAIN;
}
static void cache_req_done(struct tevent_req *subreq)
{
struct cache_req_state *state;
struct tevent_req *req;
errno_t ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct cache_req_state);
ret = cache_req_search_domains_recv(state, subreq, &state->results);
talloc_zfree(subreq);
switch (ret) {
case EOK:
CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, "Finished: Success\n");
tevent_req_done(req);
break;
case EAGAIN:
break;
case ENOENT:
CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, "Finished: Not found\n");
tevent_req_error(req, ret);
break;
default:
CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
"Finished: Error %d: %s\n", ret, sss_strerror(ret));
tevent_req_error(req, ret);
break;
}
return;
}
errno_t cache_req_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
struct cache_req_result ***_results)
{
struct cache_req_state *state;
state = tevent_req_data(req, struct cache_req_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
if (_results != NULL) {
*_results = talloc_steal(mem_ctx, state->results);
}
return EOK;
}
errno_t cache_req_single_domain_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
struct cache_req_result **_result)
{
struct cache_req_state *state;
state = tevent_req_data(req, struct cache_req_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
if (_result != NULL) {
*_result = talloc_steal(mem_ctx, state->results[0]);
}
return EOK;
}
struct tevent_req *
cache_req_steal_data_and_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct resp_ctx *rctx,
struct sss_nc_ctx *ncache,
int cache_refresh_percent,
const char *domain,
struct cache_req_data *data)
{
struct tevent_req *req;
req = cache_req_send(mem_ctx, ev, rctx, ncache,
cache_refresh_percent, domain, data);
if (req == NULL) {
talloc_zfree(data);
return NULL;
}
talloc_steal(req, data);
return req;
}