From 7197ce636c2b92152f5f6180bef6bda3752d148d Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 1 Aug 2012 18:28:04 +0200 Subject: Create a domain-realm mapping for krb5.conf to be included When new subdomains are discovered, the SSSD creates a file that includes the domain-realm mappings. This file can in turn be included in the krb5.conf using the includedir directive, such as: includedir /var/lib/sss/pubconf/realm_mappings --- Makefile.am | 1 + contrib/sssd.spec.in | 1 + src/providers/ipa/ipa_subdomains.c | 135 +++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) diff --git a/Makefile.am b/Makefile.am index 9b361a8ce..61472b622 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1602,6 +1602,7 @@ installsssddirs:: $(DESTDIR)$(pidpath) \ $(DESTDIR)$(logpath) \ $(DESTDIR)$(pubconfpath) \ + $(DESTDIR)$(pubconfpath)/krb5.include.d \ $(DESTDIR)$(sudolibdir) \ $(DESTDIR)$(autofslibdir) diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in index ccb2ce3ff..90bd07976 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -362,6 +362,7 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) %dir %{mcpath} %attr(755,root,root) %dir %{pipepath} %attr(755,root,root) %dir %{pubconfpath} +%attr(755,root,root) %dir %{pubconfpath}/krb5.include.d %attr(700,root,root) %dir %{pipepath}/private %attr(750,root,root) %dir %{_var}/log/%{name} %attr(711,root,root) %dir %{_sysconfdir}/sssd diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index fd6b6e43c..3ea8a3175 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -48,6 +48,9 @@ /* refresh automatically every 4 hours */ #define IPA_SUBDOMAIN_REFRESH_PERIOD (3600 * 4) +/* the directory domain - realm mappings are written to */ +#define IPA_SUBDOMAIN_MAPPING_DIR PUBCONF_PATH"/krb5.include.d" + enum ipa_subdomains_req_type { IPA_SUBDOMAINS_MASTER, IPA_SUBDOMAINS_SLAVE, @@ -271,6 +274,130 @@ static errno_t ipa_subdom_parse(TALLOC_CTX *memctx, return EOK; } +static errno_t +ipa_subdomains_write_mappings(struct sss_domain_info *domain, + size_t num_subdoms, + struct sysdb_subdom *subdoms) +{ + errno_t ret; + errno_t err; + TALLOC_CTX *tmp_ctx; + const char *mapping_file; + char *tmp_file = NULL; + int fd = -1; + FILE *fstream = NULL; + size_t i; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) return ENOMEM; + + mapping_file = talloc_asprintf(tmp_ctx, "%s/domain_realm_%s", + IPA_SUBDOMAIN_MAPPING_DIR, domain->name); + if (!mapping_file) { + ret = ENOMEM; + goto done; + } + + tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", mapping_file); + if (tmp_file == NULL) { + ret = ENOMEM; + goto done; + } + + fd = mkstemp(tmp_file); + 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; + } + + fstream = fdopen(fd, "a"); + if (!fstream) { + ret = errno; + DEBUG(SSSDBG_OP_FAILURE, ("fdopen failed [%d]: %s\n", + ret, strerror(ret))); + ret = close(fd); + if (ret != 0) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("fclose failed [%d][%s].\n", ret, strerror(ret))); + /* Nothing to do here, just report the failure */ + } + ret = EIO; + goto done; + } + + ret = fprintf(fstream, "[domain_realm]\n"); + if (ret < 0) { + DEBUG(SSSDBG_OP_FAILURE, ("fprintf failed\n")); + ret = EIO; + goto done; + } + + for (i = 0; i < num_subdoms; i++) { + ret = fprintf(fstream, ".%s = %s\n%s = %s\n", + subdoms[i].name, subdoms[i].realm, + subdoms[i].name, subdoms[i].realm); + if (ret < 0) { + DEBUG(SSSDBG_CRIT_FAILURE, ("fprintf failed\n")); + goto done; + } + } + + ret = fclose(fstream); + if (ret != 0) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("fclose failed [%d][%s].\n", ret, strerror(ret))); + goto done; + } + fstream = NULL; + + ret = rename(tmp_file, mapping_file); + if (ret == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("rename failed [%d][%s].\n", ret, strerror(ret))); + goto done; + } + + talloc_zfree(tmp_file); + + ret = chmod(mapping_file, 0644); + if (ret == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("fchmod failed [%d][%s].\n", ret, strerror(ret))); + goto done; + } + + ret = EOK; +done: + if (fstream) { + err = fclose(fstream); + if (err != 0) { + err = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("fclose failed [%d][%s].\n", err, strerror(err))); + /* Nothing to do here, just report the failure */ + } + } + + if (tmp_file) { + err = unlink(tmp_file); + if (err < 0) { + err = errno; + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not remove file [%s]: [%d]: %s", + tmp_file, err, strerror(err))); + } + } + talloc_free(tmp_ctx); + return ret; +} + static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, int count, struct sysdb_attrs **reply, bool *changes) @@ -598,6 +725,14 @@ static void ipa_subdomains_handler_done(struct tevent_req *req) DEBUG(SSSDBG_OP_FAILURE, ("sysdb_update_subdomains failed.\n")); goto done; } + + ret = ipa_subdomains_write_mappings(sysdb_ctx_get_domain(sysdb), + ctx->sd_ctx->num_subdoms, + ctx->sd_ctx->subdoms); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("ipa_subdomains_write_mappings failed.\n")); + } } -- cgit