pdb_samba_dsdb: implement pdb_samba_dsdb_enum_trusteddoms()
[bbaumbach/samba-autobuild/.git] / source3 / passdb / pdb_tdb.c
index da61e48a99d3bb48f86423b32db1d3ffa75ac93a..6f3dda6e2291965dda4c98f36660c1016e92c8db 100644 (file)
  */
 
 #include "includes.h"
-#include "dbwrap.h"
+#include "system/filesys.h"
+#include "passdb.h"
+#include "dbwrap/dbwrap.h"
+#include "dbwrap/dbwrap_open.h"
 #include "../libcli/security/security.h"
+#include "util_tdb.h"
+#include "passdb/pdb_tdb.h"
 
 #if 0 /* when made a module use this */
 
@@ -54,6 +59,7 @@ static int tdbsam_debug_level = DBGC_ALL;
 
 static struct db_context *db_sam;
 static char *tdbsam_filename;
+static bool map_builtin;
 
 struct tdbsam_convert_state {
        int32_t from;
@@ -68,11 +74,15 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv)
        TDB_DATA data;
        NTSTATUS status;
        bool ret;
+       TDB_DATA key;
+       TDB_DATA value;
 
-       if (rec->key.dsize < USERPREFIX_LEN) {
+       key = dbwrap_record_get_key(rec);
+
+       if (key.dsize < USERPREFIX_LEN) {
                return 0;
        }
-       if (strncmp((char *)rec->key.dptr, USERPREFIX, USERPREFIX_LEN) != 0) {
+       if (strncmp((char *)key.dptr, USERPREFIX, USERPREFIX_LEN) != 0) {
                return 0;
        }
 
@@ -84,33 +94,35 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv)
        }
 
        DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) "
-                 "(version:%d)\n", rec->key.dptr, state->from));
+                 "(version:%d)\n", (char *)key.dptr, state->from));
+
+       value = dbwrap_record_get_value(rec);
 
        switch (state->from) {
        case 0:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V0,
-                                           (uint8 *)rec->value.dptr,
-                                           rec->value.dsize);
+                                           (uint8_t *)value.dptr,
+                                           value.dsize);
                break;
        case 1:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V1,
-                                           (uint8 *)rec->value.dptr,
-                                           rec->value.dsize);
+                                           (uint8_t *)value.dptr,
+                                           value.dsize);
                break;
        case 2:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V2,
-                                           (uint8 *)rec->value.dptr,
-                                           rec->value.dsize);
+                                           (uint8_t *)value.dptr,
+                                           value.dsize);
                break;
        case 3:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V3,
-                                           (uint8 *)rec->value.dptr,
-                                           rec->value.dsize);
+                                           (uint8_t *)value.dptr,
+                                           value.dsize);
                break;
        case 4:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V4,
-                                           (uint8 *)rec->value.dptr,
-                                           rec->value.dsize);
+                                           (uint8_t *)value.dptr,
+                                           value.dsize);
                break;
        default:
                /* unknown tdbsam version */
@@ -118,7 +130,7 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv)
        }
        if (!ret) {
                DEBUG(0,("tdbsam_convert: Bad struct samu entry returned "
-                        "from TDB (key:%s) (version:%d)\n", rec->key.dptr,
+                        "from TDB (key:%s) (version:%d)\n", (char *)key.dptr,
                         state->from));
                TALLOC_FREE(user);
                state->success = false;
@@ -135,7 +147,7 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv)
                return -1;
        }
 
-       status = rec->store(rec, data, TDB_MODIFY);
+       status = dbwrap_record_store(rec, data, TDB_MODIFY);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("Could not store the new record: %s\n",
                          nt_errstr(status)));
@@ -160,14 +172,20 @@ static int backup_copy_fn(struct db_record *orig_rec, void *state)
        struct tdbsam_backup_state *bs = (struct tdbsam_backup_state *)state;
        struct db_record *new_rec;
        NTSTATUS status;
+       TDB_DATA key;
+       TDB_DATA value;
+
+       key = dbwrap_record_get_key(orig_rec);
 
