diff options
-rw-r--r-- | Makefile.am | 21 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/confdb/confdb.h | 3 | ||||
-rw-r--r-- | src/external/pac_responder.m4 | 34 | ||||
-rw-r--r-- | src/monitor/monitor.c | 2 | ||||
-rw-r--r-- | src/responder/pac/pacsrv.c | 227 | ||||
-rw-r--r-- | src/responder/pac/pacsrv.h | 52 | ||||
-rw-r--r-- | src/responder/pac/pacsrv_cmd.c | 61 |
8 files changed, 400 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index c5bde071..ad79de37 100644 --- a/Makefile.am +++ b/Makefile.am @@ -97,6 +97,10 @@ if BUILD_SSH sssdlibexec_PROGRAMS += sssd_ssh endif +if BUILD_PAC_RESPONDER + sssdlibexec_PROGRAMS += sssd_pac +endif + if HAVE_CHECK non_interactive_check_based_tests = \ sysdb-tests \ @@ -236,6 +240,7 @@ AM_CPPFLAGS = \ -DSSS_NSS_MCACHE_DIR=\"$(mcpath)\" \ -DSSS_NSS_SOCKET_NAME=\"$(pipepath)/nss\" \ -DSSS_PAM_SOCKET_NAME=\"$(pipepath)/pam\" \ + -DSSS_PAC_SOCKET_NAME=\"$(pipepath)/pac\" \ -DSSS_PAM_PRIV_SOCKET_NAME=\"$(pipepath)/private/pam\" \ -DSSS_SUDO_SOCKET_NAME=\"$(pipepath)/sudo\" \ -DSSS_AUTOFS_SOCKET_NAME=\"$(pipepath)/autofs\" \ @@ -349,6 +354,7 @@ dist_noinst_HEADERS = \ src/responder/nss/nsssrv_netgroup.h \ src/responder/nss/nsssrv_services.h \ src/responder/nss/nsssrv_mmap_cache.h \ + src/responder/pac/pacsrv.h \ src/responder/common/negcache.h \ src/responder/sudo/sudosrv_private.h \ src/responder/autofs/autofs_private.h \ @@ -581,6 +587,21 @@ sssd_ssh_LDADD = \ libsss_util.la endif +sssd_pac_SOURCES = \ + src/responder/pac/pacsrv.c \ + src/responder/pac/pacsrv_cmd.c \ + $(SSSD_UTIL_OBJ) \ + $(SSSD_RESPONDER_OBJ) +sssd_pac_CFLAGS = \ + $(AM_CFLAGS) \ + $(NDR_KRB5PAC_CFLAGS) +sssd_pac_LDADD = \ + $(NDR_KRB5PAC_LIBS) \ + $(TDB_LIBS) \ + $(SSSD_LIBS) \ + libsss_idmap.la \ + libsss_util.la + sssd_be_SOURCES = \ src/providers/data_provider_be.c \ src/providers/data_provider_fo.c \ diff --git a/configure.ac b/configure.ac index f43c32ac..7f242090 100644 --- a/configure.ac +++ b/configure.ac @@ -126,6 +126,7 @@ m4_include([src/external/nsupdate.m4]) m4_include([src/external/libkeyutils.m4]) m4_include([src/external/libnl.m4]) m4_include([src/external/systemd.m4]) +m4_include([src/external/pac_responder.m4]) m4_include([src/util/signal.m4]) WITH_UNICODE_LIB diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 3fa8b037..139dd903 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 00000000..f2841924 --- /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 1cc092f8..201d9fa8 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 00000000..feee3aee --- /dev/null +++ b/src/responder/pac/pacsrv.c @@ -0,0 +1,227 @@ +/* + SSSD + + PAC Responder + + Copyright (C) Sumit Bose <sbose@redhat.com> 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 <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <string.h> +#include <sys/time.h> +#include <errno.h> + +#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 00000000..0dfe7f9e --- /dev/null +++ b/src/responder/pac/pacsrv.h @@ -0,0 +1,52 @@ +/* + SSSD + + PAC Responder, header file + + Copyright (C) Sumit Bose <sbose@redhat.com> 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 <http://www.gnu.org/licenses/>. +*/ + +#ifndef __PACSRV_H__ +#define __PACSRV_H__ + +#include <stdint.h> +#include <sys/un.h> +#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 00000000..892ef856 --- /dev/null +++ b/src/responder/pac/pacsrv_cmd.c @@ -0,0 +1,61 @@ +/* + SSSD + + PAC Responder + + Copyright (C) Sumit Bose <sbose@redhat.com> 2012 + Jan Zeleny <jzeleny@redhat.com> 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 <http://www.gnu.org/licenses/>. +*/ + +#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; +} |