[SSSD] AUTOFS: Store entry objects below map objects

Jakub Hrozek jhrozek at redhat.com
Mon Sep 24 14:52:03 UTC 2012


On Mon, Sep 24, 2012 at 04:41:51PM +0200, Pavel Březina wrote:
> On 09/24/2012 03:44 PM, Jakub Hrozek wrote:
> >On Mon, Sep 24, 2012 at 01:12:51PM +0200, Pavel Březina wrote:
> >>On 09/23/2012 08:47 PM, Jakub Hrozek wrote:
> >>>[PATCH 1/5] AUTOFS: Do not fail if search base is not provided
> >>>We need to fall back to rootDSE provided search base instead of failing
> >>
> >>Ack.
> >>
> >>>[PATCH 2/5] AUTOFS: Add sysdb tests
> >>>I knew I would be changing the sysdb interface so I coded up tests to
> >>>avoid regressions
> >>
> >>Nack.
> >>You don't free test_ctx in the three last tests.
> >>
> >
> >Fixed.
> >
> >>>[PATCH 3/5] AUTOFS: Add entry objects below map objects
> >>>https://fedorahosted.org/sssd/ticket/1506
> >>
> >>Nack.
> >>/home/pavka/git/sssd/.git/rebase-apply/patch:273: new blank line at EOF.
> >>+
> >>warning: 1 line adds whitespace errors.
> >>
> >
> >Fixed. Sorry, I squashed that hunk into a wrong patch.
> >
> >>SSSD cannot be compiled with this patch as HEAD:
> >>src/db/sysdb_autofs.c:266:56: error: 'name' undeclared (first use in
> >>this function)
> >>
> >>>
> >>>Changes how the new autofs entry objects are handled. Instead of
> >>>creating the entry on the cn=autofs,cn=custom level, the entry is
> >>>created below the map it belongs to.
> >>>
> >>>[PATCH 4/5] AUTOFS: Use both key and value in entry RDN
> >>>This patch switches from using just key in the RDN to using both key and
> >>>value. That is neccessary to allow multiple direct mounts in a single
> >>>map.
> >>
> >>Ack,
> >>
> >>>[PATCH 5/5] AUTOFS: convert the existing autofs entries during a sysdb upgrade
> >>>The sysdb is upgraded to a new version to convert the existing entries
> >>>to the new format.
> >>
> >>Ack.
> >
> >New patches are attached. Thank you for the review.
> 
> Nack for patch 3.
> mod_autofs_entry() don't use default branch for enum in the switch
> statement. If the default branch is present, compiler cannot warn
> you that you have forgotten some value.

New patches attached again.
-------------- next part --------------
>From a160281aec669e2faddcf3b26f9cec91c244694d Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Sat, 22 Sep 2012 16:36:01 +0200
Subject: [PATCH 1/5] AUTOFS: Do not fail if search base is not provided

