On 09/10/2013 03:46 PM, Jakub Hrozek wrote:
On Tue, Sep 03, 2013 at 12:42:21PM +0200, Pavel Březina wrote:
Patch 0001: I haven't used this one after all, but I still think it
is nice to have. It reduces amount of code duplication.

Patch 0005:
+    /* Try to get group SID and assign it a domain */ +
group_sid = ldb_msg_find_attr_as_string(group, SYSDB_SID_STR,
NULL); +    if (group_sid == NULL) {

I'm not sure if this branch isn't a dead code, but I kept it there
because it mimics current behaviour.

+        /* We will look it up in main domain. */ +        domain
= state->ctx->domain; +    } else { +        domain =
find_subdomain_by_sid(state->ctx->domain, group_sid); +        if
(domain == NULL) { +            DEBUG(SSSDBG_CRIT_FAILURE,
("There is no domain information for " +
"SID %s\n", group_sid)); +            return ENOENT; +        } +
}

From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]> Date:
Mon, 2 Sep 2013 13:36:25 +0200 Subject: [PATCH 1/6] util: add
sss_idmap_talloc[_free]

Remove code duplication.

Removing code duplication added code :-) 76 insertions(+), 62
deletions(-)

But it's mostly the comment blobs, so ack.

From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]> Date:
Tue, 27 Aug 2013 14:53:03 +0200 Subject: [PATCH 2/6] simple access
tests: fix typos

ACK

From 5648c71b1a5a6bad5ce8e3361c7b4baf7d972c0b Mon Sep 17 00:00:00
2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Tue, 27 Aug 2013 14:02:42 +0200 Subject: [PATCH 3/6] simple
provider: support subdomain users

Resolves: https://fedorahosted.org/sssd/ticket/2034

There is one thing that still needs fixing -- the case sensitivity
flag is still read from the master domain through be_ctx->domain. In
general, the providers should not access be_ctx->domain directly, but
rather the handler should assign a sss_domain_info structure to some
per-provider or per-request state and the code should operate on
that.

From c1b31c3c2eefa71f5c17539fd615a785d7e1ccd0 Mon Sep 17 00:00:00
2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Mon, 2 Sep 2013 15:15:59 +0200 Subject: [PATCH 4/6] util: add
find_subdomain_by_sid()

ACK, but please file a ticket to mass-namespace the functions in
this module.

https://fedorahosted.org/sssd/ticket/2086

From 78fff868aa9f1b5a8392328973e4ce3ba000a9e6 Mon Sep 17 00:00:00
2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Wed, 28 Aug 2013 11:35:27 +0200 Subject: [PATCH 5/6] simple
provider: support subdomain groups


Same comment about case sensitivity.

From 844b9cc30ad694116772f519791b3725a72d178a Mon Sep 17 00:00:00
2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Tue, 3 Sep 2013 12:34:07 +0200 Subject: [PATCH 6/6] simple
access test: initialize be_ctx for all tests


ACK

Thanks. New patches are attached. I'm sending the case sensitivity
change in a separate patch, since I think it can stand on its own as
improvement of subdomains support in simple access provider.

I also included patch that contains find_subdomain_by_object_name().

From 4d9fca397270d9af32593a06a09c3de1b6959df3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Mon, 2 Sep 2013 13:36:25 +0200
Subject: [PATCH 1/8] util: add sss_idmap_talloc[_free]

Remove code duplication.
---
 Makefile.am                      |  4 +++-
 src/providers/ad/ad_subdomains.c | 14 +++-----------
 src/providers/ipa/ipa_idmap.c    | 17 +++--------------
 src/providers/ldap/sdap_idmap.c  | 17 +++--------------
 src/responder/nss/nsssrv.c       | 13 ++-----------
 src/responder/pac/pacsrv.c       | 13 ++-----------
 src/util/util_sss_idmap.c        | 32 ++++++++++++++++++++++++++++++++
 src/util/util_sss_idmap.h        | 28 ++++++++++++++++++++++++++++
 8 files changed, 76 insertions(+), 62 deletions(-)
 create mode 100644 src/util/util_sss_idmap.c
 create mode 100644 src/util/util_sss_idmap.h

diff --git a/Makefile.am b/Makefile.am
index 25a4cbf83c790b85fab9ccccd611f59704a5b301..8cdcb80c39dc008708298f6662733c6fc6049ac4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -406,6 +406,7 @@ dist_noinst_HEADERS = \
     src/util/auth_utils.h \
     src/util/authtok.h \
     src/util/util_safealign.h \
+    src/util/util_sss_idmap.h \
     src/monitor/monitor.h \
     src/monitor/monitor_interfaces.h \
     src/responder/common/responder.h \
@@ -570,7 +571,8 @@ libsss_util_la_SOURCES = \
     src/util/util_lock.c \
     src/util/util_errors.c \
     src/util/sss_ini.c \
-    src/util/io.c
+    src/util/io.c \
+    src/util/util_sss_idmap.c
 libsss_util_la_LIBADD = \
     $(SSSD_LIBS) \
     $(UNICODE_LIBS)
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index afd2031fe6be557f43555b6dd8b47731d9833585..876850888a8d58d7cb967bf39ecbcae1bf2d5f0c 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -24,6 +24,7 @@
 
 #include "providers/ldap/sdap_async.h"
 #include "providers/ad/ad_subdomains.h"
