예제 #1
0
파일: usertools.c 프로젝트: 3van/sssd
char *
sss_get_domain_name(TALLOC_CTX *mem_ctx,
                    const char *orig_name,
                    struct sss_domain_info *dom)
{
    char *user_name;
    char *domain = NULL;
    int ret;

    /* check if the name already contains domain part */
    if (dom->names != NULL) {
        ret = sss_parse_name(mem_ctx, dom->names, orig_name, &domain, NULL);
        if (ret == ERR_REGEX_NOMATCH) {
            DEBUG(SSSDBG_TRACE_FUNC,
                  "sss_parse_name could not parse domain from [%s]. "
                  "Assuming it is not FQDN.\n", orig_name);
        } else if (ret != EOK) {
            DEBUG(SSSDBG_TRACE_FUNC,
                  "sss_parse_name failed [%d]: %s\n", ret, sss_strerror(ret));
            return NULL;
        }
    }

    if (IS_SUBDOMAIN(dom) && dom->fqnames && domain == NULL) {
        /* we always use the fully qualified name for subdomain users */
        user_name = sss_tc_fqname(mem_ctx, dom->names, dom, orig_name);
    } else {
        user_name = talloc_strdup(mem_ctx, orig_name);
    }

    talloc_free(domain);

    return user_name;
}
예제 #2
0
struct sss_domain_info *get_next_domain(struct sss_domain_info *domain,
                                        uint32_t gnd_flags)
{
    struct sss_domain_info *dom;
    bool descend = gnd_flags & SSS_GND_DESCEND;
    bool include_disabled = gnd_flags & SSS_GND_INCLUDE_DISABLED;

    dom = domain;
    while (dom) {
        if (descend && dom->subdomains) {
            dom = dom->subdomains;
        } else if (dom->next) {
            dom = dom->next;
        } else if (descend && IS_SUBDOMAIN(dom) && dom->parent->next) {
            dom = dom->parent->next;
        } else {
            dom = NULL;
        }

        if (dom) {
            if (sss_domain_get_state(dom) == DOM_DISABLED
                    && !include_disabled) {
                continue;
            } else {
                /* Next domain found. */
                break;
            }
        }
    }

    return dom;
}
예제 #3
0
static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx,
                                   struct sss_domain_info *domain,
                                   const char **attrs,
                                   const char *filter,
                                   struct sysdb_attrs ***_rules,
                                   uint32_t *_count)
{
    TALLOC_CTX *tmp_ctx;
    errno_t ret;
    size_t count;
    struct sysdb_attrs **rules;
    struct ldb_message **msgs;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        return ENOMEM;
    }

    DEBUG(SSSDBG_FUNC_DATA, "Searching sysdb with [%s]\n", filter);

    if (IS_SUBDOMAIN(domain)) {
        /* rules are stored inside parent domain tree */
        domain = domain->parent;
    }

    ret = sysdb_search_custom(tmp_ctx, domain, filter, SUDORULE_SUBDIR,
                              attrs, &count, &msgs);
    if (ret == ENOENT) {
        *_rules = NULL;
        *_count = 0;
        ret = EOK;
        goto done;
    } else if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up SUDO rules\n");
        goto done;
    }

    ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &rules);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Could not convert ldb message to sysdb_attrs\n");
        goto done;
    }

    *_rules = talloc_steal(mem_ctx, rules);
    *_count = (uint32_t)count;

    ret = EOK;

done:
    talloc_free(tmp_ctx);
    return ret;
}
예제 #4
0
char *subdomain_create_conf_path(TALLOC_CTX *mem_ctx,
                                 struct sss_domain_info *subdomain)
{
    if (!IS_SUBDOMAIN(subdomain)) {
        DEBUG(SSSDBG_OP_FAILURE,
              "The domain \"%s\" is not a subdomain.\n",
              subdomain->name);
        return NULL;
    }

