>From be90166ee5e0bfd2599a6ee98f0a9a1180573b3a Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 26 Jun 2013 22:39:41 +0200 Subject: [PATCH 1/2] IPA: Move the code to write domain mappings to domain_info_utils.c This makes the code reusable --- src/providers/ipa/ipa_subdomains.c | 190 +++++-------------------------------- src/util/domain_info_utils.c | 154 ++++++++++++++++++++++++++++++ src/util/util.h | 2 + 3 files changed, 182 insertions(+), 164 deletions(-) diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index 881f27c5d83f03a7e3bb1afb74fee765906e9148..2300249ca941f5d6e71348a44fc512aae5abea86 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -49,9 +49,6 @@ #define IPA_SUBDOMAIN_REFRESH_PERIOD (3600 * 4) #define IPA_SUBDOMAIN_DISABLED_PERIOD 3600 -/* 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, @@ -114,6 +111,29 @@ const char *get_flat_name_from_subdomain_name(struct be_ctx *be_ctx, return NULL; } +static errno_t +ipa_write_subdom_mappings(struct sss_domain_info *domain) +{ + errno_t ret; + + ret = sss_write_domain_mappings(domain); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, ("couldn't write domain-realm mappings\n")); + } + + /* Some mappings might have been written, touch krb5.conf */ + + /* touch krb5.conf to ensure that new mappings are loaded */ + ret = sss_krb5_touch_config(); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to change last modification time " + "of krb5.conf. Created mappings may not be loaded.\n")); + return ret; + } + + return EOK; +} + static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx, size_t count, struct sysdb_attrs **reply, @@ -256,165 +276,6 @@ done: return ret; } -static errno_t -ipa_subdomains_write_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", - IPA_SUBDOMAIN_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; - } - - /* touch krb5.conf to ensure that new mappings are loaded */ - ret = sss_krb5_touch_config(); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to change last modification time " - "of krb5.conf. Created mappings may not be loaded.\n")); - /* just continue */ - } - - 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) @@ -726,10 +587,11 @@ static void ipa_subdomains_handler_done(struct tevent_req *req) goto done; } - ret = ipa_subdomains_write_mappings(domain); + ret = ipa_write_subdom_mappings(domain); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, - ("ipa_subdomains_write_mappings failed.\n")); + ("sss_krb5_write_mappings failed.\n")); + /* Just continue */ } } diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c index 34aa3f33be045413a34ec2059c0318bb7b349302..15b53b83805602397622d8de325b7f86e75a44b2 100644 --- a/src/util/domain_info_utils.c +++ b/src/util/domain_info_utils.c @@ -22,6 +22,9 @@ #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 +193,154 @@ errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, 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: + 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/util.h b/src/util/util.h index 8ae85f4f1373a80d4c35ccd5efec06eae5ffcf38..f66f57b8979870e4b6462e55ece3627ec5fad54c 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); -- 1.8.3.1