Beispiel #1
0
static void test_sysdb_handle_original_uuid(void **state)
{
    int ret;
    struct sysdb_attrs *src_attrs;
    struct sysdb_attrs *dest_attrs;
    const char *guid;
    uint8_t bin_guid[] = AD_GUID_BIN;
    struct ldb_val guid_val = {bin_guid, 16};

    ret = sysdb_handle_original_uuid(NULL, NULL, NULL, NULL, NULL);
    assert_int_equal(ret, ENOENT);

    src_attrs = sysdb_new_attrs(NULL);
    assert_non_null(src_attrs);

    dest_attrs = sysdb_new_attrs(NULL);
    assert_non_null(dest_attrs);

    ret = sysdb_handle_original_uuid("xyz", src_attrs, "abc", dest_attrs,
                                     "def");
    assert_int_equal(ret, ENOENT);

    ret = sysdb_attrs_add_val(src_attrs, "GUID", &guid_val);
    assert_int_equal(ret, EOK);

    ret = sysdb_attrs_add_string(src_attrs, "UUID", IPA_UUID);
    assert_int_equal(ret, EOK);

    ret = sysdb_handle_original_uuid(NULL, src_attrs, "GUID",
                                     dest_attrs, "def");
    assert_int_equal(ret, ENOENT);

    ret = sysdb_handle_original_uuid("objectGUID", NULL, "GUID",
                                     dest_attrs, "def");
    assert_int_equal(ret, EINVAL);

    ret = sysdb_handle_original_uuid("objectGUID", src_attrs, "GUID",
                                     dest_attrs, "def");
    assert_int_equal(ret, EOK);
    ret = sysdb_attrs_get_string(dest_attrs, "def", &guid);
    assert_int_equal(ret, EOK);
    assert_string_equal(guid, AD_GUID);

    ret = sysdb_handle_original_uuid("ipaUniqueID", src_attrs, "UUID",
                                     dest_attrs, "ghi");
    assert_int_equal(ret, EOK);
    ret = sysdb_attrs_get_string(dest_attrs, "ghi", &guid);
    assert_int_equal(ret, EOK);
    assert_string_equal(guid, IPA_UUID);

    talloc_free(src_attrs);
    src_attrs = sysdb_new_attrs(NULL);
    assert_non_null(src_attrs);

    /* check objectGUID with length other than 16 */
    ret = sysdb_attrs_add_string(src_attrs, "GUID", IPA_UUID);
    assert_int_equal(ret, EOK);
    ret = sysdb_handle_original_uuid("objectGUID", src_attrs, "GUID",
                                     dest_attrs, "jkl");
    assert_int_equal(ret, EOK);
    ret = sysdb_attrs_get_string(dest_attrs, "jkl", &guid);
    assert_int_equal(ret, EOK);
    assert_string_equal(guid, IPA_UUID);

    talloc_free(src_attrs);
    talloc_free(dest_attrs);
}
Beispiel #2
0
errno_t
sysdb_store_ssh_host(struct sysdb_ctx *sysdb,
                     struct sss_domain_info *domain,
                     const char *name,
                     const char *alias,
                     time_t now,
                     struct sysdb_attrs *attrs)
{
    TALLOC_CTX *tmp_ctx;
    errno_t ret, sret;
    bool in_transaction = false;
    const char *search_attrs[] = { SYSDB_NAME_ALIAS, NULL };
    bool new_alias;
    struct ldb_message *host = NULL;
    struct ldb_message_element *el;
    unsigned int i;

    DEBUG(SSSDBG_TRACE_FUNC, ("Storing host %s\n", name));

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

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

    in_transaction = true;

