From 58dd26b1c5b60ee992dd5d1214bb168aebb42d54 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 26 Jun 2013 22:39:41 +0200 Subject: AD: Write out domain-realm mappings This patch reuses the code from IPA provider to make sure that domain-realm mappings are written even for AD sub domains. --- src/util/domain_info_utils.c | 185 +++++++++++++++++++++++++++++++++++++++++++ src/util/sss_krb5.c | 22 ----- src/util/sss_krb5.h | 2 - src/util/util.h | 2 + 4 files changed, 187 insertions(+), 24 deletions(-) (limited to 'src/util') diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c index 34aa3f33b..b72e8e348 100644 --- a/src/util/domain_info_utils.c +++ b/src/util/domain_info_utils.c @@ -18,10 +18,15 @@ along with this program. If not, see . */ +#include + #include "confdb/confdb.h" #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_next_domain(struct sss_domain_info *domain, bool descend) { @@ -190,3 +195,183 @@ errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, return EOK; } + +static errno_t +sss_krb5_touch_config(void) +{ + const char *config = NULL; + errno_t ret; + + config = getenv("KRB5_CONFIG"); + if (config == NULL) { + config = KRB5_CONF_PATH; + } + + ret = utime(config, NULL); + if (ret == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to change mtime of \"%s\" " + "[%d]: %s\n", config, strerror(ret))); + return ret; + } + + return EOK; +} + +errno_t +sss_write_domain_mappings(struct sss_domain_info *domain) +{ + struct sss_domain_info *dom; + errno_t ret; + errno_t err; + TALLOC_CTX *tmp_ctx; + const char *mapping_file; + char *sanitized_domain; + char *tmp_file = NULL; + int fd = -1; + mode_t old_mode; + FILE *fstream = NULL; + int i; + + if (domain == NULL || domain->name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("No domain name provided\n")); + return EINVAL; + } + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) return ENOMEM; + + sanitized_domain = talloc_strdup(tmp_ctx, domain->name); + if (sanitized_domain == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_strdup() failed\n")); + return ENOMEM; + } + + /* only alpha-numeric chars, dashes and underscores are allowed in + * krb5 include directory */ + for (i = 0; sanitized_domain[i] != '\0'; i++) { + if (!isalnum(sanitized_domain[i]) + && sanitized_domain[i] != '-' && sanitized_domain[i] != '_') { + sanitized_domain[i] = '_'; + } + } + + mapping_file = talloc_asprintf(tmp_ctx, "%s/domain_realm_%s", + KRB5_MAPPING_DIR, sanitized_domain); + if (!mapping_file) { + ret = ENOMEM; + goto done; + } + + DEBUG(SSSDBG_FUNC_DATA, ("Mapping file for domain [%s] is [%s]\n", + domain->name, mapping_file)); + + tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", mapping_file); + if (tmp_file == NULL) { + 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; + } + + 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 (dom = get_next_domain(domain, true); + dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ + dom = get_next_domain(dom, false)) { + ret = fprintf(fstream, ".%s = %s\n%s = %s\n", + dom->name, dom->realm, dom->name, dom->realm); + if (ret < 0) { + DEBUG(SSSDBG_CRIT_FAILURE, ("fprintf failed\n")); + goto done; + } + } + + ret = fclose(fstream); + fstream = NULL; + if (ret != 0) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("fclose failed [%d][%s].\n", ret, strerror(ret))); + goto done; + } + + 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: + 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 */ + } + + 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; +} diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c index 9adb8ff26..7d42e97f4 100644 --- a/src/util/sss_krb5.c +++ b/src/util/sss_krb5.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "config.h" @@ -1180,24 +1179,3 @@ done: return ENOTSUP; #endif } - -errno_t sss_krb5_touch_config(void) -{ - const char *config = NULL; - errno_t ret; - - config = getenv("KRB5_CONFIG"); - if (config == NULL) { - config = KRB5_CONF_PATH; - } - - ret = utime(config, NULL); - if (ret == -1) { - ret = errno; - DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to change mtime of \"%s\" " - "[%d]: %s\n", config, strerror(ret))); - return ret; - } - - return EOK; -} diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h index 9bae2f92b..4d3b9f7ed 100644 --- a/src/util/sss_krb5.h +++ b/src/util/sss_krb5.h @@ -192,6 +192,4 @@ krb5_error_code sss_extract_pac(krb5_context ctx, krb5_keytab keytab, krb5_authdata ***_pac_authdata); -errno_t sss_krb5_touch_config(void); - #endif /* __SSS_KRB5_H__ */ diff --git a/src/util/util.h b/src/util/util.h index 8ae85f4f1..f66f57b89 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -572,6 +572,8 @@ errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, #define IS_SUBDOMAIN(dom) ((dom)->parent != NULL) +errno_t sss_write_domain_mappings(struct sss_domain_info *domain); + /* from util_lock.c */ errno_t sss_br_lock_file(int fd, size_t start, size_t len, int num_tries, useconds_t wait); -- cgit