Example #1
0
int ipa_get_options(TALLOC_CTX *memctx,
                    struct confdb_ctx *cdb,
                    const char *conf_path,
                    struct sss_domain_info *dom,
                    struct ipa_options **_opts)
{
    struct ipa_options *opts;
    char *domain;
    char *server;
    char *realm;
    char *ipa_hostname;
    int ret;
    char hostname[HOST_NAME_MAX + 1];

    opts = talloc_zero(memctx, struct ipa_options);
    if (!opts) return ENOMEM;

    ret = dp_get_options(opts, cdb, conf_path,
                         ipa_basic_opts,
                         IPA_OPTS_BASIC,
                         &opts->basic);
    if (ret != EOK) {
        goto done;
    }

    domain = dp_opt_get_string(opts->basic, IPA_DOMAIN);
    if (!domain) {
        ret = dp_opt_set_string(opts->basic, IPA_DOMAIN, dom->name);
        if (ret != EOK) {
            goto done;
        }
        domain = dom->name;
    }

    server = dp_opt_get_string(opts->basic, IPA_SERVER);
    if (!server) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "No ipa server set, will use service discovery!\n");
    }

    ipa_hostname = dp_opt_get_string(opts->basic, IPA_HOSTNAME);
    if (ipa_hostname == NULL) {
        ret = gethostname(hostname, HOST_NAME_MAX);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "gethostname failed [%d][%s].\n", errno,
                      strerror(errno));
            ret = errno;
            goto done;
        }
        hostname[HOST_NAME_MAX] = '\0';
        DEBUG(SSSDBG_TRACE_ALL, "Setting ipa_hostname to [%s].\n", hostname);
        ret = dp_opt_set_string(opts->basic, IPA_HOSTNAME, hostname);
        if (ret != EOK) {
            goto done;
        }
    }

    /* First check whether the realm has been manually specified */
    realm = dp_opt_get_string(opts->basic, IPA_KRB5_REALM);
    if (!realm) {
        /* No explicit krb5_realm, use the IPA domain, transform to upper-case */
        realm = get_uppercase_realm(opts, domain);
        if (!realm) {
            ret = ENOMEM;
            goto done;
        }

        ret = dp_opt_set_string(opts->basic, IPA_KRB5_REALM,
                                realm);
        if (ret != EOK) {
            goto done;
        }
    }

    ret = EOK;
    *_opts = opts;

done:
    if (ret != EOK) {
        talloc_zfree(opts);
    }
    return ret;
}
Example #2
0
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;
}
Example #3
0
errno_t sss_get_domain_mappings_content(TALLOC_CTX *mem_ctx,
                                        struct sss_domain_info *domain,
                                        char **content)
{
    int ret;
    char *o = NULL;
    struct sss_domain_info *dom;
    struct sss_domain_info *parent_dom;
    char *uc_parent = NULL;
    char *uc_forest = NULL;
    char *parent_capaths = NULL;
    bool capaths_started = false;

    if (domain == NULL || content == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Missing parameter.\n");
        return EINVAL;
    }

    o = talloc_strdup(mem_ctx, "[domain_realm]\n");
    if (o == NULL) {
        DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
        ret = ENOMEM;
        goto done;
    }

    /* This loops skips the starting parent and start rigth with the first
     * subdomain. Although in all the interesting cases (AD and IPA) the
     * default is that realm and DNS domain are the same strings (expect case)
     * and no domain_realm mapping is needed we might consider to add this
     * domain here as well to cover corner cases? */
    for (dom = get_next_domain(domain, SSS_GND_DESCEND);
                dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
                dom = get_next_domain(dom, 0)) {
        o = talloc_asprintf_append(o, ".%s = %s\n%s = %s\n",
                               dom->name, dom->realm, dom->name, dom->realm);
        if (o == NULL) {
            DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf_append failed.\n");
            ret = ENOMEM;
            goto done;
        }
    }

    parent_dom = domain;
    uc_parent = get_uppercase_realm(mem_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, SSS_GND_DESCEND);
            dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
            dom = get_next_domain(dom, 0)) {

        if (dom->forest == NULL) {
            continue;
        }

        talloc_free(uc_forest);
        uc_forest = get_uppercase_realm(mem_ctx, dom->forest);
        if (uc_forest == NULL) {
            DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n");
            ret = ENOMEM;
            goto done;
        }

        if (!capaths_started) {
            o = talloc_asprintf_append(o, "[capaths]\n");
            if (o == NULL) {
                DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf_append failed.\n");
                ret = ENOMEM;
                goto done;
            }
            capaths_started = true;
        }

        o = talloc_asprintf_append(o, "%s = {\n  %s = %s\n}\n",
                                   dom->realm, uc_parent, uc_forest);
        if (o == NULL) {
            DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf_append failed.\n");
            ret = ENOMEM;
            goto done;
        }

        if (parent_capaths == NULL) {
            parent_capaths = talloc_asprintf(mem_ctx, "  %s = %s\n", dom->realm,
                                                                     uc_forest);
        } else {
            parent_capaths = talloc_asprintf_append(parent_capaths,
                                                    "  %s = %s\n", dom->realm,
                                                    uc_forest);
        }
        if (parent_capaths == NULL) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "talloc_asprintf/talloc_asprintf_append failed.\n");
            ret = ENOMEM;
            goto done;
        }
    }

    if (parent_capaths != NULL) {
        o = talloc_asprintf_append(o, "%s = {\n%s}\n", uc_parent,
                                                       parent_capaths);
        if (o == NULL) {
            DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf_append failed.\n");
            ret = ENOMEM;
            goto done;
        }
    }

    ret = EOK;

done:
    talloc_free(parent_capaths);
    talloc_free(uc_parent);
    talloc_free(uc_forest);

    if (ret == EOK) {
        *content = o;
    } else {
        talloc_free(o);
    }

    return ret;
}