]> git.ipfire.org Git - ipfire-3.x.git/blame - sssd/patches/0018-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch
kernel: Drop ld.so placeholder files
[ipfire-3.x.git] / sssd / patches / 0018-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch
CommitLineData
92ae11e3
SS
1From 8e08e21b64a9ef67a4c40917786536d69d7ec4d3 Mon Sep 17 00:00:00 2001
2From: Jakub Hrozek <jhrozek@redhat.com>
3Date: Mon, 31 Oct 2016 21:39:57 +0100
4Subject: [PATCH 18/39] SYSDB: Augment sysdb_try_to_find_expected_dn to match
5 search base as well
6
7In cases where the domain name in sssd.conf does not match the AD
8domain, our previous matching process wouldn't match. This patch
9augments the matching as follows:
10 - the search base is known to sysdb_try_to_find_expected_dn and is
11 expected to be non-NULL
12 - the existing matching is ran first
13 - during the search base, matching, all the non-DC components are
14 stripped from the search base to 'canonicalize' the search base
15 - if only a single entry that matches with a non-DC DN component
16 (matching with a DC component would mean the DN comes from a
17 different domain) then this entry is a match and is returned
18
19Resolves:
20https://fedorahosted.org/sssd/ticket/3199
21
22Reviewed-by: Sumit Bose <sbose@redhat.com>
23(cherry picked from commit 24d8c85fae253f988165c112af208198cf48eef6)
24(cherry picked from commit 956fdd727f8d7a28f1456146b3b7dfee49f38626)
25---
26 src/db/sysdb.h | 1 +
27 src/db/sysdb_subdomains.c | 99 ++++++++++++++++++++++++++++++
28 src/providers/ldap/sdap_async_initgroups.c | 8 ++-
29 src/tests/cmocka/test_sysdb_subdomains.c | 43 +++++++++++--
30 4 files changed, 144 insertions(+), 7 deletions(-)
31
32diff --git a/src/db/sysdb.h b/src/db/sysdb.h
33index 901268390..5dedd97dd 100644
34--- a/src/db/sysdb.h
35+++ b/src/db/sysdb.h
36@@ -1297,6 +1297,7 @@ errno_t sysdb_handle_original_uuid(const char *orig_name,
37
38 errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
39 const char *domain_component_name,
40+ const char *ldap_search_base,
41 struct sysdb_attrs **usr_attrs,
42 size_t count,
43 struct sysdb_attrs **exp_usr);
44diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
45index b011bad6c..780140484 100644
46--- a/src/db/sysdb_subdomains.c
47+++ b/src/db/sysdb_subdomains.c
48@@ -1320,8 +1320,97 @@ static errno_t match_basedn(TALLOC_CTX *tmp_ctx,
49 _result);
50 }
51
52+static errno_t match_search_base(TALLOC_CTX *tmp_ctx,
53+ struct sss_domain_info *dom,
54+ const char *domain_component_name,
55+ const char *domain_search_base,
56+ struct sysdb_attrs **usr_attrs,
57+ size_t count,
58+ struct sysdb_attrs **_result)
59+{
60+ errno_t ret;
61+ bool ok;
62+ const char *search_base;
63+ struct ldb_context *ldb_ctx;
64+ struct sysdb_attrs *result = NULL;
65+ struct ldb_dn *ldb_search_base;
66+ int search_base_comp_num;
67+ int non_dc_comp_num;
68+ const char *component_name;
69+
70+ ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
71+ if (ldb_ctx == NULL) {
72+ DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
73+ ret = EINVAL;
74+ goto done;
75+ }
76+
77+ ldb_search_base = ldb_dn_new(tmp_ctx, ldb_ctx, domain_search_base);
78+ if (ldb_search_base == NULL) {
79+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
80+ ret = ENOMEM;
81+ goto done;
82+ }
83+
84+ /* strip non-DC components from the search base */
85+ search_base_comp_num = ldb_dn_get_comp_num(ldb_search_base);
86+ for (non_dc_comp_num = 0;
87+ non_dc_comp_num < search_base_comp_num;
88+ non_dc_comp_num++) {
89+
90+ component_name = ldb_dn_get_component_name(ldb_search_base,
91+ non_dc_comp_num);
92+ if (strcasecmp(domain_component_name, component_name) == 0) {
93+ break;
94+ }
95+ }
96+
97+ if (non_dc_comp_num == search_base_comp_num) {
98+ /* The search base does not have any non-DC components, the search wouldn't
99+ * match anyway
100+ */
101+ ret = EOK;
102+ *_result = NULL;
103+ goto done;
104+ }
105+
106+ ok = ldb_dn_remove_child_components(ldb_search_base, non_dc_comp_num);
107+ if (!ok) {
108+ ret = EINVAL;
109+ goto done;
110+ }
111+
112+ search_base = ldb_dn_get_linearized(ldb_search_base);
113+ if (search_base == NULL) {
114+ ret = ENOMEM;
115+ goto done;
116+ }
117+
118+ ret = match_cn_users(tmp_ctx, usr_attrs, count, search_base, &result);
119+ if (ret != EOK) {
120+ goto done;
121+ }
122+
123+ if (result == NULL) {
124+ ret = match_non_dc_comp(tmp_ctx, dom,
125+ usr_attrs, count,
126+ ldb_search_base, search_base,
127+ domain_component_name,
128+ &result);
129+ if (ret != EOK) {
130+ goto done;
131+ }
132+ }
133+
134+ ret = EOK;
135+ *_result = result;
136+done:
137+ return ret;
138+}
139+
140 errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
141 const char *domain_component_name,
142+ const char *domain_search_base,
143 struct sysdb_attrs **usr_attrs,
144 size_t count,
145 struct sysdb_attrs **exp_usr)
146@@ -1332,6 +1421,7 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
147 struct sysdb_attrs *result = NULL;
148
149 if (dom == NULL || domain_component_name == NULL
150+ || domain_search_base == NULL
151 || usr_attrs == NULL || count == 0) {
152 return EINVAL;
153 }
154@@ -1364,6 +1454,15 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
155 }
156
157 if (result == NULL) {
158+ ret = match_search_base(tmp_ctx, dom, domain_component_name,
159+ domain_search_base, usr_attrs, count,
160+ &result);
161+ if (ret != EOK) {
162+ goto done;
163+ }
164+ }
165+
166+ if (result == NULL) {
167 DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
168 ret = ENOENT;
169 goto done;
170diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
171index 45fc007e0..9b505e7fa 100644
172--- a/src/providers/ldap/sdap_async_initgroups.c
173+++ b/src/providers/ldap/sdap_async_initgroups.c
174@@ -2947,7 +2947,13 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
175 DEBUG(SSSDBG_OP_FAILURE,
176 "Expected one user entry and got %zu\n", count);
177
178- ret = sysdb_try_to_find_expected_dn(state->dom, "dc", usr_attrs, count,
179+ /* When matching against a search base, it's sufficient to pick only
180+ * the first search base because all bases in a single domain would
181+ * have the same DC= components
182+ */
183+ ret = sysdb_try_to_find_expected_dn(state->dom, "dc",
184+ state->sdom->search_bases[0]->basedn,
185+ usr_attrs, count,
186 &state->orig_user);
187 if (ret != EOK) {
188 DEBUG(SSSDBG_OP_FAILURE,
189diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
190index c9db56841..52056e043 100644
191--- a/src/tests/cmocka/test_sysdb_subdomains.c
192+++ b/src/tests/cmocka/test_sysdb_subdomains.c
193@@ -520,7 +520,9 @@ static void test_try_to_find_expected_dn(void **state)
194 int ret;
195 struct sysdb_attrs *result;
196 struct sysdb_attrs *usr_attrs[10] = { NULL };
197+ struct sysdb_attrs *dom_usr_attrs[10] = { NULL };
198 struct sss_domain_info *dom;
199+ char *dom_basedn;
200 struct subdom_test_ctx *test_ctx =
201 talloc_get_type(*state, struct subdom_test_ctx);
202
203@@ -528,6 +530,9 @@ static void test_try_to_find_expected_dn(void **state)
204 "child2.test_sysdb_subdomains_2", true);
205 assert_non_null(dom);
206
207+ ret = domain_to_basedn(test_ctx, dom->name, &dom_basedn);
208+ assert_int_equal(ret, EOK);
209+
210 usr_attrs[0] = sysdb_new_attrs(test_ctx);
211 assert_non_null(usr_attrs[0]);
212
213@@ -535,13 +540,13 @@ static void test_try_to_find_expected_dn(void **state)
214 "uid=user,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
215 assert_int_equal(ret, EOK);
216
217- ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, 0, NULL);
218+ ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, NULL, 0, NULL);
219 assert_int_equal(ret, EINVAL);
220
221- ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 1, &result);
222+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 1, &result);
223 assert_int_equal(ret, ENOENT);
224
225- ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 1, &result);
226+ ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 1, &result);
227 assert_int_equal(ret, EOK);
228 assert_ptr_equal(result, usr_attrs[0]);
229
230@@ -559,11 +564,11 @@ static void test_try_to_find_expected_dn(void **state)
231 "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
232 assert_int_equal(ret, EOK);
233
234- ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
235+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result);
236 assert_int_equal(ret, EOK);
237 assert_ptr_equal(result, usr_attrs[1]);
238
239- ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 3, &result);
240+ ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 3, &result);
241 assert_int_equal(ret, EINVAL);
242
243 /* Make sure cn=users match is preferred */
244@@ -575,10 +580,36 @@ static void test_try_to_find_expected_dn(void **state)
245 "uid=user2,cn=abc,cn=users,dc=child2,dc=test_sysdb_subdomains_2");
246 assert_int_equal(ret, EOK);
247
248- ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
249+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result);
250 assert_int_equal(ret, EOK);
251 assert_ptr_equal(result, usr_attrs[2]);
252
253+ /* test a case where the domain name does not match the basedn */
254+ dom->name = discard_const("default");
255+ dom_usr_attrs[0] = usr_attrs[0];
256+
257+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 1, &result);
258+ assert_int_equal(ret, ENOENT);
259+
260+ dom_usr_attrs[1] = usr_attrs[1];
261+ dom_usr_attrs[2] = usr_attrs[2];
262+
263+ /* Make sure cn=users match is preferred */
264+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result);
265+ assert_int_equal(ret, EOK);
266+ assert_ptr_equal(result, dom_usr_attrs[2]);
267+
268+ talloc_free(usr_attrs[2]);
269+ usr_attrs[2] = sysdb_new_attrs(test_ctx);
270+ assert_non_null(usr_attrs[2]);
271+ ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN,
272+ "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
273+ assert_int_equal(ret, EOK);
274+
275+ dom_usr_attrs[2] = usr_attrs[2];
276+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result);
277+ assert_int_equal(ret, EOK);
278+ assert_ptr_equal(result, usr_attrs[1]);
279
280 talloc_free(usr_attrs[0]);
281 talloc_free(usr_attrs[1]);
282--
2832.11.0
284