---
 src/providers/ldap/ldap_common.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index f0095b54685919c86dc178e9b69e7cbb55e73919..6484556bdbdc542dfe7596e605c46f5edd4cb534 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -429,8 +429,8 @@ int ldap_get_autofs_options(TALLOC_CTX *memctx,
                   dp_opt_get_string(opts->basic, SDAP_AUTOFS_SEARCH_BASE)));
         }
     } else {
-        DEBUG(SSSDBG_OP_FAILURE, ("Error: no autofs search base set\n"));
-        return ENOENT;
+        DEBUG(SSSDBG_TRACE_FUNC, ("Search base not set, trying to discover it later "
+              "connecting to the LDAP server.\n"));
     }
 
     ret = sdap_parse_search_base(opts, opts->basic,
-- 
1.7.11.4

-------------- next part --------------
>From aab69b587a569815c964cf96877de7eca5b5ca5b Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 17 Sep 2012 14:39:39 +0200
Subject: [PATCH 2/5] AUTOFS: Add sysdb tests

---
 src/tests/sysdb-tests.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 249 insertions(+)

diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index 88d959c0ba30b6b0da8faf523ac50be45c76502f..429df541966e08051a35c9f7bf1f0e17ddde91ce 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -30,6 +30,7 @@
 #include "confdb/confdb_setup.h"
 #include "db/sysdb_private.h"
 #include "db/sysdb_services.h"
+#include "db/sysdb_autofs.h"
 #include "tests/common.h"
 
 #define TESTS_PATH "tests_sysdb"
@@ -49,6 +50,8 @@
 #define MBO_USER_BASE 27500
 #define MBO_GROUP_BASE 28500
 
+#define TEST_AUTOFS_MAP_BASE 29500
+
 struct sysdb_test_ctx {
     struct sysdb_ctx *sysdb;
     struct confdb_ctx *confdb;
@@ -161,6 +164,7 @@ struct test_data {
     const char *username;
     const char *groupname;
     const char *netgrname;
+    const char *autofsmapname;
     uid_t uid;
     gid_t gid;
     const char *shell;
@@ -3611,6 +3615,217 @@ START_TEST(test_sysdb_subdomain_group_ops)
 }
 END_TEST
 
+#ifdef BUILD_AUTOFS
+START_TEST(test_autofs_create_map)
+{
+    struct sysdb_test_ctx *test_ctx;
+    const char *autofsmapname;
+    errno_t ret;
+
+    ret = setup_sysdb_tests(&test_ctx);
+    fail_if(ret != EOK, "Could not set up the test");
+
+    autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i);
+    fail_if(autofsmapname == NULL, "Out of memory\n");
+
+    ret = sysdb_save_autofsmap(test_ctx->sysdb, autofsmapname,
+                               autofsmapname, NULL, 0, 0);
+    fail_if(ret != EOK, "Could not store autofs map %s", autofsmapname);
+    talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST(test_autofs_retrieve_map)
+{
+    struct sysdb_test_ctx *test_ctx;
+    const char *autofsmapname;
+    errno_t ret;
+    struct ldb_message *map = NULL;
+
+    ret = setup_sysdb_tests(&test_ctx);
+    fail_if(ret != EOK, "Could not set up the test");
+
+    autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i);
+    fail_if(autofsmapname == NULL, "Out of memory\n");
+
+    ret = sysdb_get_map_byname(test_ctx, test_ctx->sysdb,
+                               autofsmapname, &map);
+    fail_if(ret != EOK, "Could not retrieve autofs map %s", autofsmapname);
+    fail_if(map == NULL, "No map retrieved?\n");
+    talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST(test_autofs_delete_map)
+{
+    struct sysdb_test_ctx *test_ctx;
+    const char *autofsmapname;
+    errno_t ret;
+
+    ret = setup_sysdb_tests(&test_ctx);
+    fail_if(ret != EOK, "Could not set up the test");
+
+    autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i);
+    fail_if(autofsmapname == NULL, "Out of memory\n");
+
+    ret = sysdb_delete_autofsmap(test_ctx->sysdb, autofsmapname);
+    fail_if(ret != EOK, "Could not retrieve autofs map %s", autofsmapname);
+    talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST(test_autofs_retrieve_map_neg)
+{
+    struct sysdb_test_ctx *test_ctx;
+    const char *autofsmapname;
+    errno_t ret;
+    struct ldb_message *map = NULL;
+
+    ret = setup_sysdb_tests(&test_ctx);
+    fail_if(ret != EOK, "Could not set up the test");
+
+    autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i);
+    fail_if(autofsmapname == NULL, "Out of memory\n");
+
+    ret = sysdb_get_map_byname(test_ctx, test_ctx->sysdb,
+                               autofsmapname, &map);
+    fail_if(ret != ENOENT, "Expected ENOENT, got %d instead\n", ret);
+    fail_if(map != NULL, "Unexpected map found\n");
+    talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST(test_autofs_store_entry_in_map)
+{
+    struct sysdb_test_ctx *test_ctx;
+    const char *autofsmapname;
+    const char *autofskey;
+    const char *autofsval;
+    errno_t ret;
+    int ii;
+    const int limit = 10;
+    const char *add_entries[limit+1];
+
+    ret = setup_sysdb_tests(&test_ctx);
+    fail_if(ret != EOK, "Could not set up the test");
+
+    add_entries[limit] = NULL;
+
+    autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i);
+    fail_if(autofsmapname == NULL, "Out of memory\n");
+
+    for (ii=0; ii < limit; ii++) {
+        autofskey = talloc_asprintf(test_ctx, "%s_testkey%d",
+                                    autofsmapname, ii);
+        fail_if(autofskey == NULL, "Out of memory\n");
+
+        autofsval = talloc_asprintf(test_ctx, "testserver:/testval%d", ii);
+        fail_if(autofsval == NULL, "Out of memory\n");
+
+        ret = sysdb_save_autofsentry(test_ctx->sysdb, autofskey,
+                                     autofsval, NULL);
+        fail_if(ret != EOK, "Could not save autofs entry %s", autofskey);
+
+        add_entries[ii] = autofskey;
+    }
+
+    ret = sysdb_autofs_map_update_members(test_ctx->sysdb, autofsmapname,
+                                          (const char *const *) add_entries,
+                                          NULL);
+    fail_if(ret != EOK, "Could not add entries to map %s\n");
+
+    talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST(test_autofs_retrieve_keys_by_map)
+{
+    struct sysdb_test_ctx *test_ctx;
+    const char *autofsmapname;
+    errno_t ret;
+    size_t count;
+    struct ldb_message **entries;
+    const int expected = 10;
+
+    ret = setup_sysdb_tests(&test_ctx);
+    fail_if(ret != EOK, "Could not set up the test");
+
+    autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i);
+    fail_if(autofsmapname == NULL, "Out of memory\n");
+
+    ret = sysdb_autofs_entries_by_map(test_ctx, test_ctx->sysdb,
+                                      autofsmapname, &count, &entries);
+    fail_if(ret != EOK, "Cannot get autofs entries for map %s\n",
+            autofsmapname);
+    fail_if(count != expected, "Expected to find %d entries, got %d\n",
+            expected, count);
+    talloc_free(test_ctx);
+}
+END_TEST
+
+START_TEST(test_autofs_key_duplicate)
+{
+    struct sysdb_test_ctx *test_ctx;
+    const char *autofsmapname;
+    const char *autofskey;
+    const char *autofsval;
+    errno_t ret;
+
+    ret = setup_sysdb_tests(&test_ctx);
+    fail_if(ret != EOK, "Could not set up the test");
+
+    autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i);
+    fail_if(autofsmapname == NULL, "Out of memory\n");
+
+    autofskey = talloc_asprintf(test_ctx, "testkey");
+    fail_if(autofskey == NULL, "Out of memory\n");
+
+    autofsval = talloc_asprintf(test_ctx, "testserver:/testval%d", _i);
+    fail_if(autofsval == NULL, "Out of memory\n");
+
+    ret = sysdb_save_autofsentry(test_ctx->sysdb, autofskey,
+                                 autofsval, NULL);
+    fail_if(ret != EOK, "Could not save autofs entry %s", autofskey);
+    talloc_free(test_ctx);
+}
+END_TEST
+
+#if 0
+/*
+ * Disabled due to
+ * https://fedorahosted.org/sssd/ticket/1506
+ */
+START_TEST(test_autofs_get_duplicate_keys)
+{
+    struct sysdb_test_ctx *test_ctx;
+    const char *autofskey;
+    errno_t ret;
+    const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY,
+                            SYSDB_AUTOFS_ENTRY_VALUE,
+                            NULL };
+    size_t count;
+    struct ldb_message **msgs;
+    const int expected = 10;
+
+    ret = setup_sysdb_tests(&test_ctx);
+    fail_if(ret != EOK, "Could not set up the test");
+
+    autofskey = talloc_asprintf(test_ctx, "testkey");
+    fail_if(autofskey == NULL, "Out of memory\n");
+
+    ret = sysdb_search_custom_by_name(test_ctx, test_ctx->sysdb,
+                                      autofskey, AUTOFS_ENTRY_SUBDIR,
+                                      attrs, &count, &msgs);
+    fail_if(ret != EOK, "sysdb search failed\n");
+    fail_if(count != expected, "Expected %d maps with name %s, found %d\n",
+            expected, autofskey, count);
+    talloc_free(test_ctx);
+}
+END_TEST
+#endif
+
+#endif
+
 Suite *create_sysdb_suite(void)
 {
     Suite *s = suite_create("sysdb");
@@ -3829,6 +4044,40 @@ Suite *create_sysdb_suite(void)
 
     suite_add_tcase(s, tc_subdomain);
 
+#ifdef BUILD_AUTOFS
+    TCase *tc_autofs = tcase_create("SYSDB autofs Tests");
+
+    tcase_add_loop_test(tc_subdomain, test_autofs_create_map,
+                        TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10);
+
+    tcase_add_loop_test(tc_subdomain, test_autofs_retrieve_map,
+                        TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10);
+
+    tcase_add_loop_test(tc_subdomain, test_autofs_store_entry_in_map,
+                        TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10);
+
+    tcase_add_loop_test(tc_subdomain, test_autofs_retrieve_keys_by_map,
+                        TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10);
+
+    tcase_add_loop_test(tc_subdomain, test_autofs_delete_map,
+                        TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10);
+
+    tcase_add_loop_test(tc_subdomain, test_autofs_retrieve_map_neg,
+                        TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10);
+
+    tcase_add_loop_test(tc_subdomain, test_autofs_key_duplicate,
+                        TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10);
+
+#if 0
+/*
+ * Disabled due to
+ * https://fedorahosted.org/sssd/ticket/1506
+ */
+    tcase_add_test(tc_subdomain, test_autofs_get_duplicate_keys);
+#endif
+
+    suite_add_tcase(s, tc_autofs);
+#endif
 
     return s;
 }
-- 
1.7.11.4

-------------- next part --------------
>From 1940e2ecc9c5df42e07672f5ffdf48a4fecdf3cc Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Fri, 21 Sep 2012 20:01:28 +0200
Subject: [PATCH 3/5] AUTOFS: Add entry objects below map objects

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

