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 001424a6c0ffe598d5e7ca016d7a03fae79ba822..67c08a6085f659f49de367383add8e8065c26765 100644 (file)
@@ -42,6 +42,59 @@ static int dbwrap_fallback_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
        return 0;
 }
 
+/*
+ * Fall back using fetch if no genuine parse operation is provided
+ */
+
+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)
+{
+#ifdef CLUSTER_SUPPORT
+       const char *sockname = lp_ctdbd_socket();
+
+       if(!sockname || !*sockname) {
+               sockname = CTDB_PATH;
+       }
+
+       if (lp_clustering() && socket_exist(sockname)) {
+               const char *partname;
+               /* ctdb 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, "ctdb", partname, True)) {
+                       return false;
+               }
+       }
+#endif
+       return true;
+}
+
+/**
+ * open a database
+ */
 struct db_context *db_open(TALLOC_CTX *mem_ctx,
                           const char *name,
                           int hash_size, int tdb_flags,
@@ -57,8 +110,15 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
                sockname = CTDB_PATH;
        }
 
-       if (lp_clustering() && socket_exist(sockname)) {
+       if (lp_clustering()) {
                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) {
@@ -73,8 +133,10 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
                        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;
                        }
                }
        }
@@ -89,16 +151,19 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
        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;
        }
@@ -107,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;
        }
@@ -123,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));
+}
+