data_provider_fo.c revision f9961e5f82e0ef474d6492371bfdf9e74e208a99
/*
SSSD
Data Provider Helpers
Copyright (C) Simo Sorce <ssorce@redhat.com> 2009
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 <netdb.h>
#include "providers/dp_backend.h"
#include "resolv/async_resolv.h"
struct be_svc_callback {
struct be_svc_callback *prev;
struct be_svc_callback *next;
struct be_svc_data *svc;
void *private_data;
};
struct be_svc_data {
struct be_svc_data *prev;
struct be_svc_data *next;
const char *name;
struct fo_service *fo_service;
struct fo_server *last_good_srv;
bool run_callbacks;
struct be_svc_callback *callbacks;
struct fo_server *first_resolved;
};
struct be_failover_ctx {
struct be_resolv_ctx *be_res;
struct be_svc_data *svcs;
struct tevent_timer *primary_server_handler;
};
int be_fo_is_srv_identifier(const char *server)
{
}
struct fo_options *opts)
{
return EOK;
}
{
int ret;
struct fo_options fopts;
return EOK;
}
return ENOMEM;
}
("fatal error initializing resolver context\n"));
return ret;
}
return ret;
}
return ENOMEM;
}
return EOK;
}
static int be_svc_data_destroy(void *memptr)
{
struct be_svc_data *svc;
/* callbacks removes themselves from the list,
* so this while will freem them all and then terminate */
}
return 0;
}
/*
* Find registered be_svc_data by service name.
*/
const char *service_name)
{
struct be_svc_data *svc;
return 0;
}
return svc;
}
}
return 0;
}
{
struct fo_service *service;
struct be_svc_data *svc;
int ret;
if (svc) {
/* we already have a service up and configured,
* can happen when using both id and auth provider
*/
return EOK;
}
/* if not in the be service list, try to create new one */
&service);
return ret;
}
if (!svc) {
return ENOMEM;
}
return ENOMEM;
}
return EOK;
}
static int be_svc_callback_destroy(void *memptr)
{
struct be_svc_callback *callback;
}
return 0;
}
{
struct be_svc_callback *callback;
struct be_svc_data *svc;
return ENOENT;
}
if (!callback) {
return ENOMEM;
}
return EOK;
}
void *pvt,
const char *plugin_name)
{
bool bret;
plugin_name));
if (bret) {
plugin_name));
} else {
"another plugin may be already in place\n"));
}
}
const char *service_name,
const char *query_service,
const char *default_discovery_domain,
enum be_fo_protocol proto,
bool proto_fallback, void *user_data)
{
struct be_svc_data *svc;
const char *domain;
int ret;
int i;
return ENOENT;
}
if (!domain) {
}
/* Add the first protocol as the primary lookup */
return ret;
}
if (proto_fallback) {
/* All the rest as fallback */
while (i != proto) {
proto_table[i], user_data);
return ret;
}
i = (i + 1) % BE_FO_PROTO_SENTINEL;
}
}
return EOK;
}
{
struct be_svc_data *svc_data;
if (!svc_data) {
return 0;
}
}
bool primary)
{
struct be_svc_data *svc;
int ret;
return ENOENT;
}
return ret;
}
return EOK;
}
struct be_resolve_server_state {
struct tevent_context *ev;
struct be_svc_data *svc;
int attempts;
bool first_try;
};
struct be_primary_server_ctx {
struct tevent_context *ev;
struct be_svc_data *svc;
unsigned long timeout;
int attempts;
};
struct be_resolve_server_state *state,
struct tevent_req **new_subreq);
static errno_t
struct tevent_context *ev,
struct be_svc_data *svc,
const unsigned long timeout_seconds);
static void
struct tevent_timer *te,
{
struct tevent_req *subreq;
return;
}
}
{
struct be_primary_server_ctx *ctx;
struct be_resolve_server_state *resolve_state;
struct tevent_req *new_subreq;
if (resolve_state == NULL) {
return;
}
resolve_state->first_try = true;
return;
/* Schedule another lookup
* (either no server could be found or it was not primary)
*/
}
}
/* If an error occurred just end the routine */
}
static errno_t
struct tevent_context *ev,
struct be_svc_data *svc,
const unsigned long timeout_seconds)
{
struct be_primary_server_ctx *ctx;
"is already scheduled\n"));
return EOK;
}
return ENOMEM;
}
tv = tevent_timeval_current();
return ENOMEM;
}
"to %lu seconds\n", timeout_seconds));
return EOK;
}
struct tevent_context *ev,
const char *service_name,
bool first_try)
{
struct be_resolve_server_state *state;
struct be_svc_data *svc;
return req;
}
svc->fo_service);
if (!subreq) {
return NULL;
}
return req;
}
{
struct tevent_req *new_subreq;
struct tevent_req);
struct be_resolve_server_state);
int ret;
return;
goto fail;
}
/* FIXME: make the timeout configurable */
timeout);
goto fail;
}
}
return;
fail:
}
struct be_resolve_server_state *state,
struct tevent_req **new_subreq)
{
struct be_svc_callback *callback;
switch (ret) {
case EOK:
return EFAULT;
}
break;
case ENOENT:
/* all servers have been tried and none
* was found good, go offline */
return EIO;
default:
/* mark server as bad and retry */
return EFAULT;
}
("Couldn't resolve server (%s), resolver returned (%d)\n",
return EIO;
}
/* now try next one */
if (!subreq) {
return ENOMEM;
}
if (new_subreq) {
*new_subreq = subreq;
}
return EAGAIN;
}
/* all fine we got the server */
("The fail over cycled through all available servers\n"));
return ENOENT;
}
struct resolv_hostent *srvaddr;
char ipaddr[128];
if (!srvaddr) {
("FATAL: No hostent available for server (%s)\n",
return EFAULT;
}
ipaddr, 128);
}
/* now call all svc callbacks if server changed or if it is explicitly
* requested or if the server is the same but changed status since last time*/
}
}
return EOK;
}
{
struct be_resolve_server_state);
if (srv) {
}
return EOK;
}
{
struct be_svc_data *svc;
if (svc) {
}
}
const char *service_name)
{
struct be_svc_data *svc;
return ENOENT;
}
svc->run_callbacks = true;
return EOK;
}
{
}
const char *service_name,
enum port_status status)
{
struct be_svc_data *be_svc;
("No service associated with name %s\n", service_name));
return;
}
("The server %p is not valid anymore, cannot set its status\n",
server));
return;
}
/* Now we know that the server is valid */
if (status == PORT_WORKING) {
/* We were successful in connecting to the server. Cycle through all
* available servers next time */
}
}
/* Resolver back end interface */
static struct dp_option dp_res_default_opts[] = {
};
struct confdb_ctx *cdb,
const char *conf_path)
{
const char *str_family;
return ret;
}
} else {
return EINVAL;
}
return EOK;
}
{
return EOK;
}
return ENOMEM;
}
return ret;
}
return ret;
}
return EOK;
}