    return subdomain_create_conf_path_from_str(mem_ctx,
                                               subdomain->parent->name,
                                               subdomain->name);
}
예제 #5
0
struct sss_domain_info *get_next_domain(struct sss_domain_info *domain,
                                        bool descend)
{
    struct sss_domain_info *dom;

    dom = domain;
    while (dom) {
        if (descend && dom->subdomains) {
            dom = dom->subdomains;
        } else if (dom->next) {
            dom = dom->next;
        } else if (descend && IS_SUBDOMAIN(dom) && dom->parent->next) {
            dom = dom->parent->next;
        } else {
            dom = NULL;
        }
        if (dom && !dom->disabled) break;
    }

    return dom;
}
예제 #6
0
파일: sdap_ad_groups.c 프로젝트: abbra/sssd
errno_t sdap_check_ad_group_type(struct sss_domain_info *dom,
                                 struct sdap_options *opts,
                                 struct sysdb_attrs *group_attrs,
                                 const char *group_name,
                                 bool *_need_filter)
{
    int32_t ad_group_type;
    errno_t ret = EOK;
    *_need_filter = false;

    if (opts->schema_type == SDAP_SCHEMA_AD) {
        ret = sysdb_attrs_get_int32_t(group_attrs, SYSDB_GROUP_TYPE,
                                      &ad_group_type);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_int32_t failed.\n");
            return ret;
        }

        DEBUG(SSSDBG_TRACE_ALL,
              "AD group [%s] has type flags %#x.\n",
              group_name, ad_group_type);

        /* Only security groups from AD are considered for POSIX groups.
         * Additionally only global and universal group are taken to account
         * for trusted domains. */
        if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY)
                || (IS_SUBDOMAIN(dom)
                    && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL)
                          || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) {
            DEBUG(SSSDBG_TRACE_FUNC,
                  "Filtering AD group [%s].\n", group_name);

            *_need_filter = true;
        }
    }

    return ret;
}
예제 #7
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;
}
예제 #8
0
/* FIXME: support storing additional attributes */
int sdap_save_user(TALLOC_CTX *memctx,
                   struct sdap_options *opts,
                   struct sss_domain_info *dom,
                   struct sysdb_attrs *attrs,
                   char **_usn_value,
                   time_t now)
{
    struct ldb_message_element *el;
    int ret;
    const char *user_name = NULL;
    const char *fullname = NULL;
    const char *pwd;
    const char *gecos;
    const char *homedir;
    const char *shell;
    const char *orig_dn = NULL;
    uid_t uid;
    gid_t gid;
    struct sysdb_attrs *user_attrs;
    char *upn = NULL;
    size_t i;
    int cache_timeout;
    char *usn_value = NULL;
    char **missing = NULL;
    TALLOC_CTX *tmpctx = NULL;
    bool use_id_mapping;
    char *sid_str;
    char *dom_sid_str = NULL;
    struct sss_domain_info *subdomain;

    DEBUG(SSSDBG_TRACE_FUNC, "Save user\n");

    tmpctx = talloc_new(NULL);
    if (!tmpctx) {
        ret = ENOMEM;
        goto done;
    }

    user_attrs = sysdb_new_attrs(tmpctx);
    if (user_attrs == NULL) {
        ret = ENOMEM;
        goto done;
    }

    /* Always store SID string if available */
    ret = sdap_attrs_get_sid_str(tmpctx, opts->idmap_ctx, attrs,
                                opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
                                &sid_str);
    if (ret == EOK) {
        ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
        if (ret != EOK) {
            DEBUG(SSSDBG_MINOR_FAILURE, "Could not add SID string: [%s]\n",
                                         sss_strerror(ret));
            goto done;
        }
    } else if (ret == ENOENT) {
        DEBUG(SSSDBG_TRACE_ALL, "objectSID: not available for user\n");
        sid_str = NULL;
    } else {
        DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify objectSID: [%s]\n",
                                     sss_strerror(ret));
        sid_str = NULL;
    }

    /* Always store UUID if available */
    ret = sysdb_handle_original_uuid(opts->user_map[SDAP_AT_USER_UUID].def_name,
                                     attrs,
                                     opts->user_map[SDAP_AT_USER_UUID].sys_name,
                                     user_attrs, SYSDB_UUID);
    if (ret != EOK) {
        DEBUG((ret == ENOENT) ? SSSDBG_TRACE_ALL : SSSDBG_MINOR_FAILURE,
              "Failed to retrieve UUID [%d][%s].\n", ret, sss_strerror(ret));
    }

    /* If this object has a SID available, we will determine the correct
     * domain by its SID. */
    if (sid_str != NULL) {
        subdomain = find_domain_by_sid(get_domains_head(dom), sid_str);
        if (subdomain) {
            dom = subdomain;
        } else {
            DEBUG(SSSDBG_TRACE_FUNC, "SID %s does not belong to any known "
                                      "domain\n", sid_str);
        }
    }

    ret = sdap_get_user_primary_name(memctx, opts, attrs, dom, &user_name);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "Failed to get user name\n");
        goto done;
    }
    DEBUG(SSSDBG_TRACE_FUNC, "Processing user %s\n", user_name);

    if (opts->schema_type == SDAP_SCHEMA_AD) {
        ret = sysdb_attrs_get_string(attrs,
                    opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &fullname);
        if (ret == EOK) {
            ret = sysdb_attrs_add_string(user_attrs, SYSDB_FULLNAME, fullname);
            if (ret != EOK) {
                goto done;
            }
        } else if (ret != ENOENT) {
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) pwd = NULL;
    else pwd = (const char *)el->values[0].data;

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_GECOS].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) gecos = NULL;
    else gecos = (const char *)el->values[0].data;

    if (!gecos) {
        /* Fall back to the user's full name */
        ret = sysdb_attrs_get_el(
                attrs,
                opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &el);
        if (ret) goto done;
        if (el->num_values > 0) gecos = (const char *)el->values[0].data;
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_HOME].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) homedir = NULL;
    else homedir = (const char *)el->values[0].data;

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_SHELL].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) shell = NULL;
    else shell = (const char *)el->values[0].data;

    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx,
                                                               dom->name,
                                                               sid_str);

    /* Retrieve or map the UID as appropriate */
    if (use_id_mapping) {

        if (sid_str == NULL) {
            DEBUG(SSSDBG_MINOR_FAILURE, "SID not available, cannot map a " \
                                         "unix ID to user [%s].\n", user_name);
            ret = ENOENT;
            goto done;
        }

        DEBUG(SSSDBG_TRACE_LIBS,
              "Mapping user [%s] objectSID [%s] to unix ID\n", user_name, sid_str);

        /* Convert the SID into a UNIX user ID */
        ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &uid);
        if (ret == ENOTSUP) {
            DEBUG(SSSDBG_TRACE_FUNC, "Skipping built-in object.\n");
            ret = EOK;
            goto done;
        } else if (ret != EOK) {
            goto done;
        }

        /* Store the UID in the ldap_attrs so it doesn't get
         * treated as a missing attribute from LDAP and removed.
         */
        ret = sdap_replace_id(attrs, SYSDB_UIDNUM, uid);
        if (ret) {
            DEBUG(SSSDBG_OP_FAILURE, "Cannot set the id-mapped UID\n");
            goto done;
        }
    } else {
        ret = sysdb_attrs_get_uint32_t(attrs,
                                       opts->user_map[SDAP_AT_USER_UID].sys_name,
                                       &uid);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "no uid provided for [%s] in domain [%s].\n",
                   user_name, dom->name);
            ret = EINVAL;
            goto done;
        }
    }
    /* check that the uid is valid for this domain */
    if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "User [%s] filtered out! (uid out of range)\n",
                      user_name);
        ret = EINVAL;
        goto done;
    }

    if (use_id_mapping) {
        ret = sdap_get_idmap_primary_gid(opts, attrs, sid_str, dom_sid_str,
                                         &gid);
        if (ret) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Cannot get the GID for [%s] in domain [%s].\n",
                   user_name, dom->name);
            goto done;
        }

        if (IS_SUBDOMAIN(dom)) {
            /* For subdomain users, only create the private group as
             * the subdomain is an MPG domain.
             * But we have to save the GID of the original primary group
             * becasuse otherwise this information might be lost because
             * typically (Unix and AD) the user is not listed in his primary
             * group as a member.
             */
            ret = sysdb_attrs_add_uint32(user_attrs, SYSDB_PRIMARY_GROUP_GIDNUM,
                                         (uint32_t) gid);
            if (ret != EOK) {
                DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n");
                goto done;
            }

            gid = 0;
        }

        /* Store the GID in the ldap_attrs so it doesn't get
        * treated as a missing attribute from LDAP and removed.
        */
        ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid);
        if (ret != EOK) goto done;
    } else {
        ret = sysdb_attrs_get_uint32_t(attrs,
                                       opts->user_map[SDAP_AT_USER_GID].sys_name,
                                       &gid);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "no gid provided for [%s] in domain [%s].\n",
                  user_name, dom->name);
            ret = EINVAL;
            goto done;
        }
    }

    /* check that the gid is valid for this domain */
    if (IS_SUBDOMAIN(dom) == false &&
            OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "User [%s] filtered out! (primary gid out of range)\n",
               user_name);
        ret = EINVAL;
        goto done;
    }

    ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
    if (ret) {
        goto done;
    }
    if (!el || el->num_values == 0) {
        DEBUG(SSSDBG_MINOR_FAILURE,
              "originalDN is not available for [%s].\n", user_name);
    } else {
        orig_dn = (const char *) el->values[0].data;
        DEBUG(SSSDBG_TRACE_INTERNAL, "Adding originalDN [%s] to attributes "
                "of [%s].\n", orig_dn, user_name);

        ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN, orig_dn);
        if (ret) {
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs, SYSDB_MEMBEROF, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(SSSDBG_TRACE_FUNC,
              "Original memberOf is not available for [%s].\n", user_name);
    } else {
        DEBUG(SSSDBG_TRACE_FUNC,
              "Adding original memberOf attributes to [%s].\n", user_name);
        for (i = 0; i < el->num_values; i++) {
            ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF,
                    (const char *) el->values[i].data);
            if (ret) {
                goto done;
            }
        }
    }

    ret = sdap_attrs_add_string(attrs,
                            opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name,
                            "original mod-Timestamp",
                            user_name, user_attrs);
    if (ret != EOK) {
        goto done;
    }

    ret = sysdb_attrs_get_el(attrs,
                      opts->user_map[SDAP_AT_USER_USN].sys_name, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(SSSDBG_TRACE_FUNC,
              "Original USN value is not available for [%s].\n", user_name);
    } else {
        ret = sysdb_attrs_add_string(user_attrs,
                          opts->user_map[SDAP_AT_USER_USN].sys_name,
                          (const char*)el->values[0].data);
        if (ret) {
            goto done;
        }
        usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data);
        if (!usn_value) {
            ret = ENOMEM;
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_PRINC].sys_name, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(SSSDBG_TRACE_FUNC,
              "User principal is not available for [%s].\n", user_name);
    } else {
        upn = talloc_strdup(user_attrs, (const char*) el->values[0].data);
        if (!upn) {
            ret = ENOMEM;
            goto done;
        }
        if (dp_opt_get_bool(opts->basic, SDAP_FORCE_UPPER_CASE_REALM)) {
            make_realm_upper_case(upn);
        }
        DEBUG(SSSDBG_TRACE_FUNC,
              "Adding user principal [%s] to attributes of [%s].\n",
               upn, user_name);
        ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, upn);
        if (ret) {
            goto done;
        }
    }

    for (i = SDAP_FIRST_EXTRA_USER_AT; i < opts->user_map_cnt; i++) {
        ret = sdap_attrs_add_list(attrs, opts->user_map[i].sys_name,
                                  NULL, user_name, user_attrs);
        if (ret) {
            goto done;
        }
    }

    cache_timeout = dom->user_timeout;

    ret = sdap_save_all_names(user_name, attrs, dom, user_attrs);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save user names\n");
        goto done;
    }

    /* Make sure that any attributes we requested from LDAP that we
     * did not receive are also removed from the sysdb
     */
    ret = list_missing_attrs(user_attrs, opts->user_map, opts->user_map_cnt,
                             attrs, &missing);
    if (ret != EOK) {
        goto done;
    }

    DEBUG(SSSDBG_TRACE_FUNC, "Storing info for user %s\n", user_name);

    ret = sysdb_store_user(dom, user_name, pwd, uid, gid,
                           gecos, homedir, shell, orig_dn,
                           user_attrs, missing, cache_timeout, now);
    if (ret) goto done;

    if (_usn_value) {
        *_usn_value = talloc_steal(memctx, usn_value);
    }

    talloc_steal(memctx, user_attrs);
    ret = EOK;