Changes how the new autofs entry objects are handled. Instead of
creating the entry on the cn=autofs,cn=custom level, the entry is
created below the map it belongs to.
---
 src/db/sysdb.h                         |   1 -
 src/db/sysdb_autofs.c                  | 166 ++++++++++++---------------------
 src/db/sysdb_autofs.h                  |  24 +----
 src/db/sysdb_ops.c                     |  19 ----
 src/providers/ldap/sdap_async_autofs.c | 134 +++++++++++++++++---------
 src/tests/sysdb-tests.c                |  48 ++++------
 6 files changed, 172 insertions(+), 220 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 4e458173153cd7c5ea9db5cc8fd9370dc4eb29a3..f74fceec3cf8d332fd613f16ce901a091298b738 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -687,7 +687,6 @@ enum sysdb_member_type {
     SYSDB_MEMBER_GROUP,
     SYSDB_MEMBER_NETGROUP,
     SYSDB_MEMBER_SERVICE,
-    SYSDB_MEMBER_AUTOFSENTRY
 };
 
 int sysdb_add_group_member(struct sysdb_ctx *sysdb,
diff --git a/src/db/sysdb_autofs.c b/src/db/sysdb_autofs.c
index df5f339805d530d106a3a87dbe1d8944aa7b24ed..b3df33f6657ec2668475e0384d10f41920ac7dd0 100644
--- a/src/db/sysdb_autofs.c
+++ b/src/db/sysdb_autofs.c
@@ -24,7 +24,9 @@
 #include "db/sysdb_private.h"
 #include "db/sysdb_autofs.h"
 
-struct ldb_dn *
+#define SYSDB_TMPL_AUTOFS_ENTRY SYSDB_NAME"=%s,"SYSDB_TMPL_CUSTOM
+
+static struct ldb_dn *
 sysdb_autofsmap_dn(TALLOC_CTX *mem_ctx,
                    struct sysdb_ctx *sysdb,
                    const char *map_name)
@@ -33,29 +35,27 @@ sysdb_autofsmap_dn(TALLOC_CTX *mem_ctx,
                            map_name, AUTOFS_MAP_SUBDIR);
 }
 
-struct ldb_dn *
+static struct ldb_dn *
 sysdb_autofsentry_dn(TALLOC_CTX *mem_ctx,
                      struct sysdb_ctx *sysdb,
+                     const char *map_name,
                      const char *entry_name)
 {
-    return sysdb_custom_dn(sysdb, mem_ctx, sysdb->domain->name,
-                           entry_name, AUTOFS_ENTRY_SUBDIR);
-}
-
-static char *
-sysdb_autofsmap_strdn(TALLOC_CTX *mem_ctx,
-                      struct sysdb_ctx *sysdb,
-                      const char *map_name)
-{
+    errno_t ret;
+    char *clean_name;
     struct ldb_dn *dn;
-    char *strdn;
 
-    dn = sysdb_autofsmap_dn(mem_ctx, sysdb, map_name);
-    if (!dn) return NULL;
+    ret = sysdb_dn_sanitize(NULL, entry_name, &clean_name);
+    if (ret != EOK) {
+        return NULL;
+    }
 
-    strdn = talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
-    talloc_free(dn);
-    return strdn;
+    dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_AUTOFS_ENTRY,
+                        clean_name, map_name, AUTOFS_MAP_SUBDIR,
+                        sysdb->domain->name);
+    talloc_free(clean_name);
+
+    return dn;
 }
 
 errno_t
@@ -208,12 +208,15 @@ done:
 
 errno_t
 sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx,
+                       const char *map,
                        const char *key,
                        const char *value,
                        struct sysdb_attrs *attrs)
 {
     errno_t ret;
     TALLOC_CTX *tmp_ctx;
+    struct ldb_message *msg;
+    struct ldb_dn *dn;
 
     DEBUG(SSSDBG_TRACE_FUNC,
           ("Adding autofs entry [%s] - [%s]\n", key, value));
@@ -260,20 +263,48 @@ sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx,
         goto done;
     }
 
-    ret = sysdb_store_custom(sysdb_ctx, key, AUTOFS_ENTRY_SUBDIR, attrs);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_OP_FAILURE, ("sysdb_store_custom failed [%d]: %s\n",
-              ret, strerror(ret)));
+    dn = sysdb_autofsentry_dn(tmp_ctx, sysdb_ctx, map, key);
+    if (!dn) {
+        ret = ENOMEM;
         goto done;
     }
 
-    ret = EOK;
+    msg = ldb_msg_new(tmp_ctx);
+    if (!msg) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    msg->dn = dn;
+    msg->elements = attrs->a;
+    msg->num_elements = attrs->num;
+
+    ret = ldb_add(sysdb_ctx->ldb, msg);
+    ret = sysdb_error_to_errno(ret);
 done:
     talloc_free(tmp_ctx);
     return ret;
 }
 
 errno_t
+sysdb_del_autofsentry(struct sysdb_ctx *sysdb_ctx,
+                      const char *map,
+                      const char *key)
+{
+    struct ldb_dn *dn;
+    errno_t ret;
+
+    dn = sysdb_autofsentry_dn(sysdb_ctx, sysdb_ctx, map, key);
+    if (!dn) {
+        return ENOMEM;
+    }
+
+    ret = sysdb_delete_entry(sysdb_ctx, dn, true);
+    talloc_free(dn);
+    return ret;
+}
+
+errno_t
 sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx,
                             struct sysdb_ctx *sysdb,
                             const char *mapname,
@@ -288,7 +319,7 @@ sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx,
                             NULL };
     size_t count;
     struct ldb_message **msgs;
-    char *mapdn;
+    struct ldb_dn *mapdn;
 
     DEBUG(SSSDBG_TRACE_FUNC, ("Getting entries for map %s\n", mapname));
 
@@ -297,21 +328,21 @@ sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
-    mapdn = sysdb_autofsmap_strdn(tmp_ctx, sysdb, mapname);
+    mapdn = sysdb_autofsmap_dn(tmp_ctx, sysdb, mapname);
     if (!mapdn) {
         ret = ENOMEM;
         goto done;
     }
 
-    filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=%s))",
-                             SYSDB_AUTOFS_ENTRY_OC, SYSDB_MEMBEROF, mapdn);
+    filter = talloc_asprintf(tmp_ctx, "(objectclass=%s)",
+                             SYSDB_AUTOFS_ENTRY_OC);
     if (!filter) {
         ret = ENOMEM;
         goto done;
     }
 
-    ret = sysdb_search_custom(tmp_ctx, sysdb, filter, AUTOFS_ENTRY_SUBDIR,
-                              attrs, &count, &msgs);
+    ret = sysdb_search_entry(tmp_ctx, sysdb, mapdn, LDB_SCOPE_ONELEVEL,
+                             filter, attrs, &count, &msgs);
     if (ret != EOK && ret != ENOENT) {
         DEBUG(SSSDBG_OP_FAILURE, ("sysdb search failed: %d\n", ret));
         goto done;
@@ -333,85 +364,6 @@ done:
 }
 
 errno_t