    ret = sysdb_get_ssh_host(tmp_ctx, sysdb, domain, name, search_attrs, &host);
    if (ret != EOK && ret != ENOENT) {
        goto done;
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, SYSDB_SSH_HOST_OC);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              ("Could not set object class [%d]: %s\n", ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              ("Could not set name attribute [%d]: %s\n", ret, strerror(ret)));
        goto done;
    }

    if (alias) {
        new_alias = true;

        /* copy aliases from the existing entry */
        if (host) {
            el = ldb_msg_find_element(host, SYSDB_NAME_ALIAS);

            if (el) {
                for (i = 0; i < el->num_values; i++) {
                    if (strcmp((char *)el->values[i].data, alias) == 0) {
                        new_alias = false;
                    }

                    ret = sysdb_attrs_add_val(attrs,
                                              SYSDB_NAME_ALIAS, &el->values[i]);
                    if (ret != EOK) {
                        DEBUG(SSSDBG_OP_FAILURE,
                              ("Could not add name alias %s [%d]: %s\n",
                               el->values[i].data, ret, strerror(ret)));
                        goto done;
                    }
                }
            }
        }

        /* add alias only if it is not already present */
        if (new_alias) {
            ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, alias);
            if (ret != EOK) {
                DEBUG(SSSDBG_OP_FAILURE,
                      ("Could not add name alias %s [%d]: %s\n",
                       alias, ret, strerror(ret)));
                goto done;
            }
        }
    }

    /* make sure sshPublicKey is present when modifying an existing host */
    if (host) {
        ret = sysdb_attrs_get_el(attrs, SYSDB_SSH_PUBKEY, &el);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE,
                  ("Could not get sysdb sshPublicKey [%d]: %s\n",
                   ret, strerror(ret)));
            goto done;
        }
    }

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              ("Could not set sysdb lastUpdate [%d]: %s\n",
               ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_update_ssh_host(sysdb, domain, name, attrs);
    if (ret != EOK) {
        goto done;
    }

    ret = sysdb_transaction_commit(sysdb);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
        goto done;
    }

    in_transaction = false;

    ret = EOK;