done:
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Failed to save user [%s]\n",
               user_name ? user_name : "Unknown");
    }
    talloc_free(tmpctx);
    return ret;
}
예제 #9
0
파일: sss_cache.c 프로젝트: mmsrubar/thesis
int main(int argc, const char *argv[])
{
    errno_t ret;
    struct cache_tool_ctx *tctx = NULL;
    struct sysdb_ctx *sysdb;
    bool skipped = true;
    struct sss_domain_info *dinfo;

    ret = init_context(argc, argv, &tctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Error initializing context for the application\n");
        goto done;
    }

    for (dinfo = tctx->domains; dinfo; dinfo = get_next_domain(dinfo, true)) {
         sysdb = dinfo->sysdb;

        if (!IS_SUBDOMAIN(dinfo)) {
            /* Update list of subdomains for this domain */
            ret = sysdb_update_subdomains(dinfo);
            if (ret != EOK) {
                DEBUG(SSSDBG_MINOR_FAILURE,
                      "Failed to update subdomains for domain %s.\n", dinfo->name);
            }
        }

        sysdb = dinfo->sysdb;
        /* Update filters for each domain */
        ret = update_all_filters(tctx, dinfo);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Failed to update filters.\n");
            goto done;
        }

        ret = sysdb_transaction_start(sysdb);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Could not start the transaction!\n");
            goto done;
        }

        skipped &= !invalidate_entries(tctx, dinfo, TYPE_USER,
                                       tctx->user_filter,
                                       tctx->user_name);
        skipped &= !invalidate_entries(tctx, dinfo, TYPE_GROUP,
                                       tctx->group_filter,
                                       tctx->group_name);
        skipped &= !invalidate_entries(tctx, dinfo, TYPE_NETGROUP,
                                       tctx->netgroup_filter,
                                       tctx->netgroup_name);
        skipped &= !invalidate_entries(tctx, dinfo, TYPE_SERVICE,
                                       tctx->service_filter,
                                       tctx->service_name);
        skipped &= !invalidate_entries(tctx, dinfo, TYPE_AUTOFSMAP,
                                       tctx->autofs_filter,
                                       tctx->autofs_name);

        ret = sysdb_transaction_commit(sysdb);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Could not commit the transaction!\n");
            ret = sysdb_transaction_cancel(sysdb);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "Failed to cancel transaction\n");
            }
        }
    }

    if (skipped == true) {
        ERROR("No cache object matched the specified search\n");
        ret = ENOENT;
        goto done;
    } else {
        ret = sss_memcache_clear_all();
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Failed to clear memory cache.\n");
            goto done;
        }
    }

    ret = EOK;
done:
    if (tctx) talloc_free(tctx);
    return ret;
}
예제 #10
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;
}