+#include "util/util_sss_idmap.h"
 #include <ctype.h>
 #include <ndr.h>
 #include <ndr/ndr_nbt.h>
@@ -777,16 +778,6 @@ struct bet_ops ad_subdomains_ops = {
     .finalize = NULL
 };
 
-static void *idmap_talloc(size_t size, void *pvt)
-{
-    return talloc_size(pvt, size);
-}
-
-static void idmap_free(void *ptr, void *pvt)
-{
-    talloc_free(ptr);
-}
-
 int ad_subdom_init(struct be_ctx *be_ctx,
                    struct ad_id_ctx *id_ctx,
                    const char *ad_domain,
@@ -825,7 +816,8 @@ int ad_subdom_init(struct be_ctx *be_ctx,
         DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom offline callback"));
     }
 
-    err = sss_idmap_init(idmap_talloc, ctx, idmap_free, &ctx->idmap_ctx);
+    err = sss_idmap_init(sss_idmap_talloc, ctx, sss_idmap_talloc_free,
+                         &ctx->idmap_ctx);
     if (err != IDMAP_SUCCESS) {
         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to initialize idmap context.\n"));
         return EFAULT;
diff --git a/src/providers/ipa/ipa_idmap.c b/src/providers/ipa/ipa_idmap.c
index c108ca75b84005c3d5957cd45ca89209d59f59ff..09772eb2294626f9cbf806185eb5bd7b1e4d833c 100644
--- a/src/providers/ipa/ipa_idmap.c
+++ b/src/providers/ipa/ipa_idmap.c
@@ -24,18 +24,7 @@
 #include "util/util.h"
 #include "providers/ldap/sdap_idmap.h"
 #include "providers/ipa/ipa_common.h"
-
-static void *
-ipa_idmap_talloc(size_t size, void *pvt)
-{
-    return talloc_size(pvt, size);
-}
-
-static void
-ipa_idmap_talloc_free(void *ptr, void *pvt)
-{
-    talloc_free(ptr);
-}
+#include "util/util_sss_idmap.h"
 
 errno_t ipa_idmap_find_new_domain(struct sdap_idmap_ctx *idmap_ctx,
                                   const char *dom_name,
@@ -168,8 +157,8 @@ errno_t ipa_idmap_init(TALLOC_CTX *mem_ctx,
     idmap_ctx->find_new_domain = ipa_idmap_find_new_domain;
 
     /* Initialize the map */
-    err = sss_idmap_init(ipa_idmap_talloc, idmap_ctx,
-                         ipa_idmap_talloc_free,
+    err = sss_idmap_init(sss_idmap_talloc, idmap_ctx,
+                         sss_idmap_talloc_free,
                          &idmap_ctx->map);
     if (err != IDMAP_SUCCESS) {
         DEBUG(SSSDBG_CRIT_FAILURE,
diff --git a/src/providers/ldap/sdap_idmap.c b/src/providers/ldap/sdap_idmap.c
index 0939c31e45a081a8494f4efa82ac1608314b82a3..6a76dc2c0d22061dca171be7fe5a96f4256a864c 100644
--- a/src/providers/ldap/sdap_idmap.c
+++ b/src/providers/ldap/sdap_idmap.c
@@ -24,18 +24,7 @@
 #include "util/dlinklist.h"
 #include "util/murmurhash3.h"
 #include "providers/ldap/sdap_idmap.h"
-
-static void *
-sdap_idmap_talloc(size_t size, void *pvt)
-{
-    return talloc_size(pvt, size);
-}
-
-static void
-sdap_idmap_talloc_free(void *ptr, void *pvt)
-{
-    talloc_free(ptr);
-}
+#include "util/util_sss_idmap.h"
 
 static errno_t
 sdap_idmap_add_configured_external_range(struct sdap_idmap_ctx *idmap_ctx)
@@ -172,8 +161,8 @@ sdap_idmap_init(TALLOC_CTX *mem_ctx,
     }
 
     /* Initialize the map */
-    err = sss_idmap_init(sdap_idmap_talloc, idmap_ctx,
-                         sdap_idmap_talloc_free,
+    err = sss_idmap_init(sss_idmap_talloc, idmap_ctx,
+                         sss_idmap_talloc_free,
                          &idmap_ctx->map);
     if (err != IDMAP_SUCCESS) {
         DEBUG(SSSDBG_CRIT_FAILURE,
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 253756d1bebb2ecc06740c5e6afff2799de92e1e..5f1d2e675f652c19c281263e0884d40e6b4b349e 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -47,6 +47,7 @@
 #include "providers/data_provider.h"
 #include "monitor/monitor_interfaces.h"
 #include "sbus/sbus_client.h"
+#include "util/util_sss_idmap.h"
 
 #define DEFAULT_PWFIELD "*"
 #define DEFAULT_NSS_FD_LIMIT 8192
@@ -413,16 +414,6 @@ static void nss_dp_reconnect_init(struct sbus_connection *conn,
     /* nss_shutdown(rctx); */
 }
 
-static void *idmap_talloc(size_t size, void *pvt)
-{
-    return talloc_size(pvt, size);
-}
-
-static void idmap_free(void *ptr, void *pvt)
-{
-    talloc_free(ptr);
-}
-
 int nss_process_init(TALLOC_CTX *mem_ctx,
                      struct tevent_context *ev,
                      struct confdb_ctx *cdb)
@@ -490,7 +481,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
                             nss_dp_reconnect_init, iter);
     }
 
-    err = sss_idmap_init(idmap_talloc, nctx, idmap_free,
+    err = sss_idmap_init(sss_idmap_talloc, nctx, sss_idmap_talloc_free,
                          &nctx->idmap_ctx);
     if (err != IDMAP_SUCCESS) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("sss_idmap_init failed.\n"));
diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c
index 22f87cb754f34efdf37035f9315b5f150f311061..a06d768bbc348f0a7f88428a6ce34d09bc3f5773 100644
--- a/src/responder/pac/pacsrv.c
+++ b/src/responder/pac/pacsrv.c
@@ -42,6 +42,7 @@
 #include "providers/data_provider.h"
 #include "monitor/monitor_interfaces.h"
 #include "sbus/sbus_client.h"
+#include "util/util_sss_idmap.h"
 
 #define SSS_PAC_PIPE_NAME "pac"
 #define DEFAULT_PAC_FD_LIMIT 8192
@@ -105,16 +106,6 @@ static void pac_dp_reconnect_init(struct sbus_connection *conn,
     /* nss_shutdown(rctx); */
 }
 
-static void *idmap_talloc(size_t size, void *pvt)
-{
-    return talloc_size(pvt, size);
-}
-
-static void idmap_free(void *ptr, void *pvt)
-{
-    talloc_free(ptr);
-}
-
 int pac_process_init(TALLOC_CTX *mem_ctx,
                      struct tevent_context *ev,
                      struct confdb_ctx *cdb)
@@ -186,7 +177,7 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
                             pac_dp_reconnect_init, iter);
     }
 
-    err = sss_idmap_init(idmap_talloc, pac_ctx, idmap_free,
+    err = sss_idmap_init(sss_idmap_talloc, pac_ctx, sss_idmap_talloc_free,
                          &pac_ctx->idmap_ctx);
     if (err != IDMAP_SUCCESS) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("sss_idmap_init failed.\n"));
diff --git a/src/util/util_sss_idmap.c b/src/util/util_sss_idmap.c
new file mode 100644
index 0000000000000000000000000000000000000000..4ce42507a35d17e68a65a6183eccc292d03e9fb4
--- /dev/null
+++ b/src/util/util_sss_idmap.c
@@ -0,0 +1,32 @@
+/*
+    Authors:
+        Pavel Březina <[email protected]>
+
+    Copyright (C) 2013 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 <talloc.h>
+#include "util/util_sss_idmap.h"
+
+void *sss_idmap_talloc(size_t size, void *pvt)
+{
+    return talloc_size(pvt, size);
+}
+
+void sss_idmap_talloc_free(void *ptr, void *pvt)
+{
+    talloc_free(ptr);
+}
diff --git a/src/util/util_sss_idmap.h b/src/util/util_sss_idmap.h
new file mode 100644
index 0000000000000000000000000000000000000000..bde47271b37344e10d96a352da99e30958d279a9
--- /dev/null
+++ b/src/util/util_sss_idmap.h
@@ -0,0 +1,28 @@
+/*
+    Authors:
+        Pavel Březina <[email protected]>
+
+    Copyright (C) 2013 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/>.
+*/
+
+#ifndef __UTIL_SSS_IDMAP_H__
+#define __UTIL_SSS_IDMAP_H__
+
+void *sss_idmap_talloc(size_t size, void *pvt);
+
+void sss_idmap_talloc_free(void *ptr, void *pvt);
+
+#endif /* __UTIL_SSS_IDMAP_H__ */
-- 
1.7.11.7

From eb68d77d85f5af44d873bace49fff1cbb748cd9a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Tue, 27 Aug 2013 14:53:03 +0200
Subject: [PATCH 2/8] simple access tests: fix typos

---
 src/tests/simple_access-tests.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/tests/simple_access-tests.c b/src/tests/simple_access-tests.c
index d1a6056abd2e226e07b5b6a256d19b94ed1f5650..a7a7e276de8d90a7bb0f375dc1fc3d1ac8d5ed7c 100644
--- a/src/tests/simple_access-tests.c
+++ b/src/tests/simple_access-tests.c
@@ -135,7 +135,7 @@ void teardown_simple(void)
     fail_unless(test_ctx != NULL, "Simple context already freed.");
     ret = talloc_free(test_ctx);
     test_ctx = NULL;
-    fail_unless(ret == 0, "Connot free simple context.");
+    fail_unless(ret == 0, "Cannot free simple context.");
 }
 
 void setup_simple_group(void)
@@ -568,22 +568,22 @@ START_TEST(test_provider_init)
     /* allow users */
     ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL",
                            "simple_allow_users", val);
-    fail_if(ret != EOK, "Could setup allow users list");
+    fail_if(ret != EOK, "Could not setup allow users list");
 
     /* deny users */
     ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL",
                            "simple_deny_users", val);
-    fail_if(ret != EOK, "Could setup deny users list");
+    fail_if(ret != EOK, "Could not setup deny users list");
 
     /* allow groups */
     ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL",
                            "simple_allow_groups", val);
-    fail_if(ret != EOK, "Could setup allow groups list");
+    fail_if(ret != EOK, "Could not setup allow groups list");
 
     /* deny groups */
     ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL",
                            "simple_deny_groups", val);
-    fail_if(ret != EOK, "Could setup deny groups list");
+    fail_if(ret != EOK, "Could not setup deny groups list");
 
     ret = sssm_simple_access_init(test_ctx->be_ctx, &bet_ops, (void**)&ctx);
     fail_if(ret != EOK);
-- 
1.7.11.7

From 1acf781780b79b6f3a6bef2ef9e9f886f801096f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Tue, 27 Aug 2013 14:02:42 +0200
Subject: [PATCH 3/8] simple provider: support subdomain users

Resolves:
https://fedorahosted.org/sssd/ticket/2034
---
 src/providers/simple/simple_access.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/providers/simple/simple_access.c b/src/providers/simple/simple_access.c
index 46e6dde1eeb43f2553efaebaaf079741ba662b75..46b045e531dfc5fcdff4fc4f5370734aca1e377c 100644
--- a/src/providers/simple/simple_access.c
+++ b/src/providers/simple/simple_access.c
@@ -141,13 +141,18 @@ static errno_t simple_access_parse_names(TALLOC_CTX *mem_ctx,
         }
 
         if (domain == NULL || strcasecmp(domain, be_ctx->domain->name) == 0) {
-            /* main domain, remember the name without domain part */
+            /* This object belongs to main SSSD domain. Those users and groups
+             * are stored without domain part, so we will strip it off.
+             * */
             out[i] = talloc_move(out, &name);
         } else {
-            DEBUG(SSSDBG_CRIT_FAILURE, ("Unknown domain in %s. "
-                  "Check you configuration.\n", list[i]));
-            ret = EINVAL;
-            goto done;
+            /* Subdomain users and groups are stored as fully qualified names,
+             * thus we will remember the domain part.
+             *
+             * Since subdomains may come and go, we will look for their
+             * existence later, during each access check.
+             */
+            out[i] = talloc_move(out, &list[i]);
         }
     }
 