-sysdb_map_entry_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
-                     const char *entry_dn, char **_name)
-{
-    return sysdb_get_rdn(sysdb, mem_ctx, entry_dn, NULL, _name);
-}
-
-errno_t
-sysdb_autofs_map_update_members(struct sysdb_ctx *sysdb,
-                                const char *mapname,
-                                const char *const *add_entries,
-                                const char *const *del_entries)
-{
-    errno_t ret, sret;
-    int i;
-    bool in_transaction = false;
-
-    TALLOC_CTX *tmp_ctx = talloc_new(NULL);
-    if(!tmp_ctx) {
-        return ENOMEM;
-    }
-
-    ret = sysdb_transaction_start(sysdb);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              ("Failed to start update transaction\n"));
-        goto done;
-    }
-
-    in_transaction = true;
-
-    if (add_entries) {
-        /* Add the all te add_entries to the map */
-        for (i = 0; add_entries[i]; i++) {
-            ret = sysdb_add_group_member(sysdb, mapname, add_entries[i],
-                                         SYSDB_MEMBER_AUTOFSENTRY);
-            if (ret != EOK) {
-                DEBUG(SSSDBG_MINOR_FAILURE,
-                      ("Could not add entry [%s] to map [%s]. "
-                       "Skipping.\n", add_entries[i], mapname));
-                /* Continue on, we should try to finish the rest */
-            }
-        }
-    }
-
-    if (del_entries) {
-        /* Add the all te del_entries to the map */
-        for (i = 0; del_entries[i]; i++) {
-            ret = sysdb_remove_group_member(sysdb, mapname, del_entries[i],
-                                            SYSDB_MEMBER_AUTOFSENTRY);
-            if (ret != EOK) {
-                DEBUG(SSSDBG_MINOR_FAILURE,
-                      ("Could not del entry [%s] to map [%s]. "
-                       "Skipping.\n", del_entries[i], mapname));
-                /* Continue on, we should try to finish the rest */
-            }
-        }
-    }
-
-    ret = sysdb_transaction_commit(sysdb);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
-        goto done;
-    }
-
-    in_transaction = false;
-    ret = EOK;
-
-done:
-    if (in_transaction) {
-        sret = sysdb_transaction_cancel(sysdb);
-        if (sret != EOK) {
-            DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction\n"));
-        }
-    }
-    talloc_free(tmp_ctx);
-    return ret;
-}
-
-errno_t
 sysdb_set_autofsmap_attr(struct sysdb_ctx *sysdb,
                          const char *name,
                          struct sysdb_attrs *attrs,
diff --git a/src/db/sysdb_autofs.h b/src/db/sysdb_autofs.h
index b18d505b4bae9db92af5d573edb427984a581791..616c2cbde2a0c8e269260262cb004502c39f9ac6 100644
--- a/src/db/sysdb_autofs.h
+++ b/src/db/sysdb_autofs.h
@@ -35,16 +35,6 @@
 #define SYSDB_AUTOFS_ENTRY_KEY    "automountKey"
 #define SYSDB_AUTOFS_ENTRY_VALUE  "automountInformation"
 
-struct ldb_dn *
-sysdb_autofsmap_dn(TALLOC_CTX *mem_ctx,
-                   struct sysdb_ctx *sysdb,
-                   const char *map_name);
-
-struct ldb_dn *
-sysdb_autofsentry_dn(TALLOC_CTX *mem_ctx,
-                     struct sysdb_ctx *sysdb,
-                     const char *entry_name);
-
 errno_t
 sysdb_save_autofsmap(struct sysdb_ctx *sysdb_ctx,
                      const char *name,
@@ -65,9 +55,14 @@ sysdb_delete_autofsmap(struct sysdb_ctx *sysdb_ctx,
 
 errno_t
 sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx,
+                       const char *map,
                        const char *key,
                        const char *value,
                        struct sysdb_attrs *attrs);
+errno_t
+sysdb_del_autofsentry(struct sysdb_ctx *sysdb_ctx,
+                      const char *map,
+                      const char *key);
 
 errno_t
 sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx,
@@ -76,15 +71,6 @@ sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx,
                             size_t *_count,
                             struct ldb_message ***_entries);
 
-errno_t sysdb_map_entry_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
-                             const char *entry_dn, char **_name);
-
-errno_t
-sysdb_autofs_map_update_members(struct sysdb_ctx *sysdb,
-                                const char *mapname,
-                                const char *const *add_entries,
-                                const char *const *del_entries);
-
 errno_t
 sysdb_set_autofsmap_attr(struct sysdb_ctx *sysdb,
                          const char *name,
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 33abd06b25f41d893b4d8931929f872803ed8b64..52da27d3cf8dccd547722ef0f9467c77f9aa8ab8 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -1790,21 +1790,6 @@ sysdb_group_membership_mod(struct sysdb_ctx *sysdb,
             ret = ENOMEM;
             goto done;
         }
-    } else if (type == SYSDB_MEMBER_AUTOFSENTRY) {
-        /* FIXME - I don't like autofs specific stuff in sysdb_ops.c
-         * Maybe we should introduce sysdb_common.c ?
-         */
-        member_dn = sysdb_autofsentry_dn(tmp_ctx, sysdb, member);
-        if (!member_dn) {
-            ret = ENOMEM;
-            goto done;
-        }
-
-        group_dn = sysdb_autofsmap_dn(tmp_ctx, sysdb, group);
-        if (!group_dn) {
-            ret = ENOMEM;
-            goto done;
-        }
     } else {
         ret = EINVAL;
         goto done;
@@ -3117,10 +3102,6 @@ errno_t sysdb_remove_attrs(struct sysdb_ctx *sysdb,
     case SYSDB_MEMBER_SERVICE:
         msg->dn = sysdb_svc_dn(sysdb, msg, sysdb->domain->name, name);
         break;
-
-    case SYSDB_MEMBER_AUTOFSENTRY:
-        msg->dn = sysdb_autofsmap_dn(msg, sysdb, name);
-        break;
     }
     if (!msg->dn) {
         ret = ENOMEM;
diff --git a/src/providers/ldap/sdap_async_autofs.c b/src/providers/ldap/sdap_async_autofs.c
index 9c8337d33f4772d1be717999184896e7e6553ce1..8bfabda28c7408cadb9525e14333d25df0967133 100644
--- a/src/providers/ldap/sdap_async_autofs.c
+++ b/src/providers/ldap/sdap_async_autofs.c
@@ -28,6 +28,11 @@
 #include "db/sysdb_autofs.h"
 #include "providers/ldap/ldap_common.h"
 
+enum autofs_map_op {
+    AUTOFS_MAP_OP_ADD,
+    AUTOFS_MAP_OP_DEL
+};
+
 /* ====== Utility functions ====== */
 static const char *
 get_autofs_map_name(struct sysdb_attrs *map, struct sdap_options *opts)
@@ -60,9 +65,11 @@ get_autofs_entry_key(struct sysdb_attrs *entry, struct sdap_options *opts)
 }
 
 static errno_t
-save_autofs_entry(struct sysdb_ctx *sysdb,
-                  struct sdap_options *opts,
-                  struct sysdb_attrs *entry)
+mod_autofs_entry(struct sysdb_ctx *sysdb,
+                 const char *map,
+                 struct sdap_options *opts,
+                 struct sysdb_attrs *entry,
+                 enum autofs_map_op mod_op)
 {
     const char *key;
     const char *value;
@@ -79,20 +86,27 @@ save_autofs_entry(struct sysdb_ctx *sysdb,
     if (el->num_values == 0) return EINVAL;
     else value = (const char *)el->values[0].data;
 
-    ret = sysdb_save_autofsentry(sysdb, key, value, NULL);
-    if (ret != EOK) {
-        return ret;
+    switch (mod_op) {
+    case AUTOFS_MAP_OP_ADD:
+        ret = sysdb_save_autofsentry(sysdb, map, key, value, NULL);
+        break;
+    case AUTOFS_MAP_OP_DEL:
+        ret = sysdb_del_autofsentry(sysdb, map, key);
+        break;
     }
 
-    return EOK;
+    return ret;
 }
 
 static errno_t
-save_autofs_entries(struct sysdb_ctx *sysdb,
-                    struct sdap_options *opts,
-                    char **add_entries,
-                    struct sysdb_attrs **entries,
-                    size_t num_entries)
+mod_autofs_entries(struct sysdb_ctx *sysdb,
+                   struct sdap_options *opts,
+                   const char *map,
+                   char **mod_entries,
+                   struct sysdb_attrs **entries,
+                   size_t num_entries,
+                   enum autofs_map_op mod_op)
+
 {
     errno_t ret, tret;
     const char *key;
@@ -108,8 +122,12 @@ save_autofs_entries(struct sysdb_ctx *sysdb,
     }
     in_transaction = true;
 
-    for (i=0; add_entries[i]; i++) {
+    /* Loop through entry names.. */
+    for (i=0; mod_entries[i]; i++) {
         for (j=0; j < num_entries; j++) {
+            /* get a pointer to sysdb_attrs of an entry that is not
+             * cached, skip names that are not in **entries
+             */
             key = get_autofs_entry_key(entries[j], opts);
             if (!key) {
                 DEBUG(SSSDBG_MINOR_FAILURE,
@@ -117,14 +135,14 @@ save_autofs_entries(struct sysdb_ctx *sysdb,
                 return EINVAL;
             }
 
-            if (strcmp(add_entries[i], key)) {
+            if (strcmp(mod_entries[i], key)) {
                 continue;
             }
 
-            ret = save_autofs_entry(sysdb, opts, entries[j]);
+            ret = mod_autofs_entry(sysdb, map, opts, entries[j], mod_op);
             if (ret != EOK) {
                 DEBUG(SSSDBG_OP_FAILURE,
-                    ("Cannot save autofs entry [%d]: %s. Ignoring.\n",
+                    ("Cannot modify autofs entry [%d]: %s. Ignoring.\n",
                     ret, strerror(ret)));
                 continue;
             }
@@ -154,6 +172,30 @@ done:
 }
 
 static errno_t
+save_autofs_entries(struct sysdb_ctx *sysdb,
+                    struct sdap_options *opts,
+                    const char *map,
+                    char **add_entries,
+                    struct sysdb_attrs **entries,
+                    size_t num_entries)
+{
+    return mod_autofs_entries(sysdb, opts, map, add_entries,
+                              entries, num_entries, AUTOFS_MAP_OP_ADD);
+}
+
+static errno_t
+del_autofs_entries(struct sysdb_ctx *sysdb,
+                   struct sdap_options *opts,
+                   const char *map,
+                   char **add_entries,
+                   struct sysdb_attrs **entries,
+                   size_t num_entries)
+{
+    return mod_autofs_entries(sysdb, opts, map, add_entries,
+                              entries, num_entries, AUTOFS_MAP_OP_DEL);
+}
+
+static errno_t
 save_autofs_map(struct sysdb_ctx *sysdb,
                 struct sss_domain_info *dom,
                 struct sdap_options *opts,
@@ -751,8 +793,9 @@ sdap_autofs_setautomntent_save(struct tevent_req *req)
     errno_t ret, tret;
     bool in_transaction = false;
     TALLOC_CTX *tmp_ctx;
-    struct ldb_message *sysdb_map;
-    struct ldb_message_element *map_members = NULL;
+    struct ldb_message **entries = NULL;
+    size_t count;
+    const char *val;
     char **sysdb_entrylist;
     char **ldap_entrylist;
     char **add_entries;
@@ -782,8 +825,8 @@ sdap_autofs_setautomntent_save(struct tevent_req *req)
         }
     }
 
-    ret = sysdb_get_map_byname(tmp_ctx, state->sysdb, state->mapname,
-                               &sysdb_map);
+    ret = sysdb_autofs_entries_by_map(tmp_ctx, state->sysdb, state->mapname,
+                                      &count, &entries);
     if (ret != EOK && ret != ENOENT) {
         DEBUG(SSSDBG_OP_FAILURE,
               ("cache lookup for the map failed [%d]: %s\n",
@@ -791,30 +834,32 @@ sdap_autofs_setautomntent_save(struct tevent_req *req)
         goto done;
     }
 
-    if (sysdb_map) {
-        map_members = ldb_msg_find_element(sysdb_map, SYSDB_MEMBER);
-    }
-
-    if (!map_members || map_members->num_values == 0) {
+    if (count == 0) {
         /* No map members for this map in sysdb currently */
         sysdb_entrylist = NULL;
     } else {
-        sysdb_entrylist = talloc_array(state, char *, map_members->num_values+1);
+        sysdb_entrylist = talloc_array(state, char *, count+1);
         if (!sysdb_entrylist) {
             ret = ENOMEM;
             goto done;
         }
 
         /* Get a list of the map members by name only */
-        for (i=0; i < map_members->num_values; i++) {
-            ret = sysdb_map_entry_name(sysdb_entrylist, state->sysdb,
-                                      (const char *) map_members->values[i].data,
-                                      &sysdb_entrylist[i]);
-            if (ret != EOK) {
+        for (i=0; i < count; i++) {
+            val = ldb_msg_find_attr_as_string(entries[i],
+                                              SYSDB_AUTOFS_ENTRY_KEY, NULL);
+            if (!val) {
+                DEBUG(SSSDBG_MINOR_FAILURE, ("An entry with no value?\n"));
+                continue;
+            }
+
+            sysdb_entrylist[i] = talloc_strdup(sysdb_entrylist, val);
+            if (!sysdb_entrylist[i]) {
+                ret = ENOMEM;
                 goto done;
             }
         }
-        sysdb_entrylist[map_members->num_values] = NULL;
+        sysdb_entrylist[count] = NULL;
     }
 
     /* Find the differences between the sysdb and LDAP lists
@@ -845,8 +890,8 @@ sdap_autofs_setautomntent_save(struct tevent_req *req)
     /* Create entries that don't exist yet */
     if (add_entries && add_entries[0]) {
         ret = save_autofs_entries(state->sysdb, state->opts,
-                                  add_entries, state->entries,
-                                  state->entries_count);
+                                  state->mapname, add_entries,
+                                  state->entries, state->entries_count);
         if (ret != EOK) {
             DEBUG(SSSDBG_OP_FAILURE,
                   ("Cannot save autofs entries [%d]: %s\n",
@@ -855,17 +900,20 @@ sdap_autofs_setautomntent_save(struct tevent_req *req)
         }
     }
 
-    /* Save the memberships */
-    DEBUG(SSSDBG_TRACE_FUNC, ("Updating memberships for %s\n", state->mapname));
-    ret = sysdb_autofs_map_update_members(state->sysdb, state->mapname,
-                                          (const char *const *) add_entries,
-                                          (const char *const *) del_entries);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("Membership update failed [%d]: %s\n",
-              ret, strerror(ret)));
-        goto done;
+    /* Delete entries that don't exist anymore */
+    if (del_entries && del_entries[0]) {
+        ret = del_autofs_entries(state->sysdb, state->opts,
+                                 state->mapname, del_entries,
+                                 state->entries, state->entries_count);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_OP_FAILURE,
+                  ("Cannot delete autofs entries [%d]: %s\n",
+                  ret, strerror(ret)));
+            goto done;
+        }
     }
 
+
     ret = sysdb_transaction_commit(state->sysdb);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index 429df541966e08051a35c9f7bf1f0e17ddde91ce..ffcef835cb0a9746c461849342592705d4371b6b 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -3704,13 +3704,10 @@ START_TEST(test_autofs_store_entry_in_map)
     errno_t ret;
     int ii;
     const int limit = 10;
-    const char *add_entries[limit+1];
 
     ret = setup_sysdb_tests(&test_ctx);
     fail_if(ret != EOK, "Could not set up the test");
 
-    add_entries[limit] = NULL;
-
     autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i);
     fail_if(autofsmapname == NULL, "Out of memory\n");
 
@@ -3722,18 +3719,11 @@ START_TEST(test_autofs_store_entry_in_map)
         autofsval = talloc_asprintf(test_ctx, "testserver:/testval%d", ii);
         fail_if(autofsval == NULL, "Out of memory\n");
 
-        ret = sysdb_save_autofsentry(test_ctx->sysdb, autofskey,
+        ret = sysdb_save_autofsentry(test_ctx->sysdb, autofsmapname, autofskey,
                                      autofsval, NULL);
         fail_if(ret != EOK, "Could not save autofs entry %s", autofskey);
-
-        add_entries[ii] = autofskey;
     }
 
-    ret = sysdb_autofs_map_update_members(test_ctx->sysdb, autofsmapname,
-                                          (const char *const *) add_entries,
-                                          NULL);
-    fail_if(ret != EOK, "Could not add entries to map %s\n");
-
     talloc_free(test_ctx);
 }
 END_TEST
@@ -3783,18 +3773,13 @@ START_TEST(test_autofs_key_duplicate)
     autofsval = talloc_asprintf(test_ctx, "testserver:/testval%d", _i);
     fail_if(autofsval == NULL, "Out of memory\n");
 
-    ret = sysdb_save_autofsentry(test_ctx->sysdb, autofskey,
+    ret = sysdb_save_autofsentry(test_ctx->sysdb, autofsmapname, autofskey,
                                  autofsval, NULL);
     fail_if(ret != EOK, "Could not save autofs entry %s", autofskey);
     talloc_free(test_ctx);
 }
 END_TEST
 
-#if 0
-/*
- * Disabled due to
- * https://fedorahosted.org/sssd/ticket/1506
- */
 START_TEST(test_autofs_get_duplicate_keys)
 {
     struct sysdb_test_ctx *test_ctx;
@@ -3805,6 +3790,8 @@ START_TEST(test_autofs_get_duplicate_keys)
                             NULL };
     size_t count;
     struct ldb_message **msgs;
+    struct ldb_dn *dn;
+    const char *filter;
     const int expected = 10;
 
     ret = setup_sysdb_tests(&test_ctx);
@@ -3813,18 +3800,23 @@ START_TEST(test_autofs_get_duplicate_keys)
     autofskey = talloc_asprintf(test_ctx, "testkey");
     fail_if(autofskey == NULL, "Out of memory\n");
 
-    ret = sysdb_search_custom_by_name(test_ctx, test_ctx->sysdb,
-                                      autofskey, AUTOFS_ENTRY_SUBDIR,
-                                      attrs, &count, &msgs);
-    fail_if(ret != EOK, "sysdb search failed\n");
-    fail_if(count != expected, "Expected %d maps with name %s, found %d\n",
-            expected, autofskey, count);
+    filter = talloc_asprintf(test_ctx, "(&(objectclass=%s)(%s=%s))",
+                             SYSDB_AUTOFS_ENTRY_OC, SYSDB_NAME, autofskey);
+    fail_if(filter == NULL, "Out of memory\n");
+
+    dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE,
+                        AUTOFS_MAP_SUBDIR, test_ctx->sysdb->domain->name);
+    fail_if(dn == NULL, "Out of memory\n");
+
+    ret = sysdb_search_entry(test_ctx, test_ctx->sysdb, dn, LDB_SCOPE_SUBTREE,
+                             filter, attrs, &count, &msgs);
+    fail_if(count != expected, "Found %d entries with name %s, expected %d\n",
+            count, autofskey, expected);
     talloc_free(test_ctx);
 }
 END_TEST
-#endif
 
-#endif
+#endif /* BUILD_AUTOFS */
 
 Suite *create_sysdb_suite(void)
 {
@@ -4068,13 +4060,7 @@ Suite *create_sysdb_suite(void)
     tcase_add_loop_test(tc_subdomain, test_autofs_key_duplicate,
                         TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10);
 
-#if 0
-/*
- * Disabled due to
- * https://fedorahosted.org/sssd/ticket/1506
- */
     tcase_add_test(tc_subdomain, test_autofs_get_duplicate_keys);
-#endif
 
     suite_add_tcase(s, tc_autofs);
 #endif
-- 
1.7.11.4

-------------- next part --------------
>From fcec72e71278a8cdb4a754ac680f45b14094f3af Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Sun, 23 Sep 2012 17:18:50 +0200
Subject: [PATCH 4/5] AUTOFS: Use both key and value in entry RDN

This patch switches from using just key in the RDN to using both key and
value. That is neccessary to allow multiple direct mounts in a single
map.
---
 src/db/sysdb_autofs.c                  | 48 +++++++++++++++++++++++++++-------
 src/db/sysdb_autofs.h                  |  3 ++-
 src/providers/ldap/sdap_async_autofs.c | 12 +++++++--
 src/tests/sysdb-tests.c                |  2 +-
 4 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/src/db/sysdb_autofs.c b/src/db/sysdb_autofs.c
index b3df33f6657ec2668475e0384d10f41920ac7dd0..bf4e9b172fba9616ebda875fb9b6b9475d405132 100644
--- a/src/db/sysdb_autofs.c
+++ b/src/db/sysdb_autofs.c
@@ -39,22 +39,42 @@ static struct ldb_dn *
 sysdb_autofsentry_dn(TALLOC_CTX *mem_ctx,
                      struct sysdb_ctx *sysdb,
                      const char *map_name,
-                     const char *entry_name)
+                     const char *entry_name,
+                     const char *entry_value)
 {
     errno_t ret;
+    TALLOC_CTX *tmp_ctx;
     char *clean_name;
-    struct ldb_dn *dn;
+    char *clean_value;
+    const char *rdn;
+    struct ldb_dn *dn = NULL;
 
-    ret = sysdb_dn_sanitize(NULL, entry_name, &clean_name);
-    if (ret != EOK) {
+    tmp_ctx = talloc_new(NULL);
+    if (!tmp_ctx) {
         return NULL;
     }
 
+    ret = sysdb_dn_sanitize(tmp_ctx, entry_name, &clean_name);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    ret = sysdb_dn_sanitize(tmp_ctx, entry_value, &clean_value);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    rdn = talloc_asprintf(tmp_ctx, "%s%s", clean_name, clean_value);
+    if (!rdn) {
+        goto done;
+    }
+
     dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_AUTOFS_ENTRY,
-                        clean_name, map_name, AUTOFS_MAP_SUBDIR,
+                        rdn, map_name, AUTOFS_MAP_SUBDIR,
                         sysdb->domain->name);
-    talloc_free(clean_name);
 
+done:
+    talloc_free(tmp_ctx);
     return dn;
 }
 
@@ -217,6 +237,7 @@ sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx,
     TALLOC_CTX *tmp_ctx;
     struct ldb_message *msg;
     struct ldb_dn *dn;
+    const char *name;
 
     DEBUG(SSSDBG_TRACE_FUNC,
           ("Adding autofs entry [%s] - [%s]\n", key, value));
@@ -256,14 +277,20 @@ sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx,
         goto done;
     }
 
-    ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, key);
+    name = talloc_asprintf(tmp_ctx, "%s%s", key, value);
+    if (!name) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, ("Could not set name attribute [%d]: %s\n",
               ret, strerror(ret)));
         goto done;
     }
 
-    dn = sysdb_autofsentry_dn(tmp_ctx, sysdb_ctx, map, key);
+    dn = sysdb_autofsentry_dn(tmp_ctx, sysdb_ctx, map, key, value);
     if (!dn) {
         ret = ENOMEM;
         goto done;
@@ -289,12 +316,13 @@ done:
 errno_t
 sysdb_del_autofsentry(struct sysdb_ctx *sysdb_ctx,
                       const char *map,
-                      const char *key)
+                      const char *key,
+                      const char *value)
 {
     struct ldb_dn *dn;
     errno_t ret;
 
-    dn = sysdb_autofsentry_dn(sysdb_ctx, sysdb_ctx, map, key);
+    dn = sysdb_autofsentry_dn(sysdb_ctx, sysdb_ctx, map, key, value);
     if (!dn) {
         return ENOMEM;
     }
diff --git a/src/db/sysdb_autofs.h b/src/db/sysdb_autofs.h
index 616c2cbde2a0c8e269260262cb004502c39f9ac6..c4b5253ab4e5be9c600d80a69c54bed2958b3a2d 100644
--- a/src/db/sysdb_autofs.h
+++ b/src/db/sysdb_autofs.h
@@ -62,7 +62,8 @@ sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx,
 errno_t
 sysdb_del_autofsentry(struct sysdb_ctx *sysdb_ctx,
                       const char *map,
-                      const char *key);
+                      const char *key,
+                      const char *value);
 
 errno_t
 sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx,
diff --git a/src/providers/ldap/sdap_async_autofs.c b/src/providers/ldap/sdap_async_autofs.c
index 8bfabda28c7408cadb9525e14333d25df0967133..fdffd1d5a270035831be7ac86139afc8eb57a2c5 100644
--- a/src/providers/ldap/sdap_async_autofs.c
+++ b/src/providers/ldap/sdap_async_autofs.c
@@ -91,7 +91,7 @@ mod_autofs_entry(struct sysdb_ctx *sysdb,
         ret = sysdb_save_autofsentry(sysdb, map, key, value, NULL);
         break;
     case AUTOFS_MAP_OP_DEL:
-        ret = sysdb_del_autofsentry(sysdb, map, key);
+        ret = sysdb_del_autofsentry(sysdb, map, key, value);
         break;
     }
 
@@ -794,6 +794,7 @@ sdap_autofs_setautomntent_save(struct tevent_req *req)
     bool in_transaction = false;
     TALLOC_CTX *tmp_ctx;
     struct ldb_message **entries = NULL;
+    struct sysdb_attrs **entries_attrs;
     size_t count;
     const char *val;
     char **sysdb_entrylist;
@@ -902,9 +903,16 @@ sdap_autofs_setautomntent_save(struct tevent_req *req)
 
     /* Delete entries that don't exist anymore */
     if (del_entries && del_entries[0]) {
+        ret = sysdb_msg2attrs(tmp_ctx, count, entries, &entries_attrs);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_OP_FAILURE,
+                  ("sysdb_msg2attrs failed: [%d]: %s\n", ret, strerror(ret)));
+            goto done;
+        }
+
         ret = del_autofs_entries(state->sysdb, state->opts,
                                  state->mapname, del_entries,
-                                 state->entries, state->entries_count);
+                                 entries_attrs, count);
         if (ret != EOK) {
             DEBUG(SSSDBG_OP_FAILURE,
                   ("Cannot delete autofs entries [%d]: %s\n",
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index ffcef835cb0a9746c461849342592705d4371b6b..83628af877c7114a42147d540e0b3d50482ec4e8 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -3801,7 +3801,7 @@ START_TEST(test_autofs_get_duplicate_keys)
     fail_if(autofskey == NULL, "Out of memory\n");
 
     filter = talloc_asprintf(test_ctx, "(&(objectclass=%s)(%s=%s))",
-                             SYSDB_AUTOFS_ENTRY_OC, SYSDB_NAME, autofskey);
+                             SYSDB_AUTOFS_ENTRY_OC, SYSDB_AUTOFS_ENTRY_KEY, autofskey);
     fail_if(filter == NULL, "Out of memory\n");
 
     dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE,
-- 
1.7.11.4

-------------- next part --------------
>From 2fc6f412ab0f369d40caa303fedf1d0f7344d37d Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Sun, 23 Sep 2012 18:37:04 +0200
Subject: [PATCH 5/5] AUTOFS: convert the existing autofs entries during a
 sysdb upgrade

---
 src/db/sysdb.c         |   7 +++
 src/db/sysdb_private.h |   4 +-
 src/db/sysdb_upgrade.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+), 1 deletion(-)

diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index 3354cc43ee30d1d236e7e8782644e817e34d3ec1..e949cafdc5dbc1d9c38f0940de3f0bb0e1b34e65 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -1097,6 +1097,13 @@ int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
                 }
             }
 
+            if (strcmp(version, SYSDB_VERSION_0_11) == 0) {
+                ret = sysdb_upgrade_11(sysdb, &version);
+                if (ret != EOK) {
+                    goto done;
+                }
+            }
+
             /* The version should now match SYSDB_VERSION.
              * If not, it means we didn't match any of the
              * known older versions. The DB might be
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
index 0fb7316b48b5c53be0198f719673080275c34b81..8c9aea5bf33f242357e1da26ad9f09baa74b3fc1 100644
--- a/src/db/sysdb_private.h
+++ b/src/db/sysdb_private.h
@@ -23,6 +23,7 @@
 #ifndef __INT_SYS_DB_H__
 #define __INT_SYS_DB_H__
 
+#define SYSDB_VERSION_0_12 "0.12"
 #define SYSDB_VERSION_0_11 "0.11"
 #define SYSDB_VERSION_0_10 "0.10"
 #define SYSDB_VERSION_0_9 "0.9"
@@ -35,7 +36,7 @@
 #define SYSDB_VERSION_0_2 "0.2"
 #define SYSDB_VERSION_0_1 "0.1"
 
-#define SYSDB_VERSION SYSDB_VERSION_0_11
+#define SYSDB_VERSION SYSDB_VERSION_0_12
 
 #define SYSDB_BASE_LDIF \
      "dn: @ATTRIBUTES\n" \
@@ -106,6 +107,7 @@ int sysdb_upgrade_07(struct sysdb_ctx *sysdb, const char **ver);
 int sysdb_upgrade_08(struct sysdb_ctx *sysdb, const char **ver);
 int sysdb_upgrade_09(struct sysdb_ctx *sysdb, const char **ver);
 int sysdb_upgrade_10(struct sysdb_ctx *sysdb, const char **ver);
+int sysdb_upgrade_11(struct sysdb_ctx *sysdb, const char **ver);
 
 int add_string(struct ldb_message *msg, int flags,
                const char *attr, const char *value);
diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c
index 43eff7a0fc577cdd90c25e43b59556fb47c97e71..87abd350589f27bbe023642f45ae3d005adac779 100644
--- a/src/db/sysdb_upgrade.c
+++ b/src/db/sysdb_upgrade.c
@@ -24,6 +24,7 @@
 
 #include "util/util.h"
 #include "db/sysdb_private.h"
+#include "db/sysdb_autofs.h"
 
 static int finish_upgrade(int result, struct ldb_context *ldb,
                           const char *next_ver, const char **ver)
@@ -1316,3 +1317,136 @@ done:
     talloc_free(tmp_ctx);
     return ret;
 }
+
+int sysdb_upgrade_11(struct sysdb_ctx *sysdb, const char **ver)
+{
+    TALLOC_CTX *tmp_ctx;
+    errno_t ret;
+    struct ldb_result *res;
+    struct ldb_message *msg;
+    struct ldb_message *entry;
+    const char *key;
+    const char *value;
+    struct ldb_message_element *memberof_el;
+    struct ldb_dn *memberof_dn;
+    struct ldb_dn *basedn;
+    const struct ldb_val *val;
+    const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY,
+                            SYSDB_AUTOFS_ENTRY_VALUE,
+                            SYSDB_MEMBEROF,
+                            NULL };
+    size_t i, j;
+
+    tmp_ctx = talloc_new(NULL);
+    if (!tmp_ctx) {
+        return ENOMEM;
+    }
+
+    basedn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE,
+                            AUTOFS_ENTRY_SUBDIR, sysdb->domain->name);
+    if (basedn == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    DEBUG(SSSDBG_CRIT_FAILURE,
+          ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_12));
+
+    ret = ldb_transaction_start(sysdb->ldb);
+    if (ret != LDB_SUCCESS) {
+        ret = EIO;
+        goto done;
+    }
+
+    ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE,
+                     attrs, "(objectClass=%s)", SYSDB_AUTOFS_ENTRY_OC);
+    if (ret != LDB_SUCCESS) {
+        ret = EIO;
+        goto done;
+    }
+
+    DEBUG(SSSDBG_TRACE_LIBS, ("Found %d autofs entries\n", res->count));
+
+    for (i = 0; i < res->count; i++) {
+        entry = res->msgs[i];
+        key = ldb_msg_find_attr_as_string(entry,
+                                          SYSDB_AUTOFS_ENTRY_KEY, NULL);
+        value = ldb_msg_find_attr_as_string(entry,
+                                            SYSDB_AUTOFS_ENTRY_VALUE, NULL);
+        memberof_el = ldb_msg_find_element(entry, SYSDB_MEMBEROF);
+
+        if (key && value && memberof_el) {
+            for (j = 0; j < memberof_el->num_values; j++) {
+                memberof_dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb,
+                                                  &(memberof_el->values[j]));
+                if (!memberof_dn) {
+                    DEBUG(SSSDBG_OP_FAILURE, ("Cannot convert memberof into DN, skipping\n"));
+                    continue;
+                }
+
+                val = ldb_dn_get_rdn_val(memberof_dn);
+                if (!val) {
+                    DEBUG(SSSDBG_OP_FAILURE, ("Cannot get map name from map DN\n"));
+                    continue;
+                }
+
+                ret = sysdb_save_autofsentry(sysdb, (const char *) val->data,
+                                             key, value, NULL);
+                if (ret != EOK) {
+                    DEBUG(SSSDBG_OP_FAILURE,
+                          ("Cannot save autofs entry [%s]-[%s] into map %s\n",
+                           key, value, val->data));
+                    continue;
+                }
+            }
+
+        }
+
+        /* Delete the old entry if it was either processed or incomplete */
+        DEBUG(SSSDBG_TRACE_LIBS, ("Deleting [%s]\n",
+              ldb_dn_get_linearized(entry->dn)));
+
+        ret = ldb_delete(sysdb->ldb, entry->dn);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_OP_FAILURE, ("Cannot delete old autofs entry %s\n",
+                  ldb_dn_get_linearized(entry->dn)));
+            continue;
+        }
+    }
+
+    /* conversion done, upgrade version number */
+    msg = ldb_msg_new(tmp_ctx);
+    if (!msg) {
+        ret = ENOMEM;
+        goto done;
+    }
+    msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE);
+    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_12);
+    if (ret != LDB_SUCCESS) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = ldb_modify(sysdb->ldb, msg);
+    if (ret != LDB_SUCCESS) {
+        ret = sysdb_error_to_errno(ret);
+        goto done;
+    }
+
+    ret = EOK;
+done:
+    ret = finish_upgrade(ret, sysdb->ldb, SYSDB_VERSION_0_12, ver);
+    talloc_free(tmp_ctx);
+    return ret;
+}
-- 
1.7.11.4



More information about the sssd-devel mailing list