[SSSD] [PATCH] Ability to set a domain as case sensitive or insensitive
Jakub Hrozek
jhrozek at redhat.com
Thu Dec 15 09:48:34 UTC 2011
On Wed, Dec 14, 2011 at 01:37:47PM -0500, Stephen Gallagher wrote:
> On Wed, 2011-12-14 at 14:15 +0100, Jakub Hrozek wrote:
> > Thank you for the review. New patches are attached.
>
> Patch 0008:
>
> +static bool string_equal(bool cs, const char *s1, const char *s2)
> +{
> + if (cs) {
> + return strcasecmp(s1, s2) == 0;
> + }
> +
> + return sss_utf8_case_eq((const uint8_t *)s1, (const uint8_t *)s2)
> == EOK;
> +}
> +
>
>
> I'm pretty sure you wanted:
>
>
> + if (cs) {
> + return strcmp(s1, s2) == 0;
> + }
>
> not strcasecmp() there.
>
>
> Everything else looks good.
Stupid code reviews catching my carefully crafted backdoor..
On a serious note, thank you for catching that. New patches are attached.
-------------- next part --------------
From f00c355b5c7a2837dc0574e0a13db6974f6e06ae Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 6 Dec 2011 14:57:58 +0100
Subject: [PATCH 1/9] sss_utf8_tolower utility function+unit tests
---
Makefile.am | 3 +-
src/tests/util-tests.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++
src/util/sss_tc_utf8.c | 57 ++++++++++++++++++++++++++++
src/util/sss_utf8.c | 54 +++++++++++++++++++++++++++
src/util/sss_utf8.h | 5 ++
src/util/util.c | 1 +
src/util/util.h | 6 +++
7 files changed, 221 insertions(+), 1 deletions(-)
create mode 100644 src/util/sss_tc_utf8.c
diff --git a/Makefile.am b/Makefile.am
index 8d75b8767bd30532f9a241ca1518545d602beffb..b8fb9e094c57c1c1ddbc51d10232ea64236e813a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -382,7 +382,8 @@ libsss_util_la_SOURCES = \
src/util/strtonum.c \
src/util/check_and_open.c \
src/util/refcount.c \
- src/util/sss_utf8.c
+ src/util/sss_utf8.c \
+ src/util/sss_tc_utf8.c
libsss_util_la_LIBADD = \
$(SSSD_LIBS) \
$(UNICODE_LIBS) \
diff --git a/src/tests/util-tests.c b/src/tests/util-tests.c
index 52d302778ed3c819d3ffeef96e7b52c778a15825..33406dacfd45e7e6f6ed16dc1dddbb492ccc7c53 100644
--- a/src/tests/util-tests.c
+++ b/src/tests/util-tests.c
@@ -26,6 +26,7 @@
#include <talloc.h>
#include <check.h>
#include "util/util.h"
+#include "util/sss_utf8.h"
#include "tests/common.h"
START_TEST(test_parse_args)
@@ -312,6 +313,91 @@ START_TEST(test_size_t_overflow)
}
END_TEST
+START_TEST(test_utf8_lowercase)
+{
+ const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
+ const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
+ uint8_t *lcase;
+ size_t nlen;
+
+ lcase = sss_utf8_tolower(munchen_utf8_upcase,
+ strlen((const char *)munchen_utf8_upcase),
+ &nlen);
+ fail_if(strlen((const char *) munchen_utf8_upcase) != nlen); /* This is not true for utf8 strings in general */
+ fail_if(memcmp(lcase, munchen_utf8_lowcase, nlen));
+ sss_utf8_free(lcase);
+}
+END_TEST
+
+START_TEST(test_utf8_talloc_lowercase)
+{
+ const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
+ const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
+ uint8_t *lcase;
+ size_t nsize;
+
+ TALLOC_CTX *test_ctx;
+ test_ctx = talloc_new(NULL);
+ fail_if(test_ctx == NULL);
+
+ lcase = sss_tc_utf8_tolower(test_ctx, munchen_utf8_upcase,
+ strlen((const char *) munchen_utf8_upcase),
+ &nsize);
+ fail_if(memcmp(lcase, munchen_utf8_lowcase, nsize));
+ talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST(test_utf8_talloc_str_lowercase)
+{
+ const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
+ const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
+ char *lcase;
+
+ TALLOC_CTX *test_ctx;
+ test_ctx = talloc_new(NULL);
+ fail_if(test_ctx == NULL);
+
+ lcase = sss_tc_utf8_str_tolower(test_ctx, (const char *) munchen_utf8_upcase);
+ fail_if(memcmp(lcase, munchen_utf8_lowcase, strlen(lcase)));
+ talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST(test_utf8_caseeq)
+{
+ const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
+ const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
+ const uint8_t czech_utf8_lowcase[] = { 0xC4, 0x8D, 'e', 'c', 'h', 0x0 };
+ const uint8_t czech_utf8_upcase[] = { 0xC4, 0x8C, 'e', 'c', 'h', 0x0 };
+ const uint8_t czech_utf8_lowcase_neg[] = { 0xC4, 0x8E, 'e', 'c', 'h', 0x0 };
+ errno_t ret;
+
+ ret = sss_utf8_case_eq(munchen_utf8_upcase, munchen_utf8_lowcase);
+ fail_unless(ret == EOK, "Latin 1 Supplement comparison failed\n");
+
+ ret = sss_utf8_case_eq(czech_utf8_upcase, czech_utf8_lowcase);
+ fail_unless(ret == EOK, "Latin Extended A comparison failed\n");
+
+ ret = sss_utf8_case_eq(czech_utf8_upcase, czech_utf8_lowcase_neg);
+ fail_if(ret == EOK, "Negative test succeeded\n");
+}
+END_TEST
+
+START_TEST(test_utf8_check)
+{
+ const char *invalid = "ad\351la\357d";
+ const uint8_t valid[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
+ bool ret;
+
+ ret = sss_utf8_check(valid, strlen((const char *) valid));
+ fail_unless(ret == true, "Positive test failed\n");
+
+ ret = sss_utf8_check((const uint8_t *) invalid, strlen(invalid));
+ fail_unless(ret == false, "Negative test succeeded\n");
+}
+END_TEST
+
Suite *util_suite(void)
{
Suite *s = suite_create("util");
@@ -324,7 +410,17 @@ Suite *util_suite(void)
tcase_add_test (tc_util, test_parse_args);
tcase_set_timeout(tc_util, 60);
+ TCase *tc_utf8 = tcase_create("utf8");
+ tcase_add_test (tc_util, test_utf8_lowercase);
+ tcase_add_test (tc_util, test_utf8_talloc_lowercase);
+ tcase_add_test (tc_util, test_utf8_talloc_str_lowercase);
+ tcase_add_test (tc_util, test_utf8_caseeq);
+ tcase_add_test (tc_util, test_utf8_check);
+
+ tcase_set_timeout(tc_utf8, 60);
+
suite_add_tcase (s, tc_util);
+ suite_add_tcase (s, tc_utf8);
return s;
}
diff --git a/src/util/sss_tc_utf8.c b/src/util/sss_tc_utf8.c
new file mode 100644
index 0000000000000000000000000000000000000000..6a976211f7b77d329ba3261577c43466406f3da9
--- /dev/null
+++ b/src/util/sss_tc_utf8.c
@@ -0,0 +1,57 @@
+/*
+ Authors:
+ Jakub Hrozek <jhrozek at redhat.com>
+
+ Copyright (C) 2011 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/sss_utf8.h"
+
+char *
+sss_tc_utf8_str_tolower(TALLOC_CTX *mem_ctx, const char *s)
+{
+ size_t nlen;
+ uint8_t *ret;
+
+ ret = sss_tc_utf8_tolower(mem_ctx, (const uint8_t *) s, strlen(s), &nlen);
+ if (!ret) return NULL;
+
+ ret = talloc_realloc(mem_ctx, ret, uint8_t, nlen+1);
+ if (!ret) return NULL;
+
+ ret[nlen] = '\0';
+ return (char *) ret;
+}
+
+uint8_t *
+sss_tc_utf8_tolower(TALLOC_CTX *mem_ctx, const uint8_t *s, size_t len, size_t *_nlen)
+{
+ uint8_t *lower;
+ uint8_t *ret;
+ size_t nlen;
+
+ lower = sss_utf8_tolower(s, len, &nlen);
+ if (!lower) return NULL;
+
+ ret = talloc_memdup(mem_ctx, lower, nlen);
+ sss_utf8_free(lower);
+ if (!ret) return NULL;
+
+ *_nlen = nlen;
+ return ret;
+}
+
diff --git a/src/util/sss_utf8.c b/src/util/sss_utf8.c
index 4a98233bb97bbfc77a60bba6a24ef04bf78bfa56..7997a6df4454ef2ec7e5469e244bb5e1c444b1ba 100644
--- a/src/util/sss_utf8.c
+++ b/src/util/sss_utf8.c
@@ -24,6 +24,60 @@
#include "sss_utf8.h"
#ifdef HAVE_LIBUNISTRING
+void sss_utf8_free(void *ptr)
+{
+ return free(ptr);
+}
+#elif HAVE_GLIB2
+void sss_utf8_free(void *ptr)
+{
+ return g_free(ptr);
+}
+#else
+#error No unicode library
+#endif
+
+#ifdef HAVE_LIBUNISTRING
+uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *_nlen)
+{
+ size_t llen;
+ uint8_t *lower;
+
+ lower = u8_tolower(s, len, NULL, NULL, NULL, &llen);
+ if (!lower) return NULL;
+
+ if (_nlen) *_nlen = llen;
+ return lower;
+}
+#elif HAVE_GLIB2
+uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *_nlen)
+{
+ gchar *glower;
+ size_t nlen;
+ uint8_t *lower;
+
+ glower = g_utf8_strdown((const gchar *) s, len);
+ if (!glower) return NULL;
+
+ /* strlen() is safe here because g_utf8_strdown() always null-terminates */
+ nlen = strlen(glower);
+
+ lower = g_malloc(nlen);
+ if (!lower) {
+ g_free(glower);
+ return NULL;
+ }
+
+ memcpy(lower, glower, nlen);
+ g_free(glower);
+ if (_nlen) *_nlen = nlen;
+ return (uint8_t *) lower;
+}
+#else
+#error No unicode library
+#endif
+
+#ifdef HAVE_LIBUNISTRING
bool sss_utf8_check(const uint8_t *s, size_t n)
{
if (u8_check(s, n) == NULL) {
diff --git a/src/util/sss_utf8.h b/src/util/sss_utf8.h
index 37dcff959b1a86110fba919082b075c7f4963f02..b7da76219c867b96193b414f1b9bdad75e995ec9 100644
--- a/src/util/sss_utf8.h
+++ b/src/util/sss_utf8.h
@@ -35,6 +35,11 @@
#define ENOMATCH -1
#endif
+void sss_utf8_free(void *ptr);
+
+/* The result must be freed with sss_utf8_free() */
+uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *nlen);
+
bool sss_utf8_check(const uint8_t *s, size_t n);
errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2);
diff --git a/src/util/util.c b/src/util/util.c
index b4b1b124317377fe22612576e8e2d8d3256c14ce..f525c915b6886f8f0e51f0026831e6301c2df8ff 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -23,6 +23,7 @@
#include "talloc.h"
#include "util/util.h"
+#include "util/sss_utf8.h"
#include "dhash.h"
/* split a string into an allocated array of strings.
diff --git a/src/util/util.h b/src/util/util.h
index 9a00647179b010f7dd1b9744b3aaa013cc6e5769..4ff112b7556a6634961c41edaf6d95d42f29c5d4 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -502,4 +502,10 @@ errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
char *
sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr);
+/* from sss_tc_utf8.c */
+char *
+sss_tc_utf8_str_tolower(TALLOC_CTX *mem_ctx, const char *s);
+uint8_t *
+sss_tc_utf8_tolower(TALLOC_CTX *mem_ctx, const uint8_t *s, size_t len, size_t *_nlen);
+
#endif /* __SSSD_UTIL_H__ */
--
1.7.7.4
-------------- next part --------------
From 85701ac8d5f5fbd12f9b507147b251b232752927 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 5 Dec 2011 16:00:44 +0100
Subject: [PATCH 2/9] Responders: Split getting domain by name into separate
function
---
src/responder/common/responder.h | 2 ++
src/responder/common/responder_common.c | 13 +++++++++++++
src/responder/nss/nsssrv_cmd.c | 19 +++----------------
src/responder/nss/nsssrv_netgroup.c | 2 +-
src/responder/pam/pamsrv_cmd.c | 7 ++-----
5 files changed, 21 insertions(+), 22 deletions(-)
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 3b5ab8a42136c17f0f71a202f8ae9367edfa6afb..f6784e916bbf2b7f191d2a53b6670c2a29adb996 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -150,6 +150,8 @@ int sss_parse_name(TALLOC_CTX *memctx,
int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
struct be_conn **_conn);
+struct sss_domain_info *
+responder_get_domain(struct sss_domain_info *doms, const char *domain);
/* responder_cmd.c */
int sss_cmd_execute(struct cli_ctx *cctx, struct sss_cmd_table *sss_cmds);
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 1b28a92ef6c6569a52aecf37a4e37a1c7af95de1..99b1a23aa8581e01fb2a02d36657df6c20717812 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -624,6 +624,19 @@ int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
return EOK;
}
+struct sss_domain_info *
+responder_get_domain(struct sss_domain_info *doms, const char *domain)
+{
+ struct sss_domain_info *dom;
+
+ for (dom = doms; dom; dom = dom->next) {
+ if (strcasecmp(dom->name, domain) == 0) break;
+ }
+ if (!dom) DEBUG(SSSDBG_CRIT_FAILURE, ("Unknown domain [%s]!\n", domain));
+
+ return dom;
+}
+
int responder_logrotate(DBusMessage *message,
struct sbus_connection *conn)
{
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 720813fda1efb0004b6add4fdcfa01156f1c3f12..f0270acd26659e8005a043fd9e154723cc868d0d 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -45,19 +45,6 @@ static int nss_cmd_send_error(struct nss_cmd_ctx *cmdctx, int err)
return EOK;
}
-struct sss_domain_info *nss_get_dom(struct sss_domain_info *doms,
- const char *domain)
-{
- struct sss_domain_info *dom;
-
- for (dom = doms; dom; dom = dom->next) {
- if (strcasecmp(dom->name, domain) == 0) break;
- }
- if (!dom) DEBUG(2, ("Unknown domain [%s]!\n", domain));
-
- return dom;
-}
-
int fill_empty(struct sss_packet *packet)
{
uint8_t *body;
@@ -932,7 +919,7 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
cmdctx->name, domname?domname:"<ALL>"));
if (domname) {
- dctx->domain = nss_get_dom(cctx->rctx->domains, domname);
+ dctx->domain = responder_get_domain(cctx->rctx->domains, domname);
if (!dctx->domain) {
ret = ENOENT;
goto done;
@@ -2219,7 +2206,7 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
cmdctx->name, domname?domname:"<ALL>"));
if (domname) {
- dctx->domain = nss_get_dom(cctx->rctx->domains, domname);
+ dctx->domain = responder_get_domain(cctx->rctx->domains, domname);
if (!dctx->domain) {
ret = ENOENT;
goto done;
@@ -3277,7 +3264,7 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
cmdctx->name, domname?domname:"<ALL>"));
if (domname) {
- dctx->domain = nss_get_dom(cctx->rctx->domains, domname);
+ dctx->domain = responder_get_domain(cctx->rctx->domains, domname);
if (!dctx->domain) {
ret = ENOENT;
goto done;
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 189f852485053307698720e27463456d1f97eac3..09b7fa6355421c941631775c71d33a2851edbe4e 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -204,7 +204,7 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
state->netgr_shortname, domname?domname:"<ALL>"));
if (domname) {
- dctx->domain = nss_get_dom(client->rctx->domains, domname);
+ dctx->domain = responder_get_domain(client->rctx->domains, domname);
if (!dctx->domain) {
goto error;
}
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 40df755d6af7e83d51c923f75bd0c19e4e7044de..5f77697fd33779d9cb48f993d7a8368cef8b3928 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -756,14 +756,11 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
/* now check user is valid */
if (pd->domain) {
- for (dom = cctx->rctx->domains; dom; dom = dom->next) {
- if (strcasecmp(dom->name, pd->domain) == 0) break;
- }
- if (!dom) {
+ preq->domain = responder_get_domain(cctx->rctx->domains, pd->domain);
+ if (preq->domain) {
ret = ENOENT;
goto done;
}
- preq->domain = dom;
}
else {
for (dom = preq->cctx->rctx->domains; dom; dom = dom->next) {
--
1.7.7.4
-------------- next part --------------
From cc24c741dfcd204c71e074179cae39b86986d961 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 12 Dec 2011 16:35:53 +0100
Subject: [PATCH 3/9] Canonicalize username in PAM provider
---
src/responder/pam/pamsrv_cmd.c | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 5f77697fd33779d9cb48f993d7a8368cef8b3928..7ae54ac25128868785f6c34d7f8956c052a48c82 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -93,6 +93,26 @@ static int extract_uint32_t(uint32_t *var, size_t size, uint8_t *body,
return EOK;
}
+static int pd_set_primary_name(const struct ldb_message *msg,struct pam_data *pd)
+{
+ const char *name;
+
+ name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
+ if (!name) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("A user with no name?\n"));
+ return EIO;
+ }
+
+ if (strcmp(pd->user, name)) {
+ DEBUG(SSSDBG_TRACE_FUNC, ("User's primary name is %s\n", name));
+ talloc_free(pd->user);
+ pd->user = talloc_strdup(pd, name);
+ if (!pd->user) return ENOMEM;
+ }
+
+ return EOK;
+}
+
static int pam_parse_in_data_v2(struct sss_names_ctx *snctx,
struct pam_data *pd,
uint8_t *body, size_t blen)
@@ -890,6 +910,13 @@ static int pam_check_user_search(struct pam_auth_req *preq)
DEBUG(6, ("Returning info for user [%s@%s]\n", name, dom->name));
+ /* We might have searched by alias. Pass on the primary name */
+ ret = pd_set_primary_name(preq->res->msgs[0], preq->pd);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Could not canonicalize username\n"));
+ return ret;
+ }
+
return EOK;
}
--
1.7.7.4
-------------- next part --------------
From 246a219b85482f1d58313d9c4dd25070da5d03c1 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 12 Dec 2011 16:35:22 +0100
Subject: [PATCH 4/9] Use the case sensitivity flag in responders
---
src/confdb/confdb.c | 7 +
src/confdb/confdb.h | 2 +
src/config/SSSDConfig.py | 1 +
src/config/SSSDConfigTest.py | 2 +
src/config/etc/sssd.api.conf | 1 +
src/man/sssd.conf.5.xml | 14 ++
src/responder/common/negcache.c | 267 +++++++++++++++++++++----------
src/responder/common/negcache.h | 10 +-
src/responder/common/responder_common.c | 1 -
src/responder/nss/nsssrv_cmd.c | 39 +++--
src/responder/nss/nsssrv_netgroup.c | 21 ++-
src/responder/pam/pamsrv_cmd.c | 8 +-
12 files changed, 261 insertions(+), 112 deletions(-)
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 3f668dd3dec337afc05cea4459a4eff123161cb9..9ebe0127da81c7d26e75eca4e4136472317e534d 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -856,6 +856,13 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
goto done;
}
+ ret = get_entry_as_bool(res->msgs[0], &domain->case_sensitive,
+ CONFDB_DOMAIN_CASE_SENSITIVE, true);
+ if(ret != EOK) {
+ DEBUG(0, ("Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE));
+ goto done;
+ }
+
*_domain = domain;
ret = EOK;
done:
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 266e4d27189dd14d282045cc5c7e857ebc00f974..2ebbf4f46369161a443b5ba80a58245990651948 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -117,6 +117,7 @@
#define CONFDB_DOMAIN_FAMILY_ORDER "lookup_family_order"
#define CONFDB_DOMAIN_ACCOUNT_CACHE_EXPIRATION "account_cache_expiration"
#define CONFDB_DOMAIN_OVERRIDE_GID "override_gid"
+#define CONFDB_DOMAIN_CASE_SENSITIVE "case_sensitive"
/* Local Provider */
#define CONFDB_LOCAL_DEFAULT_SHELL "default_shell"
@@ -150,6 +151,7 @@ struct sss_domain_info {
bool cache_credentials;
bool legacy_passwords;
+ bool case_sensitive;
gid_t override_gid;
const char *override_homedir;
diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py
index cb55d3de1b5ab0f08724682978e6966435b860fa..44bfb69f532adbcce88f2f0e5786987e21e69e7b 100644
--- a/src/config/SSSDConfig.py
+++ b/src/config/SSSDConfig.py
@@ -92,6 +92,7 @@ option_strings = {
'dns_resolver_timeout' : _('How long to wait for replies from DNS when resolving servers (seconds)'),
'dns_discovery_domain' : _('The domain part of service discovery DNS query'),
'override_gid' : _('Override GID value from the identity provider with this value'),
+ 'case_sensitive' : _('Treat usernames as case sensitive'),
# [provider/ipa]
'ipa_domain' : _('IPA domain'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 16ddfe5012654dc1600b79ad90493a409b0d5c9d..8421a09147dcbc25f628b4b75f278b4824413d18 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -484,6 +484,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'dns_resolver_timeout',
'dns_discovery_domain',
'override_gid',
+ 'case_sensitive',
'override_homedir',
'id_provider',
'auth_provider',
@@ -801,6 +802,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'dns_resolver_timeout',
'dns_discovery_domain',
'override_gid',
+ 'case_sensitive',
'override_homedir',
'id_provider',
'auth_provider',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 6813901ed7c2598724323a5c06529ddd62121a58..c2c425cefa9ebbb2a4169e0a13d4de2594a275dd 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -72,6 +72,7 @@ filter_groups = list, str, false
dns_resolver_timeout = int, None, false
dns_discovery_domain = str, None, false
override_gid = int, None, false
+case_sensitive = bool, None, false
override_homedir = str, None, false
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 1ed408f2e1b5ccda3f551744cbc3ea8cac7a74bf..72998b44f6637734e372b26eb7889b220ce8ac36 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -931,6 +931,20 @@
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>case_sensitive (boolean)</term>
+ <listitem>
+ <para>
+ Treat user and group names as case sensitive. At
+ the moment, this option is not supported in
+ the local provider.
+ </para>
+ <para>
+ Default: True
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index 3926574a12c898db30a1fe22ec763c2ed1d94f72..0b25baf5660b327bd3102899f55e273ce1204aec 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -21,6 +21,7 @@
#include "util/util.h"
#include "confdb/confdb.h"
+#include "responder/common/responder.h"
#include <fcntl.h>
#include <time.h>
#include "tdb.h"
@@ -158,55 +159,98 @@ done:
return ret;
}
+static int sss_ncache_check_user_int(struct sss_nc_ctx *ctx, int ttl,
+ const char *domain, const char *name)
+{
+ char *str;
+ int ret;
+
+ if (!name || !*name) return EINVAL;
+
+ str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name);
+ if (!str) return ENOMEM;
+
+ ret = sss_ncache_check_str(ctx, str, ttl);
+
+ talloc_free(str);
+ return ret;
+}
+
+static int sss_ncache_check_group_int(struct sss_nc_ctx *ctx, int ttl,
+ const char *domain, const char *name)
+{
+ char *str;
+ int ret;
+
+ if (!name || !*name) return EINVAL;
+
+ str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name);
+ if (!str) return ENOMEM;
+
+ ret = sss_ncache_check_str(ctx, str, ttl);
+
+ talloc_free(str);
+ return ret;
+}
+
+static int sss_ncache_check_netgr_int(struct sss_nc_ctx *ctx, int ttl,
+ const char *domain, const char *name)
+{
+ char *str;
+ int ret;
+
+ if (!name || !*name) return EINVAL;
+
+ str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name);
+ if (!str) return ENOMEM;
+
+ ret = sss_ncache_check_str(ctx, str, ttl);
+
+ talloc_free(str);
+ return ret;
+}
+
+typedef int (*ncache_check_byname_fn_t)(struct sss_nc_ctx *, int,
+ const char *, const char *);
+
+static int sss_cache_check_ent(struct sss_nc_ctx *ctx, int ttl,
+ struct sss_domain_info *dom, const char *name,
+ ncache_check_byname_fn_t checker)
+{
+ char *lower;
+ errno_t ret;
+
+ if (dom->case_sensitive == false) {
+ lower = sss_tc_utf8_str_tolower(ctx, name);
+ if (!lower) return ENOMEM;
+ ret = checker(ctx, ttl, dom->name, lower);
+ talloc_free(lower);
+ } else {
+ ret = checker(ctx, ttl, dom->name, name);
+ }
+
+ return ret;
+}
+
int sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl,
- const char *domain, const char *name)
+ struct sss_domain_info *dom, const char *name)
{
- char *str;
- int ret;
-
- if (!name || !*name) return EINVAL;
-
- str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name);
- if (!str) return ENOMEM;
-
- ret = sss_ncache_check_str(ctx, str, ttl);
-
- talloc_free(str);
- return ret;
+ return sss_cache_check_ent(ctx, ttl, dom, name,
+ sss_ncache_check_user_int);
}
int sss_ncache_check_group(struct sss_nc_ctx *ctx, int ttl,
- const char *domain, const char *name)
+ struct sss_domain_info *dom, const char *name)
{
- char *str;
- int ret;
-
- if (!name || !*name) return EINVAL;
-
- str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name);
- if (!str) return ENOMEM;
-
- ret = sss_ncache_check_str(ctx, str, ttl);
-
- talloc_free(str);
- return ret;
+ return sss_cache_check_ent(ctx, ttl, dom, name,
+ sss_ncache_check_group_int);
}
int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl,
- const char *domain, const char *name)
+ struct sss_domain_info *dom, const char *name)
{
- char *str;
- int ret;
-
- if (!name || !*name) return EINVAL;
-
- str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name);
- if (!str) return ENOMEM;
-
- ret = sss_ncache_check_str(ctx, str, ttl);
-
- talloc_free(str);
- return ret;
+ return sss_cache_check_ent(ctx, ttl, dom, name,
+ sss_ncache_check_netgr_int);
}
int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid)
@@ -237,55 +281,96 @@ int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, gid_t gid)
return ret;
}
+static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent,
+ const char *domain, const char *name)
+{
+ char *str;
+ int ret;
+
+ if (!name || !*name) return EINVAL;
+
+ str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name);
+ if (!str) return ENOMEM;
+
+ ret = sss_ncache_set_str(ctx, str, permanent);
+
+ talloc_free(str);
+ return ret;
+}
+
+static int sss_ncache_set_group_int(struct sss_nc_ctx *ctx, bool permanent,
+ const char *domain, const char *name)
+{
+ char *str;
+ int ret;
+
+ if (!name || !*name) return EINVAL;
+
+ str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name);
+ if (!str) return ENOMEM;
+
+ ret = sss_ncache_set_str(ctx, str, permanent);
+
+ talloc_free(str);
+ return ret;
+}
+
+static int sss_ncache_set_netgr_int(struct sss_nc_ctx *ctx, bool permanent,
+ const char *domain, const char *name)
+{
+ char *str;
+ int ret;
+
+ if (!name || !*name) return EINVAL;
+
+ str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name);
+ if (!str) return ENOMEM;
+
+ ret = sss_ncache_set_str(ctx, str, permanent);
+
+ talloc_free(str);
+ return ret;
+}
+
+typedef int (*ncache_set_byname_fn_t)(struct sss_nc_ctx *, bool,
+ const char *, const char *);
+
+static int sss_ncache_set_ent(struct sss_nc_ctx *ctx, bool permanent,
+ struct sss_domain_info *dom, const char *name,
+ ncache_set_byname_fn_t setter)
+{
+ char *lower;
+ errno_t ret;
+
+ if (dom->case_sensitive == false) {
+ lower = sss_tc_utf8_str_tolower(ctx, name);
+ if (!lower) return ENOMEM;
+ ret = setter(ctx, permanent, dom->name, lower);
+ talloc_free(lower);
+ } else {
+ ret = setter(ctx, permanent, dom->name, name);
+ }
+
+ return ret;
+}
+
+
int sss_ncache_set_user(struct sss_nc_ctx *ctx, bool permanent,
- const char *domain, const char *name)
+ struct sss_domain_info *dom, const char *name)
{
- char *str;
- int ret;
-
- if (!name || !*name) return EINVAL;
-
- str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name);
- if (!str) return ENOMEM;
-
- ret = sss_ncache_set_str(ctx, str, permanent);
-
- talloc_free(str);
- return ret;
+ return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_user_int);
}
int sss_ncache_set_group(struct sss_nc_ctx *ctx, bool permanent,
- const char *domain, const char *name)
+ struct sss_domain_info *dom, const char *name)
{
- char *str;
- int ret;
-
- if (!name || !*name) return EINVAL;
-
- str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name);
- if (!str) return ENOMEM;
-
- ret = sss_ncache_set_str(ctx, str, permanent);
-
- talloc_free(str);
- return ret;
+ return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_group_int);
}
int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent,
- const char *domain, const char *name)
+ struct sss_domain_info *dom, const char *name)
{
- char *str;
- int ret;
-
- if (!name || !*name) return EINVAL;
-
- str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name);
- if (!str) return ENOMEM;
-
- ret = sss_ncache_set_str(ctx, str, permanent);
-
- talloc_free(str);
- return ret;
+ return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_netgr_int);
}
int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, uid_t uid)
@@ -409,7 +494,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
continue;
}
- ret = sss_ncache_set_user(ncache, true, dom->name, name);
+ ret = sss_ncache_set_user(ncache, true, dom, name);
if (ret != EOK) {
DEBUG(1, ("Failed to store permanent user filter for [%s]"
" (%d [%s])\n", filter_list[i],
@@ -447,7 +532,14 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
continue;
}
if (domainname) {
- ret = sss_ncache_set_user(ncache, true, domainname, name);
+ dom = responder_get_domain(domain_list, domainname);
+ if (!dom) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Invalid domain name [%s]\n", domainname));
+ continue;
+ }
+
+ ret = sss_ncache_set_user(ncache, true, dom, name);
if (ret != EOK) {
DEBUG(1, ("Failed to store permanent user filter for [%s]"
" (%d [%s])\n", filter_list[i],
@@ -456,7 +548,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
}
} else {
for (dom = domain_list; dom; dom = dom->next) {
- ret = sss_ncache_set_user(ncache, true, dom->name, name);
+ ret = sss_ncache_set_user(ncache, true, dom, name);
if (ret != EOK) {
DEBUG(1, ("Failed to store permanent user filter for"
" [%s:%s] (%d [%s])\n",
@@ -499,7 +591,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
continue;
}
- ret = sss_ncache_set_group(ncache, true, dom->name, name);
+ ret = sss_ncache_set_group(ncache, true, dom, name);
if (ret != EOK) {
DEBUG(1, ("Failed to store permanent group filter for [%s]"
" (%d [%s])\n", filter_list[i],
@@ -537,7 +629,14 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
continue;
}
if (domainname) {
- ret = sss_ncache_set_group(ncache, true, domainname, name);
+ dom = responder_get_domain(domain_list, domainname);
+ if (!dom) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Invalid domain name [%s]\n", domainname));
+ continue;
+ }
+
+ ret = sss_ncache_set_group(ncache, true, dom, name);
if (ret != EOK) {
DEBUG(1, ("Failed to store permanent group filter for"
" [%s] (%d [%s])\n", filter_list[i],
@@ -546,7 +645,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
}
} else {
for (dom = domain_list; dom; dom = dom->next) {
- ret = sss_ncache_set_group(ncache, true, dom->name, name);
+ ret = sss_ncache_set_group(ncache, true, dom, name);
if (ret != EOK) {
DEBUG(1, ("Failed to store permanent group filter for"
" [%s:%s] (%d [%s])\n",
diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h
index fc857fce1608b2d71a75de10a6d63158dc20ce1e..72b99c969043d42c6f1329d8b0d549cadaddb998 100644
--- a/src/responder/common/negcache.h
+++ b/src/responder/common/negcache.h
@@ -29,9 +29,9 @@ int sss_ncache_init(TALLOC_CTX *memctx, struct sss_nc_ctx **_ctx);
/* check if the user is expired according to the passed in time to live */
int sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl,
- const char *domain, const char *name);
+ struct sss_domain_info *dom, const char *name);
int sss_ncache_check_group(struct sss_nc_ctx *ctx, int ttl,
- const char *domain, const char *name);
+ struct sss_domain_info *dom, const char *name);
int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl,
const char *domain, const char *name);
int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid);
@@ -42,11 +42,11 @@ int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, gid_t gid);
* and the negative cache never expires (used to permanently filter out
* users and groups) */
int sss_ncache_set_user(struct sss_nc_ctx *ctx, bool permanent,
- const char *domain, const char *name);
+ struct sss_domain_info *dom, const char *name);
int sss_ncache_set_group(struct sss_nc_ctx *ctx, bool permanent,
- const char *domain, const char *name);
+ struct sss_domain_info *dom, const char *name);
int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent,
- const char *domain, const char *name);
+ struct sss_domain_info *dom, const char *name);
int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, uid_t uid);
int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, gid_t gid);
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 99b1a23aa8581e01fb2a02d36657df6c20717812..a48ac556abe82579bf9455bf7b1eb94917e391b6 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -33,7 +33,6 @@
#include <errno.h>
#include <popt.h>
#include "util/util.h"
-#include "util/sss_utf8.h"
#include "db/sysdb.h"
#include "confdb/confdb.h"
#include "dbus/dbus.h"
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index f0270acd26659e8005a043fd9e154723cc868d0d..d8eb8b211587cfc6d3d392de301a4443e8f074d8 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -394,7 +394,7 @@ static int fill_pwent(struct sss_packet *packet,
if (filter_users) {
ncret = sss_ncache_check_user(nctx->ncache,
nctx->neg_timeout,
- domain, name);
+ dom, name);
if (ncret == EEXIST) {
DEBUG(4, ("User [%s@%s] filtered out! (negative cache)\n",
name, domain));
@@ -715,7 +715,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx)
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct sss_domain_info *dom = dctx->domain;
struct cli_ctx *cctx = cmdctx->cctx;
- const char *name = cmdctx->name;
+ char *name = NULL;
struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
int ret;
@@ -740,10 +740,15 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx)
/* make sure to update the dctx if we changed domain */
dctx->domain = dom;
+ talloc_free(name);
+ name = dom->case_sensitive ? talloc_strdup(dctx, cmdctx->name) :
+ sss_tc_utf8_str_tolower(dctx, cmdctx->name);
+ if (!name) return ENOMEM;
+
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
- dom->name, name);
+ dom, name);
/* if neg cached, return we didn't find it */
if (ret == EEXIST) {
@@ -781,7 +786,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx)
if (dctx->res->count == 0 && !dctx->check_provider) {
/* set negative cache only if not result of cache check */
- ret = sss_ncache_set_user(nctx->ncache, false, dom->name, name);
+ ret = sss_ncache_set_user(nctx->ncache, false, dom, name);
if (ret != EOK) {
return ret;
}
@@ -1788,7 +1793,7 @@ static int fill_grent(struct sss_packet *packet,
if (filter_groups) {
ret = sss_ncache_check_group(nctx->ncache,
- nctx->neg_timeout, domain, name);
+ nctx->neg_timeout, dom, name);
if (ret == EEXIST) {
DEBUG(4, ("Group [%s@%s] filtered out! (negative cache)\n",
name, domain));
@@ -1866,7 +1871,7 @@ static int fill_grent(struct sss_packet *packet,
if (nctx->filter_users_in_groups) {
ret = sss_ncache_check_user(nctx->ncache,
nctx->neg_timeout,
- domain, name);
+ dom, name);
if (ret == EEXIST) {
DEBUG(6, ("Group [%s] member [%s@%s] filtered out!"
" (negative cache)\n",
@@ -2002,7 +2007,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx)
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct sss_domain_info *dom = dctx->domain;
struct cli_ctx *cctx = cmdctx->cctx;
- const char *name = cmdctx->name;
+ char *name = NULL;
struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
int ret;
@@ -2027,10 +2032,15 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx)
/* make sure to update the dctx if we changed domain */
dctx->domain = dom;
+ talloc_free(name);
+ name = dom->case_sensitive ? talloc_strdup(dctx, cmdctx->name) :
+ sss_tc_utf8_str_tolower(dctx, cmdctx->name);
+ if (!name) return ENOMEM;
+
/* verify this group has not yet been negatively cached,
* or has been permanently filtered */
ret = sss_ncache_check_group(nctx->ncache, nctx->neg_timeout,
- dom->name, name);
+ dom, name);
/* if neg cached, return we didn't find it */
if (ret == EEXIST) {
@@ -2068,7 +2078,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx)
if (dctx->res->count == 0 && !dctx->check_provider) {
/* set negative cache only if not result of cache check */
- ret = sss_ncache_set_group(nctx->ncache, false, dom->name, name);
+ ret = sss_ncache_set_group(nctx->ncache, false, dom, name);
if (ret != EOK) {
return ret;
}
@@ -3068,7 +3078,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx)
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct sss_domain_info *dom = dctx->domain;
struct cli_ctx *cctx = cmdctx->cctx;
- const char *name = cmdctx->name;
+ char *name = NULL;
struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
int ret;
@@ -3093,10 +3103,15 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx)
/* make sure to update the dctx if we changed domain */
dctx->domain = dom;
+ talloc_free(name);
+ name = dom->case_sensitive ? talloc_strdup(dctx, cmdctx->name) :
+ sss_tc_utf8_str_tolower(dctx, cmdctx->name);
+ if (!name) return ENOMEM;
+
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
- dom->name, name);
+ dom, name);
/* if neg cached, return we didn't find it */
if (ret == EEXIST) {
@@ -3130,7 +3145,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx)
if (dctx->res->count == 0 && !dctx->check_provider) {
/* set negative cache only if not result of cache check */
- ret = sss_ncache_set_user(nctx->ncache, false, dom->name, name);
+ ret = sss_ncache_set_user(nctx->ncache, false, dom, name);
if (ret != EOK) {
return ret;
}
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 09b7fa6355421c941631775c71d33a2851edbe4e..39ba4ff7a3ca8d48a88edea2e857df53a61e501c 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -378,6 +378,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
struct sss_domain_info *dom = step_ctx->dctx->domain;
struct getent_ctx *netgr;
struct sysdb_ctx *sysdb;
+ char *name = NULL;
/* Check each domain for this netgroup name */
while (dom) {
@@ -400,8 +401,13 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
/* make sure to update the dctx if we changed domain */
step_ctx->dctx->domain = dom;
+ talloc_free(name);
+ name = dom->case_sensitive ? \
+ talloc_strdup(step_ctx, step_ctx->name) :
+ sss_tc_utf8_str_tolower(step_ctx, step_ctx->name);
+
DEBUG(4, ("Requesting info for [%s@%s]\n",
- step_ctx->name, dom->name));
+ name, dom->name));
ret = sysdb_get_ctx_from_list(step_ctx->rctx->db_list, dom, &sysdb);
if (ret != EOK) {
DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
@@ -409,7 +415,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
}
/* Look up the netgroup in the cache */
- ret = sysdb_getnetgr(step_ctx->dctx, sysdb, step_ctx->name,
+ ret = sysdb_getnetgr(step_ctx->dctx, sysdb, name,
&step_ctx->dctx->res);
if (ret == ENOENT) {
/* This netgroup was not found in this domain */
@@ -442,7 +448,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
if (ret == ENOENT) {
/* This netgroup was not found in this domain */
DEBUG(2, ("No results for netgroup %s (domain %s)\n",
- step_ctx->name, dom->name));
+ name, dom->name));
if (!step_ctx->dctx->check_provider) {
if (step_ctx->check_next) {
@@ -469,7 +475,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
step_ctx->nctx,
step_ctx->dctx->res,
SSS_DP_NETGR,
- step_ctx->name, 0,
+ name, 0,
lookup_netgr_dp_callback,
step_ctx);
if (ret != EOK) {
@@ -482,7 +488,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
/* Results found */
DEBUG(6, ("Returning info for netgroup [%s@%s]\n",
- step_ctx->name, dom->name));
+ name, dom->name));
netgr->ready = true;
netgr->found = true;
set_netgr_lifetime(dom->entry_cache_timeout, step_ctx, netgr);
@@ -490,8 +496,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
}
/* If we've gotten here, then no domain contained this netgroup */
- DEBUG(2, ("No matching domain found for [%s], fail!\n",
- step_ctx->name));
+ DEBUG(2, ("No matching domain found for [%s], fail!\n", name));
netgr = talloc_zero(step_ctx->nctx, struct getent_ctx);
if (netgr == NULL) {
@@ -501,7 +506,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
netgr->found = false;
netgr->entries = NULL;
netgr->lookup_table = step_ctx->nctx->netgroups;
- netgr->name = talloc_strdup(netgr, step_ctx->name);
+ netgr->name = talloc_strdup(netgr, name);
if (netgr->name == NULL) {
DEBUG(1, ("talloc_strdup failed.\n"));
talloc_free(netgr);
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 7ae54ac25128868785f6c34d7f8956c052a48c82..7c13ab11d5f30055869d74739db04cd5e701d1c1 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -787,7 +787,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
if (dom->fqnames) continue;
ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout,
- dom->name, pd->user);
+ dom, pd->user);
if (ncret == ENOENT) {
/* User not found in the negative cache
* Proceed with PAM actions
@@ -830,7 +830,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
{
struct sss_domain_info *dom = preq->domain;
struct cli_ctx *cctx = preq->cctx;
- const char *name = preq->pd->user;
+ char *name = NULL;
struct sysdb_ctx *sysdb;
time_t cacheExpire;
int ret;
@@ -855,6 +855,10 @@ static int pam_check_user_search(struct pam_auth_req *preq)
/* make sure to update the preq if we changed domain */
preq->domain = dom;
+ talloc_free(name);
+ name = dom->case_sensitive ? talloc_strdup(preq, preq->pd->user) :
+ sss_tc_utf8_str_tolower(preq, preq->pd->user);
+
/* Refresh the user's cache entry on any PAM query
* We put a timeout in the client context so that we limit
* the number of updates within a reasonable timeout
--
1.7.7.4
-------------- next part --------------
From 47827416929c1ee650eb5fcf7ca3dc6d0e9033bd Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 16 Nov 2011 13:57:26 +0100
Subject: [PATCH 5/9] Refactor saving sdap entities
There was too much code duplication between
sdap_save_{user,group,netgroup}. This patch removes the most egregious ones.
---
src/providers/ldap/sdap_async.c | 80 +++++++++++++++++++++++
src/providers/ldap/sdap_async.h | 21 ++++++
src/providers/ldap/sdap_async_groups.c | 49 +++-----------
src/providers/ldap/sdap_async_netgroups.c | 77 +++++------------------
src/providers/ldap/sdap_async_users.c | 98 ++++++-----------------------
5 files changed, 146 insertions(+), 179 deletions(-)
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index b1177e274bd3cf6d00d4cfa773556731b5997e97..98291e6e2e8ac13fe244c8cb1f332df30e20aa4e 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -1983,3 +1983,83 @@ done:
return ret;
}
+errno_t
+sdap_attrs_add_ldap_attr(struct sysdb_attrs *ldap_attrs,
+ const char *attr_name,
+ const char *attr_desc,
+ bool multivalued,
+ const char *name,
+ struct sysdb_attrs *attrs)
+{
+ errno_t ret;
+ struct ldb_message_element *el;
+ const char *objname = name ?: "object";
+ const char *desc = attr_desc ?: attr_name;
+ unsigned int num_values, i;
+
+ ret = sysdb_attrs_get_el(ldap_attrs, attr_name, &el);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not get %s from the "
+ "list of the LDAP attributes [%d]: %s\n", ret, strerror(ret)));
+ return ret;
+ }
+
+ if (el->num_values == 0) {
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("%s is not available "
+ "for [%s].\n", desc, objname));
+ } else {
+ num_values = multivalued ? el->num_values : 1;
+ for (i = 0; i < num_values; i++) {
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("Adding %s [%s] to attributes "
+ "of [%s].\n", desc, el->values[i].data, objname));
+
+ ret = sysdb_attrs_add_string(attrs, attr_name,
+ (const char *) el->values[i].data);
+ if (ret) {
+ return ret;
+ }
+ }
+ }
+
+ return EOK;
+}
+
+
+errno_t
+sdap_save_all_names(const char *name,
+ struct sysdb_attrs *ldap_attrs,
+ struct sysdb_attrs *attrs)
+{
+ const char **aliases = NULL;
+ errno_t ret;
+ TALLOC_CTX *tmp_ctx;
+ int i;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_aliases(tmp_ctx, ldap_attrs, name, &aliases);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Failed to get the alias list"));
+ goto done;
+ }
+
+ for (i = 0; aliases[i]; i++) {
+ ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS,
+ aliases[i]);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Failed to add alias [%s] into the "
+ "attribute list\n", aliases[i]));
+ goto done;
+ }
+ }
+
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 4ba2770c989968e5398feeca0dbeb8a99206a009..f53af1e01e683ac0918f8ee5d74e1c19713c4bb7 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -189,4 +189,25 @@ errno_t sdap_check_aliases(struct sysdb_ctx *sysdb,
struct sss_domain_info *dom,
struct sdap_options *opts,
bool steal_memberships);
+
+errno_t
+sdap_attrs_add_ldap_attr(struct sysdb_attrs *ldap_attrs,
+ const char *attr_name,
+ const char *attr_desc,
+ bool multivalued,
+ const char *name,
+ struct sysdb_attrs *attrs);
+
+#define sdap_attrs_add_string(ldap_attrs, attr_name, attr_desc, name, attrs) \
+ sdap_attrs_add_ldap_attr(ldap_attrs, attr_name, attr_desc, \
+ false, name, attrs)
+
+#define sdap_attrs_add_list(ldap_attrs, attr_name, attr_desc, name, attrs) \
+ sdap_attrs_add_ldap_attr(ldap_attrs, attr_name, attr_desc, \
+ true, name, attrs)
+
+errno_t sdap_save_all_names(const char *name,
+ struct sysdb_attrs *ldap_attrs,
+ struct sysdb_attrs *attrs);
+
#endif /* _SDAP_ASYNC_H_ */
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index ead3fd544ae74923332c0a3780c2454845b5f1e6..d2c15dedaf7417d97a91a587bc1145b21c3ebf92 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -222,11 +222,9 @@ static int sdap_save_group(TALLOC_CTX *memctx,
const char *name = NULL;
gid_t gid;
int ret;
- int i;
char *usn_value = NULL;
TALLOC_CTX *tmpctx = NULL;
bool posix_group;
- const char **aliases = NULL;
tmpctx = talloc_new(memctx);
if (!tmpctx) {
@@ -282,38 +280,19 @@ static int sdap_save_group(TALLOC_CTX *memctx,
/* Group ID OK */
}
- ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
- if (ret) {
+ ret = sdap_attrs_add_string(attrs, SYSDB_ORIG_DN, "original DN",
+ name, group_attrs);
+ if (ret != EOK) {
goto fail;
}
- if (el->num_values == 0) {
- DEBUG(7, ("Original DN is not available for [%s].\n", name));
- } else {
- DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
- el->values[0].data, name));
- ret = sysdb_attrs_add_string(group_attrs, SYSDB_ORIG_DN,
- (const char *) el->values[0].data);
- if (ret) {
- goto fail;
- }
- }
- ret = sysdb_attrs_get_el(attrs,
- opts->group_map[SDAP_AT_GROUP_MODSTAMP].sys_name, &el);
- if (ret) {
+ ret = sdap_attrs_add_string(attrs,
+ opts->group_map[SDAP_AT_GROUP_MODSTAMP].sys_name,
+ "original mod-Timestamp",
+ name, group_attrs);
+ if (ret != EOK) {
goto fail;
}
- if (el->num_values == 0) {
- DEBUG(7, ("Original mod-Timestamp is not available for [%s].\n",
- name));
- } else {
- ret = sysdb_attrs_add_string(group_attrs,
- opts->group_map[SDAP_AT_GROUP_MODSTAMP].sys_name,
- (const char*)el->values[0].data);
- if (ret) {
- goto fail;
- }
- }
ret = sysdb_attrs_get_el(attrs,
opts->group_map[SDAP_AT_GROUP_USN].sys_name, &el);
@@ -369,20 +348,12 @@ static int sdap_save_group(TALLOC_CTX *memctx,
}
}
- ret = sysdb_attrs_get_aliases(tmpctx, attrs, name, &aliases);
+ ret = sdap_save_all_names(name, attrs, group_attrs);
if (ret != EOK) {
- DEBUG(1, ("Failed to get the alias list\n"));
+ DEBUG(1, ("Failed to save user names\n"));
goto fail;
}
- for (i = 0; aliases[i]; i++) {
- ret = sysdb_attrs_add_string(group_attrs, SYSDB_NAME_ALIAS,
- aliases[i]);
- if (ret) {
- goto fail;
- }
- }
-
DEBUG(6, ("Storing info for group %s\n", name));
ret = sdap_store_group_with_gid(ctx,
diff --git a/src/providers/ldap/sdap_async_netgroups.c b/src/providers/ldap/sdap_async_netgroups.c
index bb2e1bb2ce85b16e1437140cb841264d206ff7c0..2cc8d42ad4e7d47bbf020d932e605a6e3dc5a1db 100644
--- a/src/providers/ldap/sdap_async_netgroups.c
+++ b/src/providers/ldap/sdap_async_netgroups.c
@@ -48,7 +48,6 @@ static errno_t sdap_save_netgroup(TALLOC_CTX *memctx,
const char *name = NULL;
int ret;
char *timestamp = NULL;
- size_t c;
ret = sysdb_attrs_get_el(attrs,
opts->netgroup_map[SDAP_AT_NETGROUP_NAME].sys_name,
@@ -66,21 +65,12 @@ static errno_t sdap_save_netgroup(TALLOC_CTX *memctx,
goto fail;
}
- ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
- if (ret) {
+ ret = sdap_attrs_add_string(attrs, SYSDB_ORIG_DN,
+ "original DN",
+ name, netgroup_attrs);
+ if (ret != EOK) {
goto fail;
}
- if (el->num_values == 0) {
- DEBUG(7, ("Original DN is not available for [%s].\n", name));
- } else {
- DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
- el->values[0].data, name));
- ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_ORIG_DN,
- (const char *)el->values[0].data);
- if (ret) {
- goto fail;
- }
- }
ret = sysdb_attrs_get_el(attrs,
opts->netgroup_map[SDAP_AT_NETGROUP_MODSTAMP].sys_name,
@@ -105,64 +95,27 @@ static errno_t sdap_save_netgroup(TALLOC_CTX *memctx,
}
}
- ret = sysdb_attrs_get_el(attrs,
- opts->netgroup_map[SDAP_AT_NETGROUP_TRIPLE].sys_name,
- &el);
- if (ret) {
+ ret = sdap_attrs_add_list(attrs,
+ opts->netgroup_map[SDAP_AT_NETGROUP_TRIPLE].sys_name,
+ "netgroup triple",
+ name, netgroup_attrs);
+ if (ret != EOK) {
goto fail;
}
- if (el->num_values == 0) {
- DEBUG(7, ("No netgroup triples for netgroup [%s].\n", name));
- } else {
- for(c = 0; c < el->num_values; c++) {
- ret = sysdb_attrs_add_string(netgroup_attrs,
- opts->netgroup_map[SDAP_AT_NETGROUP_TRIPLE].sys_name,
- (const char*)el->values[c].data);
- if (ret) {
- goto fail;
- }
- }
- }
- ret = sysdb_attrs_get_el(attrs,
- opts->netgroup_map[SDAP_AT_NETGROUP_MEMBER].sys_name,
- &el);
+ ret = sdap_attrs_add_list(attrs,
+ opts->netgroup_map[SDAP_AT_NETGROUP_MEMBER].sys_name,
+ "original members",
+ name, netgroup_attrs);
if (ret != EOK) {
goto fail;
}
- if (el->num_values == 0) {
- DEBUG(7, ("No original members for netgroup [%s]\n", name));
-
- } else {
- DEBUG(7, ("Adding original members to netgroup [%s]\n", name));
- for(c = 0; c < el->num_values; c++) {
- ret = sysdb_attrs_add_string(netgroup_attrs,
- opts->netgroup_map[SDAP_AT_NETGROUP_MEMBER].sys_name,
- (const char*)el->values[c].data);
- if (ret) {
- goto fail;
- }
- }
- }
-
- ret = sysdb_attrs_get_el(attrs, SYSDB_NETGROUP_MEMBER, &el);
+ ret = sdap_attrs_add_list(attrs, SYSDB_NETGROUP_MEMBER,
+ "members", name, netgroup_attrs);
if (ret != EOK) {
goto fail;
}
- if (el->num_values == 0) {
- DEBUG(7, ("No members for netgroup [%s]\n", name));
-
- } else {
- DEBUG(7, ("Adding members to netgroup [%s]\n", name));
- for(c = 0; c < el->num_values; c++) {
- ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_NETGROUP_MEMBER,
- (const char*)el->values[c].data);
- if (ret) {
- goto fail;
- }
- }
- }
DEBUG(6, ("Storing info for netgroup %s\n", name));
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index cf9a8d33cbd4deac12287852cbe78ce465f0ac61..c929e2048b310803c26be619f48cbda5d7a6bfc1 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -29,7 +29,6 @@
/* ==Save-User-Entry====================================================== */
/* FIXME: support storing additional attributes */
-
int sdap_save_user(TALLOC_CTX *memctx,
struct sysdb_ctx *ctx,
struct sdap_options *opts,
@@ -52,17 +51,14 @@ int sdap_save_user(TALLOC_CTX *memctx,
struct sysdb_attrs *user_attrs;
char *upn = NULL;
size_t i;
- char *val = NULL;
int cache_timeout;
char *usn_value = NULL;
- size_t c;
char **missing = NULL;
- const char **aliases = NULL;
TALLOC_CTX *tmpctx = NULL;
DEBUG(9, ("Save user\n"));
- tmpctx = talloc_new(memctx);
+ tmpctx = talloc_new(NULL);
if (!tmpctx) {
ret = ENOMEM;
goto fail;
@@ -151,57 +147,27 @@ int sdap_save_user(TALLOC_CTX *memctx,
goto fail;
}
- ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
- if (ret) {
+ ret = sdap_attrs_add_string(attrs, SYSDB_ORIG_DN,
+ "original DN",
+ name, user_attrs);
+ if (ret != EOK) {
goto fail;
}
- if (el->num_values == 0) {
- DEBUG(7, ("Original DN is not available for [%s].\n", name));
- } else {
- DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
- el->values[0].data, name));
- ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN,
- (const char *) el->values[0].data);
- if (ret) {
- goto fail;
- }
- }
- ret = sysdb_attrs_get_el(attrs, SYSDB_MEMBEROF, &el);
- if (ret) {
+ ret = sdap_attrs_add_list(attrs, SYSDB_MEMBEROF,
+ "original memberOf",
+ name, user_attrs);
+ if (ret != EOK) {
goto fail;
}
- if (el->num_values == 0) {
- DEBUG(7, ("Original memberOf is not available for [%s].\n",
- name));
- } else {
- DEBUG(7, ("Adding original memberOf attributes to [%s].\n",
- name));
- for (i = 0; i < el->num_values; i++) {
- ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF,
- (const char *) el->values[i].data);
- if (ret) {
- goto fail;
- }
- }
- }
- ret = sysdb_attrs_get_el(attrs,
- opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name, &el);
- if (ret) {
+ ret = sdap_attrs_add_string(attrs,
+ opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name,
+ "original mod-Timestamp",
+ name, user_attrs);
+ if (ret != EOK) {
goto fail;
}
- if (el->num_values == 0) {
- DEBUG(7, ("Original mod-Timestamp is not available for [%s].\n",
- name));
- } else {
- ret = sysdb_attrs_add_string(user_attrs,
- opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name,
- (const char*)el->values[0].data);
- if (ret) {
- goto fail;
- }
- }
ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_USN].sys_name, &el);
@@ -218,7 +184,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
if (ret) {
goto fail;
}
- usn_value = talloc_strdup(memctx, (const char*)el->values[0].data);
+ usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data);
if (!usn_value) {
ret = ENOMEM;
goto fail;
@@ -250,27 +216,11 @@ int sdap_save_user(TALLOC_CTX *memctx,
}
for (i = SDAP_FIRST_EXTRA_USER_AT; i < SDAP_OPTS_USER; i++) {
- ret = sysdb_attrs_get_el(attrs, opts->user_map[i].sys_name, &el);
+ ret = sdap_attrs_add_list(attrs, opts->user_map[i].sys_name,
+ NULL, name, user_attrs);
if (ret) {
goto fail;
}
- if (el->num_values > 0) {
- for (c = 0; c < el->num_values; c++) {
- DEBUG(9, ("Adding [%s]=[%s] to user attributes.\n",
- opts->user_map[i].sys_name,
- (const char*) el->values[c].data));
- val = talloc_strdup(user_attrs, (const char*) el->values[c].data);
- if (val == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- ret = sysdb_attrs_add_string(user_attrs,
- opts->user_map[i].sys_name, val);
- if (ret) {
- goto fail;
- }
- }
- }
}
cache_timeout = dp_opt_get_int(opts->basic, SDAP_ENTRY_CACHE_TIMEOUT);
@@ -284,20 +234,12 @@ int sdap_save_user(TALLOC_CTX *memctx,
}
}
- ret = sysdb_attrs_get_aliases(tmpctx, attrs, name, &aliases);
+ ret = sdap_save_all_names(name, attrs, user_attrs);
if (ret != EOK) {
- DEBUG(1, ("Failed to get the alias list"));
+ DEBUG(1, ("Failed to save user names\n"));
goto fail;
}
- for (i = 0; aliases[i]; i++) {
- ret = sysdb_attrs_add_string(user_attrs, SYSDB_NAME_ALIAS,
- aliases[i]);
- if (ret) {
- goto fail;
- }
- }
-
/* Make sure that any attributes we requested from LDAP that we
* did not receive are also removed from the sysdb
*/
@@ -320,7 +262,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
if (ret) goto fail;
if (_usn_value) {
- *_usn_value = usn_value;
+ *_usn_value = talloc_steal(memctx, usn_value);
}
talloc_steal(memctx, user_attrs);
--
1.7.7.4
-------------- next part --------------
From d79945651309ebb6042605e84e9139b48bf191e2 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 12 Dec 2011 18:47:27 +0100
Subject: [PATCH 6/9] sysdb_get_real_name helper function
---
src/db/sysdb.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
src/db/sysdb.h | 4 ++++
2 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index c49399f7df37d946b975a403ac522b9fbbb82c97..d66cc53ccfc407c6823a8aa96321ec1bf0c5e35c 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -1691,3 +1691,49 @@ done:
}
return ret;
}
+
+errno_t sysdb_get_real_name(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ const char *name,
+ const char **_cname)
+{
+ errno_t ret;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_result *res;
+ const char *cname;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ ret = sysdb_getpwnam(tmp_ctx, sysdb, name, &res);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot canonicalize username\n"));
+ goto done;
+ }
+
+ if (res->count == 0) {
+ /* User is not cached yet */
+ ret = ENOENT;
+ goto done;
+ } else if (res->count != 1) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("sysdb_getpwnam returned count: [%d]\n", res->count));
+ ret = EIO;
+ goto done;
+ }
+
+ cname = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL);
+ if (!cname) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("A user with no name?\n"));
+ ret = ENOENT;
+ goto done;
+ }
+
+ ret = EOK;
+ *_cname = talloc_steal(mem_ctx, cname);
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 5fc36ab5a39542838354a29c54a17ff4541b5a98..e5e781f6acc2ae26d1d387d8b8c6931bb1213367 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -248,6 +248,10 @@ errno_t sysdb_attrs_primary_name_list(struct sysdb_ctx *sysdb,
size_t attr_count,
const char *ldap_attr,
char ***name_list);
+errno_t sysdb_get_real_name(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ const char *name,
+ const char **_cname);
/* convert an ldb error into an errno error */
int sysdb_error_to_errno(int ldberr);
--
1.7.7.4
-------------- next part --------------
From 145f83499d817f513411b0cc4ed51c3a282d6dd0 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 6 Dec 2011 15:02:37 +0100
Subject: [PATCH 7/9] Use the case sensitivity flag in the LDAP provider
---
src/db/sysdb.c | 36 ++++++++++++++++++++++++---
src/db/sysdb.h | 1 +
src/providers/ldap/sdap_async.c | 9 ++++---
src/providers/ldap/sdap_async.h | 1 +
src/providers/ldap/sdap_async_groups.c | 4 +-
src/providers/ldap/sdap_async_initgroups.c | 17 ++++++++++---
src/providers/ldap/sdap_async_netgroups.c | 9 +++++++
src/providers/ldap/sdap_async_users.c | 2 +-
8 files changed, 64 insertions(+), 15 deletions(-)
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index d66cc53ccfc407c6823a8aa96321ec1bf0c5e35c..034e5da0dab2125d4ba201ecfd606d8c32897dfa 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -22,6 +22,7 @@
#include "util/util.h"
#include "util/strtonum.h"
+#include "util/sss_utf8.h"
#include "db/sysdb_private.h"
#include "confdb/confdb.h"
#include <time.h>
@@ -1587,18 +1588,22 @@ done:
* Given a primary name returned by sysdb_attrs_primary_name(), this function
* returns the other SYSDB_NAME attribute values so they can be saved as
* SYSDB_NAME_ALIAS into cache.
+ *
+ * If lowercase is set, all aliases are duplicated in lowercase as well.
*/
errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx,
struct sysdb_attrs *attrs,
const char *primary,
+ bool lowercase,
const char ***_aliases)
{
TALLOC_CTX *tmp_ctx = NULL;
struct ldb_message_element *sysdb_name_el;
- size_t i, ai;
+ size_t i, ai, num;
errno_t ret;
const char **aliases = NULL;
const char *name;
+ char *lower;
if (_aliases == NULL) return EINVAL;
@@ -1615,8 +1620,8 @@ errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx,
goto done;
}
- aliases = talloc_array(tmp_ctx, const char *,
- sysdb_name_el->num_values);
+ num = lowercase ? 2 * sysdb_name_el->num_values : sysdb_name_el->num_values;
+ aliases = talloc_array(tmp_ctx, const char *, num+1);
if (!aliases) {
ret = ENOMEM;
goto done;
@@ -1626,11 +1631,34 @@ errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx,
for (i=0; i < sysdb_name_el->num_values; i++) {
name = (const char *)sysdb_name_el->values[i].data;
if (strcmp(primary, name) != 0) {
- aliases[ai] = name;
+ aliases[ai] = talloc_strdup(aliases, name);
+ if (!aliases[ai]) {
+ ret = ENOMEM;
+ goto done;
+ }
ai++;
}
}
+ if (lowercase) {
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ ("Domain is case-insensitive; will add lowercased aliases\n"));
+ for (i=0; i < sysdb_name_el->num_values; i++) {
+ name = (const char *)sysdb_name_el->values[i].data;
+ lower = sss_tc_utf8_str_tolower(tmp_ctx, name);
+ if (!lower) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ if (strcmp(name, lower) != 0) {
+ aliases[ai] = talloc_strdup(aliases, lower);
+ ai++;
+ }
+ talloc_free(lower);
+ }
+ }
+
aliases[ai] = NULL;
ret = EOK;
done:
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index e5e781f6acc2ae26d1d387d8b8c6931bb1213367..6094a4aaab2c9453f4de40075abb3ec6e321c3b9 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -241,6 +241,7 @@ errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb,
errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx,
struct sysdb_attrs *attrs,
const char *primary,
+ bool lowercase,
const char ***_aliases);
errno_t sysdb_attrs_primary_name_list(struct sysdb_ctx *sysdb,
TALLOC_CTX *mem_ctx,
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index 98291e6e2e8ac13fe244c8cb1f332df30e20aa4e..0719f74be6b8b167f00a69abcd13a98ea36fc2e1 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -1920,7 +1920,8 @@ errno_t sdap_check_aliases(struct sysdb_ctx *sysdb,
goto done;
}
- ret = sysdb_attrs_get_aliases(tmp_ctx, user_attrs, name, &aliases);
+ ret = sysdb_attrs_get_aliases(tmp_ctx, user_attrs, name,
+ !dom->case_sensitive, &aliases);
if (ret != EOK) {
DEBUG(1, ("Failed to get the alias list\n"));
goto done;
@@ -2024,10 +2025,10 @@ sdap_attrs_add_ldap_attr(struct sysdb_attrs *ldap_attrs,
return EOK;
}
-
errno_t
sdap_save_all_names(const char *name,
struct sysdb_attrs *ldap_attrs,
+ bool lowercase,
struct sysdb_attrs *attrs)
{
const char **aliases = NULL;
@@ -2041,7 +2042,8 @@ sdap_save_all_names(const char *name,
goto done;
}
- ret = sysdb_attrs_get_aliases(tmp_ctx, ldap_attrs, name, &aliases);
+ ret = sysdb_attrs_get_aliases(tmp_ctx, ldap_attrs, name,
+ lowercase, &aliases);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Failed to get the alias list"));
goto done;
@@ -2062,4 +2064,3 @@ done:
talloc_free(tmp_ctx);
return ret;
}
-
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index f53af1e01e683ac0918f8ee5d74e1c19713c4bb7..2fd606bcaa52d557dee4c85782df0e2b4e6c6522 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -208,6 +208,7 @@ sdap_attrs_add_ldap_attr(struct sysdb_attrs *ldap_attrs,
errno_t sdap_save_all_names(const char *name,
struct sysdb_attrs *ldap_attrs,
+ bool lowercase,
struct sysdb_attrs *attrs);
#endif /* _SDAP_ASYNC_H_ */
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index d2c15dedaf7417d97a91a587bc1145b21c3ebf92..357c28c191df1c01dbf3cdb2a11feb11aee86d29 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -348,9 +348,9 @@ static int sdap_save_group(TALLOC_CTX *memctx,
}
}
- ret = sdap_save_all_names(name, attrs, group_attrs);
+ ret = sdap_save_all_names(name, attrs, !dom->case_sensitive, group_attrs);
if (ret != EOK) {
- DEBUG(1, ("Failed to save user names\n"));
+ DEBUG(1, ("Failed to save group names\n"));
goto fail;
}
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 631ce1522803103e7ea962003562e2a7dcb2fffc..73ab25ea79cd66ff5fe7131ee7606cf71aa382e5 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -444,8 +444,9 @@ static void sdap_initgr_rfc2307_process(struct tevent_req *subreq)
/* Search for all groups for which this user is a member */
attrs[0] = SYSDB_MEMBEROF;
attrs[1] = NULL;
- ret = sysdb_search_user_by_name(state, state->sysdb, state->name, attrs,
- &msg);
+
+ ret = sysdb_search_user_by_name(state, state->sysdb, state->name,
+ attrs, &msg);
if (ret != EOK) {
tevent_req_error(req, ret);
return;
@@ -2462,6 +2463,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
size_t count;
int ret;
const char *orig_dn;
+ const char *cname;
DEBUG(9, ("Receiving info for the user\n"));
@@ -2520,6 +2522,13 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
return;
}
+ ret = sysdb_get_real_name(state, state->sysdb, state->name, &cname);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot canonicalize username\n"));
+ tevent_req_error(req, ret);
+ return;
+ }
+
DEBUG(9, ("Process user's groups\n"));
switch (state->opts->schema_type) {
@@ -2533,7 +2542,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
subreq = sdap_initgr_rfc2307_send(state, state->ev, state->opts,
state->sysdb, state->sh,
- state->name);
+ cname);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
@@ -2553,7 +2562,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
subreq = sdap_initgr_rfc2307bis_send(
state, state->ev, state->opts, state->sysdb,
state->dom, state->sh,
- state->name, orig_dn);
+ cname, orig_dn);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
diff --git a/src/providers/ldap/sdap_async_netgroups.c b/src/providers/ldap/sdap_async_netgroups.c
index 2cc8d42ad4e7d47bbf020d932e605a6e3dc5a1db..2a24128a9b3a1594813346fea98503b9a9af432b 100644
--- a/src/providers/ldap/sdap_async_netgroups.c
+++ b/src/providers/ldap/sdap_async_netgroups.c
@@ -38,6 +38,7 @@ bool is_dn(const char *str)
static errno_t sdap_save_netgroup(TALLOC_CTX *memctx,
struct sysdb_ctx *ctx,
+ struct sss_domain_info *dom,
struct sdap_options *opts,
struct sysdb_attrs *attrs,
char **_timestamp,
@@ -119,6 +120,13 @@ static errno_t sdap_save_netgroup(TALLOC_CTX *memctx,
DEBUG(6, ("Storing info for netgroup %s\n", name));
+ ret = sdap_save_all_names(name, attrs, !dom->case_sensitive,
+ netgroup_attrs);
+ if (ret != EOK) {
+ DEBUG(1, ("Failed to save netgroup names\n"));
+ goto fail;
+ }
+
ret = sysdb_add_netgroup(ctx, name, NULL, netgroup_attrs,
dp_opt_get_int(opts->basic,
SDAP_ENTRY_CACHE_TIMEOUT), now);
@@ -671,6 +679,7 @@ static void netgr_translate_members_done(struct tevent_req *subreq)
now = time(NULL);
for (c = 0; c < state->count; c++) {
ret = sdap_save_netgroup(state, state->sysdb,
+ state->dom,
state->opts,
state->netgroups[c],
&state->higher_timestamp,
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index c929e2048b310803c26be619f48cbda5d7a6bfc1..cccf75b8caecd34ba6d562e2e8b8e7e3d0e18e49 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -234,7 +234,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
}
}
- ret = sdap_save_all_names(name, attrs, user_attrs);
+ ret = sdap_save_all_names(name, attrs, !dom->case_sensitive, user_attrs);
if (ret != EOK) {
DEBUG(1, ("Failed to save user names\n"));
goto fail;
--
1.7.7.4
-------------- next part --------------
From 40cd9afd5d423539a54f70a0875d5d42175aaa64 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 6 Dec 2011 17:08:27 +0100
Subject: [PATCH 8/9] Use the case sensitivity flag in the simple access
provider
---
src/providers/simple/simple_access.c | 19 +++++++++++++++----
src/tests/simple_access-tests.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/src/providers/simple/simple_access.c b/src/providers/simple/simple_access.c
index 4b9c3139853adc2c65eb65af69199f820a75ca89..06662e9dfe3ffd13d8dd785545a836b7e519c8c3 100644
--- a/src/providers/simple/simple_access.c
+++ b/src/providers/simple/simple_access.c
@@ -24,6 +24,7 @@
#include <security/pam_modules.h>
#include "util/util.h"
+#include "util/sss_utf8.h"
#include "providers/dp_backend.h"
#include "db/sysdb.h"
#include "providers/simple/simple_access.h"
@@ -34,6 +35,15 @@
#define CONFDB_SIMPLE_ALLOW_GROUPS "simple_allow_groups"
#define CONFDB_SIMPLE_DENY_GROUPS "simple_deny_groups"
+static bool string_equal(bool cs, const char *s1, const char *s2)
+{
+ if (cs) {
+ return strcmp(s1, s2) == 0;
+ }
+
+ return sss_utf8_case_eq((const uint8_t *)s1, (const uint8_t *)s2) == EOK;
+}
+
errno_t simple_access_check(struct simple_ctx *ctx, const char *username,
bool *access_granted)
{
@@ -51,13 +61,14 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username,
const char *primary_group;
gid_t gid;
bool matched;
+ bool cs = ctx->domain->case_sensitive;
*access_granted = false;
/* 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 (strcmp(username, ctx->allow_users[i]) == 0) {
+ if (string_equal(cs, username, ctx->allow_users[i])) {
DEBUG(9, ("User [%s] found in allow list, access granted.\n",
username));
@@ -78,7 +89,7 @@ errno_t simple_access_check(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 (strcmp(username, ctx->deny_users[i]) == 0) {
+ if (string_equal(cs, username, ctx->deny_users[i])) {
DEBUG(9, ("User [%s] found in deny list, access denied.\n",
username));
@@ -189,7 +200,7 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username,
matched = false;
for (i = 0; ctx->allow_groups[i]; i++) {
for(j = 0; groups[j]; j++) {
- if (strcmp(groups[j], ctx->allow_groups[i])== 0) {
+ if (string_equal(cs, groups[j], ctx->allow_groups[i])) {
matched = true;
break;
}
@@ -210,7 +221,7 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username,
matched = false;
for (i = 0; ctx->deny_groups[i]; i++) {
for(j = 0; groups[j]; j++) {
- if (strcmp(groups[j], ctx->deny_groups[i])== 0) {
+ if (string_equal(cs, groups[j], ctx->deny_groups[i])) {
matched = true;
break;
}
diff --git a/src/tests/simple_access-tests.c b/src/tests/simple_access-tests.c
index 9cd73d84c91b29fcc5a43bf12e22696d74aae545..4f041d400c948eff6077a0698ad1b4a54cb28fcf 100644
--- a/src/tests/simple_access-tests.c
+++ b/src/tests/simple_access-tests.c
@@ -26,6 +26,7 @@
#include <popt.h>
#include <check.h>
+#include "confdb/confdb.h"
#include "providers/simple/simple_access.h"
const char *ulist_1[] = {"u1", "u2", NULL};
@@ -37,6 +38,10 @@ void setup_simple(void)
fail_unless(ctx == NULL, "Simple context already initialized.");
ctx = talloc_zero(NULL, struct simple_ctx);
fail_unless(ctx != NULL, "Cannot create simple context.");
+
+ ctx->domain = talloc_zero(ctx, struct sss_domain_info);
+ fail_unless(ctx != NULL, "Cannot create domain in simple context.");
+ ctx->domain->case_sensitive = true;
}
void teardown_simple(void)
@@ -123,6 +128,30 @@ START_TEST(test_both_set)
}
END_TEST
+START_TEST(test_case)
+{
+ int ret;
+ bool access_granted = false;
+
+ ctx->allow_users = discard_const(ulist_1);
+ ctx->deny_users = NULL;
+
+ ret = simple_access_check(ctx, "U1", &access_granted);
+ fail_unless(ret == EOK, "access_simple_check failed.");
+ fail_unless(access_granted == false, "Access granted "
+ "for user with different case "
+ "in case-sensitive domain");
+
+ ctx->domain->case_sensitive = false;
+
+ ret = simple_access_check(ctx, "U1", &access_granted);
+ fail_unless(ret == EOK, "access_simple_check failed.");
+ fail_unless(access_granted == true, "Access denied "
+ "for user with different case "
+ "in case-insensitive domain");
+}
+END_TEST
+
Suite *access_simple_suite (void)
{
Suite *s = suite_create("access_simple");
@@ -133,6 +162,7 @@ Suite *access_simple_suite (void)
tcase_add_test(tc_allow_deny, test_allow_empty);
tcase_add_test(tc_allow_deny, test_deny_empty);
tcase_add_test(tc_allow_deny, test_both_set);
+ tcase_add_test(tc_allow_deny, test_case);
suite_add_tcase(s, tc_allow_deny);
return s;
--
1.7.7.4
-------------- next part --------------
From 9391ddbacf286913888209405e61fcbc682e5a8e Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 12 Dec 2011 15:28:13 +0100
Subject: [PATCH 9/9] Use the case sensitivity flag in the proxy provider
---
src/providers/proxy/proxy.h | 2 +-
src/providers/proxy/proxy_id.c | 294 +++++++++++++++++-----------------
src/providers/proxy/proxy_netgroup.c | 38 ++++-
3 files changed, 181 insertions(+), 153 deletions(-)
diff --git a/src/providers/proxy/proxy.h b/src/providers/proxy/proxy.h
index c75242890f9683d80c0ec8892a7d23326ffa78a2..41981fd85f44fa4cdfa40cc2833b972d82cdb5ab 100644
--- a/src/providers/proxy/proxy.h
+++ b/src/providers/proxy/proxy.h
@@ -142,7 +142,7 @@ void proxy_pam_handler(struct be_req *req);
/* From proxy_netgroup.c */
errno_t get_netgroup(struct proxy_id_ctx *ctx,
struct sysdb_ctx *sysdb,
+ struct sss_domain_info *dom,
const char *name);
-
#endif /* __PROXY_H__ */
diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index 0a5f5427e8758c8d8f4db023ac4ef60c70f2e39d..cfb058a8a4afd8ae2df4dfe9a21bae9dbe165668 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -30,6 +30,9 @@
static int delete_user(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
struct sss_domain_info *domain, const char *name);
+static int save_user(struct sysdb_ctx *sysdb, bool lowercase,
+ struct passwd *pwd, uint64_t cache_timeout);
+
static int get_pw_name(TALLOC_CTX *mem_ctx,
struct proxy_id_ctx *ctx,
struct sysdb_ctx *sysdb,
@@ -42,7 +45,6 @@ static int get_pw_name(TALLOC_CTX *mem_ctx,
char *buffer;
size_t buflen;
int ret;
- const char *shell;
DEBUG(7, ("Searching user by name (%s)\n", name));
@@ -98,23 +100,7 @@ static int get_pw_name(TALLOC_CTX *mem_ctx,
break;
}
- if (pwd->pw_shell && pwd->pw_shell[0] != '\0') {
- shell = pwd->pw_shell;
- } else {
- shell = NULL;
- }
-
- ret = sysdb_store_user(sysdb,
- pwd->pw_name,
- pwd->pw_passwd,
- pwd->pw_uid,
- pwd->pw_gid,
- pwd->pw_gecos,
- pwd->pw_dir,
- shell,
- NULL, NULL,
- ctx->entry_cache_timeout,
- 0);
+ ret = save_user(sysdb, !dom->case_sensitive, pwd, ctx->entry_cache_timeout);
if (ret) {
goto done;
}
@@ -139,6 +125,63 @@ done:
return ret;
}
+static int save_user(struct sysdb_ctx *sysdb, bool lowercase,
+ struct passwd *pwd, uint64_t cache_timeout)
+{
+ const char *shell;
+ char *lower;
+ struct sysdb_attrs *attrs;
+ errno_t ret;
+
+ if (pwd->pw_shell && pwd->pw_shell[0] != '\0') {
+ shell = pwd->pw_shell;
+ } else {
+ shell = NULL;
+ }
+
+ if (lowercase) {
+ attrs = sysdb_new_attrs(NULL);
+ if (!attrs) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Allocation error ?!\n"));
+ return ENOMEM;
+ }
+
+ lower = sss_tc_utf8_str_tolower(attrs, pwd->pw_name);
+ if (!lower) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot convert name to lowercase\n"));
+ talloc_zfree(attrs);
+ return ENOMEM;
+ }
+
+ ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, lower);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add name alias\n"));
+ talloc_zfree(attrs);
+ return ret;
+ }
+ }
+
+ ret = sysdb_store_user(sysdb,
+ pwd->pw_name,
+ pwd->pw_passwd,
+ pwd->pw_uid,
+ pwd->pw_gid,
+ pwd->pw_gecos,
+ pwd->pw_dir,
+ shell,
+ attrs,
+ NULL,
+ cache_timeout,
+ 0);
+ talloc_zfree(attrs);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add user to cache\n"));
+ return ret;
+ }
+
+ return EOK;
+}
+
static int delete_user(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
struct sss_domain_info *domain, const char *name)
{
@@ -170,7 +213,6 @@ static int get_pw_uid(TALLOC_CTX *mem_ctx,
size_t buflen;
bool del_user = false;
int ret;
- const char *shell;
DEBUG(7, ("Searching user by uid (%d)\n", uid));
@@ -221,23 +263,7 @@ static int get_pw_uid(TALLOC_CTX *mem_ctx,
break;
}
- if (pwd->pw_shell && pwd->pw_shell[0] != '\0') {
- shell = pwd->pw_shell;
- } else {
- shell = NULL;
- }
-
- ret = sysdb_store_user(sysdb,
- pwd->pw_name,
- pwd->pw_passwd,
- pwd->pw_uid,
- pwd->pw_gid,
- pwd->pw_gecos,
- pwd->pw_dir,
- shell,
- NULL, NULL,
- ctx->entry_cache_timeout,
- 0);
+ ret = save_user(sysdb, !dom->case_sensitive, pwd, ctx->entry_cache_timeout);
if (ret) {
goto done;
}
@@ -286,7 +312,6 @@ static int enum_users(TALLOC_CTX *mem_ctx,
char *buffer;
char *newbuf;
int ret;
- const char *shell;
DEBUG(7, ("Enumerating users\n"));
@@ -369,23 +394,7 @@ again:
goto again; /* skip */
}
- if (pwd->pw_shell && pwd->pw_shell[0] != '\0') {
- shell = pwd->pw_shell;
- } else {
- shell = NULL;
- }
-
- ret = sysdb_store_user(sysdb,
- pwd->pw_name,
- pwd->pw_passwd,
- pwd->pw_uid,
- pwd->pw_gid,
- pwd->pw_gecos,
- pwd->pw_dir,
- shell,
- NULL, NULL,
- ctx->entry_cache_timeout,
- 0);
+ ret = save_user(sysdb, !dom->case_sensitive, pwd, ctx->entry_cache_timeout);
if (ret) {
/* Do not fail completely on errors.
* Just report the failure to save and go on */
@@ -415,8 +424,7 @@ done:
return ret;
}
-/* =Getgrnam-wrapper======================================================*/
-
+/* =Save-group-utilities=================================================*/
#define DEBUG_GR_MEM(level, grp) \
do { \
if (DEBUG_IS_SET(debug_get_level(level))) { \
@@ -435,6 +443,81 @@ done:
} \
} while(0)
+static int save_group(struct sysdb_ctx *sysdb, struct sss_domain_info *dom,
+ struct group *grp, uint64_t cache_timeout)
+{
+ errno_t ret;
+ struct sysdb_attrs *attrs = NULL;
+ char *lower;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ DEBUG_GR_MEM(7, grp);
+
+ if (grp->gr_mem && grp->gr_mem[0]) {
+ attrs = sysdb_new_attrs(tmp_ctx);
+ if (!attrs) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Allocation error ?!\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_users_from_str_list(
+ attrs, SYSDB_MEMBER, dom->name,
+ (const char *const *)grp->gr_mem);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add group members\n"));
+ goto done;
+ }
+ }
+
+ if (dom->case_sensitive == false) {
+ if (!attrs) {
+ attrs = sysdb_new_attrs(tmp_ctx);
+ if (!attrs) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Allocation error ?!\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ lower = sss_tc_utf8_str_tolower(attrs, grp->gr_name);
+ if (!lower) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot convert name to lowercase\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, lower);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add name alias\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ ret = sysdb_store_group(sysdb,
+ grp->gr_name,
+ grp->gr_gid,
+ attrs,
+ cache_timeout,
+ 0);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add group to cache\n"));
+ goto done;
+ }
+
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+/* =Getgrnam-wrapper======================================================*/
static int get_gr_name(TALLOC_CTX *mem_ctx,
struct proxy_id_ctx *ctx,
struct sysdb_ctx *sysdb,
@@ -448,7 +531,6 @@ static int get_gr_name(TALLOC_CTX *mem_ctx,
char *newbuf;
size_t buflen;
bool delete_group = false;
- struct sysdb_attrs *members;
int ret;
DEBUG(7, ("Searching group by name (%s)\n", name));
@@ -521,30 +603,7 @@ again:
break;
}
- DEBUG_GR_MEM(7, grp);
-
- if (grp->gr_mem && grp->gr_mem[0]) {
- members = sysdb_new_attrs(tmpctx);
- if (!members) {
- ret = ENOMEM;
- goto done;
- }
- ret = sysdb_attrs_users_from_str_list(
- members, SYSDB_MEMBER, dom->name,
- (const char *const *)grp->gr_mem);
- if (ret) {
- goto done;
- }
- } else {
- members = NULL;
- }
-
- ret = sysdb_store_group(sysdb,
- grp->gr_name,
- grp->gr_gid,
- members,
- ctx->entry_cache_timeout,
- 0);
+ ret = save_group(sysdb, dom, grp, ctx->entry_cache_timeout);
if (ret) {
goto done;
}
@@ -603,7 +662,6 @@ static int get_gr_gid(TALLOC_CTX *mem_ctx,
char *newbuf;
size_t buflen;
bool delete_group = false;
- struct sysdb_attrs *members;
int ret;
DEBUG(7, ("Searching group by gid (%d)\n", gid));
@@ -674,30 +732,7 @@ again:
break;
}
- DEBUG_GR_MEM(7, grp);
-
- if (grp->gr_mem && grp->gr_mem[0]) {
- members = sysdb_new_attrs(tmpctx);
- if (!members) {
- ret = ENOMEM;
- goto done;
- }
- ret = sysdb_attrs_users_from_str_list(
- members, SYSDB_MEMBER, dom->name,
- (const char *const *)grp->gr_mem);
- if (ret) {
- goto done;
- }
- } else {
- members = NULL;
- }
-
- ret = sysdb_store_group(sysdb,
- grp->gr_name,
- grp->gr_gid,
- members,
- ctx->entry_cache_timeout,
- now);
+ ret = save_group(sysdb, dom, grp, ctx->entry_cache_timeout);
if (ret) {
goto done;
}
@@ -746,7 +781,6 @@ static int enum_groups(TALLOC_CTX *mem_ctx,
enum nss_status status;
size_t buflen;
char *buffer;
- struct sysdb_attrs *members;
char *newbuf;
int ret;
@@ -830,30 +864,7 @@ again:
goto again; /* skip */
}
- DEBUG_GR_MEM(7, grp);
-
- if (grp->gr_mem && grp->gr_mem[0]) {
- members = sysdb_new_attrs(tmpctx);
- if (!members) {
- ret = ENOMEM;
- goto done;
- }
- ret = sysdb_attrs_users_from_str_list(
- members, SYSDB_MEMBER, dom->name,
- (const char *const *)grp->gr_mem);
- if (ret) {
- goto done;
- }
- } else {
- members = NULL;
- }
-
- ret = sysdb_store_group(sysdb,
- grp->gr_name,
- grp->gr_gid,
- members,
- ctx->entry_cache_timeout,
- 0);
+ ret = save_group(sysdb, dom, grp, ctx->entry_cache_timeout);
if (ret) {
/* Do not fail completely on errors.
* Just report the failure to save and go on */
@@ -904,7 +915,6 @@ static int get_initgr(TALLOC_CTX *mem_ctx,
char *buffer;
size_t buflen;
int ret;
- const char *shell;
tmpctx = talloc_new(mem_ctx);
if (!tmpctx) {
@@ -957,23 +967,7 @@ static int get_initgr(TALLOC_CTX *mem_ctx,
break;
}
- if (pwd->pw_shell && pwd->pw_shell[0] != '\0') {
- shell = pwd->pw_shell;
- } else {
- shell = NULL;
- }
-
- ret = sysdb_store_user(sysdb,
- pwd->pw_name,
- pwd->pw_passwd,
- pwd->pw_uid,
- pwd->pw_gid,
- pwd->pw_gecos,
- pwd->pw_dir,
- shell,
- NULL, NULL,
- ctx->entry_cache_timeout,
- 0);
+ ret = save_user(sysdb, !dom->case_sensitive, pwd, ctx->entry_cache_timeout);
if (ret) {
goto done;
}
@@ -1176,7 +1170,7 @@ void proxy_get_account_info(struct be_req *breq)
ENODEV, "Netgroups are not supported");
}
- ret = get_netgroup(ctx, sysdb, ar->filter_value);
+ ret = get_netgroup(ctx, sysdb, domain, ar->filter_value);
break;
default: /*fail*/
diff --git a/src/providers/proxy/proxy_netgroup.c b/src/providers/proxy/proxy_netgroup.c
index d0dd819e7ec23be71a30620914678a6389cc9727..c81e60c61be9404fb16e2f4e3d422fb383ed161c 100644
--- a/src/providers/proxy/proxy_netgroup.c
+++ b/src/providers/proxy/proxy_netgroup.c
@@ -63,8 +63,42 @@ static errno_t make_netgroup_attr(struct __netgrent netgrent,
return EOK;
}
+static errno_t save_netgroup(struct sysdb_ctx *sysdb,
+ const char *name,
+ struct sysdb_attrs *attrs,
+ bool lowercase,
+ uint64_t cache_timeout)
+{
+ errno_t ret;
+ char *lower;
+
+ if (lowercase) {
+ lower = sss_tc_utf8_str_tolower(NULL, name);
+ if (!lower) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot convert name to lowercase\n"));
+ return ENOMEM;
+ }
+
+ ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, lower);
+ talloc_free(lower);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add name alias\n"));
+ return ret;
+ }
+ }
+
+ ret = sysdb_add_netgroup(sysdb, name, NULL, attrs, cache_timeout, 0);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_add_netgroup failed.\n"));
+ return ret;
+ }
+
+ return EOK;
+}
+
errno_t get_netgroup(struct proxy_id_ctx *ctx,
struct sysdb_ctx *sysdb,
+ struct sss_domain_info *dom,
const char *name)
{
struct __netgrent result;
@@ -117,8 +151,8 @@ errno_t get_netgroup(struct proxy_id_ctx *ctx,
goto done;
}
- ret = sysdb_add_netgroup(sysdb, name, NULL, attrs,
- ctx->entry_cache_timeout, 0);
+ ret = save_netgroup(sysdb, name, attrs,
+ !dom->case_sensitive, ctx->entry_cache_timeout);
if (ret != EOK) {
DEBUG(1, ("sysdb_add_netgroup failed.\n"));
goto done;
--
1.7.7.4
More information about the sssd-devel
mailing list