New patches attached.

0001: Make the sysdb case-sensitive

0002: Upgrade existing databases for case-sensitivity.

0003: Add force_lowercase_names option

0004: Add tests for force_lowercase_names


On 11/16/2009 03:41 PM, Simo Sorce wrote:
> On Mon, 2009-11-16 at 11:42 -0500, Stephen Gallagher wrote:
>> Patch 0001: Make the sysdb user and group names case-sensitive
>> POSIX requires that usernames be case-sensitive. This will make the
>> sysdb and cache compliant.
> 
> Nack, I don't see code to upgrade an existing database.
> 
>> Patch 0002: Add force_lowercase_names option for domains
>>
>> Since POSIX usernames must be case-sensitive, but remote servers do
>> not,
>> it is possible for entries on the server to have different
>> capitalization in different uses. For those systems where this is the
>> case, SSSD will now offer an option to force all user and group names
>> to
>> lowercase, which should eliminate inconsistencies.
>>
>> p.s. Don't be frightened by the size of Patch 0002. Most of the patch
>> consists of new tests for this functionality.
> 
> Can you please split the tests patch into a separate third one so that I
> can review them more easily ?
> 
> Simo.
> 
> 


-- 
Stephen Gallagher
RHCE 804006346421761

Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/
From 601c39cdea7c3a3fef66b50e2e07f3c211e25b52 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <[email protected]>
Date: Fri, 13 Nov 2009 10:50:27 -0500
Subject: [PATCH 1/5] Make the sysdb user and group names case-sensitive

---
 server/db/sysdb_private.h  |    1 -
 server/tests/sysdb-tests.c |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 1 deletions(-)

diff --git a/server/db/sysdb_private.h b/server/db/sysdb_private.h
index 1f603eb..ea4b246 100644
--- a/server/db/sysdb_private.h
+++ b/server/db/sysdb_private.h
@@ -34,7 +34,6 @@
      "cn: CASE_INSENSITIVE\n" \
      "dc: CASE_INSENSITIVE\n" \
      "dn: CASE_INSENSITIVE\n" \
-     "name: CASE_INSENSITIVE\n" \
      "objectclass: CASE_INSENSITIVE\n" \
      "\n" \
      "dn: @INDEXLIST\n" \
diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c
index fffcb72..f1d3ae4 100644
--- a/server/tests/sysdb-tests.c
+++ b/server/tests/sysdb-tests.c
@@ -1398,6 +1398,7 @@ START_TEST (test_sysdb_getpwnam)
 {
     struct sysdb_test_ctx *test_ctx;
     struct test_data *data;
+    struct test_data *data_uc;
     int ret;
 
     /* Setup */
@@ -1428,6 +1429,25 @@ START_TEST (test_sysdb_getpwnam)
     }
     fail_unless(data->uid == _i,
                 "Did not find the expected UID");
+
+    /* Search for the user with the wrong case */
+    data_uc = talloc_zero(test_ctx, struct test_data);
+    data_uc->ctx = test_ctx;
+    data_uc->username = talloc_asprintf(data_uc, "TESTUSER%d", _i);
+
+    ret = sysdb_getpwnam(test_ctx,
+                         test_ctx->sysdb,
+                         data_uc->ctx->domain,
+                         data_uc->username,
+                         test_getpwent,
+                         data_uc);
+    if (ret == EOK) {
+        ret = test_loop(data_uc);
+    }
+
+    fail_unless(ret == ENOENT,
+                "The upper-case username search should fail. ");
+
 done:
     talloc_free(test_ctx);
 }