-- 
1.7.11.7

From 9c5adf94cc6e41d0a7a5a770c3d45ee014532889 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Mon, 2 Sep 2013 15:15:59 +0200
Subject: [PATCH 4/8] util: add find_subdomain_by_sid()

This function takes domain SID (doesn't have the last component)
or object SID (have all components) and returns subdomain.

The subdomain is found by comparing domain->domainid with the SID.

E.g.
domain SID: S-1-5-21-3940105347-3434501867-2690409756
object SID: S-1-5-21-3940105347-3434501867-2690409756-513

Resolves:
https://fedorahosted.org/sssd/ticket/2034
---
 src/util/domain_info_utils.c | 33 +++++++++++++++++++++++++++++++++
 src/util/util.h              |  2 ++
 2 files changed, 35 insertions(+)

diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
index 8b03e9a53fad8614ab0dccf14dceb30232ad84d4..f9d9057a811f3e08c451d7f6b44bc14202559962 100644
--- a/src/util/domain_info_utils.c
+++ b/src/util/domain_info_utils.c
@@ -95,6 +95,39 @@ struct sss_domain_info *find_subdomain_by_name(struct sss_domain_info *domain,
     return NULL;
 }
 
+struct sss_domain_info *find_subdomain_by_sid(struct sss_domain_info *domain,
+                                              const char *sid)
+{
+    struct sss_domain_info *dom = domain;
+    size_t sid_len = strlen(sid);
+    size_t dom_sid_len;
+
+    while (dom && dom->disabled) {
+        dom = get_next_domain(dom, true);
+    }
+
+    while (dom) {
+        dom_sid_len = strlen(dom->domain_id);
+
+        if (strncasecmp(dom->domain_id, sid, dom_sid_len) == 0) {
+            if (dom_sid_len == sid_len) {
+                /* sid is domain sid */
+                return dom;
+            }
+
+            /* sid is object sid, check if domain sid is align with
+             * sid first subauthority component */
+            if (sid[dom_sid_len] == '-') {
+                return dom;
+            }
+        }
+
+        dom = get_next_domain(dom, true);
+    }
+
+    return NULL;
+}
+
 struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
                                       struct sss_domain_info *parent,
                                       const char *name,
diff --git a/src/util/util.h b/src/util/util.h
index c2c31f5d50e86315a3e751daf49cf594550bc7c6..2a77df1d811afbf66ae03d9cc1891f66e8e5a0ec 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -539,6 +539,8 @@ struct sss_domain_info *get_next_domain(struct sss_domain_info *domain,
 struct sss_domain_info *find_subdomain_by_name(struct sss_domain_info *domain,
                                                const char *name,
                                                bool match_any);
+struct sss_domain_info *find_subdomain_by_sid(struct sss_domain_info *domain,
+                                              const char *sid);
 bool subdomain_enumerates(struct sss_domain_info *parent,
                           const char *sd_name);
 
-- 
1.7.11.7

From 48a5c8ce9333ca72b614e67f3c687fc86ac86e14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Thu, 12 Sep 2013 12:55:44 +0200
Subject: [PATCH 5/8] util: add find_subdomain_by_object_name()

This function will parse object name into name and domain
name part and return appropriate sss domain.

Resolves:
https://fedorahosted.org/sssd/ticket/2034
---
 src/util/domain_info_utils.c | 35 +++++++++++++++++++++++++++++++++++
 src/util/util.h              |  4 ++++
 2 files changed, 39 insertions(+)

diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
index f9d9057a811f3e08c451d7f6b44bc14202559962..7b1eb1a399656310e8c9549731db43fd6f425e4c 100644
--- a/src/util/domain_info_utils.c
+++ b/src/util/domain_info_utils.c
@@ -128,6 +128,41 @@ struct sss_domain_info *find_subdomain_by_sid(struct sss_domain_info *domain,
     return NULL;
 }
 
+struct sss_domain_info *
+find_subdomain_by_object_name(struct sss_domain_info *domain,
+                              const char *object_name)
+{
+    TALLOC_CTX *tmp_ctx;
+    struct sss_domain_info *dom = NULL;
+    char *domainname = NULL;
+    char *name = NULL;
+    errno_t ret;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
+        return NULL;
+    }
+
+    ret = sss_parse_name(tmp_ctx, domain->names, object_name,
+                         &domainname, &name);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to parse name '%s' [%d]: %s\n",
+                                    object_name, ret, sss_strerror(ret)));
+        goto done;
+    }
+
+    if (domainname == NULL) {
+        dom = domain;
+    } else {
+        dom = find_subdomain_by_name(domain, domainname, true);
+    }
+
+done:
+    talloc_free(tmp_ctx);
+    return dom;
+}
+
 struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
                                       struct sss_domain_info *parent,
                                       const char *name,
