[SSSD] [PATCHES] IPA: check overrrides for IPA users as well

Sumit Bose sbose at redhat.com
Wed Nov 19 09:52:46 UTC 2014


On Fri, Nov 14, 2014 at 05:27:29PM +0100, Jakub Hrozek wrote:
> On Thu, Nov 13, 2014 at 11:58:13AM +0100, Sumit Bose wrote:
> 
> Hi,
> 
> Coverity run was clean, CI run succeeded and testing against a recent
> IPA server went OK. Before I ack, I also want to test against an old
> server, but I'm running out of time today.
> 
> See some comments inline.

Thank you for the review and testing.

> 
> > From 9f807e92b8db786c331842117e1481dbb494a1f7 Mon Sep 17 00:00:00 2001
> > From: Sumit Bose <sbose at redhat.com>
> > Date: Thu, 6 Nov 2014 13:13:27 +0100
> > Subject: [PATCH 1/7] ipa: add split_ipa_anchor()
> 
> ACK, see one remark inline.
> 
> > +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;
> 
> This is fine since we're only using the error as an..error..so the caller
> will only test ret != EOK, but if we used it to differentiate between
> different conditions, we should use a custom error code.
> 
> > +    }
> > +
> > +    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;
> > +    }
> 
> > From ec4cf492945cb8f30fcb2467e9d26836de7ff6d8 Mon Sep 17 00:00:00 2001
> > From: Sumit Bose <sbose at 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;
> 
> I wonder if failing is appropriate? I guess yes, but on the other hand,
> calling an unconfigured back end handler (maybe an SSH handler with a
> pure LDAP backend) is mostly a noop, right?
> 
> But I can see the point, just wanted to double check with you..

currently the UUID search is only used by the IPA provider which expects
that UUIDs are properly configured. If new use-caese come around we
might want to re-consider it.

> 
> Otherwise ACK
> 
> > From 15ea0a84cc1d1ded27c6f84ac563b7902f203526 Mon Sep 17 00:00:00 2001
> > From: Sumit Bose <sbose at 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));
> 
> Please use sss_strerror() in new code (also elsewhere in this patch).

done, I replaced the other usages of strerror() in sdap_save_group() and
sdap_save_user() as well.

> 
> Otherwise ACK
> 
> > From 3adf966d906cf491f7ca852bb36921fc05542dbf Mon Sep 17 00:00:00 2001
> > From: Sumit Bose <sbose at redhat.com>
> > Date: Fri, 7 Nov 2014 15:05:41 +0100
> > Subject: [PATCH 4/7] ipa: add get_be_acct_req_for_uuid()
> 
> ACK
> 
> > From 9047069105444545a2f5dc0be3ef30d4c43689d1 Mon Sep 17 00:00:00 2001
> > From: Sumit Bose <sbose at redhat.com>
> > Date: Fri, 7 Nov 2014 21:34:55 +0100
> > Subject: [PATCH 5/7] IPA: make get_object_from_cache() public
> 
> ACK
> 
> I just noticed one oddity when reading the code. The function mixes if
> and if-else statements, I think it would be nice to add another simple
> patch that would converge to if-else style.

fix, I commited the change to the 6ht patch because here the call was
touched to add the uuid support.

> 
> > From 9286597c2ed35db04403f72caa75bbfb966cae9b Mon Sep 17 00:00:00 2001
> > From: Sumit Bose <sbose at 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
> > ---
> 
> [...]
> 
> > +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;
> 
> ret is unused and triggers a compilation warning.

fixed

> 
> > +
> > +    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;
> > +}
> > +
> 
> The rest looks good.
> 
> > From d3d3d51a1d49936c9ad1a3733388bfd384fd07c4 Mon Sep 17 00:00:00 2001
> > From: Sumit Bose <sbose at redhat.com>
> > Date: Fri, 7 Nov 2014 21:36:12 +0100
> > Subject: [PATCH 7/7] Enable views for all domains
> 
> ACK

new version attached.

bye,
Sumit
-------------- next part --------------
From 7850dbf7c2f3b945d9e473e1c4ebf5d19ffcd808 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at 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 156ef3c..53ace65 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2064,6 +2064,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) \
@@ -2387,6 +2388,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 <sbose at 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

-------------- next part --------------
From 8d341e1460d6ab3358ea07cce73561ddb903d716 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at 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

-------------- next part --------------
From f00a88b8080fb454c234d81f38ad34278bc54199 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at 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 | 42 +++++++++++++++++++++++++---------
 src/providers/ldap/sdap_async_users.c  | 23 +++++++++++++++++--
 2 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index a82d2aa..8cf7f7f 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;
 
