From 74505b09d056883741e90cac45838c844365cae5 Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Fri, 3 Feb 2012 22:35:14 +0100 Subject: DP: Add host info handler --- src/confdb/confdb.h | 1 + src/config/SSSDConfig.py | 1 + src/config/SSSDConfigTest.py | 6 +- src/config/etc/sssd.api.conf | 1 + src/providers/data_provider.h | 4 +- src/providers/data_provider_be.c | 193 +++++++++++++++++++++++++++++++++++++++ src/providers/dp_backend.h | 1 + 7 files changed, 204 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index ce9f3763..bc8f6f23 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -115,6 +115,7 @@ #define CONFDB_DOMAIN_SUDO_PROVIDER "sudo_provider" #define CONFDB_DOMAIN_AUTOFS_PROVIDER "autofs_provider" #define CONFDB_DOMAIN_SESSION_PROVIDER "session_provider" +#define CONFDB_DOMAIN_HOSTID_PROVIDER "hostid_provider" #define CONFDB_DOMAIN_COMMAND "command" #define CONFDB_DOMAIN_TIMEOUT "timeout" #define CONFDB_DOMAIN_ATTR "cn" diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py index 71769f57..50cc4e29 100644 --- a/src/config/SSSDConfig.py +++ b/src/config/SSSDConfig.py @@ -88,6 +88,7 @@ option_strings = { 'sudo_provider' : _('SUDO provider'), 'autofs_provider' : _('Autofs provider'), 'session_provider' : _('Session-loading provider'), + 'hostid_provider' : _('Host identity provider'), # [domain] 'min_id' : _('Minimum user ID'), diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py index 186bf364..bfc89a12 100755 --- a/src/config/SSSDConfigTest.py +++ b/src/config/SSSDConfigTest.py @@ -497,7 +497,8 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'chpass_provider', 'sudo_provider', 'autofs_provider', - 'session_provider'] + 'session_provider', + 'hostid_provider'] self.assertTrue(type(options) == dict, "Options should be a dictionary") @@ -823,7 +824,8 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'chpass_provider', 'sudo_provider', 'autofs_provider', - 'session_provider'] + 'session_provider', + 'hostid_provider'] self.assertTrue(type(options) == dict, "Options should be a dictionary") diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index ecc89dcf..fa5cf8ba 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -61,6 +61,7 @@ chpass_provider = str, None, false sudo_provider = str, None, false autofs_provider = str, None, false session_provider = str, None, false +hostid_provider = str, None, false [domain] # Options available to all domains diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h index 89528721..f70d556a 100644 --- a/src/providers/data_provider.h +++ b/src/providers/data_provider.h @@ -52,6 +52,7 @@ #define DP_METHOD_GETACCTINFO "getAccountInfo" #define DP_METHOD_SUDOHANDLER "sudoHandler" #define DP_METHOD_AUTOFSHANDLER "autofsHandler" +#define DP_METHOD_HOSTHANDLER "hostHandler" /** * @defgroup pamHandler PAM DBUS request * @ingroup sss_pam @@ -141,7 +142,8 @@ #define BE_REQ_SUDO_ALL 0x0006 #define BE_REQ_SUDO_DEFAULTS 0x0007 #define BE_REQ_SUDO_USER 0x0008 -#define BE_REQ_AUTOFS 0x0007 +#define BE_REQ_AUTOFS 0x0009 +#define BE_REQ_HOST 0x0010 #define BE_REQ_FAST 0x1000 /* AUTH related common data and functions */ diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c index e7ba98fd..7dd4b279 100644 --- a/src/providers/data_provider_be.c +++ b/src/providers/data_provider_be.c @@ -83,6 +83,7 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con 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); struct sbus_method be_methods[] = { { DP_METHOD_REGISTER, client_registration }, @@ -90,6 +91,7 @@ struct sbus_method be_methods[] = { { DP_METHOD_PAMHANDLER, be_pam_handler }, { DP_METHOD_SUDOHANDLER, be_sudo_handler }, { DP_METHOD_AUTOFSHANDLER, be_autofs_handler }, + { DP_METHOD_HOSTHANDLER, be_host_handler }, { NULL, NULL } }; @@ -110,6 +112,7 @@ static struct bet_data bet_data[] = { {BET_SUDO, CONFDB_DOMAIN_SUDO_PROVIDER, "sssm_%s_sudo_init"}, {BET_AUTOFS, CONFDB_DOMAIN_SUDO_PROVIDER, "sssm_%s_autofs_init"}, {BET_SESSION, CONFDB_DOMAIN_SESSION_PROVIDER, "sssm_%s_session_init"}, + {BET_HOSTID, CONFDB_DOMAIN_HOSTID_PROVIDER, "sssm_%s_hostid_init"}, {BET_MAX, NULL, NULL} }; @@ -1068,6 +1071,179 @@ static void be_autofs_handler_callback(struct be_req *req, talloc_free(req); } +static int be_host_handler(DBusMessage *message, struct sbus_connection *conn) +{ + struct be_acct_req *req; + struct be_req *be_req; + struct be_client *becli; + DBusMessage *reply; + DBusError dbus_error; + dbus_bool_t dbret; + void *user_data; + uint32_t flags; + char *filter; + uint32_t attr_type; + int ret; + dbus_uint16_t err_maj; + dbus_uint32_t err_min; + const char *err_msg; + + be_req = NULL; + + user_data = sbus_conn_get_private_data(conn); + if (!user_data) return EINVAL; + becli = talloc_get_type(user_data, struct be_client); + if (!becli) return EINVAL; + + dbus_error_init(&dbus_error); + + ret = dbus_message_get_args(message, &dbus_error, + DBUS_TYPE_UINT32, &flags, + DBUS_TYPE_UINT32, &attr_type, + DBUS_TYPE_STRING, &filter, + DBUS_TYPE_INVALID); + if (!ret) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Failed, to parse message!\n")); + if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); + return EIO; + } + + DEBUG(SSSDBG_TRACE_LIBS, + ("Got request for [%u][%d][%s]\n", flags, attr_type, filter)); + + reply = dbus_message_new_method_return(message); + if (!reply) return ENOMEM; + + /* If we are offline and fast reply was requested + * return offline immediately + */ + if ((flags & BE_REQ_FAST) && becli->bectx->offstat.offline) { + /* Send back an immediate reply */ + err_maj = DP_ERR_OFFLINE; + err_min = EAGAIN; + err_msg = "Fast reply - offline"; + + dbret = dbus_message_append_args(reply, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); + if (!dbret) return EIO; + + DEBUG(SSSDBG_TRACE_LIBS, + ("Request processed. Returned %d,%d,%s\n", + err_maj, err_min, err_msg)); + + sbus_conn_send_reply(conn, reply); + dbus_message_unref(reply); + reply = NULL; + /* This reply will be queued and sent + * when we reenter the mainloop. + * + * Continue processing in case we are + * going back online. + */ + } + + be_req = talloc_zero(becli, struct be_req); + if (!be_req) { + err_maj = DP_ERR_FATAL; + err_min = ENOMEM; + err_msg = "Out of memory"; + goto done; + } + be_req->becli = becli; + be_req->be_ctx = becli->bectx; + be_req->fn = acctinfo_callback; + be_req->pvt = reply; + + req = talloc(be_req, struct be_acct_req); + if (!req) { + err_maj = DP_ERR_FATAL; + err_min = ENOMEM; + err_msg = "Out of memory"; + goto done; + } + req->entry_type = BE_REQ_HOST | (flags & BE_REQ_FAST); + req->attr_type = (int)attr_type; + + be_req->req_data = req; + + if ((attr_type != BE_ATTR_CORE) && + (attr_type != BE_ATTR_MEM) && + (attr_type != BE_ATTR_ALL)) { + /* Unrecognized attr type */ + err_maj = DP_ERR_FATAL; + err_min = EINVAL; + err_msg = "Invalid Attrs Parameter"; + goto done; + } + + if (filter) { + ret = EOK; + if (strncmp(filter, "name=", 5) == 0) { + req->filter_type = BE_FILTER_NAME; + req->filter_value = &filter[5]; + } else { + err_maj = DP_ERR_FATAL; + err_min = EINVAL; + err_msg = "Invalid Filter"; + goto done; + } + + if (ret != EOK) { + err_maj = DP_ERR_FATAL; + err_min = EINVAL; + err_msg = "Invalid Filter"; + goto done; + } + + } else { + err_maj = DP_ERR_FATAL; + err_min = EINVAL; + err_msg = "Missing Filter Parameter"; + goto done; + } + + /* process request */ + + ret = be_file_request(becli->bectx, + becli->bectx->bet_info[BET_HOSTID].bet_ops->handler, + be_req); + if (ret != EOK) { + err_maj = DP_ERR_FATAL; + err_min = ret; + err_msg = "Failed to file request"; + goto done; + } + + return EOK; + +done: + if (be_req) { + talloc_free(be_req); + } + + if (reply) { + dbret = dbus_message_append_args(reply, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); + if (!dbret) return EIO; + + DEBUG(SSSDBG_TRACE_LIBS, + ("Request processed. Returned %d,%d,%s\n", + err_maj, err_min, err_msg)); + + /* send reply back */ + sbus_conn_send_reply(conn, reply); + dbus_message_unref(reply); + } + + return EOK; +} + static int be_client_destructor(void *ctx) { struct be_client *becli = talloc_get_type(ctx, struct be_client); @@ -1715,6 +1891,23 @@ int be_process_init(TALLOC_CTX *mem_ctx, "from provider [%s].\n", ctx->bet_info[BET_SUDO].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")); + return ret; + } + 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)); + } + /* Handle SIGUSR1 to force offline behavior */ BlockSignals(false, SIGUSR1); tes = tevent_add_signal(ctx->ev, ctx, SIGUSR1, 0, diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h index 68b2fa10..2923a8d7 100644 --- a/src/providers/dp_backend.h +++ b/src/providers/dp_backend.h @@ -52,6 +52,7 @@ enum bet_type { BET_SUDO, BET_AUTOFS, BET_SESSION, + BET_HOSTID, BET_MAX }; -- cgit