errno_t sss_write_krb5_conf_snippet(const char *path, bool canonicalize, bool udp_limit) { 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 = sss_write_krb5_libdefaults_snippet(path, canonicalize, udp_limit); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_write_krb5_libdefaults_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; }
errno_t sss_write_domain_mappings(struct sss_domain_info *domain, bool add_capaths) { struct sss_domain_info *dom; struct sss_domain_info *parent_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; bool capaths_started; char *uc_forest; char *uc_parent; 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; } } if (add_capaths) { capaths_started = false; parent_dom = domain; uc_parent = get_uppercase_realm(tmp_ctx, parent_dom->name); if (uc_parent == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; 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)) { if (dom->forest == NULL) { continue; } uc_forest = get_uppercase_realm(tmp_ctx, dom->forest); if (uc_forest == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; goto done; } if (!capaths_started) { ret = fprintf(fstream, "[capaths]\n"); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "fprintf failed\n"); ret = EIO; goto done; } capaths_started = true; } ret = fprintf(fstream, "%s = {\n %s = %s\n}\n%s = {\n %s = %s\n}\n", dom->realm, uc_parent, uc_forest, uc_parent, dom->realm, uc_forest); 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; }
errno_t sss_write_domain_mappings(struct sss_domain_info *domain) { 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; char *content = NULL; 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; ret = sss_get_domain_mappings_content(tmp_ctx, domain, &content); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_get_domain_mappings_content failed.\n"); goto done; } 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(SSS_DFL_UMASK); fd = mkstemp(tmp_file); umask(old_mode); if (fd < 0) { DEBUG(SSSDBG_OP_FAILURE, "creating the temp file [%s] for domain-realm mappings " "failed.\n", 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, "%s", content); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "fprintf failed\n"); ret = EIO; 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\n", tmp_file, err, strerror(err)); } } talloc_free(tmp_ctx); return ret; }