@@ -1437,6 +1457,7 @@ START_TEST (test_sysdb_getgrnam)
 {
     struct sysdb_test_ctx *test_ctx;
     struct test_data *data;
+    struct test_data *data_uc;
     int ret;
 
     /* Setup */
@@ -1468,6 +1489,24 @@ START_TEST (test_sysdb_getgrnam)
     fail_unless(data->gid == _i,
                 "Did not find the expected GID (found %d expected %d)",
                 data->gid, _i);
+
+    /* Search for the group with the wrong case */
+    data_uc = talloc_zero(test_ctx, struct test_data);
+    data_uc->ctx = test_ctx;
+    data_uc->groupname = talloc_asprintf(data_uc, "TESTGROUP%d", _i);
+
+    ret = sysdb_getgrnam(test_ctx,
+                         test_ctx->sysdb,
+                         data_uc->ctx->domain,
+                         data_uc->groupname,
+                         test_getgrent,
+                         data_uc);
+    if (ret == EOK) {
+        ret = test_loop(data_uc);
+    }
+
+    fail_unless(ret == ENOENT,
+                "The upper-case groupname search should fail. ");
 done:
     talloc_free(test_ctx);
 }
-- 
1.6.2.5

From 5888c1b93ca54d82e7eeebcd813f6ddb1dc26256 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <[email protected]>
Date: Tue, 17 Nov 2009 09:47:04 -0500
Subject: [PATCH 2/5] Upgrade cache and local databases to case-sensitive names

---
 server/db/sysdb.c         |   92 +++++++++++++++++++++++++++++++++++++++++++++
 server/db/sysdb_private.h |    4 +-
 2 files changed, 95 insertions(+), 1 deletions(-)

diff --git a/server/db/sysdb.c b/server/db/sysdb.c
index e4131f1..4baa989 100644
--- a/server/db/sysdb.c
+++ b/server/db/sysdb.c
@@ -1065,6 +1065,93 @@ done:
     return ret;
 }
 
+static int sysdb_upgrade_03(struct sysdb_ctx *ctx, const char **ver)
+{
+    TALLOC_CTX *tmp_ctx;
+    int ret;
+    struct ldb_message *msg;
+
+    tmp_ctx = talloc_new(ctx);
+    if (!tmp_ctx) {
+        return ENOMEM;
+    }
+
+    ret = ldb_transaction_start(ctx->ldb);
+    if (ret != LDB_SUCCESS) {
+        ret = EIO;
+        goto done;
+    }
+
+    /* Make this database case-sensitive */
+    msg = ldb_msg_new(tmp_ctx);
+    if (!msg) {
+        ret = ENOMEM;
+        goto done;
+    }
+    msg->dn = ldb_dn_new(tmp_ctx, ctx->ldb, "@ATTRIBUTES");
+    if (!msg->dn) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_DELETE, NULL);
+    if (ret != LDB_SUCCESS) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = ldb_modify(ctx->ldb, msg);
+    if (ret != LDB_SUCCESS) {
+        ret = sysdb_error_to_errno(ret);
+        goto done;
+    }
+
+    /* conversion done, upgrade version number */
+    msg = ldb_msg_new(tmp_ctx);
+    if (!msg) {
+        ret = ENOMEM;
+        goto done;
+    }
+    msg->dn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb");
+    if (!msg->dn) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL);
+    if (ret != LDB_SUCCESS) {
+        ret = ENOMEM;
+        goto done;
+    }
+    ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_4);
+    if (ret != LDB_SUCCESS) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = ldb_modify(ctx->ldb, msg);
+    if (ret != LDB_SUCCESS) {
+        ret = sysdb_error_to_errno(ret);
+        goto done;
+    }
+
+    ret = EOK;
+
+done:
+    talloc_zfree(tmp_ctx);
+
+    if (ret != EOK) {
+        ret = ldb_transaction_cancel(ctx->ldb);
+    } else {
+        ret = ldb_transaction_commit(ctx->ldb);
+    }
+    if (ret != LDB_SUCCESS) {
+        ret = EIO;
+    }
+
+    *ver = "0.4";
+    return ret;
+}
 
 static int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
                                       struct tevent_context *ev,
@@ -1201,6 +1288,11 @@ static int sysdb_domain_init_internal(TALLOC_CTX 
*mem_ctx,
                 goto done;
             }
 
