Fix bug #6195 - Migrating from 3.0.x to 3.3.x can fail to update passdb.tdb correctly...
[ira/wip.git] / source3 / lib / dbwrap.c
index b498c46615c50554bfe0cc29430619cc7f97c227..67c08a6085f659f49de367383add8e8065c26765 100644 (file)
@@ -42,33 +42,40 @@ static int dbwrap_fallback_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
        return 0;
 }
 
-/**
- * If you need transaction support use db_open_trans()
+/*
+ * Fall back using fetch if no genuine parse operation is provided
  */
-struct db_context *db_open(TALLOC_CTX *mem_ctx,
-                          const char *name,
-                          int hash_size, int tdb_flags,
-                          int open_flags, mode_t mode)
+
+static int dbwrap_fallback_parse_record(struct db_context *db, TDB_DATA key,
+                                       int (*parser)(TDB_DATA key,
+                                                     TDB_DATA data,
+                                                     void *private_data),
+                                       void *private_data)
+{
+       TDB_DATA data;
+       int res;
+
+       res = db->fetch(db, talloc_tos(), key, &data);
+       if (res != 0) {
+               return res;
+       }
+
+       res = parser(key, data, private_data);
+       TALLOC_FREE(data.dptr);
+       return res;
+}
+
+bool db_is_local(const char *name)
 {
-       struct db_context *result = NULL;
 #ifdef CLUSTER_SUPPORT
        const char *sockname = lp_ctdbd_socket();
-#endif
 
-#ifdef CLUSTER_SUPPORT
        if(!sockname || !*sockname) {
                sockname = CTDB_PATH;
        }
 
-       if (lp_clustering()) {
+       if (lp_clustering() && socket_exist(sockname)) {
                const char *partname;
-
-               if (!socket_exist(sockname)) {
-                       DEBUG(1, ("ctdb socket does not exist - is ctdb not "
-                                 "running?\n"));
-                       return NULL;
-               }
-
                /* ctdb only wants the file part of the name */
                partname = strrchr(name, '/');
                if (partname) {
@@ -78,49 +85,26 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
                }
                /* allow ctdb for individual databases to be disabled */
                if (lp_parm_bool(-1, "ctdb", partname, True)) {
-                       result = db_open_ctdb(mem_ctx, partname, hash_size,
-                                             tdb_flags, open_flags, mode);
-                       if (result == NULL) {
-                               DEBUG(0,("failed to attach to ctdb %s\n",
-                                        partname));
-                               return NULL;
-                       }
+                       return false;
                }
        }
-
 #endif
-
-       if (result == NULL) {
-               result = db_open_tdb(mem_ctx, name, hash_size,
-                                    tdb_flags, open_flags, mode);
-       }
-
-       if ((result != NULL) && (result->fetch == NULL)) {
-               result->fetch = dbwrap_fallback_fetch;
-       }
-
-       return result;
+       return true;
 }
 
 /**
- * If you use this you can only modify with a transaction
+ * open a database
  */
-struct db_context *db_open_trans(TALLOC_CTX *mem_ctx,
-                                const char *name,
-                                int hash_size, int tdb_flags,
-                                int open_flags, mode_t mode)
+struct db_context *db_open(TALLOC_CTX *mem_ctx,
+                          const char *name,
+                          int hash_size, int tdb_flags,
+                          int open_flags, mode_t mode)
 {
-       bool use_tdb2 = lp_parm_bool(-1, "dbwrap", "use_tdb2", false);
+       struct db_context *result = NULL;
 #ifdef CLUSTER_SUPPORT
        const char *sockname = lp_ctdbd_socket();
 #endif
 
-       if (tdb_flags & TDB_CLEAR_IF_FIRST) {
-               DEBUG(0,("db_open_trans: called with TDB_CLEAR_IF_FIRST: %s\n",
-                        name));
-               smb_panic("db_open_trans: called with TDB_CLEAR_IF_FIRST");
-       }
-
 #ifdef CLUSTER_SUPPORT
        if(!sockname || !*sockname) {
                sockname = CTDB_PATH;
@@ -143,47 +127,43 @@ struct db_context *db_open_trans(TALLOC_CTX *mem_ctx,
                        partname = name;
                }
                /* allow ctdb for individual databases to be disabled */
-               if (lp_parm_bool(-1, "ctdb", partname, true)) {
-                       struct db_context *result = NULL;
+               if (lp_parm_bool(-1, "ctdb", partname, True)) {
                        result = db_open_ctdb(mem_ctx, partname, hash_size,
                                              tdb_flags, open_flags, mode);
                        if (result == NULL) {
                                DEBUG(0,("failed to attach to ctdb %s\n",
                                         partname));
-                               smb_panic("failed to attach to a ctdb "
-                                         "database");
+                               if (errno == 0) {
+                                       errno = EIO;
+                               }
+                               return NULL;
                        }
-                       return result;
                }
        }
+
 #endif
 
-       if (use_tdb2) {
-               const char *partname;
-               /* tdb2 only wants the file part of the name */
-               partname = strrchr(name, '/');
-               if (partname) {
-                       partname++;
-               } else {
-                       partname = name;
-               }
-               /* allow ctdb for individual databases to be disabled */
-               if (lp_parm_bool(-1, "tdb2", partname, true)) {
-                       return db_open_tdb2(mem_ctx, partname, hash_size,
-                                           tdb_flags, open_flags, mode);
-               }
+       if (result == NULL) {
+               result = db_open_tdb(mem_ctx, name, hash_size,
+                                    tdb_flags, open_flags, mode);
        }
 
-       return db_open_tdb(mem_ctx, name, hash_size,
-                          tdb_flags, open_flags, mode);
+       if ((result != NULL) && (result->fetch == NULL)) {
+               result->fetch = dbwrap_fallback_fetch;
+       }
+       if ((result != NULL) && (result->parse_record == NULL)) {
+               result->parse_record = dbwrap_fallback_parse_record;
+       }
+
+       return result;
 }
 
-NTSTATUS dbwrap_delete_bystring(struct db_context *db, const char *key)
+NTSTATUS dbwrap_delete(struct db_context *db, TDB_DATA key)
 {
        struct db_record *rec;
        NTSTATUS status;
 
-       rec = db->fetch_locked(db, talloc_tos(), string_term_tdb_data(key));
+       rec = db->fetch_locked(db, talloc_tos(), key);
        if (rec == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -192,13 +172,13 @@ NTSTATUS dbwrap_delete_bystring(struct db_context *db, const char *key)
        return status;
 }
 
-NTSTATUS dbwrap_store_bystring(struct db_context *db, const char *key,
-                              TDB_DATA data, int flags)
+NTSTATUS dbwrap_store(struct db_context *db, TDB_DATA key,
+                     TDB_DATA data, int flags)
 {
        struct db_record *rec;
        NTSTATUS status;
 
-       rec = db->fetch_locked(db, talloc_tos(), string_term_tdb_data(key));
+       rec = db->fetch_locked(db, talloc_tos(), key);
        if (rec == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -208,14 +188,32 @@ NTSTATUS dbwrap_store_bystring(struct db_context *db, const char *key,
        return status;
 }
 
-TDB_DATA dbwrap_fetch_bystring(struct db_context *db, TALLOC_CTX *mem_ctx,
-                              const char *key)
+TDB_DATA dbwrap_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
+                     TDB_DATA key)
 {
        TDB_DATA result;
 
-       if (db->fetch(db, mem_ctx, string_term_tdb_data(key), &result) == -1) {
+       if (db->fetch(db, mem_ctx, key, &result) == -1) {
                return make_tdb_data(NULL, 0);
        }
 
        return result;
 }
+
+NTSTATUS dbwrap_delete_bystring(struct db_context *db, const char *key)
+{
+       return dbwrap_delete(db, string_term_tdb_data(key));
+}
+
+NTSTATUS dbwrap_store_bystring(struct db_context *db, const char *key,
+                              TDB_DATA data, int flags)
+{
+       return dbwrap_store(db, string_term_tdb_data(key), data, flags);
+}
+
+TDB_DATA dbwrap_fetch_bystring(struct db_context *db, TALLOC_CTX *mem_ctx,
+                              const char *key)
+{
+       return dbwrap_fetch(db, mem_ctx, string_term_tdb_data(key));
+}
+