-       new_rec = bs->new_db->fetch_locked(bs->new_db, talloc_tos(), orig_rec->key);
+       new_rec = dbwrap_fetch_locked(bs->new_db, talloc_tos(), key);
        if (new_rec == NULL) {
                bs->success = false;
                return 1;
        }
 
-       status = new_rec->store(new_rec, orig_rec->value, TDB_INSERT);
+       value = dbwrap_record_get_value(orig_rec);
+
+       status = dbwrap_record_store(new_rec, value, TDB_INSERT);
 
        TALLOC_FREE(new_rec);
 
@@ -193,7 +211,7 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
        struct db_context *tmp_db = NULL;
        struct db_context *orig_db = *pp_db;
        struct tdbsam_backup_state bs;
-       int ret;
+       NTSTATUS status;
 
        tmp_fname = talloc_asprintf(frame, "%s.tmp", dbname);
        if (!tmp_fname) {
@@ -207,7 +225,8 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
         * it to stay around after we return from here. */
 
        tmp_db = db_open(NULL, tmp_fname, 0,
-                               TDB_DEFAULT, O_CREAT|O_RDWR, 0600);
+                        TDB_DEFAULT, O_CREAT|O_RDWR, 0600,
+                        DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
        if (tmp_db == NULL) {
                DEBUG(0, ("tdbsam_convert_backup: Failed to create backup TDB passwd "
                          "[%s]\n", tmp_fname));
@@ -215,16 +234,16 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
                return false;
        }
 
-       if (orig_db->transaction_start(orig_db) != 0) {
+       if (dbwrap_transaction_start(orig_db) != 0) {
                DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (1)\n"));
                unlink(tmp_fname);
                TALLOC_FREE(tmp_db);
                TALLOC_FREE(frame);
                return false;
        }
-       if (tmp_db->transaction_start(tmp_db) != 0) {
+       if (dbwrap_transaction_start(tmp_db) != 0) {
                DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (2)\n"));
-               orig_db->transaction_cancel(orig_db);
+               dbwrap_transaction_cancel(orig_db);
                unlink(tmp_fname);
                TALLOC_FREE(tmp_db);
                TALLOC_FREE(frame);
@@ -234,8 +253,8 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
        bs.new_db = tmp_db;
        bs.success = true;
 
-        ret = orig_db->traverse(orig_db, backup_copy_fn, (void *)&bs);
-        if (ret < 0) {
+        status = dbwrap_traverse(orig_db, backup_copy_fn, (void *)&bs, NULL);
+        if (!NT_STATUS_IS_OK(status)) {
                 DEBUG(0, ("tdbsam_convert_backup: traverse failed\n"));
                 goto cancel;
         }
@@ -245,10 +264,10 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
                goto cancel;
        }
 
-       if (orig_db->transaction_commit(orig_db) != 0) {
+       if (dbwrap_transaction_commit(orig_db) != 0) {
                smb_panic("tdbsam_convert_backup: orig commit failed\n");
        }
-       if (tmp_db->transaction_commit(tmp_db) != 0) {
+       if (dbwrap_transaction_commit(tmp_db) != 0) {
                smb_panic("tdbsam_convert_backup: orig commit failed\n");
        }
 
@@ -273,7 +292,8 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
        /* re-open the converted TDB */
 
        orig_db = db_open(NULL, dbname, 0,
-                         TDB_DEFAULT, O_CREAT|O_RDWR, 0600);
+                         TDB_DEFAULT, O_CREAT|O_RDWR, 0600,
+                         DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
        if (orig_db == NULL) {
                DEBUG(0, ("tdbsam_convert_backup: Failed to re-open "
                          "converted passdb TDB [%s]\n", dbname));
@@ -289,11 +309,11 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
 
   cancel:
 
-       if (orig_db->transaction_cancel(orig_db) != 0) {
+       if (dbwrap_transaction_cancel(orig_db) != 0) {
                smb_panic("tdbsam_convert: transaction_cancel failed");
        }
 
-       if (tmp_db->transaction_cancel(tmp_db) != 0) {
+       if (dbwrap_transaction_cancel(tmp_db) != 0) {
                smb_panic("tdbsam_convert: transaction_cancel failed");
        }
 
@@ -306,17 +326,24 @@ static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
 static bool tdbsam_upgrade_next_rid(struct db_context *db)
 {
        TDB_CONTEXT *tdb;
-       uint32 rid;
+       uint32_t rid;
        bool ok = false;
+       NTSTATUS status;
+       char *db_path;
 
-       ok = dbwrap_fetch_uint32(db, NEXT_RID_STRING, &rid);
-       if (ok) {
+       status = dbwrap_fetch_uint32_bystring(db, NEXT_RID_STRING, &rid);
+       if (NT_STATUS_IS_OK(status)) {
                return true;
        }
 
-       tdb = tdb_open_log(state_path("winbindd_idmap.tdb"), 0,
-                          TDB_DEFAULT, O_RDONLY, 0644);
+       db_path = state_path("winbindd_idmap.tdb");
+       if (db_path == NULL) {
+               return false;
+       }
 
+       tdb = tdb_open_log(db_path, 0,
+                          TDB_DEFAULT, O_RDONLY, 0644);
+       TALLOC_FREE(db_path);
        if (tdb) {
                ok = tdb_fetch_uint32(tdb, "RID_COUNTER", &rid);
                if (!ok) {
@@ -327,18 +354,19 @@ static bool tdbsam_upgrade_next_rid(struct db_context *db)
                rid = BASE_RID;
        }
 
-       if (dbwrap_store_uint32(db, NEXT_RID_STRING, rid) != 0) {
+       status = dbwrap_store_uint32_bystring(db, NEXT_RID_STRING, rid);
+       if (!NT_STATUS_IS_OK(status)) {
                return false;
        }
 
        return true;
 }
 
-static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 from)
+static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32_t from)
 {
        struct tdbsam_convert_state state;
        struct db_context *db = NULL;
-       int ret;
+       NTSTATUS status;
 
        /* We only need the update backup for local db's. */
        if (db_is_local(name) && !tdbsam_convert_backup(name, pp_db)) {
@@ -350,7 +378,7 @@ static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 fr
        state.from = from;
        state.success = true;
 
-       if (db->transaction_start(db) != 0) {
+       if (dbwrap_transaction_start(db) != 0) {
                DEBUG(0, ("tdbsam_convert: Could not start transaction\n"));
                return false;
        }
@@ -360,8 +388,8 @@ static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 fr
                goto cancel;
        }
 
-       ret = db->traverse(db, tdbsam_convert_one, &state);
-       if (ret < 0) {
+       status = dbwrap_traverse(db, tdbsam_convert_one, &state, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("tdbsam_convert: traverse failed\n"));
                goto cancel;
        }
@@ -371,19 +399,23 @@ static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 fr
                goto cancel;
        }
 
-       if (dbwrap_store_int32(db, TDBSAM_VERSION_STRING,
-                              TDBSAM_VERSION) != 0) {
-               DEBUG(0, ("tdbsam_convert: Could not store tdbsam version\n"));
+       status = dbwrap_store_int32_bystring(db, TDBSAM_VERSION_STRING,
+                                            TDBSAM_VERSION);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("tdbsam_convert: Could not store tdbsam version: "
+                         "%s\n", nt_errstr(status)));
                goto cancel;
        }
 
-       if (dbwrap_store_int32(db, TDBSAM_MINOR_VERSION_STRING,
-                              TDBSAM_MINOR_VERSION) != 0) {
-               DEBUG(0, ("tdbsam_convert: Could not store tdbsam minor version\n"));
+       status = dbwrap_store_int32_bystring(db, TDBSAM_MINOR_VERSION_STRING,
+                                            TDBSAM_MINOR_VERSION);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("tdbsam_convert: Could not store tdbsam minor "
+                         "version: %s\n", nt_errstr(status)));
                goto cancel;
        }
 
-       if (db->transaction_commit(db) != 0) {
+       if (dbwrap_transaction_commit(db) != 0) {
                DEBUG(0, ("tdbsam_convert: Could not commit transaction\n"));
                return false;
        }
@@ -391,7 +423,7 @@ static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 fr
        return true;
 
  cancel:
-       if (db->transaction_cancel(db) != 0) {
+       if (dbwrap_transaction_cancel(db) != 0) {
                smb_panic("tdbsam_convert: transaction_cancel failed");
        }
 
@@ -405,8 +437,9 @@ static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 fr
 
 static bool tdbsam_open( const char *name )
 {
-       int32   version;
-       int32   minor_version;
+       int32_t version;
+       int32_t minor_version;
+       NTSTATUS status;
 
        /* check if we are already open */
 
@@ -416,7 +449,8 @@ static bool tdbsam_open( const char *name )
 
        /* Try to open tdb passwd.  Create a new one if necessary */
 
-       db_sam = db_open(NULL, name, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600);
+       db_sam = db_open(NULL, name, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600,
+                        DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
        if (db_sam == NULL) {
                DEBUG(0, ("tdbsam_open: Failed to open/create TDB passwd "
                          "[%s]\n", name));
@@ -424,14 +458,16 @@ static bool tdbsam_open( const char *name )
        }
 
        /* Check the version */
-       version = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING);
-       if (version == -1) {
+       status = dbwrap_fetch_int32_bystring(db_sam, TDBSAM_VERSION_STRING,
+                                            &version);
+       if (!NT_STATUS_IS_OK(status)) {
                version = 0;    /* Version not found, assume version 0 */
        }
 
        /* Get the minor version */
-       minor_version = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING);
-       if (minor_version == -1) {
+       status = dbwrap_fetch_int32_bystring(
+               db_sam, TDBSAM_MINOR_VERSION_STRING, &minor_version);
+       if (!NT_STATUS_IS_OK(status)) {
                minor_version = 0; /* Minor version not found, assume 0 */
        }
 
@@ -465,14 +501,16 @@ static bool tdbsam_open( const char *name )
                }
 
                /* Re-check the version */
-               version = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING);
-               if (version == -1) {
+               status = dbwrap_fetch_int32_bystring(
+                       db_sam, TDBSAM_VERSION_STRING, &version);
+               if (!NT_STATUS_IS_OK(status)) {
                        version = 0;    /* Version not found, assume version 0 */
                }
 
                /* Re-check the minor version */
-               minor_version = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING);
-               if (minor_version == -1) {
+               status = dbwrap_fetch_int32_bystring(
+                       db_sam, TDBSAM_MINOR_VERSION_STRING, &minor_version);
+               if (!NT_STATUS_IS_OK(status)) {
                        minor_version = 0; /* Minor version not found, assume 0 */
                }
 
@@ -532,6 +570,7 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods,
        TDB_DATA        data;
        fstring         keystr;
        fstring         name;
+       NTSTATUS status;
 
        if ( !user ) {
                DEBUG(0,("pdb_getsampwnam: struct samu is NULL.\n"));
@@ -540,10 +579,12 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods,
 
        /* Data is stored in all lower-case */
        fstrcpy(name, sname);
-       strlower_m(name);
+       if (!strlower_m(name)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
 
        /* set search key */
-       slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
+       fstr_sprintf(keystr, "%s%s", USERPREFIX, name);
 
        /* open the database */
 
@@ -554,18 +595,24 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods,
 
        /* get the record */
 
-       data = dbwrap_fetch_bystring(db_sam, talloc_tos(), keystr);
-       if (!data.dptr) {
+       status = dbwrap_fetch_bystring(db_sam, talloc_tos(), keystr, &data);
+       if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
                DEBUGADD(5, (" Key: %s\n", keystr));
                return NT_STATUS_NO_SUCH_USER;
        }
 
+       if (data.dsize == 0) {
+               DEBUG(5, ("%s: Got 0-sized record for key %s\n", __func__,
+                         keystr));
+               return NT_STATUS_NO_SUCH_USER;
+       }
+
        /* unpack the buffer */
 
        if (!init_samu_from_buffer(user, SAMU_BUFFER_LATEST, data.dptr, data.dsize)) {
                DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
-               SAFE_FREE(data.dptr);
+               TALLOC_FREE(data.dptr);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -581,7 +628,7 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods,
  **************************************************************************/
 
 static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods,
-                                   struct samu *user, uint32 rid)
+                                   struct samu *user, uint32_t rid)
 {
        NTSTATUS                nt_status = NT_STATUS_UNSUCCESSFUL;
        TDB_DATA                data;
@@ -595,7 +642,7 @@ static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods,
 
        /* set search key */
 
-       slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
+       fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, rid);
 
        /* open the database */
 
@@ -606,10 +653,10 @@ static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods,
 
        /* get the record */
 
-       data = dbwrap_fetch_bystring(db_sam, talloc_tos(), keystr);
-       if (!data.dptr) {
+       nt_status = dbwrap_fetch_bystring(db_sam, talloc_tos(), keystr, &data);
+       if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid, keystr));
-               return NT_STATUS_UNSUCCESSFUL;
+               return nt_status;
        }
 
        fstrcpy(name, (const char *)data.dptr);
@@ -621,7 +668,7 @@ static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods,
 static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods,
                                   struct samu * user, const struct dom_sid *sid)
 {
-       uint32 rid;
+       uint32_t rid;
 
        if ( !sid_peek_check_rid(get_global_sam_sid(), sid, &rid) )
                return NT_STATUS_UNSUCCESSFUL;
@@ -636,11 +683,13 @@ static bool tdb_delete_samacct_only( struct samu *sam_pass )
        NTSTATUS status;
 
        fstrcpy(name, pdb_get_username(sam_pass));
-       strlower_m(name);
+       if (!strlower_m(name)) {
+               return false;
+       }
 
        /* set the search key */
 
-       slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
+       fstr_sprintf(keystr, "%s%s", USERPREFIX, name);
 
        /* it's outaa here!  8^) */
        if ( !tdbsam_open( tdbsam_filename ) ) {
@@ -668,7 +717,7 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods,
 {
        NTSTATUS        nt_status = NT_STATUS_UNSUCCESSFUL;
        fstring         keystr;
-       uint32          rid;
+       uint32_t        rid;
        fstring         name;
 
        /* open the database */
@@ -680,17 +729,19 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods,
        }
 
        fstrcpy(name, pdb_get_username(sam_pass));
-       strlower_m(name);
+       if (!strlower_m(name)) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
 
        /* set the search key */
 
-       slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
+       fstr_sprintf(keystr, "%s%s", USERPREFIX, name);
 
        rid = pdb_get_user_rid(sam_pass);
 
        /* it's outaa here!  8^) */
 
-       if (db_sam->transaction_start(db_sam) != 0) {
+       if (dbwrap_transaction_start(db_sam) != 0) {
                DEBUG(0, ("Could not start transaction\n"));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -704,7 +755,7 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods,
 
        /* set the search key */
 
-       slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
+       fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, rid);
 
        /* it's outaa here!  8^) */
 
@@ -715,7 +766,7 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods,
                goto cancel;
        }
 
-       if (db_sam->transaction_commit(db_sam) != 0) {
+       if (dbwrap_transaction_commit(db_sam) != 0) {
                DEBUG(0, ("Could not commit transaction\n"));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -723,7 +774,7 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods,
        return NT_STATUS_OK;
 
  cancel:
-       if (db_sam->transaction_cancel(db_sam) != 0) {
+       if (dbwrap_transaction_cancel(db_sam) != 0) {
                smb_panic("transaction_cancel failed");
        }
 
@@ -738,7 +789,7 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods,
 static bool tdb_update_samacct_only( struct samu* newpwd, int flag )
 {
        TDB_DATA        data;
-       uint8           *buf = NULL;
+       uint8_t         *buf = NULL;
        fstring         keystr;
        fstring         name;
        bool            ret = false;
@@ -753,14 +804,16 @@ static bool tdb_update_samacct_only( struct samu* newpwd, int flag )
        data.dptr = buf;
 
        fstrcpy(name, pdb_get_username(newpwd));
-       strlower_m(name);
+       if (!strlower_m(name)) {
+               goto done;
+       }
 
        DEBUG(5, ("Storing %saccount %s with RID %d\n",
                  flag == TDB_INSERT ? "(new) " : "", name,
                  pdb_get_user_rid(newpwd)));
 
        /* setup the USER index key */
-       slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
+       fstr_sprintf(keystr, "%s%s", USERPREFIX, name);
 
        /* add the account */
 
@@ -791,14 +844,15 @@ static bool tdb_update_ridrec_only( struct samu* newpwd, int flag )
        NTSTATUS status;
 
        fstrcpy(name, pdb_get_username(newpwd));
-       strlower_m(name);
+       if (!strlower_m(name)) {
+               return false;
+       }
 
        /* setup RID data */
        data = string_term_tdb_data(name);
 
        /* setup the RID index key */
-       slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX,
-                pdb_get_user_rid(newpwd));
+       fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
 
        /* add the reference */
        status = dbwrap_store_bystring(db_sam, keystr, data, flag);
@@ -837,7 +891,7 @@ static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd,
                return False;
        }
 
-       if (db_sam->transaction_start(db_sam) != 0) {
+       if (dbwrap_transaction_start(db_sam) != 0) {
                DEBUG(0, ("Could not start transaction\n"));
                return false;
        }
@@ -878,7 +932,7 @@ static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd,
 
                /* Delete old RID key */
                DEBUG(10, ("tdb_update_sam: Deleting key for RID %u\n", oldrid));
-               slprintf(keystr, sizeof(keystr) - 1, "%s%.8x", RIDPREFIX, oldrid);
+               fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, oldrid);
                if (!NT_STATUS_IS_OK(dbwrap_delete_bystring(db_sam, keystr))) {
                        DEBUG(0, ("tdb_update_sam: Can't delete %s\n", keystr));
                        goto cancel;
@@ -896,7 +950,7 @@ static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd,
                }
        }
 
-       if (db_sam->transaction_commit(db_sam) != 0) {
+       if (dbwrap_transaction_commit(db_sam) != 0) {
                DEBUG(0, ("Could not commit transaction\n"));
                return false;
        }
@@ -904,7 +958,7 @@ static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd,
        return true;
 
  cancel:
-       if (db_sam->transaction_cancel(db_sam) != 0) {
+       if (dbwrap_transaction_cancel(db_sam) != 0) {
                smb_panic("transaction_cancel failed");
        }
        return false;
@@ -959,7 +1013,7 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
                return NT_STATUS_NO_MEMORY;
        }
 
-       rename_script = talloc_strdup(new_acct, lp_renameuser_script());
+       rename_script = lp_rename_user_script(new_acct);
        if (!rename_script) {
                TALLOC_FREE(new_acct);
                return NT_STATUS_NO_MEMORY;
@@ -984,7 +1038,7 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       if (db_sam->transaction_start(db_sam) != 0) {
+       if (dbwrap_transaction_start(db_sam) != 0) {
                DEBUG(0, ("Could not start transaction\n"));
                TALLOC_FREE(new_acct);
                return NT_STATUS_ACCESS_DENIED;
@@ -1000,10 +1054,14 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
           so that we lower case the posix name but preserve the case in passdb */
 
        fstrcpy( oldname_lower, pdb_get_username(old_acct) );
-       strlower_m( oldname_lower );
+       if (!strlower_m( oldname_lower )) {
+               goto cancel;
+       }
 
        fstrcpy( newname_lower, newname );
-       strlower_m( newname_lower );
+       if (!strlower_m( newname_lower )) {
+               goto cancel;
+       }
 
        rename_script = talloc_string_sub2(new_acct,
                                rename_script,
@@ -1025,7 +1083,7 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
        if (!rename_script) {
                goto cancel;
        }
-       rename_ret = smbrun(rename_script, NULL);
+       rename_ret = smbrun(rename_script, NULL, NULL);
 
        DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n",
                                rename_script, rename_ret));
@@ -1044,7 +1102,7 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
 
        tdb_delete_samacct_only( old_acct );
 
-       if (db_sam->transaction_commit(db_sam) != 0) {
+       if (dbwrap_transaction_commit(db_sam) != 0) {
                /*
                 * Ok, we're screwed. We've changed the posix account, but
                 * could not adapt passdb.tdb. Shall we change the posix
@@ -1059,7 +1117,7 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
        return NT_STATUS_OK;
 
  cancel:
-       if (db_sam->transaction_cancel(db_sam) != 0) {
+       if (dbwrap_transaction_cancel(db_sam) != 0) {
                smb_panic("transaction_cancel failed");
        }
 
@@ -1073,9 +1131,9 @@ static uint32_t tdbsam_capabilities(struct pdb_methods *methods)
        return PDB_CAP_STORE_RIDS;
 }
 
-static bool tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid)
+static bool tdbsam_new_rid(struct pdb_methods *methods, uint32_t *prid)
 {
-       uint32 rid;
+       uint32_t rid;
        NTSTATUS status;
 
        rid = BASE_RID;         /* Default if not set */
@@ -1086,8 +1144,8 @@ static bool tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid)
                return false;
        }
 
-       status = dbwrap_trans_change_uint32_atomic(db_sam, NEXT_RID_STRING,
-                                                  &rid, 1);
+       status = dbwrap_trans_change_uint32_atomic_bystring(
+               db_sam, NEXT_RID_STRING, &rid, 1);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3, ("tdbsam_new_rid: Failed to increase %s: %s\n",
                        NEXT_RID_STRING, nt_errstr(status)));
@@ -1114,16 +1172,19 @@ static int tdbsam_collect_rids(struct db_record *rec, void *private_data)
        struct tdbsam_search_state *state = talloc_get_type_abort(
                private_data, struct tdbsam_search_state);
        size_t prefixlen = strlen(RIDPREFIX);
-       uint32 rid;
+       uint32_t rid;
+       TDB_DATA key;
 
-       if ((rec->key.dsize < prefixlen)
-           || (strncmp((char *)rec->key.dptr, RIDPREFIX, prefixlen))) {
+       key = dbwrap_record_get_key(rec);
+
+       if ((key.dsize < prefixlen)
+           || (strncmp((char *)key.dptr, RIDPREFIX, prefixlen))) {
                return 0;
        }
 
-       rid = strtoul((char *)rec->key.dptr+prefixlen, NULL, 16);
+       rid = strtoul((char *)key.dptr+prefixlen, NULL, 16);
 
-       ADD_TO_LARGE_ARRAY(state, uint32, rid, &state->rids, &state->num_rids,
+       ADD_TO_LARGE_ARRAY(state, uint32_t, rid, &state->rids, &state->num_rids,
                           &state->array_size);
 
        return 0;
@@ -1154,6 +1215,7 @@ static bool tdbsam_search_next_entry(struct pdb_search *search,
        }
 
        if (state->current == state->num_rids) {
+               TALLOC_FREE(user);
                return false;
        }
 
@@ -1199,7 +1261,7 @@ static bool tdbsam_search_next_entry(struct pdb_search *search,
 
 static bool tdbsam_search_users(struct pdb_methods *methods,
                                struct pdb_search *search,
-                               uint32 acct_flags)
+                               uint32_t acct_flags)
 {
        struct tdbsam_search_state *state;
 
@@ -1217,7 +1279,7 @@ static bool tdbsam_search_users(struct pdb_methods *methods,
        state->acct_flags = acct_flags;
        state->methods = methods;
 
-       db_sam->traverse_read(db_sam, tdbsam_collect_rids, state);
+       dbwrap_traverse_read(db_sam, tdbsam_collect_rids, state, NULL);
 
        search->private_data = state;
        search->next_entry = tdbsam_search_next_entry;
@@ -1226,6 +1288,11 @@ static bool tdbsam_search_users(struct pdb_methods *methods,
        return true;
 }
 
+static bool tdbsam_is_responsible_for_builtin(struct pdb_methods *m)
+{
+       return map_builtin;
+}
+
 /*********************************************************************
  Initialize the tdb sam backend.  Setup the dispath table of methods,
  open the tdb, etc...
@@ -1254,6 +1321,10 @@ static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *loc
        (*pdb_method)->capabilities = tdbsam_capabilities;
        (*pdb_method)->new_rid = tdbsam_new_rid;
 
+       (*pdb_method)->is_responsible_for_builtin =
+                                       tdbsam_is_responsible_for_builtin;
+       map_builtin = lp_parm_bool(-1, "tdbsam", "map builtin", true);
+
        /* save the path for later */
 
        if (!location) {
@@ -1277,7 +1348,7 @@ static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *loc
        return NT_STATUS_OK;
 }
 
-NTSTATUS pdb_tdbsam_init(void)
+NTSTATUS pdb_tdbsam_init(TALLOC_CTX *ctx)
 {
        return smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam);
 }