+            if (strcmp(version, SYSDB_VERSION_0_3) == 0) {
+                ret = sysdb_upgrade_03(ctx, &version);
+                if (ret != EOK) goto done;
+            }
+
         }
 
         DEBUG(0,("Unknown DB version [%s], expected [%s] for domain %s!\n",
diff --git a/server/db/sysdb_private.h b/server/db/sysdb_private.h
index ea4b246..4400665 100644
--- a/server/db/sysdb_private.h
+++ b/server/db/sysdb_private.h
@@ -23,11 +23,13 @@
 #ifndef __INT_SYS_DB_H__
 #define __INT_SYS_DB_H__
 
-#define SYSDB_VERSION "0.3"
+#define SYSDB_VERSION_0_4 "0.4"
 #define SYSDB_VERSION_0_3 "0.3"
 #define SYSDB_VERSION_0_2 "0.2"
 #define SYSDB_VERSION_0_1 "0.1"
 
+#define SYSDB_VERSION SYSDB_VERSION_0_4
+
 #define SYSDB_BASE_LDIF \
      "dn: @ATTRIBUTES\n" \
      "userPrincipalName: CASE_INSENSITIVE\n" \
-- 
1.6.2.5

From 4cd2b47d4d0548d6f56e9ba8a9fb6846e2e3e6a7 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <[email protected]>
Date: Tue, 17 Nov 2009 08:56:40 -0500
Subject: [PATCH 3/5] Add force_lowercase_names option for domains

Since POSIX usernames must be case-sensitive, but remote servers do not,
it is possible for entries on the server to have different
capitalization in different uses. For those systems where this is the
case, SSSD will now offer an option to force all user and group names to
lowercase, which should eliminate inconsistencies.
---
 server/confdb/confdb.c          |    7 ++++
 server/confdb/confdb.h          |    2 +
 server/config/SSSDConfig.py     |    1 +
 server/config/SSSDConfigTest.py |    2 +
 server/config/etc/sssd.api.conf |    2 +-
 server/db/sysdb_ops.c           |   69 +++++++++++++++++++++++++++++++++++++++
 server/util/memory.c            |   22 ++++++++++++
 server/util/util.h              |    2 +
 8 files changed, 106 insertions(+), 1 deletions(-)

diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c
index 5dd8669..1fd85d8 100644
--- a/server/confdb/confdb.c
+++ b/server/confdb/confdb.c
@@ -989,6 +989,13 @@ static int confdb_get_domain_internal(struct confdb_ctx 
*cdb,
         goto done;
     }
 
+    ret = get_entry_as_bool(res->msgs[0], &domain->force_lowercase,
+                            CONFDB_DOMAIN_FORCE_LOWERCASE_NAMES, 0);
+    if(ret != EOK) {
+        DEBUG(0, ("Invalid value for %s\n", 
CONFDB_DOMAIN_FORCE_LOWERCASE_NAMES));
+        goto done;
+    }
+
     *_domain = domain;
     ret = EOK;
 
diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h
index 0a64f9e..b5cf12c 100644
--- a/server/confdb/confdb.h
+++ b/server/confdb/confdb.h
@@ -86,6 +86,7 @@
 #define CONFDB_DOMAIN_MPG "magic_private_groups"
 #define CONFDB_DOMAIN_FQ "use_fully_qualified_names"
 #define CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT "entry_cache_timeout"
+#define CONFDB_DOMAIN_FORCE_LOWERCASE_NAMES "force_lowercase_names"
 
 /* Local Provider */
 #define CONFDB_LOCAL_DEFAULT_SHELL   "default_shell"
@@ -122,6 +123,7 @@ struct sss_domain_info {
 
     bool cache_credentials;
     bool legacy_passwords;
+    bool force_lowercase;
 
     struct sss_domain_info *next;
 };
diff --git a/server/config/SSSDConfig.py b/server/config/SSSDConfig.py
index 1fa6d4c..b0e488a 100644
--- a/server/config/SSSDConfig.py
+++ b/server/config/SSSDConfig.py
@@ -75,6 +75,7 @@ option_strings = {
     'store_legacy_passwords' : _('Store password hashes'),
     'use_fully_qualified_names' : _('Display users/groups in fully-qualified 
form'),
     'entry_cache_timeout' : _('Entry cache timeout length (seconds)'),
+    'force_lowercase_names' : _('Force user and group names in the cache to be 
lowercase'),
 
     # [provider/ipa]
     'ipa_domain' : _('IPA domain'),
diff --git a/server/config/SSSDConfigTest.py b/server/config/SSSDConfigTest.py
index 944f86f..4b6569e 100644
--- a/server/config/SSSDConfigTest.py
+++ b/server/config/SSSDConfigTest.py
@@ -412,6 +412,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'cache_credentials',
             'store_legacy_passwords',
             'use_fully_qualified_names',
+            'force_lowercase_names',
             'entry_cache_timeout',
             'id_provider',
             'auth_provider',
@@ -631,6 +632,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'cache_credentials',
             'store_legacy_passwords',
             'use_fully_qualified_names',
+            'force_lowercase_names',
             'entry_cache_timeout',
             'id_provider',
             'auth_provider',
diff --git a/server/config/etc/sssd.api.conf b/server/config/etc/sssd.api.conf
index e8b266b..2f5b8db 100644
--- a/server/config/etc/sssd.api.conf
+++ b/server/config/etc/sssd.api.conf
@@ -50,4 +50,4 @@ cache_credentials = bool, None, false
 store_legacy_passwords = bool, None, false
 use_fully_qualified_names = bool, None, false
 entry_cache_timeout = int, None
-
+force_lowercase_names = bool, None, false
diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c
index 7e232a4..7d3e8d1 100644
--- a/server/db/sysdb_ops.c
+++ b/server/db/sysdb_ops.c
@@ -1737,6 +1737,10 @@ struct tevent_req *sysdb_add_user_send(TALLOC_CTX 
*mem_ctx,
     state->attrs = attrs;
     state->cache_timeout = cache_timeout;
 
+    if (domain->force_lowercase) {
+        state->name = make_lowercase(state, name);
+    }
+
     if (handle->ctx->mpg) {
         if (gid != 0) {
             DEBUG(0, ("Cannot add user with arbitrary GID in MPG domain!\n"));
@@ -2182,6 +2186,10 @@ struct tevent_req *sysdb_add_group_send(TALLOC_CTX 
*mem_ctx,
     state->gid = gid;
     state->attrs = attrs;
 
+    if (domain->force_lowercase) {
+        state->name = make_lowercase(state, name);
+    }
+
     if (domain->id_max != 0 && gid != 0 &&
         (gid < domain->id_min || gid > domain->id_max)) {
         DEBUG(2, ("Supplied gid [%d] is not in the allowed range [%d-%d].\n",
@@ -2488,6 +2496,13 @@ struct tevent_req 
*sysdb_mod_group_member_send(TALLOC_CTX *mem_ctx,
         ERROR_OUT(ret, EINVAL, fail);
     }
 
+    if (handle->ctx->domain->force_lowercase) {
+        dn = make_lowercase(state, dn);
+        if(!dn) {
+            ERROR_OUT(ret, ENOMEM, fail);
+        }
+    }
+
     ret = ldb_msg_add_fmt(msg, SYSDB_MEMBER, "%s", dn);
     if (ret != LDB_SUCCESS) {
         ERROR_OUT(ret, EINVAL, fail);
@@ -2579,6 +2594,10 @@ struct tevent_req *sysdb_store_user_send(TALLOC_CTX 
*mem_ctx,
     state->attrs = attrs;
     state->cache_timeout = cache_timeout;
 
+    if(domain->force_lowercase) {
+        state->name = make_lowercase(state, name);
+    }
+
     if (pwd && (domain->legacy_passwords || !*pwd)) {
         ret = sysdb_attrs_add_string(state->attrs, SYSDB_PWD, pwd);
         if (ret) goto fail;
@@ -2805,6 +2824,9 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX 
*mem_ctx,
     static const char *src_attrs[] = { SYSDB_NAME, SYSDB_GIDNUM,
                                        SYSDB_ORIG_MODSTAMP, NULL };
     int ret;
+    uint32_t num_users;
+    uint32_t num_groups;
+    uint32_t i;
 
     req = tevent_req_create(mem_ctx, &state, struct sysdb_store_group_state);
     if (!req) return NULL;
@@ -2819,6 +2841,53 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX 
*mem_ctx,
     state->attrs = attrs;
     state->cache_timeout = cache_timeout;
 
+    if (domain->force_lowercase) {
+        state->name = make_lowercase(state, name);
+
+        /* Lower-case the member names as well */
+        if (member_users && member_users[0] != NULL) {
+            num_users = 0;
+            while(member_users[num_users] != NULL) {
+                num_users++;
+            }
+
+            state->member_users = talloc_array(state, const char *,
+                                               num_users+1);
+            if (!state->member_users) {
+                ERROR_OUT(ret, ENOMEM, fail);
+            }
+
+            i = 0;
+            while (i < num_users) {
+                state->member_users[i] = make_lowercase(state->member_users,
+                                                        member_users[i]);
+                i++;
+            }
+            state->member_users[i] = NULL;
+        }
+
+        if (member_groups && member_groups[0] != NULL) {
+            num_groups = 0;
+            while(member_groups[num_groups] != NULL) {
+                num_groups++;
+            }
+
+            state->member_groups = talloc_array(state, const char *,
+                                               num_groups+1);
+            if (!state->member_groups) {
+                ERROR_OUT(ret, ENOMEM, fail);
+            }
+
+            i = 0;
+            while (i < num_groups) {
+                state->member_groups[i] = make_lowercase(state->member_groups,
+                                                         member_groups[i]);
+                i++;
+            }
+            state->member_groups[i] = NULL;
+        }
+    }
+
     subreq = sysdb_search_group_by_name_send(state, ev, NULL, handle,
                                              domain, name, src_attrs);
     if (!subreq) {
diff --git a/server/util/memory.c b/server/util/memory.c
index a2c8b54..9a8a241 100644
--- a/server/util/memory.c
+++ b/server/util/memory.c
@@ -18,6 +18,7 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <ctype.h>
 #include "talloc.h"
 #include "util/util.h"
 
@@ -65,3 +66,24 @@ void *sss_mem_attach(TALLOC_CTX *mem_ctx,
 
     return h;
 }
+
+const char *make_lowercase(TALLOC_CTX *mem_ctx, const char *str)
+{
+    int len, i;
+    char *retval;
+
+    len = strlen(str);
+    retval = talloc_array(mem_ctx, char, len+1);
+    if (!retval) {
+        return NULL;
+    }
+
+    i = 0;
+    while (i < len) {
+        retval[i] = tolower(str[i]);
+        i++;
+    }
+    retval[len] = '\0';
+
+    return (const char *)retval;
+}
diff --git a/server/util/util.h b/server/util/util.h
index 661bceb..d5fdac2 100644
--- a/server/util/util.h
+++ b/server/util/util.h
@@ -193,6 +193,8 @@ void *sss_mem_attach(TALLOC_CTX *mem_ctx,
 
 int password_destructor(void *memctx);
 
+const char *make_lowercase(TALLOC_CTX *mem_ctx, const char *str);
+
 /* from usertools.c */
 char *get_username_from_uid(TALLOC_CTX *mem_ctx, uid_t uid);
 
-- 
1.6.2.5

From f9632f3aa41d5c73d7d82bab42c57b99ce46d96e Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <[email protected]>
Date: Tue, 17 Nov 2009 08:58:09 -0500
Subject: [PATCH 4/5] Add tests for force_lowercase_names

Also adds a group membership test for both force_lowercase and
standard configs.
---
 server/Makefile.am         |    1 +
 server/tests/sysdb-tests.c |  310 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 310 insertions(+), 1 deletions(-)

diff --git a/server/Makefile.am b/server/Makefile.am
index 08c0295..d880d99 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -729,6 +729,7 @@ install-exec-hook: installsssddirs
 
 clean-local:
        cd $(srcdir)/config; $(PYTHON) setup.py clean --all
+       rm -rf $(builddir)/tests_sysdb
 
 CLEANFILES = *.X */*.X */*/*.X
 
diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c
index f1d3ae4..2e22f14 100644
--- a/server/tests/sysdb-tests.c
+++ b/server/tests/sysdb-tests.c
@@ -155,6 +155,7 @@ struct test_data {
     uid_t uid;
     gid_t gid;
     const char *shell;
+    const char *member;
 
     bool finished;
     int error;
@@ -616,6 +617,39 @@ static void test_getgrent(void *pvt, int error, struct 
ldb_result *res)
     }
 }
 
+static void test_get_group_member(void *pvt, int error, struct ldb_result *res)
+{
+    struct test_data *data = talloc_get_type(pvt, struct test_data);
+    data->finished = true;
+
+    if (error != EOK) {
+        data->error = error;
+        return;
+    }
+
+    switch (res->count) {
+        case 0:
+            data->error = ENOENT;
+            break;
+
+        case 1:
+            data->error = EOK;
+            data->gid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_GIDNUM, 
0);
+            data->member = NULL;
+            break;
+
+        default:
+            /* The first message is always the group, subsequent messages
+             * are the members. In these tests, we never have more than
+             * one member.
+             */
+            data->gid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_GIDNUM, 
0);
+            data->member = ldb_msg_find_attr_as_string(res->msgs[1], "name", 
NULL);
+            data->error = EOK;
+            break;
+    }
+}
+
 static void test_getgrgid(void *pvt, int error, struct ldb_result *res)
 {
     struct test_data *data = talloc_get_type(pvt, struct test_data);
@@ -777,7 +811,12 @@ static void test_add_group_member(struct tevent_req *req)
         return test_return(data, ret);
     }
 
-    username = talloc_asprintf(data, "testuser%d", data->uid);
+    if (data->ctx->domain->force_lowercase) {
+        username = talloc_asprintf(data, "TESTUSER%d", data->uid);
+    }
+    else {
+        username = talloc_asprintf(data, "testuser%d", data->uid);
+    }
     if (username == NULL) {
         test_return(data, ENOMEM);
     }
@@ -1357,6 +1396,49 @@ START_TEST (test_sysdb_add_user)
 }
 END_TEST
 
+START_TEST (test_sysdb_add_user_force_lc)
+{
+    struct sysdb_test_ctx *test_ctx;
+    struct test_data *data;
+    struct tevent_req *subreq;
+    int ret;
+
+    /* Setup */
+    ret = setup_sysdb_tests(&test_ctx);
+    if (ret != EOK) {
+        fail("Could not set up the test");
+        return;
+    }
+
+    test_ctx->domain->force_lowercase = true;
+
+    data = talloc_zero(test_ctx, struct test_data);
+    data->ctx = test_ctx;
+    data->ev = test_ctx->ev;
+    data->uid = _i;
+    data->gid = _i;
+    data->username = talloc_asprintf(data, "TESTUSER%d", _i);
+
+    subreq = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
+    if (!subreq) {
+        ret = ENOMEM;
+    }
+
+    if (ret == EOK) {
+        tevent_req_set_callback(subreq, test_add_user, data);
+
+        ret = test_loop(data);
+    }
+
+
+    fail_if(ret != EOK, "Could not add user %s", data->username);
+
+    test_ctx->domain->force_lowercase = false;
+
+    talloc_free(test_ctx);
+}
+END_TEST
+
 START_TEST (test_sysdb_add_group)
 {
     struct sysdb_test_ctx *test_ctx;
@@ -1394,6 +1476,48 @@ START_TEST (test_sysdb_add_group)
 }
 END_TEST
 
+START_TEST (test_sysdb_add_group_force_lc)
+{
+    struct sysdb_test_ctx *test_ctx;
+    struct test_data *data;
+    struct tevent_req *subreq;
+    int ret;
+
+    /* Setup */
+    ret = setup_sysdb_tests(&test_ctx);
+    if (ret != EOK) {
+        fail("Could not set up the test");
+        return;
+    }
+
+    test_ctx->domain->force_lowercase = true;
+
+    data = talloc_zero(test_ctx, struct test_data);
+    data->ctx = test_ctx;
+    data->ev = test_ctx->ev;
+    data->uid = _i;
+    data->gid = _i;
+    data->groupname = talloc_asprintf(data, "TESTGROUP%d", _i);
+
+    subreq = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
+    if (!subreq) {
+        ret = ENOMEM;
+    }
+
+    if (ret == EOK) {
+        tevent_req_set_callback(subreq, test_add_group, data);
+
+        ret = test_loop(data);
+    }
+
+    fail_if(ret != EOK, "Could not add group %s", data->groupname);
+
+    test_ctx->domain->force_lowercase = false;
+
+    talloc_free(test_ctx);
+}
+END_TEST
+
 START_TEST (test_sysdb_getpwnam)
 {
     struct sysdb_test_ctx *test_ctx;
@@ -1453,6 +1577,69 @@ done:
 }
 END_TEST
 
+START_TEST (test_sysdb_getpwnam_force_lc)
+{
+    struct sysdb_test_ctx *test_ctx;
+    struct test_data *data;
+    struct test_data *data_uc;
+    int ret;
+
+    /* Setup */
+    ret = setup_sysdb_tests(&test_ctx);
+    if (ret != EOK) {
+        fail("Could not set up the test");
+        return;
+    }
+
+    test_ctx->domain->force_lowercase = true;
+
+    data = talloc_zero(test_ctx, struct test_data);
+    data->ctx = test_ctx;
+    data->username = talloc_asprintf(data, "testuser%d", _i);
+
+    ret = sysdb_getpwnam(test_ctx,
+                         test_ctx->sysdb,
+                         data->ctx->domain,
+                         data->username,
+                         test_getpwent,
+                         data);
+    if (ret == EOK) {
+        ret = test_loop(data);
+    }
+
+    if (ret) {
+        fail("sysdb_getpwnam failed for username %s (%d: %s)",
+             data->username, ret, strerror(ret));
+        goto done;
+    }
+    fail_unless(data->uid == _i,
+                "Did not find the expected UID");
+
+    /* Search for the user with the wrong case */
+    data_uc = talloc_zero(test_ctx, struct test_data);
+    data_uc->ctx = test_ctx;
+    data_uc->username = talloc_asprintf(data_uc, "TESTUSER%d", _i);
+
+    ret = sysdb_getpwnam(test_ctx,
+                         test_ctx->sysdb,
+                         data_uc->ctx->domain,
+                         data_uc->username,
+                         test_getpwent,
+                         data_uc);
+    if (ret == EOK) {
+        ret = test_loop(data_uc);
+    }
+
+    fail_unless(ret == ENOENT,
+                "The upper-case username search should fail. ");
+
+    test_ctx->domain->force_lowercase = false;
+
+done:
+    talloc_free(test_ctx);
+}
+END_TEST
+
 START_TEST (test_sysdb_getgrnam)
 {
     struct sysdb_test_ctx *test_ctx;
@@ -1512,6 +1699,54 @@ done:
 }
 END_TEST
 
+START_TEST (test_sysdb_verify_group_member)
+{
+    struct sysdb_test_ctx *test_ctx;
+    struct test_data *data;
+    int ret;
+
+    /* Setup */
+    ret = setup_sysdb_tests(&test_ctx);
+    if (ret != EOK) {
+        fail("Could not set up the test");
+        return;
+    }
+
+    data = talloc_zero(test_ctx, struct test_data);
+    data->ctx = test_ctx;
+    data->groupname = talloc_asprintf(data, "testgroup%d", _i);
+    data->username = talloc_asprintf(data, "testuser%d", _i-1000);
+
+    ret = sysdb_getgrnam(test_ctx,
+                         test_ctx->sysdb,
+                         data->ctx->domain,
+                         data->groupname,
+                         test_get_group_member,
+                         data);
+    if (ret == EOK) {
+        ret = test_loop(data);
+    }
+
+    if (ret) {
+        fail("sysdb_getgrnam failed for groupname %s (%d: %s)",
+             data->groupname, ret, strerror(ret));
+        goto done;
+    }
+    fail_unless(data->gid == _i,
+                "Did not find the expected GID (found %d expected %d)",
+                data->gid, _i);
+
+    fail_if(data->member == NULL, "No members returned");
+    fail_unless(strcmp(data->member, data->username) == 0,
+                "Member username did not match. "
+                "Got [%s], expected [%s]",
+                data->member, data->username);
+
+done:
+    talloc_free(test_ctx);
+}
+END_TEST
+
 START_TEST (test_sysdb_getgrgid)
 {
     struct sysdb_test_ctx *test_ctx;
@@ -1802,6 +2037,46 @@ START_TEST (test_sysdb_add_group_member)
 }
 END_TEST
 
+START_TEST (test_sysdb_add_group_member_force_lc)
+{
+    struct sysdb_test_ctx *test_ctx;
+    struct test_data *data;
+    struct tevent_req *req;
+    int ret;
+
+    /* Setup */
+    ret = setup_sysdb_tests(&test_ctx);
+    if (ret != EOK) {
+        fail("Could not set up the test");
+        return;
+    }
+
+    test_ctx->domain->force_lowercase = 1;
+
+    data = talloc_zero(test_ctx, struct test_data);
+    data->ctx = test_ctx;
+    data->ev = test_ctx->ev;
+    data->groupname = talloc_asprintf(data, "testgroup%d", _i);
+    data->uid = _i - 1000; /* the UID of user to add */
+
+    req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
+    if (!req) {
+        ret = ENOMEM;
+    }
+
+    if (ret == EOK) {
+        tevent_req_set_callback(req, test_add_group_member, data);
+
+        ret = test_loop(data);
+    }
+
+    fail_if(ret != EOK, "Could not modify group %s", data->groupname);
+
+    test_ctx->domain->force_lowercase = 0;
+    talloc_free(test_ctx);
+}
+END_TEST
+
 START_TEST (test_sysdb_remove_group_member)
 {
     struct sysdb_test_ctx *test_ctx;
@@ -2457,6 +2732,9 @@ Suite *create_sysdb_suite(void)
     /* Add some members to the groups */
     tcase_add_loop_test(tc_sysdb, test_sysdb_add_group_member, 28010, 28020);
 
+    /* Verify the group memberships */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_verify_group_member, 28010, 
28020);
+
     /* ASQ search test */
     tcase_add_loop_test(tc_sysdb, test_sysdb_prepare_asq_test_user, 28011, 
28020);
     tcase_add_test(tc_sysdb, test_sysdb_asq_search);
@@ -2491,6 +2769,36 @@ Suite *create_sysdb_suite(void)
 
     tcase_add_test(tc_sysdb, test_sysdb_attrs_replace_name);
 
+
+    /* ==== Force lowercase name tests ==== */
+
+    /* Create new users */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_add_user_force_lc,27050,27060);
+
+    /* Verify the users were added */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_getpwnam, 27050, 27060);
+
+    /* Create new groups */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_add_group_force_lc, 28050, 28060);
+
+    /* Verify the groups were added */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_getgrnam, 28050, 28060);
+
+    /* Add some group members */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_add_group_member_force_lc, 28050, 
28060);
+
+    /* Verify group members */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_verify_group_member, 28050, 
28060);
+
+    /* Remove group members */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_remove_group_member, 28050, 
28060);
+
+    /* Remove groups */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_remove_local_group, 28050, 28060);
+
+    /* Remove users */
+    tcase_add_loop_test(tc_sysdb, test_sysdb_remove_local_user, 27050, 27060);
+
 /* Add all test cases to the test suite */
     suite_add_tcase(s, tc_sysdb);
 
-- 
1.6.2.5

Attachment: signature.asc
Description: OpenPGP digital signature

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

Reply via email to