summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-11-21 18:07:10 +0100
committerJakub Hrozek <jhrozek@redhat.com>2014-11-25 13:28:39 +0100
commit4fa184e2c60b377fd71e0115a618bd68dc73627d (patch)
tree58e84cd4c984c579537e0451272f88d14dcfb9b9
parenteaaeaa7e00c3d4bfa792cc4d3c6770dc1e28ef0c (diff)
downloadsssd-4fa184e2c60b377fd71e0115a618bd68dc73627d.zip
sssd-4fa184e2c60b377fd71e0115a618bd68dc73627d.tar.gz
sssd-4fa184e2c60b377fd71e0115a618bd68dc73627d.tar.xz
AD/IPA: add krb5_confd_path configuration option
With this new parameter the directory where Kerberos configuration snippets are created can be specified. Fixes https://fedorahosted.org/sssd/ticket/2473 Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r--src/config/SSSDConfig/__init__.py.in1
-rw-r--r--src/config/etc/sssd.api.d/sssd-ad.conf1
-rw-r--r--src/config/etc/sssd.api.d/sssd-ipa.conf1
-rw-r--r--src/man/sssd-ad.5.xml18
-rw-r--r--src/man/sssd-ipa.5.xml18
-rw-r--r--src/providers/ad/ad_common.h1
-rw-r--r--src/providers/ad/ad_opts.h1
-rw-r--r--src/providers/ad/ad_subdomains.c8
-rw-r--r--src/providers/ipa/ipa_common.h1
-rw-r--r--src/providers/ipa/ipa_opts.h1
-rw-r--r--src/providers/ipa/ipa_subdomains.c8
-rw-r--r--src/tests/cmocka/test_utils.c48
-rw-r--r--src/util/domain_info_utils.c146
-rw-r--r--src/util/util.h6
14 files changed, 256 insertions, 3 deletions
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 283ed2d..500bd71 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -195,6 +195,7 @@ option_strings = {
'krb5_realm' : _('Kerberos realm'),
'krb5_auth_timeout' : _('Authentication timeout'),
'krb5_use_kdcinfo' : _('Whether to create kdcinfo files'),
+ 'krb5_confd_path' : _('Where to drop krb5 config snippets'),
# [provider/krb5/auth]
'krb5_ccachedir' : _('Directory to store credential caches'),
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index 3daa256..3496fb4 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -54,6 +54,7 @@ ldap_page_size = int, None, false
ldap_deref_threshold = int, None, false
ldap_connection_expire_timeout = int, None, false
ldap_disable_paging = bool, None, false
+krb5_confd_path = str, None, false
[provider/ad/id]
ldap_search_timeout = int, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 5df5258..2a3b7ef 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -51,6 +51,7 @@ ldap_page_size = int, None, false
ldap_deref_threshold = int, None, false
ldap_connection_expire_timeout = int, None, false
ldap_disable_paging = bool, None, false
+krb5_confd_path = str, None, false
[provider/ipa/id]
ldap_search_timeout = int, None, false
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index f63a496..4e29d4f 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -778,6 +778,24 @@ FOREST:EXAMPLE.COM:(memberOf=cn=admins,ou=groups,dc=example,dc=com)
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>krb5_confd_path (string)</term>
+ <listitem>
+ <para>
+ Absolute path of a directory where SSSD should place
+ Kerberos configuration snippets.
+ </para>
+ <para>
+ To disable the creation of the configuration
+ snippets set the parameter to 'none'.
+ </para>
+ <para>
+ Default: not set (krb5.include.d subdirectory of
+ SSSD's pubconf directory)
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
</refsect1>
diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
index e8a716c..2d8654a 100644
--- a/src/man/sssd-ipa.5.xml
+++ b/src/man/sssd-ipa.5.xml
@@ -447,6 +447,24 @@
</varlistentry>
<varlistentry>
+ <term>krb5_confd_path (string)</term>
+ <listitem>
+ <para>
+ Absolute path of a directory where SSSD should place
+ Kerberos configuration snippets.
+ </para>
+ <para>
+ To disable the creation of the configuration
+ snippets set the parameter to 'none'.
+ </para>
+ <para>
+ Default: not set (krb5.include.d subdirectory of
+ SSSD's pubconf directory)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ipa_hbac_refresh (integer)</term>
<listitem>
<para>
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
index df8dcff..b39ade4 100644
--- a/src/providers/ad/ad_common.h
+++ b/src/providers/ad/ad_common.h
@@ -60,6 +60,7 @@ enum ad_basic_opt {
AD_GPO_MAP_PERMIT,
AD_GPO_MAP_DENY,
AD_GPO_DEFAULT_RIGHT,
+ AD_KRB5_CONFD_PATH,
AD_OPTS_BASIC /* opts counter */
};
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
index ac6006c..c3de3d9 100644
--- a/src/providers/ad/ad_opts.h
+++ b/src/providers/ad/ad_opts.h
@@ -48,6 +48,7 @@ struct dp_option ad_basic_opts[] = {
{ "ad_gpo_map_permit", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ad_gpo_map_deny", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ad_gpo_default_right", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "krb5_confd_path", DP_OPT_STRING, { KRB5_MAPPING_DIR }, NULL_STRING },
DP_OPTION_TERMINATOR
};
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index bc5bc89..3c61d13 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -461,6 +461,14 @@ static errno_t ad_subdom_reinit(struct ad_subdomains_ctx *ctx)
{
errno_t ret;
+ ret = sss_write_krb5_conf_snippet(
+ dp_opt_get_string(ctx->ad_id_ctx->ad_options->basic,
+ AD_KRB5_CONFD_PATH));
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "sss_write_krb5_conf_snippet failed.\n");
+ /* Just continue */
+ }
+
ret = sysdb_update_subdomains(ctx->be_ctx->domain);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_subdomains failed.\n");
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index 4952765..3308519 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -54,6 +54,7 @@ enum ipa_basic_opt {
IPA_ENABLE_DNS_SITES,
IPA_SERVER_MODE,
IPA_VIEWS_SEARCH_BASE,
+ IPA_KRB5_CONFD_PATH,
IPA_OPTS_BASIC /* opts counter */
};
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 59282e8..f77ff1d 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -51,6 +51,7 @@ struct dp_option ipa_basic_opts[] = {
{ "ipa_enable_dns_sites", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ipa_server_mode", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ipa_views_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "krb5_confd_path", DP_OPT_STRING, { KRB5_MAPPING_DIR }, NULL_STRING },
DP_OPTION_TERMINATOR
};
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index 9281aab..883558c 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -312,6 +312,14 @@ ipa_subdom_reinit(struct ipa_subdomains_ctx *ctx)
{
errno_t ret;
+ ret = sss_write_krb5_conf_snippet(
+ dp_opt_get_string(ctx->id_ctx->ipa_options->basic,
+ IPA_KRB5_CONFD_PATH));
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "sss_write_krb5_conf_snippet failed.\n");
+ /* Just continue */
+ }
+
ret = sysdb_update_subdomains(ctx->be_ctx->domain);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_subdomains failed.\n");
diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
index d978137..5dc00c4 100644
--- a/src/tests/cmocka/test_utils.c
+++ b/src/tests/cmocka/test_utils.c
@@ -20,6 +20,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define _GNU_SOURCE
+#include <stdio.h>
#include <popt.h>
#include "tests/cmocka/common_mock.h"
@@ -983,6 +985,51 @@ void test_add_strings_lists(void **state)
talloc_free(res);
}
+void test_sss_write_krb5_conf_snippet(void **state)
+{
+ int ret;
+ char buf[PATH_MAX];
+ char *cwd;
+ char *path;
+ char *file;
+
+ ret = sss_write_krb5_conf_snippet(NULL);
+ assert_int_equal(ret, EINVAL);
+
+ ret = sss_write_krb5_conf_snippet("abc");
+ assert_int_equal(ret, EINVAL);
+
+ ret = sss_write_krb5_conf_snippet("");
+ assert_int_equal(ret, EOK);
+
+ ret = sss_write_krb5_conf_snippet("none");
+ assert_int_equal(ret, EOK);
+
+ cwd = getcwd(buf, PATH_MAX);
+ assert_non_null(cwd);
+
+ ret = asprintf(&path, "%s/%s", cwd, TESTS_PATH);
+ assert_true(ret > 0);
+
+ ret = asprintf(&file, "%s/%s/localauth_plugin", cwd, TESTS_PATH);
+ assert_true(ret > 0);
+
+ ret = sss_write_krb5_conf_snippet(path);
+ assert_int_equal(ret, EOK);
+
+ /* Check if writing a second time will work as well */
+ ret = sss_write_krb5_conf_snippet(path);
+ assert_int_equal(ret, EOK);
+
+#ifdef HAVE_KRB5_LOCALAUTH_PLUGIN
+ ret = unlink(file);
+ assert_int_equal(ret, EOK);
+#endif
+
+ free(file);
+ free(path);
+}
+
int main(int argc, const char *argv[])
{
poptContext pc;
@@ -1030,6 +1077,7 @@ int main(int argc, const char *argv[])
unit_test_setup_teardown(test_add_strings_lists,
setup_add_strings_lists,
teardown_add_strings_lists),
+ unit_test(test_sss_write_krb5_conf_snippet),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
index 4e2c14c..e04b905 100644
--- a/src/util/domain_info_utils.c
+++ b/src/util/domain_info_utils.c
@@ -24,9 +24,6 @@
#include "db/sysdb.h"
#include "util/util.h"
-/* the directory domain - realm mappings are written to */
-#define KRB5_MAPPING_DIR PUBCONF_PATH"/krb5.include.d"
-
struct sss_domain_info *get_domains_head(struct sss_domain_info *domain)
{
struct sss_domain_info *dom = NULL;
@@ -637,3 +634,146 @@ done:
talloc_free(tmp_ctx);
return ret;
}
+
+#define LOCALAUTH_PLUGIN_CONFIG \
+"[plugins]\n" \
+" localauth = {\n" \
+" module = sssd:"APP_MODULES_PATH"/sssd_krb5_localauth_plugin.so\n" \
+" enable_only = sssd\n" \
+" }"
+
+static errno_t sss_write_krb5_localauth_snippet(const char *path)
+{
+#ifdef HAVE_KRB5_LOCALAUTH_PLUGIN
+ int ret;
+ errno_t err;
+ TALLOC_CTX *tmp_ctx = NULL;
+ char *tmp_file = NULL;
+ const char *file_name;
+ int fd = -1;
+ mode_t old_mode;
+ ssize_t written;
+ size_t size;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+ return ENOMEM;
+ }
+
+ file_name = talloc_asprintf(tmp_ctx, "%s/localauth_plugin", path);
+ if (file_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ DEBUG(SSSDBG_FUNC_DATA, "File for localauth plugin configuration is [%s]\n",
+ file_name);
+
+ tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", file_name);
+ if (tmp_file == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ old_mode = umask(077);
+ fd = mkstemp(tmp_file);
+ umask(old_mode);
+ if (fd < 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "creating the temp file [%s] for domain-realm "
+ "mappings failed.", tmp_file);
+ ret = EIO;
+ talloc_zfree(tmp_ctx);
+ goto done;
+ }
+
+ size = sizeof(LOCALAUTH_PLUGIN_CONFIG) -1;
+ written = sss_atomic_write_s(fd, discard_const(LOCALAUTH_PLUGIN_CONFIG),
+ size);
+ close(fd);
+ if (written == -1) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "write failed [%d][%s]\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ if (written != size) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Wrote %zd bytes expected %zu\n", written, size);
+ ret = EIO;
+ goto done;
+ }
+
+ ret = rename(tmp_file, file_name);
+ if (ret == -1) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "rename failed [%d][%s].\n", ret, sss_strerror(ret));
+ goto done;
+ }
+ tmp_file = NULL;
+
+ ret = chmod(file_name, 0644);
+ if (ret == -1) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "chmod failed [%d][%s].\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+done:
+ if (tmp_file != NULL) {
+ err = unlink(tmp_file);
+ if (err == -1) {
+ err = errno;
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Could not remove file [%s]: [%d]: %s",
+ tmp_file, err, sss_strerror(err));
+ }
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+#else
+ DEBUG(SSSDBG_TRACE_ALL, "Kerberos localauth plugin not available.\n");
+ return EOK;
+#endif
+}
+
+errno_t sss_write_krb5_conf_snippet(const char *path)
+{
+ errno_t ret;
+ errno_t err;
+
+ if (path != NULL && (*path == '\0' || strcasecmp(path, "none") == 0)) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Empty path, nothing to do.\n");
+ return EOK;
+ }
+
+ if (path == NULL || *path != '/') {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid or missing path [%s]-\n",
+ path == NULL ? "missing" : path);
+ return EINVAL;
+ }
+
+ ret = sss_write_krb5_localauth_snippet(path);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_write_krb5_localauth_snippet failed.\n");
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ err = sss_krb5_touch_config();
+ if (err != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change last modification time "
+ "of krb5.conf. Created mappings may not be loaded.\n");
+ /* Ignore */
+ }
+
+ return ret;
+}
diff --git a/src/util/util.h b/src/util/util.h
index 7c335b9..45efd1a 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -576,8 +576,14 @@ errno_t sssd_domain_init(TALLOC_CTX *mem_ctx,
#define DOM_HAS_VIEWS(dom) ((dom)->has_views)
+/* the directory domain - realm mappings and other krb5 config snippers are
+ * written to */
+#define KRB5_MAPPING_DIR PUBCONF_PATH"/krb5.include.d"
+
errno_t sss_write_domain_mappings(struct sss_domain_info *domain);
+errno_t sss_write_krb5_conf_snippet(const char *path);
+
errno_t get_dom_names(TALLOC_CTX *mem_ctx,
struct sss_domain_info *start_dom,
char ***_dom_names,