From b9e5bd09a5ff7009537a18914dbebcf10498f592 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 13 May 2011 18:44:15 +0200 Subject: PAC responder: add basic infrastructure This adds only the basic outline of the PAC responder, it won't support any operations, it will just start and initialize itself. --- src/confdb/confdb.h | 3 + src/external/pac_responder.m4 | 34 ++++++ src/monitor/monitor.c | 2 +- src/responder/pac/pacsrv.c | 227 +++++++++++++++++++++++++++++++++++++++++ src/responder/pac/pacsrv.h | 52 ++++++++++ src/responder/pac/pacsrv_cmd.c | 61 +++++++++++ 6 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 src/external/pac_responder.m4 create mode 100644 src/responder/pac/pacsrv.c create mode 100644 src/responder/pac/pacsrv.h create mode 100644 src/responder/pac/pacsrv_cmd.c (limited to 'src') diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 3fa8b0377..139dd9030 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -119,6 +119,9 @@ #define CONFDB_SSH_HASH_KNOWN_HOSTS "ssh_hash_known_hosts" #define CONFDB_DEFAULT_SSH_HASH_KNOWN_HOSTS true +/* PAC */ +#define CONFDB_PAC_CONF_ENTRY "config/pac" + /* Data Provider */ #define CONFDB_DP_CONF_ENTRY "config/dp" diff --git a/src/external/pac_responder.m4 b/src/external/pac_responder.m4 new file mode 100644 index 000000000..f2841924b --- /dev/null +++ b/src/external/pac_responder.m4 @@ -0,0 +1,34 @@ +AC_SUBST(NDR_KRB5PAC_CFLAGS) +AC_SUBST(NDR_KRB5PAC_LIBS) + +AC_ARG_ENABLE([experimental-pac-responder], + [AS_HELP_STRING([--enable-experimental-pac-responder], + [build experimental pac responder])], + [build_pac_responder=$enableval], + [build_pac_responder=no]) + +if test x$build_all_experimental_features != xno +then + build_pac_responder=yes +fi + +if test x$build_pac_responder == xyes +then + PKG_CHECK_MODULES(NDR_KRB5PAC, ndr_krb5pac,, + AC_MSG_ERROR([Cannot build pac responder without libndr_krb5pac])) + + AC_PATH_PROG(KRB5_CONFIG, krb5-config) + AC_MSG_CHECKING(for supported MIT krb5 version) + KRB5_VERSION="`$KRB5_CONFIG --version`" + case $KRB5_VERSION in + Kerberos\ 5\ release\ 1.9* | \ + Kerberos\ 5\ release\ 1.10*) + AC_MSG_RESULT(yes) + ;; + *) + AC_MSG_ERROR([Cannot build authdata plugin with this version of + MIT Kerberos, please use 1.9.x or 1.10.x]) + esac +fi + +AM_CONDITIONAL([BUILD_PAC_RESPONDER], [test x$build_pac_responder = xyes ]) diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 1cc092f84..201d9fa8d 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -759,7 +759,7 @@ static int check_local_domain_unique(struct sss_domain_info *domains) static char *check_services(char **services) { const char *known_services[] = { "nss", "pam", "sudo", "autofs", "ssh", - NULL }; + "pac", NULL }; int i; int ii; diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c new file mode 100644 index 000000000..feee3aeed --- /dev/null +++ b/src/responder/pac/pacsrv.c @@ -0,0 +1,227 @@ +/* + SSSD + + PAC Responder + + Copyright (C) Sumit Bose 2011 + + 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 . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "popt.h" +#include "util/util.h" +#include "responder/pac/pacsrv.h" +#include "db/sysdb.h" +#include "confdb/confdb.h" +#include "dbus/dbus.h" +#include "sbus/sssd_dbus.h" +#include "responder/common/responder_packet.h" +#include "responder/common/responder.h" +#include "providers/data_provider.h" +#include "monitor/monitor_interfaces.h" +#include "sbus/sbus_client.h" + +#define SSS_PAC_PIPE_NAME "pac" + +struct sbus_method monitor_pac_methods[] = { + { MON_CLI_METHOD_PING, monitor_common_pong }, + { MON_CLI_METHOD_RES_INIT, monitor_common_res_init }, + { MON_CLI_METHOD_ROTATE, monitor_common_rotate_logs }, + { NULL, NULL } +}; + +struct sbus_interface monitor_pac_interface = { + MONITOR_INTERFACE, + MONITOR_PATH, + SBUS_DEFAULT_VTABLE, + monitor_pac_methods, + NULL +}; + +static struct sbus_method pac_dp_methods[] = { + { NULL, NULL } +}; + +struct sbus_interface pac_dp_interface = { + DP_INTERFACE, + DP_PATH, + SBUS_DEFAULT_VTABLE, + pac_dp_methods, + NULL +}; + + +/* TODO: check if this can be made generic for all responders */ +static void pac_dp_reconnect_init(struct sbus_connection *conn, + int status, void *pvt) +{ + struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn); + int ret; + + /* Did we reconnect successfully? */ + if (status == SBUS_RECONNECT_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, ("Reconnected to the Data Provider.\n")); + + /* Identify ourselves to the data provider */ + ret = dp_common_send_id(be_conn->conn, + DATA_PROVIDER_VERSION, + "PAC"); + /* all fine */ + if (ret == EOK) { + handle_requests_after_reconnect(be_conn->rctx); + return; + } + } + + /* Failed to reconnect */ + DEBUG(SSSDBG_FATAL_FAILURE, ("Could not reconnect to %s provider.\n", + be_conn->domain->name)); + + /* FIXME: kill the frontend and let the monitor restart it ? */ + /* nss_shutdown(rctx); */ +} + +static void *idmap_talloc(size_t size, void *pvt) +{ + return talloc_size(pvt, size); +} + +static void idmap_free(void *ptr, void *pvt) +{ + talloc_free(ptr); +} + +int pac_process_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct confdb_ctx *cdb) +{ + struct sss_cmd_table *pac_cmds; + struct be_conn *iter; + struct pac_ctx *pac_ctx; + int ret, max_retries; + enum idmap_error_code err; + + pac_ctx = talloc_zero(mem_ctx, struct pac_ctx); + if (!pac_ctx) { + DEBUG(SSSDBG_FATAL_FAILURE, ("fatal error initializing pac_ctx\n")); + return ENOMEM; + } + + pac_cmds = get_pac_cmds(); + + ret = sss_process_init(pac_ctx, ev, cdb, + pac_cmds, + SSS_PAC_SOCKET_NAME, NULL, + CONFDB_PAC_CONF_ENTRY, + PAC_SBUS_SERVICE_NAME, + PAC_SBUS_SERVICE_VERSION, + &monitor_pac_interface, + "PAC", &pac_dp_interface, + &pac_ctx->rctx); + if (ret != EOK) { + return ret; + } + pac_ctx->rctx->pvt_ctx = pac_ctx; + + /* Enable automatic reconnection to the Data Provider */ + ret = confdb_get_int(pac_ctx->rctx->cdb, + CONFDB_PAC_CONF_ENTRY, + CONFDB_SERVICE_RECON_RETRIES, + 3, &max_retries); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to set up automatic reconnection\n")); + return ret; + } + + for (iter = pac_ctx->rctx->be_conns; iter; iter = iter->next) { + sbus_reconnect_init(iter->conn, max_retries, + pac_dp_reconnect_init, iter); + } + + err = sss_idmap_init(idmap_talloc, pac_ctx, idmap_free, + &pac_ctx->idmap_ctx); + if (err != IDMAP_SUCCESS) { + DEBUG(SSSDBG_FATAL_FAILURE, ("sss_idmap_init failed.\n")); + return EFAULT; + } + + DEBUG(SSSDBG_TRACE_FUNC, ("PAC Initialization complete\n")); + + return EOK; +} + +int main(int argc, const char *argv[]) +{ + int opt; + poptContext pc; + struct main_context *main_ctx; + int ret; + + struct poptOption long_options[] = { + POPT_AUTOHELP + SSSD_MAIN_OPTS + POPT_TABLEEND + }; + + /* Set debug level to invalid value so we can decide 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; + } + } + + poptFreeContext(pc); + + CONVERT_AND_SET_DEBUG_LEVEL(debug_level); + + /* set up things like debug, signals, daemonization, etc... */ + debug_log_file = "sssd_pac"; + + ret = server_setup("sssd[pac]", 0, CONFDB_PAC_CONF_ENTRY, &main_ctx); + if (ret != EOK) return 2; + + ret = die_if_parent_died(); + if (ret != EOK) { + /* This is not fatal, don't return */ + DEBUG(SSSDBG_OP_FAILURE, ("Could not set up to exit when parent process does\n")); + } + + ret = pac_process_init(main_ctx, + main_ctx->event_ctx, + main_ctx->confdb_ctx); + if (ret != EOK) return 3; + + /* loop on main */ + server_loop(main_ctx); + + return 0; +} diff --git a/src/responder/pac/pacsrv.h b/src/responder/pac/pacsrv.h new file mode 100644 index 000000000..0dfe7f9ee --- /dev/null +++ b/src/responder/pac/pacsrv.h @@ -0,0 +1,52 @@ +/* + SSSD + + PAC Responder, header file + + Copyright (C) Sumit Bose 2011 + + 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 . +*/ + +#ifndef __PACSRV_H__ +#define __PACSRV_H__ + +#include +#include +#include "config.h" +#include "talloc.h" +#include "tevent.h" +#include "ldb.h" +#include "dbus/dbus.h" +#include "sbus/sssd_dbus.h" +#include "responder/common/responder_packet.h" +#include "responder/common/responder.h" +#include "lib/idmap/sss_idmap.h" + +#define PAC_SBUS_SERVICE_VERSION 0x0001 +#define PAC_SBUS_SERVICE_NAME "pac" + +#define PAC_PACKET_MAX_RECV_SIZE 1024 + +struct getent_ctx; + +struct pac_ctx { + struct resp_ctx *rctx; +}; + +int pac_cmd_execute(struct cli_ctx *cctx); + +struct sss_cmd_table *get_pac_cmds(void); + +#endif /* __PACSRV_H__ */ diff --git a/src/responder/pac/pacsrv_cmd.c b/src/responder/pac/pacsrv_cmd.c new file mode 100644 index 000000000..892ef8568 --- /dev/null +++ b/src/responder/pac/pacsrv_cmd.c @@ -0,0 +1,61 @@ +/* + SSSD + + PAC Responder + + Copyright (C) Sumit Bose 2012 + Jan Zeleny 2012 + + 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 . +*/ + +#include "util/util.h" +#include "responder/pac/pacsrv.h" +#include "confdb/confdb.h" +#include "db/sysdb.h" + +struct cli_protocol_version *register_cli_protocol_version(void) +{ + static struct cli_protocol_version pac_cli_protocol_version[] = { + {1, "2011-04-12", "initial version"}, + {0, NULL, NULL} + }; + + return pac_cli_protocol_version; +} + +static struct sss_cmd_table pac_cmds[] = { + {SSS_GET_VERSION, sss_cmd_get_version}, + {SSS_CLI_NULL, NULL} +}; + +struct sss_cmd_table *get_pac_cmds(void) { + return pac_cmds; +} + +int pac_cmd_execute(struct cli_ctx *cctx) +{ + enum sss_cli_command cmd; + int i; + + cmd = sss_packet_get_cmd(cctx->creq->in); + + for (i = 0; pac_cmds[i].cmd != SSS_CLI_NULL; i++) { + if (cmd == pac_cmds[i].cmd) { + return pac_cmds[i].fn(cctx); + } + } + + return EINVAL; +} -- cgit