On Thu, Nov 13, 2014 at 11:46:43AM +0100, Lukas Slebodnik wrote: > On (12/11/14 21:39), Sumit Bose wrote: > >On Mon, Nov 10, 2014 at 03:17:04PM +0100, Sumit Bose wrote: > >> Hi, > >> > >> this patch-set should solve https://fedorahosted.org/sssd/ticket/2481 > >> "ID Views implementation does not support IPA user&group overrides". It > >> depends on the already commit patches which bring back ldap_user_uuid > >> and ldap_group_uuid and "sysdb: add sysdb_search_object_by_uuid()" which > >> is still under review. > >> > >> Most of the patches adds support for UUIDs here and there, The main part > >> of the work is done in the 0006 where the user and group lookup request > >> is extended in a similar way like for AD users where the overrides are > >> checked first, then the original object and eventually a final lookup in > >> the override tree. I will file a ticket to refactor the code so that code > >> paths for IPA and AD users are unified but for the time being I think > >> it is better to have them separate so that changes in one path do not > >> break the other path. > >> > > > >Please find attached a new version of the patch set. It is rebased on > >current master plus the "sysdb: add sysdb_search_object_by_uuid()" patch > >and fixes a segfault in the 6th patch. > > > >bye, > >Sumit > > >From 9047069105444545a2f5dc0be3ef30d4c43689d1 Mon Sep 17 00:00:00 2001 > >From: Sumit Bose <sb...@redhat.com> > >Date: Fri, 7 Nov 2014 21:34:55 +0100 > >Subject: [PATCH 5/7] IPA: make get_object_from_cache() public > > > >Related to https://fedorahosted.org/sssd/ticket/2481 > >--- > > src/providers/ipa/ipa_id.h | 5 +++++ > > src/providers/ipa/ipa_subdomains_id.c | 9 +++++---- > > 2 files changed, 10 insertions(+), 4 deletions(-) > > > > >From 9047069105444545a2f5dc0be3ef30d4c43689d1 Mon Sep 17 00:00:00 2001 > >From: Sumit Bose <sb...@redhat.com> > >Date: Fri, 7 Nov 2014 21:34:55 +0100 > >Subject: [PATCH 5/7] IPA: make get_object_from_cache() public > > > >Related to https://fedorahosted.org/sssd/ticket/2481 > >--- > > src/providers/ipa/ipa_id.h | 5 +++++ > > src/providers/ipa/ipa_subdomains_id.c | 9 +++++---- > > 2 files changed, 10 insertions(+), 4 deletions(-) > > > > > I can see two attachements 0005-IPA-make-get_object_from_cache-public.patch > but there isn't 6th patch. > > Is it expected?
no, new set attached. bye, Sumit > > LS > _______________________________________________ > sssd-devel mailing list > sssd-devel@lists.fedorahosted.org > https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
From 9f807e92b8db786c331842117e1481dbb494a1f7 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Thu, 6 Nov 2014 13:13:27 +0100 Subject: [PATCH 1/7] ipa: add split_ipa_anchor() This call extracts the domain and the UUID part from an IPA override anchor. Related to https://fedorahosted.org/sssd/ticket/2481 --- Makefile.am | 2 ++ src/providers/ipa/ipa_id.h | 2 ++ src/providers/ipa/ipa_utils.c | 63 +++++++++++++++++++++++++++++++++++++ src/tests/cmocka/test_sysdb_views.c | 32 +++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 src/providers/ipa/ipa_utils.c diff --git a/Makefile.am b/Makefile.am index b85341f..c083a2e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2066,6 +2066,7 @@ endif # BUILD_IFP test_sysdb_views_SOURCES = \ src/tests/cmocka/test_sysdb_views.c \ + src/providers/ipa/ipa_utils.c \ $(NULL) test_sysdb_views_CFLAGS = \ $(AM_CFLAGS) \ @@ -2388,6 +2389,7 @@ libsss_ipa_la_SOURCES = \ src/providers/ipa/ipa_subdomains_id.c \ src/providers/ipa/ipa_subdomains_ext_groups.c \ src/providers/ipa/ipa_views.c \ + src/providers/ipa/ipa_utils.c \ src/providers/ipa/ipa_s2n_exop.c \ src/providers/ipa/ipa_hbac_hosts.c \ src/providers/ipa/ipa_hbac_private.h \ diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h index e13aded..033ac40 100644 --- a/src/providers/ipa/ipa_id.h +++ b/src/providers/ipa/ipa_id.h @@ -103,4 +103,6 @@ struct tevent_req *ipa_subdomain_account_send(TALLOC_CTX *memctx, errno_t ipa_subdomain_account_recv(struct tevent_req *req, int *dp_error_out); +errno_t split_ipa_anchor(TALLOC_CTX *mem_ctx, const char *anchor, + char **_anchor_domain, char **_ipa_uuid); #endif diff --git a/src/providers/ipa/ipa_utils.c b/src/providers/ipa/ipa_utils.c new file mode 100644 index 0000000..86ba51c --- /dev/null +++ b/src/providers/ipa/ipa_utils.c @@ -0,0 +1,63 @@ +/* + SSSD + + IPA Module utility functions + + Authors: + Sumit Bose <sb...@redhat.com> + + Copyright (C) 2014 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "util/util.h" + +#define OVERRIDE_ANCHOR_IPA_PREFIX ":IPA:" +#define OVERRIDE_ANCHOR_IPA_PREFIX_LEN (sizeof(OVERRIDE_ANCHOR_IPA_PREFIX) -1 ) + +errno_t split_ipa_anchor(TALLOC_CTX *mem_ctx, const char *anchor, + char **_anchor_domain, char **_ipa_uuid) +{ + const char *sep; + + if (anchor == NULL) { + return EINVAL; + } + if (strncmp(OVERRIDE_ANCHOR_IPA_PREFIX, anchor, + OVERRIDE_ANCHOR_IPA_PREFIX_LEN) != 0) { + DEBUG(SSSDBG_CRIT_FAILURE, "No IPA anchor [%s].\n", anchor); + return ENOMSG; + } + + sep = strchr(anchor + OVERRIDE_ANCHOR_IPA_PREFIX_LEN, ':'); + if (sep == NULL || sep[1] == '\0') { + DEBUG(SSSDBG_CRIT_FAILURE, "Broken IPA anchor [%s].\n", anchor); + return EINVAL; + } + + *_anchor_domain = talloc_strndup(mem_ctx, + anchor + OVERRIDE_ANCHOR_IPA_PREFIX_LEN, + sep - anchor - OVERRIDE_ANCHOR_IPA_PREFIX_LEN); + *_ipa_uuid = talloc_strdup(mem_ctx, sep + 1); + + if (*_anchor_domain == NULL || *_ipa_uuid == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); + talloc_free(*_anchor_domain); + talloc_free(*_ipa_uuid); + return ENOMEM; + } + + return EOK; +} diff --git a/src/tests/cmocka/test_sysdb_views.c b/src/tests/cmocka/test_sysdb_views.c index 9fb2d72..0dc5144 100644 --- a/src/tests/cmocka/test_sysdb_views.c +++ b/src/tests/cmocka/test_sysdb_views.c @@ -29,6 +29,7 @@ #include <popt.h> #include "tests/cmocka/common_mock.h" +#include "providers/ipa/ipa_id.h" #define TESTS_PATH "tests_sysdb_views" #define TEST_CONF_FILE "tests_conf.ldb" @@ -189,6 +190,35 @@ void test_sysdb_add_overrides_to_object(void **state) assert_int_equal(ldb_val_string_cmp(&el->values[1], "OVERRIDEKEY2"), 0); } +void test_split_ipa_anchor(void **state) +{ + int ret; + char *dom; + char *uuid; + struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, + struct sysdb_test_ctx); + + ret = split_ipa_anchor(test_ctx, NULL, &dom, &uuid); + assert_int_equal(ret, EINVAL); + + ret = split_ipa_anchor(test_ctx, "fwfkwjfkw", &dom, &uuid); + assert_int_equal(ret, ENOMSG); + + ret = split_ipa_anchor(test_ctx, ":IPA:", &dom, &uuid); + assert_int_equal(ret, EINVAL); + + ret = split_ipa_anchor(test_ctx, ":IPA:abc", &dom, &uuid); + assert_int_equal(ret, EINVAL); + + ret = split_ipa_anchor(test_ctx, ":IPA:abc:", &dom, &uuid); + assert_int_equal(ret, EINVAL); + + ret = split_ipa_anchor(test_ctx, ":IPA:abc:def", &dom, &uuid); + assert_int_equal(ret, EOK); + assert_string_equal(dom, "abc"); + assert_string_equal(uuid, "def"); +} + int main(int argc, const char *argv[]) { int rv; @@ -206,6 +236,8 @@ int main(int argc, const char *argv[]) const UnitTest tests[] = { unit_test_setup_teardown(test_sysdb_add_overrides_to_object, test_sysdb_setup, test_sysdb_teardown), + unit_test_setup_teardown(test_split_ipa_anchor, + test_sysdb_setup, test_sysdb_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ -- 1.8.3.1
From ec4cf492945cb8f30fcb2467e9d26836de7ff6d8 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 7 Nov 2014 13:55:01 +0100 Subject: [PATCH 2/7] LDAP: add support for lookups by UUID Related to https://fedorahosted.org/sssd/ticket/2481 --- src/providers/data_provider.h | 2 ++ src/providers/ldap/ldap_id.c | 58 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h index e1cb4be..5df493e 100644 --- a/src/providers/data_provider.h +++ b/src/providers/data_provider.h @@ -127,6 +127,7 @@ #define BE_FILTER_IDNUM 2 #define BE_FILTER_ENUM 3 #define BE_FILTER_SECID 4 +#define BE_FILTER_UUID 5 #define BE_REQ_USER 0x0001 #define BE_REQ_GROUP 0x0002 @@ -139,6 +140,7 @@ #define BE_REQ_HOST 0x0010 #define BE_REQ_BY_SECID 0x0011 #define BE_REQ_USER_AND_GROUP 0x0012 +#define BE_REQ_BY_UUID 0x0013 #define BE_REQ_TYPE_MASK 0x00FF #define BE_REQ_FAST 0x1000 diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index e8b3a0e..2e58f4e 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -179,6 +179,20 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, goto done; } break; + case BE_FILTER_UUID: + attr_name = ctx->opts->user_map[SDAP_AT_USER_UUID].name; + if (attr_name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "UUID search not configured for this backend.\n"); + ret = EINVAL; + goto done; + } + + ret = sss_filter_sanitize(state, name, &clean_name); + if (ret != EOK) { + goto done; + } + break; default: ret = EINVAL; goto done; @@ -458,8 +472,9 @@ static void users_get_done(struct tevent_req *subreq) break; case BE_FILTER_SECID: - /* Since it is not clear if the SID belongs to a user or a group - * we have nothing to do here. */ + case BE_FILTER_UUID: + /* Since it is not clear if the SID/UUID belongs to a user or a + * group we have nothing to do here. */ break; default: @@ -635,6 +650,20 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, goto done; } break; + case BE_FILTER_UUID: + attr_name = ctx->opts->group_map[SDAP_AT_GROUP_UUID].name; + if (attr_name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "UUID search not configured for this backend.\n"); + ret = EINVAL; + goto done; + } + + ret = sss_filter_sanitize(state, name, &clean_name); + if (ret != EOK) { + goto done; + } + break; default: ret = EINVAL; goto done; @@ -884,8 +913,9 @@ static void groups_get_done(struct tevent_req *subreq) break; case BE_FILTER_SECID: - /* Since it is not clear if the SID belongs to a user or a group - * we have nothing to do here. */ + case BE_FILTER_UUID: + /* Since it is not clear if the SID/UUID belongs to a user or a + * group we have nothing to do here. */ break; default: @@ -1401,7 +1431,8 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, goto done; } - if (ar->filter_type == BE_FILTER_SECID) { + if (ar->filter_type == BE_FILTER_SECID + || ar->filter_type == BE_FILTER_UUID) { ret = EINVAL; state->err = "Invalid filter type"; goto done; @@ -1430,6 +1461,21 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, noexist_delete); break; + case BE_REQ_BY_UUID: + if (ar->filter_type != BE_FILTER_UUID) { + ret = EINVAL; + state->err = "Invalid filter type"; + goto done; + } + + subreq = get_user_and_group_send(breq, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + ar->filter_type, + ar->attr_type, + noexist_delete); + break; + case BE_REQ_USER_AND_GROUP: if (!(ar->filter_type == BE_FILTER_NAME || ar->filter_type == BE_FILTER_IDNUM)) { @@ -1504,6 +1550,8 @@ sdap_handle_acct_req_done(struct tevent_req *subreq) break; case BE_REQ_BY_SECID: /* Fallthrough */ + case BE_REQ_BY_UUID: + /* Fallthrough */ case BE_REQ_USER_AND_GROUP: err = "Lookup by SID failed"; ret = sdap_get_user_and_group_recv(subreq, &state->dp_error, -- 1.8.3.1
From 15ea0a84cc1d1ded27c6f84ac563b7902f203526 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 7 Nov 2014 21:33:36 +0100 Subject: [PATCH 3/7] LDAP: always store UUID if available Related to https://fedorahosted.org/sssd/ticket/2481 --- src/providers/ldap/sdap_async_groups.c | 20 ++++++++++++++++++++ src/providers/ldap/sdap_async_users.c | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c index a82d2aa..dc1b60d 100644 --- a/src/providers/ldap/sdap_async_groups.c +++ b/src/providers/ldap/sdap_async_groups.c @@ -511,6 +511,7 @@ static int sdap_save_group(TALLOC_CTX *memctx, bool posix_group; bool use_id_mapping; char *sid_str; + const char *uuid; struct sss_domain_info *subdomain; int32_t ad_group_type; @@ -547,6 +548,25 @@ static int sdap_save_group(TALLOC_CTX *memctx, sid_str = NULL; } + /* Always store UUID if available */ + ret = sysdb_attrs_get_string(attrs, + opts->group_map[SDAP_AT_GROUP_UUID].sys_name, + &uuid); + if (ret == EOK) { + ret = sysdb_attrs_add_string(group_attrs, SYSDB_UUID, uuid); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Could not add UUID string: [%s]\n", + strerror(ret)); + goto done; + } + } else if (ret == ENOENT) { + DEBUG(SSSDBG_TRACE_ALL, "UUID not available for group [%s].\n", + group_name); + } else { + DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify UUID [%s]\n", + strerror(ret)); + } + /* If this object has a SID available, we will determine the correct * domain by its SID. */ if (sid_str != NULL) { diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c index 2331ba9..c6da5c1 100644 --- a/src/providers/ldap/sdap_async_users.c +++ b/src/providers/ldap/sdap_async_users.c @@ -140,6 +140,7 @@ int sdap_save_user(TALLOC_CTX *memctx, TALLOC_CTX *tmpctx = NULL; bool use_id_mapping; char *sid_str; + const char *uuid; char *dom_sid_str = NULL; struct sss_domain_info *subdomain; @@ -177,6 +178,24 @@ int sdap_save_user(TALLOC_CTX *memctx, sid_str = NULL; } + /* Always store UUID if available */ + ret = sysdb_attrs_get_string(attrs, + opts->user_map[SDAP_AT_USER_UUID].sys_name, + &uuid); + if (ret == EOK) { + ret = sysdb_attrs_add_string(user_attrs, SYSDB_UUID, uuid); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Could not add UUID string: [%s]\n", + strerror(ret)); + goto done; + } + } else if (ret == ENOENT) { + DEBUG(SSSDBG_TRACE_ALL, "UUID not available for user.\n"); + } else { + DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify UUID [%s]\n", + strerror(ret)); + } + /* If this object has a SID available, we will determine the correct * domain by its SID. */ if (sid_str != NULL) { -- 1.8.3.1
From 3adf966d906cf491f7ca852bb36921fc05542dbf Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 7 Nov 2014 15:05:41 +0100 Subject: [PATCH 4/7] ipa: add get_be_acct_req_for_uuid() This new call creates the needs data for a lookup by UUID which is needed when trying to find the original object for an IPA override object. Related to https://fedorahosted.org/sssd/ticket/2481 --- src/providers/ipa/ipa_id.h | 4 ++++ src/providers/ipa/ipa_views.c | 42 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h index 033ac40..890d00d 100644 --- a/src/providers/ipa/ipa_id.h +++ b/src/providers/ipa/ipa_id.h @@ -83,6 +83,10 @@ errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid, const char *domain_name, struct be_acct_req **_ar); +errno_t get_be_acct_req_for_uuid(TALLOC_CTX *mem_ctx, const char *uuid, + const char *domain_name, + struct be_acct_req **_ar); + struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_id_ctx, diff --git a/src/providers/ipa/ipa_views.c b/src/providers/ipa/ipa_views.c index 2eb7721..ee58689 100644 --- a/src/providers/ipa/ipa_views.c +++ b/src/providers/ipa/ipa_views.c @@ -140,9 +140,10 @@ static errno_t be_acct_req_to_override_filter(TALLOC_CTX *mem_ctx, return EOK; } -errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid, - const char *domain_name, - struct be_acct_req **_ar) +static errno_t get_be_acct_req_for_xyz(TALLOC_CTX *mem_ctx, const char *val, + const char *domain_name, + int type, + struct be_acct_req **_ar) { struct be_acct_req *ar; @@ -152,9 +153,22 @@ errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid, return ENOMEM; } - ar->entry_type = BE_REQ_BY_SECID; - ar->filter_type = BE_FILTER_SECID; - ar->filter_value = talloc_strdup(ar, sid); + switch (type) { + case BE_REQ_BY_SECID: + ar->entry_type = BE_REQ_BY_SECID; + ar->filter_type = BE_FILTER_SECID; + break; + case BE_REQ_BY_UUID: + ar->entry_type = BE_REQ_BY_UUID; + ar->filter_type = BE_FILTER_UUID; + break; + default: + DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported request type [%d].\n", type); + talloc_free(ar); + return EINVAL; + } + + ar->filter_value = talloc_strdup(ar, val); ar->domain = talloc_strdup(ar, domain_name); if (ar->filter_value == NULL || ar->domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); @@ -168,6 +182,22 @@ errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid, return EOK; } +errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid, + const char *domain_name, + struct be_acct_req **_ar) +{ + return get_be_acct_req_for_xyz(mem_ctx, sid, domain_name, BE_REQ_BY_SECID, + _ar); +} + +errno_t get_be_acct_req_for_uuid(TALLOC_CTX *mem_ctx, const char *uuid, + const char *domain_name, + struct be_acct_req **_ar) +{ + return get_be_acct_req_for_xyz(mem_ctx, uuid, domain_name, BE_REQ_BY_UUID, + _ar); +} + struct ipa_get_ad_override_state { struct tevent_context *ev; struct sdap_id_ctx *sdap_id_ctx; -- 1.8.3.1
From 9047069105444545a2f5dc0be3ef30d4c43689d1 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 7 Nov 2014 21:34:55 +0100 Subject: [PATCH 5/7] IPA: make get_object_from_cache() public Related to https://fedorahosted.org/sssd/ticket/2481 --- src/providers/ipa/ipa_id.h | 5 +++++ src/providers/ipa/ipa_subdomains_id.c | 9 +++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h index 890d00d..9d219f2 100644 --- a/src/providers/ipa/ipa_id.h +++ b/src/providers/ipa/ipa_id.h @@ -109,4 +109,9 @@ errno_t ipa_subdomain_account_recv(struct tevent_req *req, int *dp_error_out); errno_t split_ipa_anchor(TALLOC_CTX *mem_ctx, const char *anchor, char **_anchor_domain, char **_ipa_uuid); + +errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, + struct be_acct_req *ar, + struct ldb_message **_msg); #endif diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c index 0d00d09..dd1eae1 100644 --- a/src/providers/ipa/ipa_subdomains_id.c +++ b/src/providers/ipa/ipa_subdomains_id.c @@ -848,10 +848,10 @@ done: return ret; } -static errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, - struct sss_domain_info *dom, - struct be_acct_req *ar, - struct ldb_message **_msg) +errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, + struct be_acct_req *ar, + struct ldb_message **_msg) { errno_t ret; uint32_t id; @@ -861,6 +861,7 @@ static errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, SYSDB_UIDNUM, SYSDB_SID_STR, SYSDB_OBJECTCLASS, + SYSDB_UUID, NULL }; char *name; -- 1.8.3.1
From 9286597c2ed35db04403f72caa75bbfb966cae9b Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Wed, 5 Nov 2014 15:58:04 +0100 Subject: [PATCH 6/7] IPA: check overrrides for IPA users as well Currently overrides were only available for sub-domains, e.g. trusted AD domains. With this patch overrides can be used for IPA users as well. Related to https://fedorahosted.org/sssd/ticket/2481 --- src/providers/ipa/ipa_id.c | 406 +++++++++++++++++++++++++++++++++- src/providers/ipa/ipa_subdomains_id.c | 16 ++ src/providers/ipa/ipa_views.c | 15 ++ 3 files changed, 435 insertions(+), 2 deletions(-) diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c index cd65f5b..fe14c33 100644 --- a/src/providers/ipa/ipa_id.c +++ b/src/providers/ipa/ipa_id.c @@ -56,6 +56,13 @@ static const char *ipa_account_info_error_text(int ret, int *dp_error, return default_text; } +static struct tevent_req * +ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev, + struct ipa_id_ctx *ipa_ctx, struct be_req *be_req, + struct be_acct_req *ar); + +static int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error); + static struct tevent_req *ipa_id_get_netgroup_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, @@ -100,7 +107,9 @@ void ipa_account_info_handler(struct be_req *breq) } else { /* any account request is handled by sdap, * any invalid request is caught there. */ - return sdap_handle_account_info(breq, ctx, ctx->conn); + + req = ipa_id_get_account_info_send(breq, be_ctx->ev, ipa_ctx, breq, + ar); } if (!req) { @@ -115,13 +124,18 @@ static void ipa_account_info_done(struct tevent_req *req) struct be_req *breq = tevent_req_callback_data(req, struct be_req); struct be_acct_req *ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req); + struct be_ctx *be_ctx = be_req_get_be_ctx(breq); const char *error_text; int ret, dp_error; if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_NETGROUP) { ret = ipa_id_get_netgroup_recv(req, &dp_error); } else { - ret = ipa_subdomain_account_recv(req, &dp_error); + if (strcasecmp(ar->domain, be_ctx->domain->name) != 0) { + ret = ipa_subdomain_account_recv(req, &dp_error); + } else { + ret = ipa_id_get_account_info_recv(req, &dp_error); + } } talloc_zfree(req); @@ -130,6 +144,394 @@ static void ipa_account_info_done(struct tevent_req *req) sdap_handler_done(breq, dp_error, ret, error_text); } +struct ipa_id_get_account_info_state { + struct tevent_context *ev; + struct ipa_id_ctx *ipa_ctx; + struct sdap_id_ctx *ctx; + struct sdap_id_op *op; + struct sysdb_ctx *sysdb; + struct sss_domain_info *domain; + struct be_req *be_req; + struct be_acct_req *ar; + const char *realm; + + struct sysdb_attrs *override_attrs; + struct ldb_message *obj_msg; + int dp_error; +}; + +static void ipa_id_get_account_info_connected(struct tevent_req *subreq); +static void ipa_id_get_account_info_got_override(struct tevent_req *subreq); +static errno_t ipa_id_get_account_info_get_original_step(struct tevent_req *req, + struct be_acct_req *ar); +static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq); +static void ipa_id_get_account_info_done(struct tevent_req *subreq); + +static struct tevent_req * +ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev, + struct ipa_id_ctx *ipa_ctx, struct be_req *be_req, + struct be_acct_req *ar) +{ + int ret; + struct tevent_req *req; + struct tevent_req *subreq; + struct ipa_id_get_account_info_state *state; + + req = tevent_req_create(memctx, &state, + struct ipa_id_get_account_info_state); + if (req == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); + return NULL; + } + + state->ev = ev; + state->ipa_ctx = ipa_ctx; + state->ctx = ipa_ctx->sdap_id_ctx; + state->dp_error = DP_ERR_FATAL; + + state->op = sdap_id_op_create(state, state->ctx->conn->conn_cache); + if (state->op == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); + ret = ENOMEM; + goto fail; + } + + state->domain = find_domain_by_name(state->ctx->be->domain, + ar->domain, true); + if (state->domain == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n"); + ret = ENOMEM; + goto fail; + } + state->sysdb = state->domain->sysdb; + state->be_req = be_req; + state->ar = ar; + state->realm = dp_opt_get_string(state->ipa_ctx->ipa_options->basic, + IPA_KRB5_REALM); + if (state->realm == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n"); + ret = EINVAL; + goto fail; + } + + /* We can skip the override lookup and go directly to the original object + * if + * - the lookup is by SID + * - there is no view set of it is the default view + * - if the EXTRA_INPUT_MAYBE_WITH_VIEW flag is not set + */ + if (state->ipa_ctx->view_name == NULL + || state->ar->filter_type == BE_FILTER_SECID + || strcmp(state->ipa_ctx->view_name, + SYSDB_DEFAULT_VIEW_NAME) == 0 + || state->ar->extra_value == NULL + || strcmp(state->ar->extra_value, + EXTRA_INPUT_MAYBE_WITH_VIEW) != 0 ) { + ret = ipa_id_get_account_info_get_original_step(req, ar); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "ipa_subdomain_account_get_original_step failed.\n"); + goto fail; + } + } else { + subreq = sdap_id_op_connect_send(state->op, state, &ret); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed.\n"); + goto fail; + } + tevent_req_set_callback(subreq, ipa_id_get_account_info_connected, req); + } + + return req; + +fail: + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; +} + +static void ipa_id_get_account_info_connected(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct ipa_id_get_account_info_state *state = tevent_req_data(req, + struct ipa_id_get_account_info_state); + int dp_error = DP_ERR_FATAL; + int ret; + + ret = sdap_id_op_connect_recv(subreq, &dp_error); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect request failed.\n"); + goto fail; + } + + subreq = ipa_get_ad_override_send(state, state->ev, state->ctx, + state->ipa_ctx->ipa_options, state->realm, + state->ipa_ctx->view_name, state->ar); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + ret = ENOMEM; + goto fail; + } + + tevent_req_set_callback(subreq, ipa_id_get_account_info_got_override, req); + + return; + +fail: + state->dp_error = dp_error; + tevent_req_error(req, ret); + return; +} + +static void ipa_id_get_account_info_got_override(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct ipa_id_get_account_info_state *state = tevent_req_data(req, + struct ipa_id_get_account_info_state); + int dp_error = DP_ERR_FATAL; + int ret; + const char *anchor = NULL; + char *anchor_domain; + char *ipa_uuid; + + ret = ipa_get_ad_override_recv(subreq, &dp_error, state, + &state->override_attrs); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); + goto fail; + } + + if (state->override_attrs != NULL) { + ret = sysdb_attrs_get_string(state->override_attrs, + SYSDB_OVERRIDE_ANCHOR_UUID, + &anchor); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); + goto fail; + } + + ret = split_ipa_anchor(state, anchor, &anchor_domain, &ipa_uuid); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unsupported override anchor [%s].\n", anchor); + ret = EINVAL; + goto fail; + } + + if (strcmp(state->ar->domain, anchor_domain) == 0) { + + ret = get_be_acct_req_for_uuid(state, ipa_uuid, + state->ar->domain, + &state->ar); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); + goto fail; + } + } else { + DEBUG(SSSDBG_MINOR_FAILURE, + "Anchor from a different domain [%s], expected [%s]. " \ + "This is currently not supported, continue lookup in " \ + "local IPA domain.\n", + anchor_domain, state->ar->domain); + } + } + + ret = ipa_id_get_account_info_get_original_step(req, state->ar); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "ipa_subdomain_account_get_original_step failed.\n"); + goto fail; + } + + return; + +fail: + state->dp_error = dp_error; + tevent_req_error(req, ret); + return; +} + +static errno_t ipa_id_get_account_info_get_original_step(struct tevent_req *req, + struct be_acct_req *ar) +{ + struct ipa_id_get_account_info_state *state = tevent_req_data(req, + struct ipa_id_get_account_info_state); + struct tevent_req *subreq; + int ret; + + subreq = sdap_handle_acct_req_send(state, state->be_req, ar, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->sdap_id_ctx->opts->sdom, + state->ipa_ctx->sdap_id_ctx->conn, true); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct_req_send failed.\n"); + return ENOMEM; + } + tevent_req_set_callback(subreq, ipa_id_get_account_info_orig_done, req); + + return EOK; +} + +static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct ipa_id_get_account_info_state *state = tevent_req_data(req, + struct ipa_id_get_account_info_state); + int dp_error = DP_ERR_FATAL; + int ret; + const char *uuid; + const char *class; + enum sysdb_member_type type; + + ret = sdap_handle_acct_req_recv(subreq, &dp_error, NULL, NULL); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct request failed: %d\n", ret); + goto fail; + } + + ret = get_object_from_cache(state, state->domain, state->ar, + &state->obj_msg); + if (ret == ENOENT) { + DEBUG(SSSDBG_MINOR_FAILURE, "Object not found, ending request\n"); + tevent_req_done(req); + return; + } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "get_object_from_cache failed.\n"); + goto fail; + } + + if (state->override_attrs == NULL) { + uuid = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_UUID, NULL); + if (uuid == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find a UUID.\n"); + ret = EINVAL; + goto fail; + } + + ret = get_be_acct_req_for_uuid(state, uuid, state->domain->name, + &state->ar); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); + goto fail; + } + + subreq = ipa_get_ad_override_send(state, state->ev, + state->ipa_ctx->sdap_id_ctx, + state->ipa_ctx->ipa_options, + state->realm, + state->ipa_ctx->view_name, + state->ar); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); + ret = ENOMEM; + goto fail; + } + tevent_req_set_callback(subreq, ipa_id_get_account_info_done, req); + return; + } else { + class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS, + NULL); + if (class == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n"); + ret = EINVAL; + goto fail; + } + + if (strcmp(class, SYSDB_USER_CLASS) == 0) { + type = SYSDB_MEMBER_USER; + } else { + type = SYSDB_MEMBER_GROUP; + } + + ret = sysdb_store_override(state->domain, state->ipa_ctx->view_name, + type, + state->override_attrs, state->obj_msg->dn); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n"); + goto fail; + } + } + + state->dp_error = DP_ERR_OK; + tevent_req_done(req); + return; + +fail: + state->dp_error = dp_error; + tevent_req_error(req, ret); + return; +} + +static void ipa_id_get_account_info_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct ipa_id_get_account_info_state *state = tevent_req_data(req, + struct ipa_id_get_account_info_state); + int dp_error = DP_ERR_FATAL; + int ret; + const char *class; + enum sysdb_member_type type; + + ret = ipa_get_ad_override_recv(subreq, &dp_error, state, + &state->override_attrs); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); + goto fail; + } + + class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS, + NULL); + if (class == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n"); + ret = EINVAL; + goto fail; + } + + if (strcmp(class, SYSDB_USER_CLASS) == 0) { + type = SYSDB_MEMBER_USER; + } else { + type = SYSDB_MEMBER_GROUP; + } + + ret = sysdb_store_override(state->domain, state->ipa_ctx->view_name, + type, + state->override_attrs, state->obj_msg->dn); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n"); + goto fail; + } + + state->dp_error = DP_ERR_OK; + tevent_req_done(req); + return; + +fail: + state->dp_error = dp_error; + tevent_req_error(req, ret); + return; +} + +static int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error) +{ + struct ipa_id_get_account_info_state *state = tevent_req_data(req, + struct ipa_id_get_account_info_state); + + if (dp_error) { + *dp_error = state->dp_error; + } + + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} /* Request for netgroups * - first start here and then go to ipa_netgroups.c diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c index dd1eae1..2f74798 100644 --- a/src/providers/ipa/ipa_subdomains_id.c +++ b/src/providers/ipa/ipa_subdomains_id.c @@ -881,6 +881,22 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, goto done; } + if (ar->filter_type == BE_FILTER_UUID) { + ret = sysdb_search_object_by_uuid(mem_ctx, dom, ar->filter_value, attrs, + &res); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to make request to our cache: [%d]: [%s]\n", + ret, sss_strerror(ret)); + goto done; + } + + *_msg = res->msgs[0]; + + ret = EOK; + goto done; + } + if (ar->filter_type == BE_FILTER_IDNUM) { errno = 0; id = strtouint32(ar->filter_value, NULL, 10); diff --git a/src/providers/ipa/ipa_views.c b/src/providers/ipa/ipa_views.c index ee58689..c768186 100644 --- a/src/providers/ipa/ipa_views.c +++ b/src/providers/ipa/ipa_views.c @@ -125,6 +125,21 @@ static errno_t be_acct_req_to_override_filter(TALLOC_CTX *mem_ctx, } break; + case BE_FILTER_UUID: + if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_UUID) { + filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=:IPA:%s:%s))", + ipa_opts->override_map[IPA_OC_OVERRIDE].name, + ipa_opts->override_map[IPA_AT_OVERRIDE_ANCHOR_UUID].name, + dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN), + ar->filter_value); + } else { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unexpected entry type [%d] for UUID filter.\n", + ar->entry_type); + return EINVAL; + } + break; + default: DEBUG(SSSDBG_OP_FAILURE, "Invalid sub-domain filter type.\n"); return EINVAL; -- 1.8.3.1
From d3d3d51a1d49936c9ad1a3733388bfd384fd07c4 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 7 Nov 2014 21:36:12 +0100 Subject: [PATCH 7/7] Enable views for all domains Currently views and overrides were only available for sub-domains, this patch enables the lookup for the configured domains as well. Related to https://fedorahosted.org/sssd/ticket/2481 --- src/util/util.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/util/util.h b/src/util/util.h index ffc8a87..7c335b9 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -574,8 +574,7 @@ errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, #define IS_SUBDOMAIN(dom) ((dom)->parent != NULL) -/* Currently views are only supported for subdomains */ -#define DOM_HAS_VIEWS(dom) ((dom)->has_views && IS_SUBDOMAIN(dom)) +#define DOM_HAS_VIEWS(dom) ((dom)->has_views) errno_t sss_write_domain_mappings(struct sss_domain_info *domain); -- 1.8.3.1
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel