Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 704995 Details for
Bug 910938
CVE-2013-0287 sssd: simple access provider flaw prevents intended ACL use when client to an AD provider
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
[PATCH 2/5] Split the data provider interface into its own module
0002-Split-the-data-provider-interface-into-its-own-modul.patch (text/plain), 56.26 KB, created by
Jakub Hrozek
on 2013-03-04 14:01:51 UTC
(
hide
)
Description:
[PATCH 2/5] Split the data provider interface into its own module
Filename:
MIME Type:
Creator:
Jakub Hrozek
Created:
2013-03-04 14:01:51 UTC
Size:
56.26 KB
patch
obsolete
>From b02d9279ba5838613ef6682dec89098501f015ee Mon Sep 17 00:00:00 2001 >From: Jakub Hrozek <jhrozek@redhat.com> >Date: Fri, 1 Mar 2013 23:07:48 +0100 >Subject: [PATCH 2/5] Split the data provider interface into its own module > >--- > Makefile.am | 1 + > src/providers/data_provider_be.c | 758 +------------------------------------ > src/providers/data_provider_be.h | 41 ++ > src/providers/data_provider_srv.c | 767 ++++++++++++++++++++++++++++++++++++++ > 4 files changed, 820 insertions(+), 747 deletions(-) > create mode 100644 src/providers/data_provider_be.h > create mode 100644 src/providers/data_provider_srv.c > >diff --git a/Makefile.am b/Makefile.am >index 4ff02b8e7f65876c6d42217e955053f420111132..e0010d85fb7fe991cce84267cd6da2df6780ca3b 100644 >--- a/Makefile.am >+++ b/Makefile.am >@@ -653,6 +653,7 @@ sssd_pac_LDADD = \ > > sssd_be_SOURCES = \ > src/providers/data_provider_be.c \ >+ src/providers/data_provider_srv.c \ > src/providers/data_provider_fo.c \ > src/providers/data_provider_opts.c \ > src/providers/data_provider_callbacks.c \ >diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c >index c1feafd77fbb6ee6c417946ed50ce78fe4d06e83..f39158829fbb509dee811fbe8a23d529883f4dd8 100644 >--- a/src/providers/data_provider_be.c >+++ b/src/providers/data_provider_be.c >@@ -29,12 +29,10 @@ > #include <string.h> > #include <sys/time.h> > #include <errno.h> >-#include <dlfcn.h> > > #include <security/pam_appl.h> > #include <security/pam_modules.h> > >-#include "popt.h" > #include "util/util.h" > #include "confdb/confdb.h" > #include "db/sysdb.h" >@@ -48,77 +46,6 @@ > > #define MSG_TARGET_NO_CONFIGURED "sssd_be: The requested target is not configured" > >-#define ACCESS_PERMIT "permit" >-#define ACCESS_DENY "deny" >-#define NO_PROVIDER "none" >- >-static int data_provider_res_init(DBusMessage *message, >- struct sbus_connection *conn); >-static int data_provider_go_offline(DBusMessage *message, >- struct sbus_connection *conn); >-static int data_provider_reset_offline(DBusMessage *message, >- struct sbus_connection *conn); >-static int data_provider_logrotate(DBusMessage *message, >- struct sbus_connection *conn); >- >-struct sbus_method monitor_be_methods[] = { >- { MON_CLI_METHOD_PING, monitor_common_pong }, >- { MON_CLI_METHOD_RES_INIT, data_provider_res_init }, >- { MON_CLI_METHOD_OFFLINE, data_provider_go_offline }, >- { MON_CLI_METHOD_RESET_OFFLINE, data_provider_reset_offline }, >- { MON_CLI_METHOD_ROTATE, data_provider_logrotate }, >- { NULL, NULL } >-}; >- >-struct sbus_interface monitor_be_interface = { >- MONITOR_INTERFACE, >- MONITOR_PATH, >- SBUS_DEFAULT_VTABLE, >- monitor_be_methods, >- NULL >-}; >- >-static int client_registration(DBusMessage *message, struct sbus_connection *conn); >-static int be_get_account_info(DBusMessage *message, struct sbus_connection *conn); >-static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn); >-static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn); >-static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn); >-static int be_host_handler(DBusMessage *message, struct sbus_connection *conn); >-static int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn); >- >-struct sbus_method be_methods[] = { >- { DP_METHOD_REGISTER, client_registration }, >- { DP_METHOD_GETACCTINFO, be_get_account_info }, >- { DP_METHOD_PAMHANDLER, be_pam_handler }, >- { DP_METHOD_SUDOHANDLER, be_sudo_handler }, >- { DP_METHOD_AUTOFSHANDLER, be_autofs_handler }, >- { DP_METHOD_HOSTHANDLER, be_host_handler }, >- { DP_METHOD_GETDOMAINS, be_get_subdomains }, >- { NULL, NULL } >-}; >- >-struct sbus_interface be_interface = { >- DP_INTERFACE, >- DP_PATH, >- SBUS_DEFAULT_VTABLE, >- be_methods, >- NULL >-}; >- >-static struct bet_data bet_data[] = { >- {BET_NULL, NULL, NULL}, >- {BET_ID, CONFDB_DOMAIN_ID_PROVIDER, "sssm_%s_id_init"}, >- {BET_AUTH, CONFDB_DOMAIN_AUTH_PROVIDER, "sssm_%s_auth_init"}, >- {BET_ACCESS, CONFDB_DOMAIN_ACCESS_PROVIDER, "sssm_%s_access_init"}, >- {BET_CHPASS, CONFDB_DOMAIN_CHPASS_PROVIDER, "sssm_%s_chpass_init"}, >- {BET_SUDO, CONFDB_DOMAIN_SUDO_PROVIDER, "sssm_%s_sudo_init"}, >- {BET_AUTOFS, CONFDB_DOMAIN_AUTOFS_PROVIDER, "sssm_%s_autofs_init"}, >- {BET_SELINUX, CONFDB_DOMAIN_SELINUX_PROVIDER, "sssm_%s_selinux_init"}, >- {BET_HOSTID, CONFDB_DOMAIN_HOSTID_PROVIDER, "sssm_%s_hostid_init"}, >- {BET_SUBDOMAINS, CONFDB_DOMAIN_SUBDOMAINS_PROVIDER, "sssm_%s_subdomains_init"}, >- {BET_MAX, NULL, NULL} >-}; >- > #define REQ_PHASE_ACCESS 0 > #define REQ_PHASE_SELINUX 1 > >@@ -422,7 +349,7 @@ done: > talloc_free(req); > } > >-static int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn) >+int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn) > { > struct be_subdom_req *req; > struct be_req *be_req = NULL; >@@ -793,7 +720,7 @@ split_name_extended(TALLOC_CTX *mem_ctx, > return EOK; > } > >-static int be_get_account_info(DBusMessage *message, struct sbus_connection *conn) >+int be_get_account_info(DBusMessage *message, struct sbus_connection *conn) > { > struct be_acct_req *req; > struct be_req *be_req; >@@ -1065,7 +992,7 @@ done: > talloc_free(req); > } > >-static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn) >+int be_pam_handler(DBusMessage *message, struct sbus_connection *conn) > { > DBusError dbus_error; > DBusMessage *reply; >@@ -1235,7 +1162,7 @@ static void be_sudo_handler_callback(struct be_req *req, > talloc_free(req); > } > >-static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn) >+int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn) > { > DBusError dbus_error; > DBusMessage *reply = NULL; >@@ -1411,7 +1338,7 @@ static void be_autofs_handler_callback(struct be_req *req, > int errnum, > const char *errstr); > >-static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn) >+int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn) > { > DBusError dbus_error; > DBusMessage *reply = NULL; >@@ -1652,7 +1579,7 @@ static void be_autofs_handler_callback(struct be_req *req, > talloc_free(req); > } > >-static int be_host_handler(DBusMessage *message, struct sbus_connection *conn) >+int be_host_handler(DBusMessage *message, struct sbus_connection *conn) > { > struct be_host_req *req; > struct be_req *be_req; >@@ -1839,8 +1766,8 @@ static int be_client_destructor(void *ctx) > return 0; > } > >-static int client_registration(DBusMessage *message, >- struct sbus_connection *conn) >+int be_client_registration(DBusMessage *message, >+ struct sbus_connection *conn) > { > dbus_uint16_t version = DATA_PROVIDER_VERSION; > struct be_client *becli; >@@ -1970,7 +1897,7 @@ done: > return; > } > >-static void check_if_online(struct be_ctx *ctx) >+void be_check_if_online(struct be_ctx *ctx) > { > int ret; > struct be_req *be_req = NULL; >@@ -2026,86 +1953,7 @@ failed: > return; > } > >-static void init_timeout(struct tevent_context *ev, >- struct tevent_timer *te, >- struct timeval t, void *ptr) >-{ >- struct be_client *becli; >- >- DEBUG(2, ("Client timed out before Identification [%p]!\n", te)); >- >- becli = talloc_get_type(ptr, struct be_client); >- >- sbus_disconnect(becli->conn); >- talloc_zfree(becli); >-} >- >-static int be_client_init(struct sbus_connection *conn, void *data) >-{ >- struct be_ctx *bectx; >- struct be_client *becli; >- struct timeval tv; >- >- bectx = talloc_get_type(data, struct be_ctx); >- >- /* hang off this memory to the connection so that when the connection >- * is freed we can potentially call a destructor */ >- >- becli = talloc(conn, struct be_client); >- if (!becli) { >- DEBUG(0,("Out of memory?!\n")); >- talloc_zfree(conn); >- return ENOMEM; >- } >- becli->bectx = bectx; >- becli->conn = conn; >- becli->initialized = false; >- >- /* 5 seconds should be plenty */ >- tv = tevent_timeval_current_ofs(5, 0); >- >- becli->timeout = tevent_add_timer(bectx->ev, becli, >- tv, init_timeout, becli); >- if (!becli->timeout) { >- DEBUG(0,("Out of memory?!\n")); >- talloc_zfree(conn); >- return ENOMEM; >- } >- DEBUG(4, ("Set-up Backend ID timeout [%p]\n", becli->timeout)); >- >- /* Attach the client context to the connection context, so that it is >- * always available when we need to manage the connection. */ >- sbus_conn_set_private_data(conn, becli); >- >- return EOK; >-} >- >-/* be_srv_init >- * set up per-domain sbus channel */ >-static int be_srv_init(struct be_ctx *ctx) >-{ >- char *sbus_address; >- int ret; >- >- /* Set up SBUS connection to the monitor */ >- ret = dp_get_sbus_address(ctx, &sbus_address, ctx->domain->name); >- if (ret != EOK) { >- DEBUG(0, ("Could not get sbus backend address.\n")); >- return ret; >- } >- >- ret = sbus_new_server(ctx, ctx->ev, sbus_address, >- &be_interface, true, &ctx->sbus_srv, >- be_client_init, ctx); >- if (ret != EOK) { >- DEBUG(0, ("Could not set up sbus server.\n")); >- return ret; >- } >- >- return EOK; >-} >- >-static void be_target_access_permit(struct be_req *be_req) >+void be_target_access_permit(struct be_req *be_req) > { > struct pam_data *pd = > talloc_get_type(be_req_get_data(be_req), struct pam_data); >@@ -2115,13 +1963,7 @@ static void be_target_access_permit(struct be_req *be_req) > be_req_terminate(be_req, DP_ERR_OK, PAM_SUCCESS, NULL); > } > >-static struct bet_ops be_target_access_permit_ops = { >- .check_online = NULL, >- .handler = be_target_access_permit, >- .finalize = NULL >-}; >- >-static void be_target_access_deny(struct be_req *be_req) >+void be_target_access_deny(struct be_req *be_req) > { > struct pam_data *pd = > talloc_get_type(be_req_get_data(be_req), struct pam_data); >@@ -2130,581 +1972,3 @@ static void be_target_access_deny(struct be_req *be_req) > pd->pam_status = PAM_PERM_DENIED; > be_req_terminate(be_req, DP_ERR_OK, PAM_PERM_DENIED, NULL); > } >- >-static struct bet_ops be_target_access_deny_ops = { >- .check_online = NULL, >- .handler = be_target_access_deny, >- .finalize = NULL >-}; >- >-static int load_backend_module(struct be_ctx *ctx, >- enum bet_type bet_type, >- struct bet_info *bet_info, >- const char *default_mod_name) >-{ >- TALLOC_CTX *tmp_ctx; >- int ret = EINVAL; >- bool already_loaded = false; >- int lb=0; >- char *mod_name = NULL; >- char *path = NULL; >- void *handle; >- char *mod_init_fn_name = NULL; >- bet_init_fn_t mod_init_fn = NULL; >- >- (*bet_info).bet_type = bet_type; >- (*bet_info).mod_name = NULL; >- (*bet_info).bet_ops = NULL; >- (*bet_info).pvt_bet_data = NULL; >- >- if (bet_type <= BET_NULL || bet_type >= BET_MAX || >- bet_type != bet_data[bet_type].bet_type) { >- DEBUG(2, ("invalid bet_type or bet_data corrupted.\n")); >- return EINVAL; >- } >- >- tmp_ctx = talloc_new(ctx); >- if (!tmp_ctx) { >- DEBUG(7, ("talloc_new failed.\n")); >- return ENOMEM; >- } >- >- ret = confdb_get_string(ctx->cdb, tmp_ctx, ctx->conf_path, >- bet_data[bet_type].option_name, NULL, >- &mod_name); >- if (ret != EOK) { >- ret = EFAULT; >- goto done; >- } >- if (!mod_name) { >- if (default_mod_name != NULL) { >- DEBUG(5, ("no module name found in confdb, using [%s].\n", >- default_mod_name)); >- mod_name = talloc_strdup(ctx, default_mod_name); >- } else { >- ret = ENOENT; >- goto done; >- } >- } >- >- if (strcasecmp(mod_name, NO_PROVIDER) == 0) { >- ret = ENOENT; >- goto done; >- } >- >- if (bet_type == BET_ACCESS) { >- if (strcmp(mod_name, ACCESS_PERMIT) == 0) { >- (*bet_info).bet_ops = &be_target_access_permit_ops; >- (*bet_info).pvt_bet_data = NULL; >- (*bet_info).mod_name = talloc_strdup(ctx, ACCESS_PERMIT); >- >- ret = EOK; >- goto done; >- } >- if (strcmp(mod_name, ACCESS_DENY) == 0) { >- (*bet_info).bet_ops = &be_target_access_deny_ops; >- (*bet_info).pvt_bet_data = NULL; >- (*bet_info).mod_name = talloc_strdup(ctx, ACCESS_DENY); >- >- ret = EOK; >- goto done; >- } >- } >- >- mod_init_fn_name = talloc_asprintf(tmp_ctx, >- bet_data[bet_type].mod_init_fn_name_fmt, >- mod_name); >- if (mod_init_fn_name == NULL) { >- DEBUG(7, ("talloc_asprintf failed\n")); >- ret = ENOMEM; >- goto done; >- } >- >- >- lb = 0; >- while(ctx->loaded_be[lb].be_name != NULL) { >- if (strncmp(ctx->loaded_be[lb].be_name, mod_name, >- strlen(mod_name)) == 0) { >- DEBUG(7, ("Backend [%s] already loaded.\n", mod_name)); >- already_loaded = true; >- break; >- } >- >- ++lb; >- if (lb >= BET_MAX) { >- DEBUG(2, ("Backend context corrupted.\n")); >- ret = EINVAL; >- goto done; >- } >- } >- >- if (!already_loaded) { >- path = talloc_asprintf(tmp_ctx, "%s/libsss_%s.so", >- DATA_PROVIDER_PLUGINS_PATH, mod_name); >- if (!path) { >- ret = ENOMEM; >- goto done; >- } >- >- DEBUG(7, ("Loading backend [%s] with path [%s].\n", mod_name, path)); >- handle = dlopen(path, RTLD_NOW); >- if (!handle) { >- DEBUG(0, ("Unable to load %s module with path (%s), error: %s\n", >- mod_name, path, dlerror())); >- ret = ELIBACC; >- goto done; >- } >- >- ctx->loaded_be[lb].be_name = talloc_strdup(ctx, mod_name); >- ctx->loaded_be[lb].handle = handle; >- } >- >- mod_init_fn = (bet_init_fn_t)dlsym(ctx->loaded_be[lb].handle, >- mod_init_fn_name); >- if (mod_init_fn == NULL) { >- if (default_mod_name != NULL && >- strcmp(default_mod_name, mod_name) == 0 ) { >- /* If the default is used and fails we indicate this to the caller >- * by returning ENOENT. Ths way the caller can decide how to >- * handle the different types of error conditions. */ >- ret = ENOENT; >- } else { >- DEBUG(0, ("Unable to load init fn %s from module %s, error: %s\n", >- mod_init_fn_name, mod_name, dlerror())); >- ret = ELIBBAD; >- } >- goto done; >- } >- >- ret = mod_init_fn(ctx, &(*bet_info).bet_ops, &(*bet_info).pvt_bet_data); >- if (ret != EOK) { >- DEBUG(0, ("Error (%d) in module (%s) initialization (%s)!\n", >- ret, mod_name, mod_init_fn_name)); >- goto done; >- } >- >- (*bet_info).mod_name = talloc_strdup(ctx, mod_name); >- >- ret = EOK; >- >-done: >- talloc_free(tmp_ctx); >- return ret; >-} >- >-static void signal_be_offline(struct tevent_context *ev, >- struct tevent_signal *se, >- int signum, >- int count, >- void *siginfo, >- void *private_data) >-{ >- struct be_ctx *ctx = talloc_get_type(private_data, struct be_ctx); >- be_mark_offline(ctx); >-} >- >-int be_process_init_sudo(struct be_ctx *be_ctx) >-{ >- TALLOC_CTX *tmp_ctx = NULL; >- char **services = NULL; >- char *provider = NULL; >- bool responder_enabled = false; >- int i; >- int ret; >- >- tmp_ctx = talloc_new(NULL); >- if (tmp_ctx == NULL) { >- DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n")); >- return ENOMEM; >- } >- >- ret = confdb_get_string_as_list(be_ctx->cdb, tmp_ctx, >- CONFDB_MONITOR_CONF_ENTRY, >- CONFDB_MONITOR_ACTIVE_SERVICES, &services); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, ("Unable to read from confdb [%d]: %s\n", >- ret, strerror(ret))); >- goto done; >- } >- >- for (i = 0; services[i] != NULL; i++) { >- if (strcmp(services[i], "sudo") == 0) { >- responder_enabled = true; >- break; >- } >- } >- >- ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path, >- CONFDB_DOMAIN_SUDO_PROVIDER, NULL, &provider); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, ("Unable to read from confdb [%d]: %s\n", >- ret, strerror(ret))); >- goto done; >- } >- >- if (!responder_enabled && provider == NULL) { >- /* provider is not set explicitly */ >- DEBUG(SSSDBG_TRACE_FUNC, >- ("SUDO is not listed in services, disabling SUDO module.\n")); >- ret = ENOENT; >- goto done; >- } >- >- if (!responder_enabled && provider != NULL >- && strcmp(provider, NO_PROVIDER) != 0) { >- /* provider is set but responder is disabled */ >- DEBUG(SSSDBG_MINOR_FAILURE, ("SUDO provider is set, but it is not " >- "listed in active services. SUDO support will not work!\n")); >- } >- >- ret = load_backend_module(be_ctx, BET_SUDO, &be_ctx->bet_info[BET_SUDO], >- be_ctx->bet_info[BET_ID].mod_name); >- >-done: >- talloc_free(tmp_ctx); >- return ret; >-} >- >-int be_process_init(TALLOC_CTX *mem_ctx, >- const char *be_domain, >- struct tevent_context *ev, >- struct confdb_ctx *cdb) >-{ >- struct be_ctx *ctx; >- struct tevent_signal *tes; >- int ret; >- >- ctx = talloc_zero(mem_ctx, struct be_ctx); >- if (!ctx) { >- DEBUG(0, ("fatal error initializing be_ctx\n")); >- return ENOMEM; >- } >- ctx->ev = ev; >- ctx->cdb = cdb; >- ctx->identity = talloc_asprintf(ctx, "%%BE_%s", be_domain); >- ctx->conf_path = talloc_asprintf(ctx, CONFDB_DOMAIN_PATH_TMPL, be_domain); >- if (!ctx->identity || !ctx->conf_path) { >- DEBUG(0, ("Out of memory!?\n")); >- ret = ENOMEM; >- goto fail; >- } >- >- ret = be_init_failover(ctx); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("fatal error initializing failover context\n")); >- goto fail; >- } >- >- ret = sssd_domain_init(ctx, cdb, be_domain, DB_PATH, &ctx->domain); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, ("fatal error opening cache database\n")); >- goto fail; >- } >- >- ret = sss_monitor_init(ctx, ctx->ev, &monitor_be_interface, >- ctx->identity, DATA_PROVIDER_VERSION, >- ctx, &ctx->mon_conn); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("fatal error setting up monitor bus\n")); >- goto fail; >- } >- >- /* We need this for subdomains support, as they have to store fully >- * qualified user and group names for now */ >- ret = sss_names_init(ctx->domain, cdb, >- ctx->domain->name, &ctx->domain->names); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("fatal error setting fully qualified name format for %s\n", >- ctx->domain->name)); >- goto fail; >- } >- >- ret = be_srv_init(ctx); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, ("fatal error setting up server bus\n")); >- goto fail; >- } >- >- ret = load_backend_module(ctx, BET_ID, >- &ctx->bet_info[BET_ID], NULL); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("fatal error initializing data providers\n")); >- goto fail; >- } >- DEBUG(SSSDBG_TRACE_INTERNAL, >- ("ID backend target successfully loaded from provider [%s].\n", >- ctx->bet_info[BET_ID].mod_name)); >- >- ret = load_backend_module(ctx, BET_AUTH, >- &ctx->bet_info[BET_AUTH], >- ctx->bet_info[BET_ID].mod_name); >- if (ret != EOK) { >- if (ret != ENOENT) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("fatal error initializing data providers\n")); >- goto fail; >- } >- DEBUG(SSSDBG_MINOR_FAILURE, >- ("No authentication module provided for [%s] !!\n", >- be_domain)); >- } else { >- DEBUG(SSSDBG_TRACE_INTERNAL, >- ("AUTH backend target successfully loaded " >- "from provider [%s].\n", ctx->bet_info[BET_AUTH].mod_name)); >- } >- >- ret = load_backend_module(ctx, BET_ACCESS, &ctx->bet_info[BET_ACCESS], >- ACCESS_PERMIT); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("Failed to setup ACCESS backend.\n")); >- goto fail; >- } >- DEBUG(SSSDBG_TRACE_INTERNAL, >- ("ACCESS backend target successfully loaded " >- "from provider [%s].\n", ctx->bet_info[BET_ACCESS].mod_name)); >- >- ret = load_backend_module(ctx, BET_CHPASS, >- &ctx->bet_info[BET_CHPASS], >- ctx->bet_info[BET_AUTH].mod_name); >- if (ret != EOK) { >- if (ret != ENOENT) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("fatal error initializing data providers\n")); >- goto fail; >- } >- DEBUG(SSSDBG_MINOR_FAILURE, >- ("No change password module provided for [%s] !!\n", >- be_domain)); >- } else { >- DEBUG(SSSDBG_TRACE_INTERNAL, >- ("CHPASS backend target successfully loaded " >- "from provider [%s].\n", ctx->bet_info[BET_CHPASS].mod_name)); >- } >- >- ret = be_process_init_sudo(ctx); >- if (ret != EOK) { >- if (ret != ENOENT) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("fatal error initializing data providers\n")); >- goto fail; >- } >- DEBUG(SSSDBG_MINOR_FAILURE, >- ("No SUDO module provided for [%s] !!\n", be_domain)); >- } else { >- DEBUG(SSSDBG_TRACE_INTERNAL, >- ("SUDO backend target successfully loaded " >- "from provider [%s].\n", ctx->bet_info[BET_SUDO].mod_name)); >- } >- >- ret = load_backend_module(ctx, BET_AUTOFS, >- &ctx->bet_info[BET_AUTOFS], >- ctx->bet_info[BET_ID].mod_name); >- if (ret != EOK) { >- if (ret != ENOENT) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("fatal error initializing data providers\n")); >- goto fail; >- } >- DEBUG(SSSDBG_MINOR_FAILURE, >- ("No autofs module provided for [%s] !!\n", be_domain)); >- } else { >- DEBUG(SSSDBG_TRACE_INTERNAL, >- ("autofs backend target successfully loaded " >- "from provider [%s].\n", ctx->bet_info[BET_AUTOFS].mod_name)); >- } >- >- ret = load_backend_module(ctx, BET_SELINUX, >- &ctx->bet_info[BET_SELINUX], >- ctx->bet_info[BET_ID].mod_name); >- if (ret != EOK) { >- if (ret != ENOENT) { >- DEBUG(SSSDBG_FATAL_FAILURE, ("fatal error initializing data providers\n")); >- goto fail; >- } >- DEBUG(SSSDBG_CRIT_FAILURE, ("No selinux module provided for [%s] !!\n", >- be_domain)); >- } else { >- DEBUG(SSSDBG_TRACE_ALL, ("selinux backend target successfully loaded " >- "from provider [%s].\n", ctx->bet_info[BET_SELINUX].mod_name)); >- } >- >- ret = load_backend_module(ctx, BET_HOSTID, >- &ctx->bet_info[BET_HOSTID], >- ctx->bet_info[BET_ID].mod_name); >- if (ret != EOK) { >- if (ret != ENOENT) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("fatal error initializing data providers\n")); >- goto fail; >- } >- DEBUG(SSSDBG_CRIT_FAILURE, >- ("No host info module provided for [%s] !!\n", be_domain)); >- } else { >- DEBUG(SSSDBG_TRACE_ALL, >- ("HOST backend target successfully loaded from provider [%s].\n", >- ctx->bet_info[BET_HOSTID].mod_name)); >- } >- >- ret = load_backend_module(ctx, BET_SUBDOMAINS, >- &ctx->bet_info[BET_SUBDOMAINS], >- ctx->bet_info[BET_ID].mod_name); >- if (ret != EOK) { >- DEBUG(SSSDBG_CRIT_FAILURE, ("Subdomains are not supported for [%s] !!\n", be_domain)); >- } else { >- DEBUG(SSSDBG_TRACE_ALL, ("Get-Subdomains backend target successfully loaded " >- "from provider [%s].\n", >- ctx->bet_info[BET_SUBDOMAINS].mod_name)); >- } >- >- /* Handle SIGUSR1 to force offline behavior */ >- BlockSignals(false, SIGUSR1); >- tes = tevent_add_signal(ctx->ev, ctx, SIGUSR1, 0, >- signal_be_offline, ctx); >- if (tes == NULL) { >- ret = EIO; >- goto fail; >- } >- >- ret = sss_sigchld_init(ctx, ctx->ev, &ctx->sigchld_ctx); >- if (ret != EOK) { >- DEBUG(SSSDBG_FATAL_FAILURE, >- ("Could not initialize sigchld context: [%s]\n", >- strerror(ret))); >- goto fail; >- } >- >- return EOK; >- >-fail: >- talloc_free(ctx); >- return ret; >-} >- >-int main(int argc, const char *argv[]) >-{ >- int opt; >- poptContext pc; >- char *be_domain = NULL; >- char *srv_name = NULL; >- struct main_context *main_ctx; >- char *confdb_path; >- int ret; >- >- struct poptOption long_options[] = { >- POPT_AUTOHELP >- SSSD_MAIN_OPTS >- {"domain", 0, POPT_ARG_STRING, &be_domain, 0, >- _("Domain of the information provider (mandatory)"), NULL }, >- POPT_TABLEEND >- }; >- >- /* Set debug level to invalid value so we can deside if -d 0 was used. */ >- debug_level = SSSDBG_INVALID; >- >- pc = poptGetContext(argv[0], argc, argv, long_options, 0); >- while((opt = poptGetNextOpt(pc)) != -1) { >- switch(opt) { >- default: >- fprintf(stderr, "\nInvalid option %s: %s\n\n", >- poptBadOption(pc, 0), poptStrerror(opt)); >- poptPrintUsage(pc, stderr, 0); >- return 1; >- } >- } >- >- if (be_domain == NULL) { >- fprintf(stderr, "\nMissing option, --domain is a mandatory option.\n\n"); >- poptPrintUsage(pc, stderr, 0); >- return 1; >- } >- >- poptFreeContext(pc); >- >- DEBUG_INIT(debug_level); >- >- /* set up things like debug , signals, daemonization, etc... */ >- debug_log_file = talloc_asprintf(NULL, "sssd_%s", be_domain); >- if (!debug_log_file) return 2; >- >- srv_name = talloc_asprintf(NULL, "sssd[be[%s]]", be_domain); >- if (!srv_name) return 2; >- >- confdb_path = talloc_asprintf(NULL, CONFDB_DOMAIN_PATH_TMPL, be_domain); >- if (!confdb_path) return 2; >- >- ret = server_setup(srv_name, 0, confdb_path, &main_ctx); >- if (ret != EOK) { >- DEBUG(0, ("Could not set up mainloop [%d]\n", ret)); >- return 2; >- } >- >- ret = die_if_parent_died(); >- if (ret != EOK) { >- /* This is not fatal, don't return */ >- DEBUG(2, ("Could not set up to exit when parent process does\n")); >- } >- >- ret = be_process_init(main_ctx, >- be_domain, >- main_ctx->event_ctx, >- main_ctx->confdb_ctx); >- if (ret != EOK) { >- DEBUG(0, ("Could not initialize backend [%d]\n", ret)); >- return 3; >- } >- >- DEBUG(SSSDBG_TRACE_FUNC, ("Backend provider (%s) started!\n", be_domain)); >- >- /* loop on main */ >- server_loop(main_ctx); >- >- return 0; >-} >- >-static int data_provider_res_init(DBusMessage *message, >- struct sbus_connection *conn) >-{ >- struct be_ctx *be_ctx; >- be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); >- >- resolv_reread_configuration(); >- check_if_online(be_ctx); >- >- return monitor_common_res_init(message, conn); >-} >- >-static int data_provider_go_offline(DBusMessage *message, >- struct sbus_connection *conn) >-{ >- struct be_ctx *be_ctx; >- be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); >- be_mark_offline(be_ctx); >- return monitor_common_pong(message, conn); >-} >- >-static int data_provider_reset_offline(DBusMessage *message, >- struct sbus_connection *conn) >-{ >- struct be_ctx *be_ctx; >- be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); >- check_if_online(be_ctx); >- return monitor_common_pong(message, conn); >-} >- >-static int data_provider_logrotate(DBusMessage *message, >- struct sbus_connection *conn) >-{ >- errno_t ret; >- struct be_ctx *be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), >- struct be_ctx); >- >- ret = monitor_common_rotate_logs(be_ctx->cdb, be_ctx->conf_path); >- if (ret != EOK) return ret; >- >- return monitor_common_pong(message, conn); >-} >diff --git a/src/providers/data_provider_be.h b/src/providers/data_provider_be.h >new file mode 100644 >index 0000000000000000000000000000000000000000..c7e68535bda7eac4c468431da48a734eff701297 >--- /dev/null >+++ b/src/providers/data_provider_be.h >@@ -0,0 +1,41 @@ >+/* >+ SSSD >+ >+ Data Provider, private header file >+ >+ Copyright (C) Simo Sorce <ssorce@redhat.com> 2008 >+ >+ This program is free software; you can redistribute it and/or modify >+ 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/>. >+*/ >+ >+#ifndef __DATA_PROVIDER_BE_H_ >+#define __DATA_PROVIDER_BE_H_ >+ >+/* Provider handlers */ >+int be_client_registration(DBusMessage *message, struct sbus_connection *conn); >+int be_get_account_info(DBusMessage *message, struct sbus_connection *conn); >+int be_pam_handler(DBusMessage *message, struct sbus_connection *conn); >+int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn); >+int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn); >+int be_host_handler(DBusMessage *message, struct sbus_connection *conn); >+int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn); >+ >+/* Internal requests */ >+void be_check_if_online(struct be_ctx *ctx); >+ >+/* Built in access provider handler */ >+void be_target_access_permit(struct be_req *be_req); >+void be_target_access_deny(struct be_req *be_req); >+ >+#endif /* __DATA_PROVIDER_BE_H_ */ >diff --git a/src/providers/data_provider_srv.c b/src/providers/data_provider_srv.c >new file mode 100644 >index 0000000000000000000000000000000000000000..e0aba7f5ebe21183c80ab44614a4e5fc9dade2ff >--- /dev/null >+++ b/src/providers/data_provider_srv.c >@@ -0,0 +1,767 @@ >+/* >+ SSSD >+ >+ Data Provider Process >+ >+ Copyright (C) Simo Sorce <ssorce@redhat.com> 2008 >+ >+ This program is free software; you can redistribute it and/or modify >+ 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 <errno.h> >+#include <popt.h> >+#include <tevent.h> >+#include <dlfcn.h> >+ >+#include "util/util.h" >+#include "monitor/monitor_interfaces.h" >+#include "providers/dp_backend.h" >+#include "providers/data_provider_be.h" >+#include "confdb/confdb.h" >+ >+#define ACCESS_PERMIT "permit" >+#define ACCESS_DENY "deny" >+#define NO_PROVIDER "none" >+ >+static int data_provider_res_init(DBusMessage *message, >+ struct sbus_connection *conn); >+static int data_provider_go_offline(DBusMessage *message, >+ struct sbus_connection *conn); >+static int data_provider_reset_offline(DBusMessage *message, >+ struct sbus_connection *conn); >+static int data_provider_logrotate(DBusMessage *message, >+ struct sbus_connection *conn); >+ >+static struct bet_data bet_data[] = { >+ {BET_NULL, NULL, NULL}, >+ {BET_ID, CONFDB_DOMAIN_ID_PROVIDER, "sssm_%s_id_init"}, >+ {BET_AUTH, CONFDB_DOMAIN_AUTH_PROVIDER, "sssm_%s_auth_init"}, >+ {BET_ACCESS, CONFDB_DOMAIN_ACCESS_PROVIDER, "sssm_%s_access_init"}, >+ {BET_CHPASS, CONFDB_DOMAIN_CHPASS_PROVIDER, "sssm_%s_chpass_init"}, >+ {BET_SUDO, CONFDB_DOMAIN_SUDO_PROVIDER, "sssm_%s_sudo_init"}, >+ {BET_AUTOFS, CONFDB_DOMAIN_AUTOFS_PROVIDER, "sssm_%s_autofs_init"}, >+ {BET_SELINUX, CONFDB_DOMAIN_SELINUX_PROVIDER, "sssm_%s_selinux_init"}, >+ {BET_HOSTID, CONFDB_DOMAIN_HOSTID_PROVIDER, "sssm_%s_hostid_init"}, >+ {BET_SUBDOMAINS, CONFDB_DOMAIN_SUBDOMAINS_PROVIDER, "sssm_%s_subdomains_init"}, >+ {BET_MAX, NULL, NULL} >+}; >+ >+struct sbus_method be_methods[] = { >+ { DP_METHOD_REGISTER, be_client_registration }, >+ { DP_METHOD_GETACCTINFO, be_get_account_info }, >+ { DP_METHOD_PAMHANDLER, be_pam_handler }, >+ { DP_METHOD_SUDOHANDLER, be_sudo_handler }, >+ { DP_METHOD_AUTOFSHANDLER, be_autofs_handler }, >+ { DP_METHOD_HOSTHANDLER, be_host_handler }, >+ { DP_METHOD_GETDOMAINS, be_get_subdomains }, >+ { NULL, NULL } >+}; >+ >+struct sbus_interface be_interface = { >+ DP_INTERFACE, >+ DP_PATH, >+ SBUS_DEFAULT_VTABLE, >+ be_methods, >+ NULL >+}; >+ >+struct sbus_method monitor_be_methods[] = { >+ { MON_CLI_METHOD_PING, monitor_common_pong }, >+ { MON_CLI_METHOD_RES_INIT, data_provider_res_init }, >+ { MON_CLI_METHOD_OFFLINE, data_provider_go_offline }, >+ { MON_CLI_METHOD_RESET_OFFLINE, data_provider_reset_offline }, >+ { MON_CLI_METHOD_ROTATE, data_provider_logrotate }, >+ { NULL, NULL } >+}; >+ >+struct sbus_interface monitor_be_interface = { >+ MONITOR_INTERFACE, >+ MONITOR_PATH, >+ SBUS_DEFAULT_VTABLE, >+ monitor_be_methods, >+ NULL >+}; >+ >+static struct bet_ops be_target_access_permit_ops = { >+ .check_online = NULL, >+ .handler = be_target_access_permit, >+ .finalize = NULL >+}; >+ >+static struct bet_ops be_target_access_deny_ops = { >+ .check_online = NULL, >+ .handler = be_target_access_deny, >+ .finalize = NULL >+}; >+ >+static int load_backend_module(struct be_ctx *ctx, >+ enum bet_type bet_type, >+ struct bet_info *bet_info, >+ const char *default_mod_name) >+{ >+ TALLOC_CTX *tmp_ctx; >+ int ret = EINVAL; >+ bool already_loaded = false; >+ int lb=0; >+ char *mod_name = NULL; >+ char *path = NULL; >+ void *handle; >+ char *mod_init_fn_name = NULL; >+ bet_init_fn_t mod_init_fn = NULL; >+ >+ (*bet_info).bet_type = bet_type; >+ (*bet_info).mod_name = NULL; >+ (*bet_info).bet_ops = NULL; >+ (*bet_info).pvt_bet_data = NULL; >+ >+ if (bet_type <= BET_NULL || bet_type >= BET_MAX || >+ bet_type != bet_data[bet_type].bet_type) { >+ DEBUG(SSSDBG_CRIT_FAILURE, >+ ("invalid bet_type or bet_data corrupted.\n")); >+ return EINVAL; >+ } >+ >+ tmp_ctx = talloc_new(ctx); >+ if (!tmp_ctx) { >+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new failed.\n")); >+ return ENOMEM; >+ } >+ >+ ret = confdb_get_string(ctx->cdb, tmp_ctx, ctx->conf_path, >+ bet_data[bet_type].option_name, NULL, >+ &mod_name); >+ if (ret != EOK) { >+ ret = EFAULT; >+ goto done; >+ } >+ if (!mod_name) { >+ if (default_mod_name != NULL) { >+ DEBUG(SSSDBG_CONF_SETTINGS, >+ ("no module name found in confdb, using [%s].\n", >+ default_mod_name)); >+ mod_name = talloc_strdup(ctx, default_mod_name); >+ } else { >+ ret = ENOENT; >+ goto done; >+ } >+ } >+ >+ if (strcasecmp(mod_name, NO_PROVIDER) == 0) { >+ ret = ENOENT; >+ goto done; >+ } >+ >+ if (bet_type == BET_ACCESS) { >+ if (strcmp(mod_name, ACCESS_PERMIT) == 0) { >+ (*bet_info).bet_ops = &be_target_access_permit_ops; >+ (*bet_info).pvt_bet_data = NULL; >+ (*bet_info).mod_name = talloc_strdup(ctx, ACCESS_PERMIT); >+ >+ ret = EOK; >+ goto done; >+ } >+ if (strcmp(mod_name, ACCESS_DENY) == 0) { >+ (*bet_info).bet_ops = &be_target_access_deny_ops; >+ (*bet_info).pvt_bet_data = NULL; >+ (*bet_info).mod_name = talloc_strdup(ctx, ACCESS_DENY); >+ >+ ret = EOK; >+ goto done; >+ } >+ } >+ >+ mod_init_fn_name = talloc_asprintf(tmp_ctx, >+ bet_data[bet_type].mod_init_fn_name_fmt, >+ mod_name); >+ if (mod_init_fn_name == NULL) { >+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_asprintf failed\n")); >+ ret = ENOMEM; >+ goto done; >+ } >+ >+ >+ lb = 0; >+ while(ctx->loaded_be[lb].be_name != NULL) { >+ if (strncmp(ctx->loaded_be[lb].be_name, mod_name, >+ strlen(mod_name)) == 0) { >+ DEBUG(SSSDBG_TRACE_LIBS, >+ ("Backend [%s] already loaded.\n", mod_name)); >+ already_loaded = true; >+ break; >+ } >+ >+ ++lb; >+ if (lb >= BET_MAX) { >+ DEBUG(SSSDBG_CRIT_FAILURE, ("Backend context corrupted.\n")); >+ ret = EINVAL; >+ goto done; >+ } >+ } >+ >+ if (!already_loaded) { >+ path = talloc_asprintf(tmp_ctx, "%s/libsss_%s.so", >+ DATA_PROVIDER_PLUGINS_PATH, mod_name); >+ if (!path) { >+ ret = ENOMEM; >+ goto done; >+ } >+ >+ DEBUG(SSSDBG_TRACE_LIBS, >+ ("Loading backend [%s] with path [%s].\n", mod_name, path)); >+ handle = dlopen(path, RTLD_NOW); >+ if (!handle) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("Unable to load %s module with path (%s), error: %s\n", >+ mod_name, path, dlerror())); >+ ret = ELIBACC; >+ goto done; >+ } >+ >+ ctx->loaded_be[lb].be_name = talloc_strdup(ctx, mod_name); >+ ctx->loaded_be[lb].handle = handle; >+ } >+ >+ mod_init_fn = (bet_init_fn_t)dlsym(ctx->loaded_be[lb].handle, >+ mod_init_fn_name); >+ if (mod_init_fn == NULL) { >+ if (default_mod_name != NULL && >+ strcmp(default_mod_name, mod_name) == 0 ) { >+ /* If the default is used and fails we indicate this to the caller >+ * by returning ENOENT. Ths way the caller can decide how to >+ * handle the different types of error conditions. */ >+ ret = ENOENT; >+ } else { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("Unable to load init fn %s from module %s, error: %s\n", >+ mod_init_fn_name, mod_name, dlerror())); >+ ret = ELIBBAD; >+ } >+ goto done; >+ } >+ >+ ret = mod_init_fn(ctx, &(*bet_info).bet_ops, &(*bet_info).pvt_bet_data); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("Error (%d) in module (%s) initialization (%s)!\n", >+ ret, mod_name, mod_init_fn_name)); >+ goto done; >+ } >+ >+ (*bet_info).mod_name = talloc_strdup(ctx, mod_name); >+ >+ ret = EOK; >+ >+done: >+ talloc_free(tmp_ctx); >+ return ret; >+} >+ >+static void init_timeout(struct tevent_context *ev, >+ struct tevent_timer *te, >+ struct timeval t, void *ptr) >+{ >+ struct be_client *becli; >+ >+ DEBUG(SSSDBG_CRIT_FAILURE, >+ ("Client timed out before Identification [%p]!\n", te)); >+ >+ becli = talloc_get_type(ptr, struct be_client); >+ >+ sbus_disconnect(becli->conn); >+ talloc_zfree(becli); >+} >+ >+static int be_client_init(struct sbus_connection *conn, void *data) >+{ >+ struct be_ctx *bectx; >+ struct be_client *becli; >+ struct timeval tv; >+ >+ bectx = talloc_get_type(data, struct be_ctx); >+ >+ /* hang off this memory to the connection so that when the connection >+ * is freed we can potentially call a destructor */ >+ >+ becli = talloc(conn, struct be_client); >+ if (!becli) { >+ DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory?!\n")); >+ talloc_zfree(conn); >+ return ENOMEM; >+ } >+ becli->bectx = bectx; >+ becli->conn = conn; >+ becli->initialized = false; >+ >+ /* 5 seconds should be plenty */ >+ tv = tevent_timeval_current_ofs(5, 0); >+ >+ becli->timeout = tevent_add_timer(bectx->ev, becli, >+ tv, init_timeout, becli); >+ if (!becli->timeout) { >+ DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory?!\n")); >+ talloc_zfree(conn); >+ return ENOMEM; >+ } >+ DEBUG(SSSDBG_CONF_SETTINGS, >+ ("Set-up Backend ID timeout [%p]\n", becli->timeout)); >+ >+ /* Attach the client context to the connection context, so that it is >+ * always available when we need to manage the connection. */ >+ sbus_conn_set_private_data(conn, becli); >+ >+ return EOK; >+} >+ >+/* be_srv_init >+ * set up per-domain sbus channel */ >+static int be_srv_init(struct be_ctx *ctx) >+{ >+ char *sbus_address; >+ int ret; >+ >+ /* Set up SBUS connection to the monitor */ >+ ret = dp_get_sbus_address(ctx, &sbus_address, ctx->domain->name); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, ("Could not get sbus backend address.\n")); >+ return ret; >+ } >+ >+ ret = sbus_new_server(ctx, ctx->ev, sbus_address, >+ &be_interface, true, &ctx->sbus_srv, >+ be_client_init, ctx); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, ("Could not set up sbus server.\n")); >+ return ret; >+ } >+ >+ return EOK; >+} >+ >+static void signal_be_offline(struct tevent_context *ev, >+ struct tevent_signal *se, >+ int signum, >+ int count, >+ void *siginfo, >+ void *private_data) >+{ >+ struct be_ctx *ctx = talloc_get_type(private_data, struct be_ctx); >+ be_mark_offline(ctx); >+} >+ >+static int be_process_init_sudo(struct be_ctx *be_ctx) >+{ >+ TALLOC_CTX *tmp_ctx = NULL; >+ char **services = NULL; >+ char *provider = NULL; >+ bool responder_enabled = false; >+ int i; >+ int ret; >+ >+ tmp_ctx = talloc_new(NULL); >+ if (tmp_ctx == NULL) { >+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n")); >+ return ENOMEM; >+ } >+ >+ ret = confdb_get_string_as_list(be_ctx->cdb, tmp_ctx, >+ CONFDB_MONITOR_CONF_ENTRY, >+ CONFDB_MONITOR_ACTIVE_SERVICES, &services); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, ("Unable to read from confdb [%d]: %s\n", >+ ret, strerror(ret))); >+ goto done; >+ } >+ >+ for (i = 0; services[i] != NULL; i++) { >+ if (strcmp(services[i], "sudo") == 0) { >+ responder_enabled = true; >+ break; >+ } >+ } >+ >+ ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path, >+ CONFDB_DOMAIN_SUDO_PROVIDER, NULL, &provider); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, ("Unable to read from confdb [%d]: %s\n", >+ ret, strerror(ret))); >+ goto done; >+ } >+ >+ if (!responder_enabled && provider == NULL) { >+ /* provider is not set explicitly */ >+ DEBUG(SSSDBG_TRACE_FUNC, >+ ("SUDO is not listed in services, disabling SUDO module.\n")); >+ ret = ENOENT; >+ goto done; >+ } >+ >+ if (!responder_enabled && provider != NULL >+ && strcmp(provider, NO_PROVIDER) != 0) { >+ /* provider is set but responder is disabled */ >+ DEBUG(SSSDBG_MINOR_FAILURE, ("SUDO provider is set, but it is not " >+ "listed in active services. SUDO support will not work!\n")); >+ } >+ >+ ret = load_backend_module(be_ctx, BET_SUDO, &be_ctx->bet_info[BET_SUDO], >+ be_ctx->bet_info[BET_ID].mod_name); >+ >+done: >+ talloc_free(tmp_ctx); >+ return ret; >+} >+ >+int be_process_init(TALLOC_CTX *mem_ctx, >+ const char *be_domain, >+ struct tevent_context *ev, >+ struct confdb_ctx *cdb) >+{ >+ struct be_ctx *ctx; >+ struct tevent_signal *tes; >+ int ret; >+ >+ ctx = talloc_zero(mem_ctx, struct be_ctx); >+ if (!ctx) { >+ DEBUG(SSSDBG_CRIT_FAILURE, ("fatal error initializing be_ctx\n")); >+ return ENOMEM; >+ } >+ ctx->ev = ev; >+ ctx->cdb = cdb; >+ ctx->identity = talloc_asprintf(ctx, "%%BE_%s", be_domain); >+ ctx->conf_path = talloc_asprintf(ctx, CONFDB_DOMAIN_PATH_TMPL, be_domain); >+ if (!ctx->identity || !ctx->conf_path) { >+ DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory!?\n")); >+ ret = ENOMEM; >+ goto fail; >+ } >+ >+ ret = be_init_failover(ctx); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("fatal error initializing failover context\n")); >+ goto fail; >+ } >+ >+ ret = sssd_domain_init(ctx, cdb, be_domain, DB_PATH, &ctx->domain); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, ("fatal error opening cache database\n")); >+ goto fail; >+ } >+ >+ ret = sss_monitor_init(ctx, ctx->ev, &monitor_be_interface, >+ ctx->identity, DATA_PROVIDER_VERSION, >+ ctx, &ctx->mon_conn); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("fatal error setting up monitor bus\n")); >+ goto fail; >+ } >+ >+ /* We need this for subdomains support, as they have to store fully >+ * qualified user and group names for now */ >+ ret = sss_names_init(ctx->domain, cdb, >+ ctx->domain->name, &ctx->domain->names); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("fatal error setting fully qualified name format for %s\n", >+ ctx->domain->name)); >+ goto fail; >+ } >+ >+ ret = be_srv_init(ctx); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, ("fatal error setting up server bus\n")); >+ goto fail; >+ } >+ >+ ret = load_backend_module(ctx, BET_ID, >+ &ctx->bet_info[BET_ID], NULL); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("fatal error initializing data providers\n")); >+ goto fail; >+ } >+ DEBUG(SSSDBG_TRACE_INTERNAL, >+ ("ID backend target successfully loaded from provider [%s].\n", >+ ctx->bet_info[BET_ID].mod_name)); >+ >+ ret = load_backend_module(ctx, BET_AUTH, >+ &ctx->bet_info[BET_AUTH], >+ ctx->bet_info[BET_ID].mod_name); >+ if (ret != EOK) { >+ if (ret != ENOENT) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("fatal error initializing data providers\n")); >+ goto fail; >+ } >+ DEBUG(SSSDBG_MINOR_FAILURE, >+ ("No authentication module provided for [%s] !!\n", >+ be_domain)); >+ } else { >+ DEBUG(SSSDBG_TRACE_INTERNAL, >+ ("AUTH backend target successfully loaded " >+ "from provider [%s].\n", ctx->bet_info[BET_AUTH].mod_name)); >+ } >+ >+ ret = load_backend_module(ctx, BET_ACCESS, &ctx->bet_info[BET_ACCESS], >+ ACCESS_PERMIT); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("Failed to setup ACCESS backend.\n")); >+ goto fail; >+ } >+ DEBUG(SSSDBG_TRACE_INTERNAL, >+ ("ACCESS backend target successfully loaded " >+ "from provider [%s].\n", ctx->bet_info[BET_ACCESS].mod_name)); >+ >+ ret = load_backend_module(ctx, BET_CHPASS, >+ &ctx->bet_info[BET_CHPASS], >+ ctx->bet_info[BET_AUTH].mod_name); >+ if (ret != EOK) { >+ if (ret != ENOENT) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("fatal error initializing data providers\n")); >+ goto fail; >+ } >+ DEBUG(SSSDBG_MINOR_FAILURE, >+ ("No change password module provided for [%s] !!\n", >+ be_domain)); >+ } else { >+ DEBUG(SSSDBG_TRACE_INTERNAL, >+ ("CHPASS backend target successfully loaded " >+ "from provider [%s].\n", ctx->bet_info[BET_CHPASS].mod_name)); >+ } >+ >+ ret = be_process_init_sudo(ctx); >+ if (ret != EOK) { >+ if (ret != ENOENT) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("fatal error initializing data providers\n")); >+ goto fail; >+ } >+ DEBUG(SSSDBG_MINOR_FAILURE, >+ ("No SUDO module provided for [%s] !!\n", be_domain)); >+ } else { >+ DEBUG(SSSDBG_TRACE_INTERNAL, >+ ("SUDO backend target successfully loaded " >+ "from provider [%s].\n", ctx->bet_info[BET_SUDO].mod_name)); >+ } >+ >+ ret = load_backend_module(ctx, BET_AUTOFS, >+ &ctx->bet_info[BET_AUTOFS], >+ ctx->bet_info[BET_ID].mod_name); >+ if (ret != EOK) { >+ if (ret != ENOENT) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("fatal error initializing data providers\n")); >+ goto fail; >+ } >+ DEBUG(SSSDBG_MINOR_FAILURE, >+ ("No autofs module provided for [%s] !!\n", be_domain)); >+ } else { >+ DEBUG(SSSDBG_TRACE_INTERNAL, >+ ("autofs backend target successfully loaded " >+ "from provider [%s].\n", ctx->bet_info[BET_AUTOFS].mod_name)); >+ } >+ >+ ret = load_backend_module(ctx, BET_SELINUX, >+ &ctx->bet_info[BET_SELINUX], >+ ctx->bet_info[BET_ID].mod_name); >+ if (ret != EOK) { >+ if (ret != ENOENT) { >+ DEBUG(SSSDBG_FATAL_FAILURE, ("fatal error initializing data providers\n")); >+ goto fail; >+ } >+ DEBUG(SSSDBG_CRIT_FAILURE, ("No selinux module provided for [%s] !!\n", >+ be_domain)); >+ } else { >+ DEBUG(SSSDBG_TRACE_ALL, ("selinux backend target successfully loaded " >+ "from provider [%s].\n", ctx->bet_info[BET_SELINUX].mod_name)); >+ } >+ >+ ret = load_backend_module(ctx, BET_HOSTID, >+ &ctx->bet_info[BET_HOSTID], >+ ctx->bet_info[BET_ID].mod_name); >+ if (ret != EOK) { >+ if (ret != ENOENT) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("fatal error initializing data providers\n")); >+ goto fail; >+ } >+ DEBUG(SSSDBG_CRIT_FAILURE, >+ ("No host info module provided for [%s] !!\n", be_domain)); >+ } else { >+ DEBUG(SSSDBG_TRACE_ALL, >+ ("HOST backend target successfully loaded from provider [%s].\n", >+ ctx->bet_info[BET_HOSTID].mod_name)); >+ } >+ >+ ret = load_backend_module(ctx, BET_SUBDOMAINS, >+ &ctx->bet_info[BET_SUBDOMAINS], >+ ctx->bet_info[BET_ID].mod_name); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_CRIT_FAILURE, ("Subdomains are not supported for [%s] !!\n", be_domain)); >+ } else { >+ DEBUG(SSSDBG_TRACE_ALL, ("Get-Subdomains backend target successfully loaded " >+ "from provider [%s].\n", >+ ctx->bet_info[BET_SUBDOMAINS].mod_name)); >+ } >+ >+ /* Handle SIGUSR1 to force offline behavior */ >+ BlockSignals(false, SIGUSR1); >+ tes = tevent_add_signal(ctx->ev, ctx, SIGUSR1, 0, >+ signal_be_offline, ctx); >+ if (tes == NULL) { >+ ret = EIO; >+ goto fail; >+ } >+ >+ ret = sss_sigchld_init(ctx, ctx->ev, &ctx->sigchld_ctx); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, >+ ("Could not initialize sigchld context: [%s]\n", >+ strerror(ret))); >+ goto fail; >+ } >+ >+ return EOK; >+ >+fail: >+ talloc_free(ctx); >+ return ret; >+} >+ >+int main(int argc, const char *argv[]) >+{ >+ int opt; >+ poptContext pc; >+ char *be_domain = NULL; >+ char *srv_name = NULL; >+ struct main_context *main_ctx; >+ char *confdb_path; >+ int ret; >+ >+ struct poptOption long_options[] = { >+ POPT_AUTOHELP >+ SSSD_MAIN_OPTS >+ {"domain", 0, POPT_ARG_STRING, &be_domain, 0, >+ _("Domain of the information provider (mandatory)"), NULL }, >+ POPT_TABLEEND >+ }; >+ >+ /* Set debug level to invalid value so we can deside if -d 0 was used. */ >+ debug_level = SSSDBG_INVALID; >+ >+ pc = poptGetContext(argv[0], argc, argv, long_options, 0); >+ while((opt = poptGetNextOpt(pc)) != -1) { >+ switch(opt) { >+ default: >+ fprintf(stderr, "\nInvalid option %s: %s\n\n", >+ poptBadOption(pc, 0), poptStrerror(opt)); >+ poptPrintUsage(pc, stderr, 0); >+ return 1; >+ } >+ } >+ >+ if (be_domain == NULL) { >+ fprintf(stderr, "\nMissing option, --domain is a mandatory option.\n\n"); >+ poptPrintUsage(pc, stderr, 0); >+ return 1; >+ } >+ >+ poptFreeContext(pc); >+ >+ DEBUG_INIT(debug_level); >+ >+ /* set up things like debug , signals, daemonization, etc... */ >+ debug_log_file = talloc_asprintf(NULL, "sssd_%s", be_domain); >+ if (!debug_log_file) return 2; >+ >+ srv_name = talloc_asprintf(NULL, "sssd[be[%s]]", be_domain); >+ if (!srv_name) return 2; >+ >+ confdb_path = talloc_asprintf(NULL, CONFDB_DOMAIN_PATH_TMPL, be_domain); >+ if (!confdb_path) return 2; >+ >+ ret = server_setup(srv_name, 0, confdb_path, &main_ctx); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, ("Could not set up mainloop [%d]\n", ret)); >+ return 2; >+ } >+ >+ ret = die_if_parent_died(); >+ if (ret != EOK) { >+ /* This is not fatal, don't return */ >+ DEBUG(SSSDBG_MINOR_FAILURE, >+ ("Could not set up to exit when parent process does\n")); >+ } >+ >+ ret = be_process_init(main_ctx, >+ be_domain, >+ main_ctx->event_ctx, >+ main_ctx->confdb_ctx); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_FATAL_FAILURE, ("Could not initialize backend [%d]\n", ret)); >+ return 3; >+ } >+ >+ DEBUG(SSSDBG_TRACE_FUNC, ("Backend provider (%s) started!\n", be_domain)); >+ >+ /* loop on main */ >+ server_loop(main_ctx); >+ >+ return 0; >+} >+ >+static int data_provider_res_init(DBusMessage *message, >+ struct sbus_connection *conn) >+{ >+ struct be_ctx *be_ctx; >+ be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); >+ >+ resolv_reread_configuration(); >+ be_check_if_online(be_ctx); >+ >+ return monitor_common_res_init(message, conn); >+} >+ >+static int data_provider_go_offline(DBusMessage *message, >+ struct sbus_connection *conn) >+{ >+ struct be_ctx *be_ctx; >+ be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); >+ be_mark_offline(be_ctx); >+ return monitor_common_pong(message, conn); >+} >+ >+static int data_provider_reset_offline(DBusMessage *message, >+ struct sbus_connection *conn) >+{ >+ struct be_ctx *be_ctx; >+ be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); >+ be_check_if_online(be_ctx); >+ return monitor_common_pong(message, conn); >+} >+ >+static int data_provider_logrotate(DBusMessage *message, >+ struct sbus_connection *conn) >+{ >+ errno_t ret; >+ struct be_ctx *be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), >+ struct be_ctx); >+ >+ ret = monitor_common_rotate_logs(be_ctx->cdb, be_ctx->conf_path); >+ if (ret != EOK) return ret; >+ >+ return monitor_common_pong(message, conn); >+} >-- >1.8.1.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 910938
:
704993
|
704995
|
704996
|
704997
|
704998
|
705198
|
705200
|
705201
|
705202