diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2013-06-26 22:39:41 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-06-27 18:43:57 +0200 |
commit | 58dd26b1c5b60ee992dd5d1214bb168aebb42d54 (patch) | |
tree | b9cdf45f5519050f77e81cbe9a84fc482eb70aba /src/util | |
parent | 80a874555d8b2737827bb150133ba70a83c65bb7 (diff) | |
download | sssd-58dd26b1c5b60ee992dd5d1214bb168aebb42d54.tar.gz sssd-58dd26b1c5b60ee992dd5d1214bb168aebb42d54.tar.bz2 sssd-58dd26b1c5b60ee992dd5d1214bb168aebb42d54.zip |
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.
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/domain_info_utils.c | 185 | ||||
-rw-r--r-- | src/util/sss_krb5.c | 22 | ||||
-rw-r--r-- | src/util/sss_krb5.h | 2 | ||||
-rw-r--r-- | src/util/util.h | 2 |
4 files changed, 187 insertions, 24 deletions
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c index 34aa3f33..b72e8e34 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 <http://www.gnu.org/licenses/>. */ +#include <utime.h> + #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 9adb8ff2..7d42e97f 100644 --- a/src/util/sss_krb5.c +++ b/src/util/sss_krb5.c @@ -20,7 +20,6 @@ #include <stdio.h> #include <errno.h> #include <talloc.h> -#include <utime.h> #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 9bae2f92..4d3b9f7e 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 8ae85f4f..f66f57b8 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); |