diff --git a/src/util/util.h b/src/util/util.h
index 2a77df1d811afbf66ae03d9cc1891f66e8e5a0ec..89b5b221b626b5515847fd06e6bac52c52438a95 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -541,6 +541,10 @@ struct sss_domain_info *find_subdomain_by_name(struct sss_domain_info *domain,
                                                bool match_any);
 struct sss_domain_info *find_subdomain_by_sid(struct sss_domain_info *domain,
                                               const char *sid);
+struct sss_domain_info *
+find_subdomain_by_object_name(struct sss_domain_info *domain,
+                              const char *object_name);
+
 bool subdomain_enumerates(struct sss_domain_info *parent,
                           const char *sd_name);
 
-- 
1.7.11.7

From f301c7074d3ce02dcf38201ba714006abb5b8e5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Wed, 28 Aug 2013 11:35:27 +0200
Subject: [PATCH 6/8] simple provider: support subdomain groups

Resolves:
https://fedorahosted.org/sssd/ticket/2034
---
 src/providers/simple/simple_access_check.c | 86 ++++++++++++++++++++++--------
 1 file changed, 63 insertions(+), 23 deletions(-)

diff --git a/src/providers/simple/simple_access_check.c b/src/providers/simple/simple_access_check.c
index dc5f3676484c3748186cbe69fd4260ee329568a6..efcb7b97dd2c8bd1ba5bc7aba0f6c629357c120d 100644
--- a/src/providers/simple/simple_access_check.c
+++ b/src/providers/simple/simple_access_check.c
@@ -152,6 +152,7 @@ simple_check_groups(struct simple_ctx *ctx, const char **group_names,
 }
 
 struct simple_resolve_group_state {
+    struct sss_domain_info *domain;
     gid_t gid;
     struct simple_ctx *ctx;
 
@@ -166,6 +167,7 @@ static struct tevent_req *
 simple_resolve_group_send(TALLOC_CTX *mem_ctx,
                           struct tevent_context *ev,
                           struct simple_ctx *ctx,
+                          struct sss_domain_info *domain,
                           gid_t gid)
 {
     errno_t ret;
@@ -178,6 +180,7 @@ simple_resolve_group_send(TALLOC_CTX *mem_ctx,
                             struct simple_resolve_group_state);
     if (!req) return NULL;
 
+    state->domain = domain;
     state->gid = gid;
     state->ctx = ctx;
 
@@ -206,7 +209,7 @@ simple_resolve_group_send(TALLOC_CTX *mem_ctx,
     ar->attr_type = BE_ATTR_CORE;
     ar->filter_type = BE_FILTER_IDNUM;
     ar->filter_value = talloc_asprintf(ar, "%llu", (unsigned long long) gid);
-    ar->domain = talloc_strdup(ar, ctx->domain->name);
+    ar->domain = talloc_strdup(ar, state->domain->name);
     if (!ar->domain || !ar->filter_value) {
         ret = ENOMEM;
         goto done;
@@ -240,10 +243,13 @@ simple_resolve_group_check(struct simple_resolve_group_state *state)
                                   SYSDB_GIDNUM, NULL };
 
     /* Check the cache by GID again and fetch the name */
-    ret = sysdb_search_group_by_gid(state, state->ctx->domain->sysdb,
-                                    state->ctx->domain, state->gid,
+    ret = sysdb_search_group_by_gid(state, state->domain->sysdb,
+                                    state->domain, state->gid,
                                     group_attrs, &group);
-    if (ret != EOK) {
+    if (ret == ENOENT) {
+        /* The group is missing, we will try to update it. */
+        return EAGAIN;
+    } else if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE,
                ("Could not look up group by gid [%lu]: [%d][%s]\n",
                state->gid, ret, sss_strerror(ret)));
@@ -321,12 +327,18 @@ simple_resolve_group_recv(struct tevent_req *req,
     return EOK;
 }
 
+struct simple_group {
+    struct sss_domain_info *domain;
+    gid_t gid;
+};
+
 struct simple_check_groups_state {
     struct tevent_context *ev;
     struct simple_ctx *ctx;
+    struct sss_domain_info *domain;
 
-    gid_t *lookup_gids;
-    size_t num_gids;
+    struct simple_group *lookup_groups;
+    size_t num_groups;
     size_t giter;
 
     const char **group_names;
@@ -352,7 +364,8 @@ simple_check_get_groups_send(TALLOC_CTX *mem_ctx,
     struct tevent_req *req;
     struct tevent_req *subreq;
     struct simple_check_groups_state *state;
-    const char *attrs[] = { SYSDB_NAME, SYSDB_POSIX, SYSDB_GIDNUM, NULL };
+    const char *attrs[] = { SYSDB_NAME, SYSDB_POSIX, SYSDB_GIDNUM,
+                            SYSDB_SID_STR, NULL };
     size_t group_count;
     struct ldb_message *user;
     struct ldb_message **groups;
@@ -368,7 +381,15 @@ simple_check_get_groups_send(TALLOC_CTX *mem_ctx,
 
     DEBUG(SSSDBG_TRACE_LIBS, ("Looking up groups for user %s\n", username));
 
-    ret = sysdb_search_user_by_name(state, ctx->domain->sysdb, ctx->domain,
+    /* get domain from username */
+    state->domain = find_subdomain_by_object_name(ctx->domain, username);
+    if (state->domain == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid user %s!\n", username));
+        ret = EINVAL;
+        goto done;
+    }
+
+    ret = sysdb_search_user_by_name(state, state->domain->sysdb, state->domain,
                                     username, attrs, &user);
     if (ret == ENOENT) {
         DEBUG(SSSDBG_MINOR_FAILURE, ("No such user %s\n", username));
@@ -381,7 +402,7 @@ simple_check_get_groups_send(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    ret = sysdb_asq_search(state, ctx->domain->sysdb,
+    ret = sysdb_asq_search(state, state->domain->sysdb,
                            user->dn, NULL, SYSDB_MEMBEROF,
                            attrs, &group_count, &groups);
     if (ret != EOK) {
@@ -394,8 +415,9 @@ simple_check_get_groups_send(TALLOC_CTX *mem_ctx,
 
     /* One extra space for terminator, one extra space for private group */
     state->group_names = talloc_zero_array(state, const char *, group_count + 2);
-    state->lookup_gids = talloc_zero_array(state, gid_t, group_count + 2);
-    if (!state->group_names || !state->lookup_gids) {
+    state->lookup_groups = talloc_zero_array(state, struct simple_group,
+                                             group_count + 2);
+    if (!state->group_names || !state->lookup_groups) {
         ret = ENOMEM;
         goto done;
     }
@@ -426,7 +448,7 @@ simple_check_get_groups_send(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    if (state->num_gids == 0) {
+    if (state->num_groups == 0) {
         /* If all groups could have been resolved by name, we are
          * done
          */
@@ -435,10 +457,11 @@ simple_check_get_groups_send(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    DEBUG(SSSDBG_TRACE_FUNC, ("Need to resolve %d groups\n", state->num_gids));
+    DEBUG(SSSDBG_TRACE_FUNC, ("Need to resolve %d groups\n", state->num_groups));
     state->giter = 0;
     subreq = simple_resolve_group_send(req, state->ev, state->ctx,
-                                       state->lookup_gids[state->giter]);
+                                       state->lookup_groups[state->giter].domain,
+                                       state->lookup_groups[state->giter].gid);
     if (!subreq) {
         ret = ENOMEM;
         goto done;
@@ -471,7 +494,7 @@ static void simple_check_get_groups_next(struct tevent_req *subreq)
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE,
               ("Could not resolve name of group with GID %llu\n",
-              state->lookup_gids[state->giter]));
+              state->lookup_groups[state->giter]));
         tevent_req_error(req, ret);
         return;
     }
@@ -479,9 +502,10 @@ static void simple_check_get_groups_next(struct tevent_req *subreq)
     state->num_names++;
     state->giter++;
 
-    if (state->giter < state->num_gids) {
+    if (state->giter < state->num_groups) {
         subreq = simple_resolve_group_send(req, state->ev, state->ctx,
-                                           state->lookup_gids[state->giter]);
+                                   state->lookup_groups[state->giter].domain,
+                                   state->lookup_groups[state->giter].gid);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -499,6 +523,8 @@ simple_check_process_group(struct simple_check_groups_state *state,
                            struct ldb_message *group)
 {
     const char *name;
+    const char *group_sid;
+    struct sss_domain_info *domain;
     gid_t gid;
     bool posix;
 
@@ -543,10 +569,25 @@ simple_check_process_group(struct simple_check_groups_state *state,
         return EOK;
     }
 
-    /* Non-posix group with a GID. Needs resolving */
-    state->lookup_gids[state->num_gids] = gid;
+    /* Try to get group SID and assign it a domain */
+    group_sid = ldb_msg_find_attr_as_string(group, SYSDB_SID_STR, NULL);
+    if (group_sid == NULL) {
+        /* We will look it up in main domain. */
+        domain = state->ctx->domain;
+    } else {
+        domain = find_subdomain_by_sid(state->ctx->domain, group_sid);
+        if (domain == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE, ("There is no domain information for "
+                                        "SID %s\n", group_sid));
+            return ENOENT;
+        }
+    }
+
+    /* It is a non-posix group with a GID. Needs resolving */
+    state->lookup_groups[state->num_groups].domain = domain;
+    state->lookup_groups[state->num_groups].gid = gid;
     DEBUG(SSSDBG_TRACE_INTERNAL, ("Adding GID %llu\n", gid));
-    state->num_gids++;
+    state->num_groups++;
     return EOK;
 }
 
@@ -556,11 +597,10 @@ simple_check_get_groups_primary(struct simple_check_groups_state *state,
 {
     errno_t ret;
     const char *group_attrs[] = { SYSDB_NAME, SYSDB_POSIX,
-                                  SYSDB_GIDNUM, NULL };
+                                  SYSDB_GIDNUM, SYSDB_SID_STR, NULL };
     struct ldb_message *msg;
 
-    ret = sysdb_search_group_by_gid(state, state->ctx->domain->sysdb,
-                                    state->ctx->domain,
+    ret = sysdb_search_group_by_gid(state, state->domain->sysdb, state->domain,
                                     gid, group_attrs, &msg);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE,
-- 
1.7.11.7

From 5728684478066cc75406edf36c665cb5cb97dfcd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Tue, 3 Sep 2013 12:34:07 +0200
Subject: [PATCH 7/8] simple access test: initialize be_ctx for all tests

Recent simple access provider patches started using
be_ctx during access check. This caused segfault in
unit tests, since be_ctx wasn't initialized.

Resolves:
https://fedorahosted.org/sssd/ticket/2034
---
 src/tests/simple_access-tests.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/src/tests/simple_access-tests.c b/src/tests/simple_access-tests.c
index a7a7e276de8d90a7bb0f375dc1fc3d1ac8d5ed7c..aaf7578715430306b04dcb3a53889fe550a977ee 100644
--- a/src/tests/simple_access-tests.c
+++ b/src/tests/simple_access-tests.c
@@ -127,6 +127,21 @@ void setup_simple(void)
     test_ctx->sysdb = test_ctx->ctx->domain->sysdb;
     test_ctx->ctx->domain->case_sensitive = true;
     test_ctx->ctx->domain->mpg = false; /* Simulate an LDAP domain better */
+
+    /* be_ctx */
+    test_ctx->be_ctx = talloc_zero(test_ctx, struct be_ctx);
+    fail_if(test_ctx->be_ctx == NULL, "Unable to setup be_ctx");
+
+    test_ctx->be_ctx->cdb = test_ctx->confdb;
+    test_ctx->be_ctx->ev = test_ctx->ev;
+    test_ctx->be_ctx->conf_path = "config/domain/LOCAL";
+    test_ctx->be_ctx->domain = test_ctx->ctx->domain;
+
+    test_ctx->ctx->be_ctx = test_ctx->be_ctx;
+
+    ret = sss_names_init(test_ctx->ctx->domain, test_ctx->confdb,
+                         "LOCAL", &test_ctx->be_ctx->domain->names);
+    fail_if(ret != EOK, "Unable to setup domain names (%d)", ret);
 }
 
 void teardown_simple(void)
@@ -148,7 +163,7 @@ void setup_simple_group(void)
      * g1 and g2 respectively */
     ret = sysdb_add_group(test_ctx->sysdb, test_ctx->ctx->domain,
                           "pvt", 999, NULL, 0, 0);
-    fail_if(ret != EOK, "Could not add private group");
+    fail_if(ret != EOK, "Could not add private group %s", strerror(ret));
 
     ret = sysdb_store_user(test_ctx->sysdb, test_ctx->ctx->domain,
                            "u1", NULL, 123, 999, "u1", "/home/u1",
@@ -204,21 +219,7 @@ void teardown_simple_group(void)
 
 void setup_simple_init(void)
 {
-    errno_t ret;
-
     setup_simple();
-
-    test_ctx->be_ctx = talloc_zero(test_ctx, struct be_ctx);
-    fail_if(test_ctx->be_ctx == NULL, "Unable to setup be_ctx");
-
-    test_ctx->be_ctx->cdb = test_ctx->confdb;
-    test_ctx->be_ctx->ev = test_ctx->ev;
-    test_ctx->be_ctx->conf_path = "config/domain/LOCAL";
-    test_ctx->be_ctx->domain = test_ctx->ctx->domain;
-
-    ret = sss_names_init(test_ctx->ctx->domain, test_ctx->confdb,
-                         "LOCAL", &test_ctx->be_ctx->domain->names);
-    fail_if(ret != EOK, "Unable to setup domain names (%d)", ret);
 }
 
 void teardown_simple_init(void)
-- 
1.7.11.7

From 4a4394b58a5169bb659e1ccc9bbfa1f903456486 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Thu, 12 Sep 2013 13:15:47 +0200
Subject: [PATCH 8/8] simple provider: obey case sensitivity for subdomain
 users and groups

When comparing username and his groups to access list, we will
obey case sensitivity of object from access list.

Resolves:
https://fedorahosted.org/sssd/ticket/2034
---
 src/providers/simple/simple_access_check.c | 50 +++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 7 deletions(-)

diff --git a/src/providers/simple/simple_access_check.c b/src/providers/simple/simple_access_check.c
index efcb7b97dd2c8bd1ba5bc7aba0f6c629357c120d..9a7e0e680115ee3c3ce7ae7672b549f88ac78529 100644
--- a/src/providers/simple/simple_access_check.c
+++ b/src/providers/simple/simple_access_check.c
@@ -44,13 +44,22 @@ static errno_t
 simple_check_users(struct simple_ctx *ctx, const char *username,
                    bool *access_granted)
 {
+    struct sss_domain_info *domain = NULL;
     int i;
-    bool cs = ctx->domain->case_sensitive;
 
     /* First, check whether the user is in the allowed users list */
     if (ctx->allow_users != NULL) {
         for(i = 0; ctx->allow_users[i] != NULL; i++) {
-            if (sss_string_equal(cs, username, ctx->allow_users[i])) {
+            domain = find_subdomain_by_object_name(ctx->domain,
+                                                   ctx->allow_users[i]);
+            if (domain == NULL) {
+                DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid user %s!\n",
+                                            ctx->allow_users[i]));
+                return EINVAL;
+            }
+
+            if (sss_string_equal(domain->case_sensitive, username,
+                                 ctx->allow_users[i])) {
                 DEBUG(SSSDBG_TRACE_LIBS,
                       ("User [%s] found in allow list, access granted.\n",
                       username));
@@ -74,10 +83,19 @@ simple_check_users(struct simple_ctx *ctx, const char *username,
     /* Next check whether this user has been specifically denied */
     if (ctx->deny_users != NULL) {
         for(i = 0; ctx->deny_users[i] != NULL; i++) {
-            if (sss_string_equal(cs, username, ctx->deny_users[i])) {
+            domain = find_subdomain_by_object_name(ctx->domain,
+                                                   ctx->deny_users[i]);
+            if (domain == NULL) {
+                DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid user %s!\n",
+                                            ctx->deny_users[i]));
+                return EINVAL;
+            }
+
+            if (sss_string_equal(domain->case_sensitive, username,
+                                 ctx->deny_users[i])) {
                 DEBUG(SSSDBG_TRACE_LIBS,
                       ("User [%s] found in deny list, access denied.\n",
-                      username));
+                        ctx->deny_users[i]));
 
                 /* Return immediately on explicit denial */
                 *access_granted = false;
@@ -93,9 +111,9 @@ static errno_t
 simple_check_groups(struct simple_ctx *ctx, const char **group_names,
                     bool *access_granted)
 {
+    struct sss_domain_info *domain = NULL;
     bool matched;
     int i, j;
-    bool cs = ctx->domain->case_sensitive;
 
     /* Now process allow and deny group rules
      * If access was already granted above, we'll skip
@@ -104,8 +122,17 @@ simple_check_groups(struct simple_ctx *ctx, const char **group_names,
     if (ctx->allow_groups && !*access_granted) {
         matched = false;
         for (i = 0; ctx->allow_groups[i]; i++) {
+            domain = find_subdomain_by_object_name(ctx->domain,
+                                                   ctx->allow_groups[i]);
+            if (domain == NULL) {
+                DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid group %s!\n",
+                                            ctx->allow_groups[i]));
+                return EINVAL;
+            }
+
             for(j = 0; group_names[j]; j++) {
-                if (sss_string_equal(cs, group_names[j], ctx->allow_groups[i])) {
+                if (sss_string_equal(domain->case_sensitive,
+                                     group_names[j], ctx->allow_groups[i])) {
                     matched = true;
                     break;
                 }
@@ -128,8 +155,17 @@ simple_check_groups(struct simple_ctx *ctx, const char **group_names,
     if (ctx->deny_groups) {
         matched = false;
         for (i = 0; ctx->deny_groups[i]; i++) {
+            domain = find_subdomain_by_object_name(ctx->domain,
+                                                   ctx->deny_groups[i]);
+            if (domain == NULL) {
+                DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid group %s!\n",
+                                            ctx->deny_groups[i]));
+                return EINVAL;
+            }
+
             for(j = 0; group_names[j]; j++) {
-                if (sss_string_equal(cs, group_names[j], ctx->deny_groups[i])) {
+                if (sss_string_equal(domain->case_sensitive,
+                                     group_names[j], ctx->deny_groups[i])) {
                     matched = true;
                     break;
                 }
-- 
1.7.11.7

_______________________________________________
sssd-devel mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to