@@ -534,7 +535,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
         ret = sysdb_attrs_add_string(group_attrs, SYSDB_SID_STR, sid_str);
         if (ret != EOK) {
             DEBUG(SSSDBG_MINOR_FAILURE, "Could not add SID string: [%s]\n",
-                                         strerror(ret));
+                                         sss_strerror(ret));
             goto done;
         }
     } else if (ret == ENOENT) {
@@ -543,10 +544,29 @@ static int sdap_save_group(TALLOC_CTX *memctx,
         sid_str = NULL;
     } else {
         DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify objectSID: [%s]\n",
-                                     strerror(ret));
+                                     sss_strerror(ret));
         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",
+                                         sss_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",
+                                     sss_strerror(ret));
+    }
+
     /* If this object has a SID available, we will determine the correct
      * domain by its SID. */
     if (sid_str != NULL) {
@@ -633,7 +653,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
             } else if (ret != EOK) {
                 DEBUG(SSSDBG_MINOR_FAILURE,
                       "Could not convert SID string: [%s]\n",
-                       strerror(ret));
+                       sss_strerror(ret));
                 goto done;
             }
 
@@ -652,7 +672,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
             } else if (ret != EOK) {
                 DEBUG(SSSDBG_MINOR_FAILURE,
                       "Error reading posix attribute: [%s]\n",
-                       strerror(ret));
+                       sss_strerror(ret));
                 goto done;
             }
 
@@ -662,7 +682,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
             if (ret != EOK) {
                 DEBUG(SSSDBG_MINOR_FAILURE,
                       "Error setting posix attribute: [%s]\n",
-                       strerror(ret));
+                       sss_strerror(ret));
                 goto done;
             }
 
@@ -695,7 +715,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_MINOR_FAILURE,
               "Error setting original DN: [%s]\n",
-               strerror(ret));
+               sss_strerror(ret));
         goto done;
     }
 
@@ -706,7 +726,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_MINOR_FAILURE,
               "Error setting mod timestamp: [%s]\n",
-               strerror(ret));
+               sss_strerror(ret));
         goto done;
     }
 
@@ -715,7 +735,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     if (ret) {
         DEBUG(SSSDBG_MINOR_FAILURE,
               "Error looking up group USN: [%s]\n",
-               strerror(ret));
+               sss_strerror(ret));
         goto done;
     }
     if (el->num_values == 0) {
@@ -728,7 +748,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
         if (ret) {
             DEBUG(SSSDBG_MINOR_FAILURE,
                   "Error setting group USN: [%s]\n",
-                   strerror(ret));
+                   sss_strerror(ret));
             goto done;
         }
         usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data);
@@ -759,7 +779,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     if (ret) {
         DEBUG(SSSDBG_MINOR_FAILURE,
               "Could not store group with GID: [%s]\n",
-               strerror(ret));
+               sss_strerror(ret));
         goto done;
     }
 
@@ -775,7 +795,7 @@ done:
         DEBUG(SSSDBG_MINOR_FAILURE,
               "Failed to save group [%s]: [%s]\n",
                group_name ? group_name : "Unknown",
-               strerror(ret));
+               sss_strerror(ret));
     }
     talloc_free(tmpctx);
     return ret;
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index 2331ba9..367e3d7 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;
 
@@ -165,7 +166,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
         ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
         if (ret != EOK) {
             DEBUG(SSSDBG_MINOR_FAILURE, "Could not add SID string: [%s]\n",
-                                         strerror(ret));
+                                         sss_strerror(ret));
             goto done;
         }
     } else if (ret == ENOENT) {
@@ -173,10 +174,28 @@ int sdap_save_user(TALLOC_CTX *memctx,
         sid_str = NULL;
     } else {
         DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify objectSID: [%s]\n",
-                                     strerror(ret));
+                                     sss_strerror(ret));
         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",
+                                         sss_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",
+                                     sss_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

-------------- next part --------------
From 1b73a945683b22ec22b218d4d0977aea6a14105e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at 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

-------------- next part --------------
From 78c61407d61295f246bd232cf57bba80d887b020 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at 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

-------------- next part --------------
From f20443135668012b1977c9773ce37c84befce555 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at 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            | 405 +++++++++++++++++++++++++++++++++-
 src/providers/ipa/ipa_subdomains_id.c |  16 +-
 src/providers/ipa/ipa_views.c         |  15 ++
 3 files changed, 432 insertions(+), 4 deletions(-)

diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
index cd65f5b..5665a18 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,393 @@ 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;
+
+    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..5c53876 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -879,9 +879,21 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx,
 
         ret = EOK;
         goto done;
-    }
+    } else 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];
 
-    if (ar->filter_type == BE_FILTER_IDNUM) {
+        ret = EOK;
+        goto done;
+    } else if (ar->filter_type == BE_FILTER_IDNUM) {
         errno = 0;
         id = strtouint32(ar->filter_value, NULL, 10);
         if (errno != 0) {
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

-------------- next part --------------
From 13475d88e32122d9f27a1ff528a0a28287337085 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at 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



More information about the sssd-devel mailing list