done:
    if (in_transaction) {
        sret = sysdb_transaction_cancel(sysdb);
        if (sret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction\n"));
        }
    }

    talloc_free(tmp_ctx);

    return ret;
}
Beispiel #3
0
int sdap_parse_entry(TALLOC_CTX *memctx,
                     struct sdap_handle *sh, struct sdap_msg *sm,
                     struct sdap_attr_map *map, int attrs_num,
                     struct sysdb_attrs **_attrs, char **_dn,
                     bool disable_range_retrieval)
{
    struct sysdb_attrs *attrs;
    BerElement *ber = NULL;
    struct berval **vals;
    struct ldb_val v;
    char *str;
    int lerrno;
    int a, i, ret;
    const char *name;
    bool store;
    bool base64;
    char *base_attr;
    char *dn = NULL;
    uint32_t range_offset;
    TALLOC_CTX *tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) return ENOMEM;

    lerrno = 0;
    ret = ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
    if (ret != LDAP_OPT_SUCCESS) {
        DEBUG(1, ("ldap_set_option failed [%s], ignored.\n",
                  sss_ldap_err2string(ret)));
    }

    attrs = sysdb_new_attrs(tmp_ctx);
    if (!attrs) {
        ret = ENOMEM;
        goto done;
    }

    str = ldap_get_dn(sh->ldap, sm->msg);
    if (!str) {
        ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
        DEBUG(1, ("ldap_get_dn failed: %d(%s)\n",
                  lerrno, sss_ldap_err2string(lerrno)));
        ret = EIO;
        goto done;
    }

    DEBUG(9, ("OriginalDN: [%s].\n", str));
    ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_DN, str);
    if (ret) goto done;
    if (_dn) {
        dn = talloc_strdup(tmp_ctx, str);
        if (!dn) {
            ret = ENOMEM;
            ldap_memfree(str);
            goto done;
        }
    }
    ldap_memfree(str);

    if (map) {
        vals = ldap_get_values_len(sh->ldap, sm->msg, "objectClass");
        if (!vals) {
            DEBUG(1, ("Unknown entry type, no objectClasses found!\n"));
            ret = EINVAL;
            goto done;
        }

        for (i = 0; vals[i]; i++) {
            /* the objectclass is always the first name in the map */
            if (strncasecmp(map[0].name,
                            vals[i]->bv_val, vals[i]->bv_len) == 0) {
                /* ok it's an entry of the right type */
                break;
            }
        }
        if (!vals[i]) {
            DEBUG(1, ("objectClass not matching: %s\n",
                      map[0].name));
            ldap_value_free_len(vals);
            ret = EINVAL;
            goto done;
        }
        ldap_value_free_len(vals);
    }

    str = ldap_first_attribute(sh->ldap, sm->msg, &ber);
    if (!str) {
        ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
        DEBUG(lerrno == LDAP_SUCCESS
              ? SSSDBG_TRACE_INTERNAL
              : SSSDBG_MINOR_FAILURE,
              ("Entry has no attributes [%d(%s)]!?\n",
               lerrno, sss_ldap_err2string(lerrno)));
        if (map) {
            ret = EINVAL;
            goto done;
        }
    }
    while (str) {
        base64 = false;

        ret = sdap_parse_range(tmp_ctx, str, &base_attr, &range_offset,
                               disable_range_retrieval);
        switch(ret) {
        case EAGAIN:
            /* This attribute contained range values and needs more to
             * be retrieved
             */
            /* TODO: return the set of attributes that need additional retrieval
             * For now, we'll continue below and treat it as regular values.
             */
            /* FALLTHROUGH */
        case ECANCELED:
            /* FALLTHROUGH */
        case EOK:
            break;
        default:
            DEBUG(SSSDBG_MINOR_FAILURE,
                  ("Could not determine if attribute [%s] was ranged\n", str));
            goto done;
        }

        if (map) {
            for (a = 1; a < attrs_num; a++) {
                /* check if this attr is valid with the chosen schema */
                if (!map[a].name) continue;
                /* check if it is an attr we are interested in */
                if (strcasecmp(base_attr, map[a].name) == 0) break;
            }
            /* interesting attr */
            if (a < attrs_num) {
                store = true;
                name = map[a].sys_name;
                if (strcmp(name, SYSDB_SSH_PUBKEY) == 0) {
                    base64 = true;
                }
            } else {
                store = false;
                name = NULL;
            }
        } else {
            name = base_attr;
            store = true;
        }

        if (ret == ECANCELED) {
            ret = EOK;
            store = false;
        }

        if (store) {
            vals = ldap_get_values_len(sh->ldap, sm->msg, str);
            if (!vals) {
                ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
                if (lerrno != LDAP_SUCCESS) {
                    DEBUG(1, ("LDAP Library error: %d(%s)",
                              lerrno, sss_ldap_err2string(lerrno)));
                    ret = EIO;
                    goto done;
                }

                DEBUG(5, ("Attribute [%s] has no values, skipping.\n", str));

            } else {
                if (!vals[0]) {
                    DEBUG(1, ("Missing value after ldap_get_values() ??\n"));
                    ret = EINVAL;
                    goto done;
                }
                for (i = 0; vals[i]; i++) {
                    if (vals[i]->bv_len == 0) {
                        DEBUG(SSSDBG_MINOR_FAILURE,
                              ("Value of attribute [%s] is empty. "
                               "Skipping this value.\n", str));
                        continue;
                    }
                    if (base64) {
                        v.data = (uint8_t *)sss_base64_encode(attrs,
                                (uint8_t *)vals[i]->bv_val, vals[i]->bv_len);
                        if (!v.data) {
                            ret = ENOMEM;
                            goto done;
                        }
                        v.length = strlen((const char *)v.data);
                    } else {
                        v.data = (uint8_t *)vals[i]->bv_val;
                        v.length = vals[i]->bv_len;
                    }

                    ret = sysdb_attrs_add_val(attrs, name, &v);
                    if (ret) goto done;
                }
                ldap_value_free_len(vals);
            }
        }

        ldap_memfree(str);
        str = ldap_next_attribute(sh->ldap, sm->msg, ber);
    }
    ber_free(ber, 0);
    ber = NULL;

    ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);
    if (lerrno) {
        DEBUG(1, ("LDAP Library error: %d(%s)",
                  lerrno, sss_ldap_err2string(lerrno)));
        ret = EIO;
        goto done;
    }

    *_attrs = talloc_steal(memctx, attrs);
    if (_dn) *_dn = talloc_steal(memctx, dn);
    ret = EOK;

done:
    if (ber) ber_free(ber, 0);
    talloc_free(tmp_ctx);
    return ret;
}