diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2014-07-04 16:58:11 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2014-07-08 20:28:03 +0200 |
commit | eed2073f6f7bed7df0327b9fc0f2d410975d5332 (patch) | |
tree | 77d1b5b6d79dcc9ae6f617949fd600e792362446 | |
parent | e592d5f157be869151983bd1b46d6f4f7a29daaf (diff) | |
download | sssd-eed2073f6f7bed7df0327b9fc0f2d410975d5332.tar.gz sssd-eed2073f6f7bed7df0327b9fc0f2d410975d5332.tar.xz sssd-eed2073f6f7bed7df0327b9fc0f2d410975d5332.zip |
LDAP: Try all attributes when saving an entry
The same LDAP attribute might be used several times for the same user or
group attribute. For instance, some servers have a global "ID" number
that should be used for both UID and GID. However, our
sdap_parse_entry() function only copied the LDAP attribute to the first
matching sysdb attribute.
This patch adds a second nested loop that checks if any of the other
LDAP attributes are eligible.
Reviewed-by: Michal Židek <mzidek@redhat.com>
-rw-r--r-- | src/providers/ldap/sdap.c | 27 | ||||
-rw-r--r-- | src/tests/cmocka/test_sdap.c | 55 |
2 files changed, 79 insertions, 3 deletions
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index e8d23c9dc..133e6dcf3 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -302,7 +302,7 @@ int sdap_parse_entry(TALLOC_CTX *memctx, struct ldb_val v; char *str; int lerrno; - int a, i, ret; + int a, i, ret, ai; const char *name; bool store; bool base64; @@ -480,8 +480,29 @@ int sdap_parse_entry(TALLOC_CTX *memctx, v.length = vals[i]->bv_len; } - ret = sysdb_attrs_add_val(attrs, name, &v); - if (ret) goto done; + if (map) { + /* The same LDAP attr might be used for more sysdb + * attrs in case there is a map. Find all that match + * and copy the value + */ + for (ai = a; ai < attrs_num; ai++) { + /* check if this attr is valid with the chosen + * schema */ + if (!map[ai].name) continue; + + /* check if it is an attr we are interested in */ + if (strcasecmp(base_attr, map[ai].name) == 0) { + ret = sysdb_attrs_add_val(attrs, + map[ai].sys_name, + &v); + if (ret) goto done; + } + } + } else { + /* No map, just store the attribute */ + ret = sysdb_attrs_add_val(attrs, name, &v); + if (ret) goto done; + } } ldap_value_free_len(vals); } diff --git a/src/tests/cmocka/test_sdap.c b/src/tests/cmocka/test_sdap.c index 3990d7a3e..8fdf1a4a2 100644 --- a/src/tests/cmocka/test_sdap.c +++ b/src/tests/cmocka/test_sdap.c @@ -372,6 +372,58 @@ void test_parse_no_attrs(void **state) talloc_free(attrs); } +void test_parse_dups(void **state) +{ + int ret; + struct sysdb_attrs *attrs; + struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, + struct parse_test_ctx); + struct mock_ldap_entry test_dupattr_user; + struct sdap_attr_map *map; + int i; + + const char *oc_values[] = { "posixAccount", NULL }; + const char *uid_values[] = { "1234", NULL }; + struct mock_ldap_attr test_dupattr_attrs[] = { + { .name = "objectClass", .values = oc_values }, + { .name = "idNumber", .values = uid_values }, + { NULL, NULL } + }; + + test_dupattr_user.dn = "cn=dupuser,dc=example,dc=com"; + test_dupattr_user.attrs = test_dupattr_attrs; + set_entry_parse(&test_dupattr_user); + + ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map); + assert_int_equal(ret, ERR_OK); + /* Set both uidNumber and gidNumber to idNumber */ + for (i = 0; i < SDAP_OPTS_USER; i++) { + if (map[i].name == NULL) continue; + + if (strcmp(map[i].name, "uidNumber") == 0 + || strcmp(map[i].name, "gidNumber") == 0) { + map[i].name = discard_const("idNumber"); + } + } + + ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm, + map, SDAP_OPTS_USER, + &attrs, NULL, false); + assert_int_equal(ret, ERR_OK); + + assert_int_equal(attrs->num, 3); + + /* Every entry has a DN */ + assert_entry_has_attr(attrs, SYSDB_ORIG_DN, + "cn=dupuser,dc=example,dc=com"); + /* Test the single-valued attribute */ + assert_entry_has_attr(attrs, SYSDB_UIDNUM, "1234"); + assert_entry_has_attr(attrs, SYSDB_GIDNUM, "1234"); + + talloc_free(map); + talloc_free(attrs); +} + /* Negative test - objectclass doesn't match the map */ void test_parse_bad_oc(void **state) { @@ -493,6 +545,9 @@ int main(int argc, const char *argv[]) unit_test_setup_teardown(test_parse_no_attrs, parse_entry_test_setup, parse_entry_test_teardown), + unit_test_setup_teardown(test_parse_dups, + parse_entry_test_setup, + parse_entry_test_teardown), /* Negative tests */ unit_test_setup_teardown(test_parse_no_oc, parse_entry_test_setup, |