test_sdap.c revision 34de8a00f5b480ef3f46d2516e072e4acf1ebf87
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek Copyright (C) 2014 Red Hat
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek This program is free software; you can redistribute it and/or modify
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek it under the terms of the GNU General Public License as published by
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek the Free Software Foundation; either version 3 of the License, or
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek (at your option) any later version.
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek This program is distributed in the hope that it will be useful,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek GNU General Public License for more details.
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek You should have received a copy of the GNU General Public License
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek/* mock an LDAP entry */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *name;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char **values;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *dn;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozekstatic struct mock_ldap_entry *mock_ldap_entry_get(void)
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek return sss_mock_ptr_type(struct mock_ldap_entry *);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozekvoid set_entry_parse(struct mock_ldap_entry *entry)
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek will_return_always(mock_ldap_entry_get, entry);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek/* libldap wrappers */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozekchar *__wrap_ldap_get_dn(LDAP *ld, LDAPMessage *entry)
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_entry *ldap_entry = mock_ldap_entry_get();
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozekstruct berval **__wrap_ldap_get_values_len(LDAP *ld,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char **attrvals;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_entry *ldap_entry = mock_ldap_entry_get();
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* Should we return empty array here? */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek for (i = 0; ldap_entry->attrs[i].name != NULL; i++) {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek if (strcmp(ldap_entry->attrs[i].name, target) == 0) {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek for (i = 0; attrvals[i]; i++) {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek vals = talloc_zero_array(global_talloc_context,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek for (i = 0; attrvals[i]; i++) {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek vals[i]->bv_val = talloc_strdup(vals[i], attrvals[i]);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozekvoid __wrap_ldap_value_free_len(struct berval **vals)
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek talloc_free(vals); /* Allocated on global_talloc_context */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_entry *ldap_entry = mock_ldap_entry_get();
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek return discard_const(ldap_entry->attrs[0].name);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_entry *ldap_entry = mock_ldap_entry_get();
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek val = discard_const(ldap_entry->attrs[index].name);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek/* Mock parsing search base without overlinking the test */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozekerrno_t sdap_parse_search_base(TALLOC_CTX *mem_ctx,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek/* Utility function */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozekvoid assert_entry_has_attr(struct sysdb_attrs *attrs,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *attr,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *v;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozekvoid assert_entry_has_no_attr(struct sysdb_attrs *attrs,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *attr)
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *v;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_ctx = talloc_zero(global_talloc_context, struct parse_test_ctx);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek assert_true(check_leaks_pop(test_ctx) == true);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *oc_values[] = { "posixAccount", NULL };
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *extra_values[] = { "extra", NULL };
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *multi_values[] = { "svc1", "svc2", NULL };
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_attr test_ipa_user_attrs[] = {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek { .name = "objectClass", .values = oc_values },
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek { .name = "authorizedService", .values = multi_values },
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek { .name = "ipaSshPubKey", .values = ssh_values },
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_ipa_user.dn = "cn=testuser,dc=example,dc=com";
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_copy_map(test_ctx, ipa_user_map, SDAP_OPTS_USER, &map);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* Every entry has a DN */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek "cn=testuser,dc=example,dc=com");
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* Test the single-valued attribute */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek assert_entry_has_attr(attrs, SYSDB_NAME, "tuser1");
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* Multivalued attributes must return all values */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sysdb_attrs_get_el_ext(attrs, SYSDB_AUTHORIZED_SERVICE, false, &el);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek assert_true((strcmp((const char *) el->values[0].data, "svc1") == 0 &&
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek strcmp((const char *) el->values[1].data, "svc2") == 0) ||
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek (strcmp((const char *) el->values[1].data, "svc1") == 0 &&
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek strcmp((const char *) el->values[0].data, "svc2") == 0));
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* The SSH attribute must be base64 encoded */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sysdb_attrs_get_el_ext(attrs, SYSDB_SSH_PUBKEY, false, &el);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* The extra attribute must not be downloaded, it's not present in map */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek/* Some searches, like rootDSE search do not use any map */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *foo_values[] = { "fooval1", "fooval2", NULL };
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *bar_values[] = { "barval1", NULL };
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_attr test_nomap_entry_attrs[] = {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_nomap_entry.dn = "cn=testentry,dc=example,dc=com";
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_nomap_entry.attrs = test_nomap_entry_attrs;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek "cn=testentry,dc=example,dc=com");
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek assert_entry_has_attr(attrs, "bar", "barval1");
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* Multivalued attributes must return all values */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sysdb_attrs_get_el_ext(attrs, "foo", false, &el);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek assert_true((strcmp((const char *) el->values[0].data, "fooval1") == 0 &&
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek strcmp((const char *) el->values[1].data, "fooval2") == 0) ||
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek (strcmp((const char *) el->values[1].data, "fooval1") == 0 &&
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek strcmp((const char *) el->values[0].data, "fooval2") == 0));
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek/* Only DN and OC, no real attributes */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *oc_values[] = { "posixAccount", NULL };
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_attr test_rfc2307_user_attrs[] = {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek { .name = "objectClass", .values = oc_values },
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_rfc2307_user.dn = "cn=testuser,dc=example,dc=com";
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_rfc2307_user.attrs = test_rfc2307_user_attrs;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek "cn=testuser,dc=example,dc=com");
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state,
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek const char *oc_values[] = { "posixAccount", NULL };
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek { .name = "objectClass", .values = oc_values },
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek test_dupattr_user.dn = "cn=dupuser,dc=example,dc=com";
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map);
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek /* Set both uidNumber and gidNumber to idNumber */
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek for (i = 0; i < SDAP_OPTS_USER; i++) {
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm,
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek /* Every entry has a DN */
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek "cn=dupuser,dc=example,dc=com");
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek /* Test the single-valued attribute */
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek assert_entry_has_attr(attrs, SYSDB_UIDNUM, "1234");
eed2073f6f7bed7df0327b9fc0f2d410975d5332Jakub Hrozek assert_entry_has_attr(attrs, SYSDB_GIDNUM, "1234");
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek/* Negative test - objectclass doesn't match the map */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *oc_values[] = { "someRandomValueWhoCaresItsAUnitTest", NULL };
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_attr test_rfc2307_user_attrs[] = {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek { .name = "objectClass", .values = oc_values },
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_rfc2307_user.dn = "cn=testuser,dc=example,dc=com";
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_rfc2307_user.attrs = test_rfc2307_user_attrs;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek/* Negative test - the entry has no objectClass. Just make sure
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek * we don't crash
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_attr test_rfc2307_user_attrs[] = {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_rfc2307_user.dn = "cn=testuser,dc=example,dc=com";
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_rfc2307_user.attrs = test_rfc2307_user_attrs;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek/* Negative test - the entry has no DN. Just make sure
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek * we don't crash and detect the failure.
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek const char *oc_values[] = { "posixAccount", NULL };
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek struct mock_ldap_attr test_rfc2307_user_attrs[] = {
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek { .name = "objectClass", .values = oc_values },
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek test_rfc2307_user.attrs = test_rfc2307_user_attrs;
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm,
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* Negative tests */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* Set debug level to invalid value so we can deside if -d 0 was used. */
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek pc = poptGetContext(argv[0], argc, argv, long_options, 0);
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek /* Even though normally the tests should clean up after themselves
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek * they might not after a failed run. Remove the old db to be sure */