From 3b4deb7deb64136094aa5e70705b467a836dd05b Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 22 Jul 2016 20:10:42 +0200 Subject: [PATCH 14/14] SDAP: add enterprise principal strings for user searches Unfortunately principal aliases with an alternative realm are stored in IPA as the string representation of an enterprise principal, i.e. name\@alt.realm@IPA.REALM. To be able to lookup the alternative principal in LDAP properly the UPN search filter is extended to search for this type of name as well. --- src/providers/ldap/ldap_common.h | 5 +++++ src/providers/ldap/ldap_id.c | 10 +++++++-- src/providers/ldap/sdap_async_initgroups.c | 7 +++++- src/providers/ldap/sdap_utils.c | 28 ++++++++++++++++++++++++ src/tests/cmocka/test_nested_groups.c | 34 ++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h index 713b1dadf4053339e02db3a34ffac7f778f52a98..ff7ff2854ee55238d0b044b6a95980d08ba3ee84 100644 --- a/src/providers/ldap/ldap_common.h +++ b/src/providers/ldap/ldap_common.h @@ -300,6 +300,11 @@ char *sdap_combine_filters(TALLOC_CTX *mem_ctx, const char *base_filter, const char *extra_filter); +char *get_enterprise_principal_string_filter(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *princ, + struct dp_option *sdap_basic_opts); + char *sdap_get_access_filter(TALLOC_CTX *mem_ctx, const char *base_filter); diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index f27759e45c27f781617f53bc3ca5808a6dcbb601..fe0e219a255640b2934de4338ad796a65f348424 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -89,6 +89,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, enum idmap_error_code err; char *sid; char *user_filter = NULL; + char *ep_filter; req = tevent_req_create(memctx, &state, struct users_get_state); if (!req) return NULL; @@ -131,12 +132,17 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, if (ret != EOK) { goto done; } + + ep_filter = get_enterprise_principal_string_filter(state, + ctx->opts->user_map[SDAP_AT_USER_PRINC].name, + clean_value, ctx->opts->basic); /* TODO: Do we have to check the attribute names more carefully? */ - user_filter = talloc_asprintf(state, "(|(%s=%s)(%s=%s))", + user_filter = talloc_asprintf(state, "(|(%s=%s)(%s=%s)%s)", ctx->opts->user_map[SDAP_AT_USER_PRINC].name, clean_value, ctx->opts->user_map[SDAP_AT_USER_EMAIL].name, - clean_value); + clean_value, + ep_filter == NULL ? "" : ep_filter); talloc_zfree(clean_value); if (user_filter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c index 0a42b18662a8fe12cf048aadfef257b5d9cb48a3..4b90645877983456922a32113743cad65ccfcc9c 100644 --- a/src/providers/ldap/sdap_async_initgroups.c +++ b/src/providers/ldap/sdap_async_initgroups.c @@ -2683,6 +2683,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, char *clean_name; bool use_id_mapping; const char *search_attr; + char *ep_filter; DEBUG(SSSDBG_TRACE_ALL, "Retrieving info for initgroups call\n"); @@ -2743,13 +2744,17 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, return NULL; } + ep_filter = get_enterprise_principal_string_filter(state, + state->opts->user_map[SDAP_AT_USER_PRINC].name, + clean_name, state->opts->basic); state->user_base_filter = talloc_asprintf(state, - "(&(|(%s=%s)(%s=%s))(objectclass=%s)", + "(&(|(%s=%s)(%s=%s)%s)(objectclass=%s)", state->opts->user_map[SDAP_AT_USER_PRINC].name, clean_name, state->opts->user_map[SDAP_AT_USER_EMAIL].name, clean_name, + ep_filter == NULL ? "" : ep_filter, state->opts->user_map[SDAP_OC_USER].name); if (state->user_base_filter == NULL) { talloc_zfree(req); diff --git a/src/providers/ldap/sdap_utils.c b/src/providers/ldap/sdap_utils.c index a3a9642171ca057be5a59dfae192803b84c501c8..d224c89aa5f3948e9372cca64058ce1ef8d1cd6c 100644 --- a/src/providers/ldap/sdap_utils.c +++ b/src/providers/ldap/sdap_utils.c @@ -227,3 +227,31 @@ char *sdap_combine_filters(TALLOC_CTX *mem_ctx, { return sdap_combine_filters_ex(mem_ctx, '&', base_filter, extra_filter); } + +char *get_enterprise_principal_string_filter(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *princ, + struct dp_option *sdap_basic_opts) +{ + const char *realm; + char *p; + + if (attr_name == NULL || princ == NULL || sdap_basic_opts == NULL) { + return NULL; + } + + realm = dp_opt_get_cstring(sdap_basic_opts, SDAP_KRB5_REALM); + if (realm == NULL) { + return NULL; + } + + p = strchr(princ, '@'); + if (p == NULL) { + return NULL; + } + + + return talloc_asprintf(mem_ctx, "(%s=%.*s\\\\@%s@%s)", attr_name, + p - princ, princ, + p + 1, realm); +} diff --git a/src/tests/cmocka/test_nested_groups.c b/src/tests/cmocka/test_nested_groups.c index 6af7e1f4393992e7f16d72b86e40664487896ea1..c8e80f29fb65f8f8935fea32cd4bf3e16de7d06f 100644 --- a/src/tests/cmocka/test_nested_groups.c +++ b/src/tests/cmocka/test_nested_groups.c @@ -31,6 +31,7 @@ #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ldap/sdap_async_private.h" +#include "providers/ldap/ldap_opts.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_ldap_nested_groups_conf.ldb" @@ -1242,6 +1243,38 @@ static void nested_group_external_member_test(void **state) nested_group.gr_name); } +static void test_get_enterprise_principal_string_filter(void **state) +{ + int ret; + char *ep_filter; + struct dp_option *no_krb5_realm_opt = default_basic_opts; + + struct dp_option *krb5_realm_opt; + + ret = dp_copy_defaults(NULL, default_basic_opts, SDAP_OPTS_BASIC, + &krb5_realm_opt); + assert_int_equal(ret, EOK); + + ret = dp_opt_set_string(krb5_realm_opt, SDAP_KRB5_REALM, "TEST.DOM"); + assert_int_equal(ret, EOK); + + ep_filter = get_enterprise_principal_string_filter(NULL, NULL, NULL, NULL); + assert_null(ep_filter); + + ep_filter = get_enterprise_principal_string_filter(NULL, "aBC", "p@d.c", + no_krb5_realm_opt); + assert_null(ep_filter); + + ep_filter = get_enterprise_principal_string_filter(NULL, "aBC", "p", + krb5_realm_opt); + assert_null(ep_filter); + + ep_filter = get_enterprise_principal_string_filter(NULL, "aBC", "p@d.c", + krb5_realm_opt); + assert_non_null(ep_filter); + assert_string_equal(ep_filter, "(aBC=p\\\\@d.c@TEST.DOM)"); + talloc_free(ep_filter); +} int main(int argc, const char *argv[]) { @@ -1268,6 +1301,7 @@ int main(int argc, const char *argv[]) cmocka_unit_test_setup_teardown(nested_group_external_member_test, nested_group_external_member_setup, nested_group_external_member_teardown), + cmocka_unit_test(test_get_enterprise_principal_string_filter), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ -- 2.1.0