r23779: Change from v2 or later to v3 or later.
[samba.git] / source3 / nsswitch / idmap_tdb.c
index 4d70986b84aa3c7428814a93540739875d255992..a36393910b5784d28aefd98ebaf0110d6ae6d0a6 100644 (file)
@@ -10,7 +10,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -57,24 +57,24 @@ static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state
        TDB_DATA key2;
        BOOL *failed = (BOOL *)state;
 
-       DEBUG(10,("Converting %s\n", key.dptr));
+       DEBUG(10,("Converting %s\n", (const char *)key.dptr));
 
-       p = strchr(key.dptr, '/');
+       p = strchr((const char *)key.dptr, '/');
        if (!p)
                return 0;
 
        *p = 0;
-       fstrcpy(dom_name, key.dptr);
+       fstrcpy(dom_name, (const char *)key.dptr);
        *p++ = '/';
 
        domain = find_domain_from_name(dom_name);
        if (domain == NULL) {
                /* We must delete the old record. */
                DEBUG(0,("Unable to find domain %s\n", dom_name ));
-               DEBUG(0,("deleting record %s\n", key.dptr ));
+               DEBUG(0,("deleting record %s\n", (const char *)key.dptr ));
 
                if (tdb_delete(tdb, key) != 0) {
-                       DEBUG(0, ("Unable to delete record %s\n", key.dptr));
+                       DEBUG(0, ("Unable to delete record %s\n", (const char *)key.dptr));
                        *failed = True;
                        return -1;
                }
@@ -88,23 +88,22 @@ static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state
        sid_append_rid(&sid, rid);
 
        sid_to_string(keystr, &sid);
-       key2.dptr = keystr;
-       key2.dsize = strlen(keystr) + 1;
+       key2 = string_term_tdb_data(keystr);
 
        if (tdb_store(tdb, key2, data, TDB_INSERT) != 0) {
-               DEBUG(0,("Unable to add record %s\n", key2.dptr ));
+               DEBUG(0,("Unable to add record %s\n", (const char *)key2.dptr ));
                *failed = True;
                return -1;
        }
 
        if (tdb_store(tdb, data, key2, TDB_REPLACE) != 0) {
-               DEBUG(0,("Unable to update record %s\n", data.dptr ));
+               DEBUG(0,("Unable to update record %s\n", (const char *)data.dptr ));
                *failed = True;
                return -1;
        }
 
        if (tdb_delete(tdb, key) != 0) {
-               DEBUG(0,("Unable to delete record %s\n", key.dptr ));
+               DEBUG(0,("Unable to delete record %s\n", (const char *)key.dptr ));
                *failed = True;
                return -1;
        }
@@ -116,13 +115,15 @@ static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state
  Convert the idmap database from an older version.
 *****************************************************************************/
 
-static BOOL idmap_tdb_convert(const char *idmap_name)
+static BOOL idmap_tdb_upgrade(const char *idmap_name)
 {
        int32 vers;
        BOOL bigendianheader;
        BOOL failed = False;
        TDB_CONTEXT *idmap_tdb;
 
+       DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n"));
+
        if (!(idmap_tdb = tdb_open_log(idmap_name, 0,
                                        TDB_DEFAULT, O_RDWR,
                                        0600))) {
@@ -190,32 +191,6 @@ static BOOL idmap_tdb_convert(const char *idmap_name)
        return True;
 }
 
-/*****************************************************************************
- Convert the idmap database from an older version if necessary
-*****************************************************************************/
-
-BOOL idmap_tdb_upgrade(TALLOC_CTX *ctx, const char *tdbfile)
-{
-       char *backup_name;
-
-       DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n"));
-
-       backup_name = talloc_asprintf(ctx, "%s.bak", tdbfile);
-       if ( ! backup_name) {
-               DEBUG(0, ("Out of memory!\n"));
-               return False;
-       }
-
-       if (backup_tdb(tdbfile, backup_name, 0) != 0) {
-               DEBUG(0, ("Could not backup idmap database\n"));
-               talloc_free(backup_name);
-               return False;
-       }
-
-       talloc_free(backup_name);
-       return idmap_tdb_convert(tdbfile);
-}
-
 /* WARNING: We can't open a tdb twice inthe same process, for that reason
  * I'm going to use a hack with open ref counts to open the winbindd_idmap.tdb
  * only once. We will later decide whether to split the db in multiple files
@@ -283,7 +258,7 @@ static NTSTATUS idmap_tdb_open_db(TALLOC_CTX *memctx, TDB_CONTEXT **tdbctx)
                /* backup_tdb expects the tdb not to be open */
                tdb_close(idmap_tdb_common_ctx);
 
-               if ( ! idmap_tdb_upgrade(ctx, tdbfile)) {
+               if ( ! idmap_tdb_upgrade(tdbfile)) {
                
                        DEBUG(0, ("Unable to open idmap database, it's in an old formati, and upgrade failed!\n"));
                        ret = NT_STATUS_INTERNAL_DB_ERROR;
@@ -340,8 +315,10 @@ static NTSTATUS idmap_tdb_alloc_init( const char *params )
        NTSTATUS ret;
        TALLOC_CTX *ctx;
        const char *range;
-       uint32_t low_id = 0;
-       uint32_t high_id = 0;
+       uid_t low_uid = 0;
+       uid_t high_uid = 0;
+       gid_t low_gid = 0;
+       gid_t high_gid = 0;
 
        /* use our own context here */
        ctx = talloc_new(NULL);
@@ -366,6 +343,8 @@ static NTSTATUS idmap_tdb_alloc_init( const char *params )
 
        range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
        if (range && range[0]) {
+               unsigned low_id, high_id;
+
                if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
                        if (low_id < high_id) {
                                idmap_tdb_state.low_gid = idmap_tdb_state.low_uid = low_id;
@@ -379,14 +358,14 @@ static NTSTATUS idmap_tdb_alloc_init( const char *params )
        }
 
        /* Create high water marks for group and user id */
-       if (lp_idmap_uid(&low_id, &high_id)) {
-               idmap_tdb_state.low_uid = low_id;
-               idmap_tdb_state.high_uid = high_id;
+       if (lp_idmap_uid(&low_uid, &high_uid)) {
+               idmap_tdb_state.low_uid = low_uid;
+               idmap_tdb_state.high_uid = high_uid;
        }
 
-       if (lp_idmap_gid(&low_id, &high_id)) {
-               idmap_tdb_state.low_gid = low_id;
-               idmap_tdb_state.high_gid = high_id;
+       if (lp_idmap_gid(&low_gid, &high_gid)) {
+               idmap_tdb_state.low_gid = low_gid;
+               idmap_tdb_state.high_gid = high_gid;
        }
 
        if (idmap_tdb_state.high_uid <= idmap_tdb_state.low_uid) {
@@ -394,6 +373,8 @@ static NTSTATUS idmap_tdb_alloc_init( const char *params )
                DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
                return NT_STATUS_UNSUCCESSFUL;
        } else {
+               uint32 low_id;
+
                if (((low_id = tdb_fetch_int32(idmap_alloc_tdb, HWM_USER)) == -1) ||
                    (low_id < idmap_tdb_state.low_uid)) {
                        if (tdb_store_int32(idmap_alloc_tdb, HWM_USER, idmap_tdb_state.low_uid) == -1) {
@@ -408,6 +389,8 @@ static NTSTATUS idmap_tdb_alloc_init( const char *params )
                DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
                return NT_STATUS_UNSUCCESSFUL;
        } else {
+               uint32 low_id;
+
                if (((low_id = tdb_fetch_int32(idmap_alloc_tdb, HWM_GROUP)) == -1) ||
                    (low_id < idmap_tdb_state.low_gid)) {
                        if (tdb_store_int32(idmap_alloc_tdb, HWM_GROUP, idmap_tdb_state.low_gid) == -1) {
@@ -603,7 +586,7 @@ struct idmap_tdb_context {
  Initialise idmap database. 
 *****************************/
 
-static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *compat_params)
+static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom)
 {
        NTSTATUS ret;
        struct idmap_tdb_context *ctx;
@@ -637,6 +620,7 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *compat_p
        }
 
        dom->private_data = ctx;
+       dom->initialized = True;
 
        talloc_free(config_option);
        return NT_STATUS_OK;
@@ -653,7 +637,8 @@ failed:
 static NTSTATUS idmap_tdb_id_to_sid(struct idmap_tdb_context *ctx, struct id_map *map)
 {
        NTSTATUS ret;
-       TDB_DATA key, data;
+       TDB_DATA data;
+       char *keystr;
 
        if (!ctx || !map) {
                return NT_STATUS_INVALID_PARAMETER;
@@ -670,11 +655,11 @@ static NTSTATUS idmap_tdb_id_to_sid(struct idmap_tdb_context *ctx, struct id_map
        switch (map->xid.type) {
 
        case ID_TYPE_UID:
-               key.dptr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+               keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
                break;
                
        case ID_TYPE_GID:
-               key.dptr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+               keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
                break;
 
        default:
@@ -685,38 +670,36 @@ static NTSTATUS idmap_tdb_id_to_sid(struct idmap_tdb_context *ctx, struct id_map
        /* final SAFE_FREE safe */
        data.dptr = NULL;
 
-       if (key.dptr == NULL) {
+       if (keystr == NULL) {
                DEBUG(0, ("Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
-       key.dsize = strlen(key.dptr) + 1;
-
-       DEBUG(10,("Fetching record %s\n", key.dptr));
+       DEBUG(10,("Fetching record %s\n", keystr));
 
        /* Check if the mapping exists */
-       data = tdb_fetch(ctx->tdb, key);
+       data = tdb_fetch_bystring(ctx->tdb, keystr);
 
        if (!data.dptr) {
-               DEBUG(10,("Record %s not found\n", key.dptr));
+               DEBUG(10,("Record %s not found\n", keystr));
                ret = NT_STATUS_NONE_MAPPED;
                goto done;
        }
                
-       if (!string_to_sid(map->sid, data.dptr)) {
+       if (!string_to_sid(map->sid, (const char *)data.dptr)) {
                DEBUG(10,("INVALID SID (%s) in record %s\n",
-                               data.dptr, key.dptr));
+                       (const char *)data.dptr, keystr));
                ret = NT_STATUS_INTERNAL_DB_ERROR;
                goto done;
        }
 
-       DEBUG(10,("Found record %s -> %s\n", key.dptr, data.dptr));
+       DEBUG(10,("Found record %s -> %s\n", keystr, (const char *)data.dptr));
        ret = NT_STATUS_OK;
 
 done:
        SAFE_FREE(data.dptr);
-       talloc_free(key.dptr);
+       talloc_free(keystr);
        return ret;
 }
 
@@ -727,42 +710,41 @@ done:
 static NTSTATUS idmap_tdb_sid_to_id(struct idmap_tdb_context *ctx, struct id_map *map)
 {
        NTSTATUS ret;
-       TDB_DATA key, data;
+       TDB_DATA data;
+       char *keystr;
        unsigned long rec_id = 0;
 
-       if ((key.dptr = talloc_asprintf(ctx, "%s", sid_string_static(map->sid))) == NULL) {
+       if ((keystr = talloc_asprintf(ctx, "%s", sid_string_static(map->sid))) == NULL) {
                DEBUG(0, ("Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
-       key.dsize = strlen(key.dptr) + 1;
-
-       DEBUG(10,("Fetching record %s\n", key.dptr));
+       DEBUG(10,("Fetching record %s\n", keystr));
 
        /* Check if sid is present in database */
-       data = tdb_fetch(ctx->tdb, key);
+       data = tdb_fetch_bystring(ctx->tdb, keystr);
        if (!data.dptr) {
-               DEBUG(10,("Record %s not found\n", key.dptr));
+               DEBUG(10,("Record %s not found\n", keystr));
                ret = NT_STATUS_NONE_MAPPED;
                goto done;
        }
 
        /* What type of record is this ? */
-       if (sscanf(data.dptr, "UID %lu", &rec_id) == 1) { /* Try a UID record. */
+       if (sscanf((const char *)data.dptr, "UID %lu", &rec_id) == 1) { /* Try a UID record. */
                map->xid.id = rec_id;
                map->xid.type = ID_TYPE_UID;
-               DEBUG(10,("Found uid record %s -> %s \n", key.dptr, data.dptr ));
+               DEBUG(10,("Found uid record %s -> %s \n", keystr, (const char *)data.dptr ));
                ret = NT_STATUS_OK;
 
-       } else if (sscanf(data.dptr, "GID %lu", &rec_id) == 1) { /* Try a GID record. */
+       } else if (sscanf((const char *)data.dptr, "GID %lu", &rec_id) == 1) { /* Try a GID record. */
                map->xid.id = rec_id;
                map->xid.type = ID_TYPE_GID;
-               DEBUG(10,("Found gid record %s -> %s \n", key.dptr, data.dptr ));
+               DEBUG(10,("Found gid record %s -> %s \n", keystr, (const char *)data.dptr ));
                ret = NT_STATUS_OK;
 
        } else { /* Unknown record type ! */
-               DEBUG(2, ("Found INVALID record %s -> %s\n", key.dptr, data.dptr));
+               DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr));
                ret = NT_STATUS_INTERNAL_DB_ERROR;
        }
        
@@ -777,7 +759,7 @@ static NTSTATUS idmap_tdb_sid_to_id(struct idmap_tdb_context *ctx, struct id_map
        }
 
 done:
-       talloc_free(key.dptr);
+       talloc_free(keystr);
        return ret;
 }
 
@@ -791,6 +773,14 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
        for (i = 0; ids[i]; i++) {
@@ -801,7 +791,7 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
                        if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
 
                                /* make sure it is marked as unmapped */
-                               ids[i]->mapped = False;
+                               ids[i]->status = ID_UNMAPPED;
                                continue;
                        }
                        
@@ -810,7 +800,7 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
                }
 
                /* all ok, id is mapped */
-               ids[i]->mapped = True;
+               ids[i]->status = ID_MAPPED;
        }
 
        ret = NT_STATUS_OK;
@@ -829,6 +819,14 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
        for (i = 0; ids[i]; i++) {
@@ -839,7 +837,7 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
                        if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
 
                                /* make sure it is marked as unmapped */
-                               ids[i]->mapped = False;
+                               ids[i]->status = ID_UNMAPPED;
                                continue;
                        }
                        
@@ -848,7 +846,7 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
                }
 
                /* all ok, id is mapped */
-               ids[i]->mapped = True;
+               ids[i]->status = ID_MAPPED;
        }
 
        ret = NT_STATUS_OK;
@@ -866,12 +864,22 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
        struct idmap_tdb_context *ctx;
        NTSTATUS ret;
        TDB_DATA ksid, kid, data;
+       char *ksidstr, *kidstr;
+
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
 
        if (!map || !map->sid) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       ksid.dptr = kid.dptr = data.dptr = NULL;
+       ksidstr = kidstr = NULL;
+       data.dptr = NULL;
 
        /* TODO: should we filter a set_mapping using low/high filters ? */
        
@@ -880,11 +888,11 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
        switch (map->xid.type) {
 
        case ID_TYPE_UID:
-               kid.dptr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+               kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
                break;
                
        case ID_TYPE_GID:
-               kid.dptr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+               kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
                break;
 
        default:
@@ -892,21 +900,21 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (kid.dptr == NULL) {
+       if (kidstr == NULL) {
                DEBUG(0, ("ERROR: Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
                goto done;
        }
-       kid.dsize = strlen(kid.dptr) + 1;
 
-       if ((ksid.dptr = talloc_asprintf(ctx, "%s", sid_string_static(map->sid))) == NULL) {
+       if ((ksidstr = talloc_asprintf(ctx, "%s", sid_string_static(map->sid))) == NULL) {
                DEBUG(0, ("Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
                goto done;
        }
-       ksid.dsize = strlen(ksid.dptr) + 1;
 
-       DEBUG(10, ("Storing %s <-> %s map\n", ksid.dptr, kid.dptr));
+       DEBUG(10, ("Storing %s <-> %s map\n", ksidstr, kidstr));
+       kid = string_term_tdb_data(kidstr);
+       ksid = string_term_tdb_data(ksidstr);
 
        /* *DELETE* previous mappings if any.
         * This is done both SID and [U|G]ID passed in */
@@ -914,13 +922,13 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
        /* Lock the record for this SID. */
        if (tdb_chainlock(ctx->tdb, ksid) != 0) {
                DEBUG(10,("Failed to lock record %s. Error %s\n",
-                               ksid.dptr, tdb_errorstr(ctx->tdb) ));
+                               ksidstr, tdb_errorstr(ctx->tdb) ));
                return NT_STATUS_UNSUCCESSFUL;
        }
 
        data = tdb_fetch(ctx->tdb, ksid);
        if (data.dptr) {
-               DEBUG(10, ("Deleting existing mapping %s <-> %s\n", data.dptr, ksid.dptr ));
+               DEBUG(10, ("Deleting existing mapping %s <-> %s\n", (const char *)data.dptr, ksidstr ));
                tdb_delete(ctx->tdb, data);
                tdb_delete(ctx->tdb, ksid);
                SAFE_FREE(data.dptr);
@@ -928,7 +936,7 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
 
        data = tdb_fetch(ctx->tdb, kid);
        if (data.dptr) {
-               DEBUG(10,("Deleting existing mapping %s <-> %s\n", data.dptr, kid.dptr ));
+               DEBUG(10,("Deleting existing mapping %s <-> %s\n", (const char *)data.dptr, kidstr ));
                tdb_delete(ctx->tdb, data);
                tdb_delete(ctx->tdb, kid);
                SAFE_FREE(data.dptr);
@@ -950,12 +958,12 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
        }
 
        tdb_chainunlock(ctx->tdb, ksid);
-       DEBUG(10,("Stored %s <-> %s\n", ksid.dptr, kid.dptr));
+       DEBUG(10,("Stored %s <-> %s\n", ksidstr, kidstr));
        ret = NT_STATUS_OK;
 
 done:
-       talloc_free(ksid.dptr);
-       talloc_free(kid.dptr);
+       talloc_free(ksidstr);
+       talloc_free(kidstr);
        SAFE_FREE(data.dptr);
        return ret;
 }
@@ -969,12 +977,22 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
        struct idmap_tdb_context *ctx;
        NTSTATUS ret;
        TDB_DATA ksid, kid, data;
+       char *ksidstr, *kidstr;
+
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
 
        if (!map || !map->sid) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       ksid.dptr = kid.dptr = data.dptr = NULL;
+       ksidstr = kidstr = NULL;
+       data.dptr = NULL;
 
        /* TODO: should we filter a remove_mapping using low/high filters ? */
        
@@ -983,11 +1001,11 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
        switch (map->xid.type) {
 
        case ID_TYPE_UID:
-               kid.dptr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+               kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
                break;
                
        case ID_TYPE_GID:
-               kid.dptr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+               kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
                break;
 
        default:
@@ -995,33 +1013,33 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (kid.dptr == NULL) {
+       if (kidstr == NULL) {
                DEBUG(0, ("ERROR: Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
                goto done;
        }
-       kid.dsize = strlen(kid.dptr) + 1;
 
-       if ((ksid.dptr = talloc_asprintf(ctx, "%s", sid_string_static(map->sid))) == NULL) {
+       if ((ksidstr = talloc_asprintf(ctx, "%s", sid_string_static(map->sid))) == NULL) {
                DEBUG(0, ("Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
                goto done;
        }
-       ksid.dsize = strlen(ksid.dptr) + 1;
 
-       DEBUG(10, ("Checking %s <-> %s map\n", ksid.dptr, kid.dptr));
+       DEBUG(10, ("Checking %s <-> %s map\n", ksidstr, kidstr));
+       ksid = string_term_tdb_data(ksidstr);
+       kid = string_term_tdb_data(kidstr);
 
        /* Lock the record for this SID. */
        if (tdb_chainlock(ctx->tdb, ksid) != 0) {
                DEBUG(10,("Failed to lock record %s. Error %s\n",
-                               ksid.dptr, tdb_errorstr(ctx->tdb) ));
+                               ksidstr, tdb_errorstr(ctx->tdb) ));
                return NT_STATUS_UNSUCCESSFUL;
        }
 
        /* Check if sid is present in database */
        data = tdb_fetch(ctx->tdb, ksid);
        if (!data.dptr) {
-               DEBUG(10,("Record %s not found\n", ksid.dptr));
+               DEBUG(10,("Record %s not found\n", ksidstr));
                tdb_chainunlock(ctx->tdb, ksid);
                ret = NT_STATUS_NONE_MAPPED;
                goto done;
@@ -1031,36 +1049,28 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
        if ((data.dsize != kid.dsize) ||
            (memcmp(data.dptr, kid.dptr, data.dsize) != 0)) {
                DEBUG(10,("Specified SID does not map to specified ID\n"));
-               DEBUGADD(10,("Actual mapping is %s -> %s\n", ksid.dptr, data.dptr));
+               DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr, (const char *)data.dptr));
                tdb_chainunlock(ctx->tdb, ksid);
                ret = NT_STATUS_NONE_MAPPED;
                goto done;
        }
        
-       DEBUG(10, ("Removing %s <-> %s map\n", ksid.dptr, kid.dptr));
+       DEBUG(10, ("Removing %s <-> %s map\n", ksidstr, kidstr));
 
        /* Delete previous mappings. */
        
-       data = tdb_fetch(ctx->tdb, ksid);
-       if (data.dptr) {
-               DEBUG(10, ("Deleting existing mapping %s -> %s\n", ksid.dptr, kid.dptr ));
-               tdb_delete(ctx->tdb, ksid);
-               SAFE_FREE(data.dptr);
-       }
+       DEBUG(10, ("Deleting existing mapping %s -> %s\n", ksidstr, kidstr ));
+       tdb_delete(ctx->tdb, ksid);
 
-       data = tdb_fetch(ctx->tdb, kid);
-       if (data.dptr) {
-               DEBUG(10,("Deleting existing mapping %s -> %s\n", kid.dptr, ksid.dptr ));
-               tdb_delete(ctx->tdb, kid);
-               SAFE_FREE(data.dptr);
-       }
+       DEBUG(10,("Deleting existing mapping %s -> %s\n", kidstr, ksidstr ));
+       tdb_delete(ctx->tdb, kid);
 
        tdb_chainunlock(ctx->tdb, ksid);
        ret = NT_STATUS_OK;
 
 done:
-       talloc_free(ksid.dptr);
-       talloc_free(kid.dptr);
+       talloc_free(ksidstr);
+       talloc_free(kidstr);
        SAFE_FREE(data.dptr);
        return ret;
 }
@@ -1099,7 +1109,7 @@ static int idmap_tdb_dump_one_entry(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA val
        int num_maps = *data->num_maps;
 
        /* ignore any record but the ones with a SID as key */
-       if (strncmp(key.dptr, "S-", 2) == 0) {
+       if (strncmp((const char *)key.dptr, "S-", 2) == 0) {
 
                maps = talloc_realloc(NULL, *data->maps, struct id_map, num_maps+1);
                if ( ! maps) {
@@ -1115,28 +1125,30 @@ static int idmap_tdb_dump_one_entry(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA val
                        return -1;
                }
 
-               if (!string_to_sid(maps[num_maps].sid, key.dptr)) {
-                       DEBUG(10,("INVALID record %s\n", key.dptr));
+               if (!string_to_sid(maps[num_maps].sid, (const char *)key.dptr)) {
+                       DEBUG(10,("INVALID record %s\n", (const char *)key.dptr));
                        /* continue even with errors */
                        return 0;
                }
 
                /* Try a UID record. */
-               if (sscanf(value.dptr, "UID %u", &(maps[num_maps].xid.id)) == 1) {
+               if (sscanf((const char *)value.dptr, "UID %u", &(maps[num_maps].xid.id)) == 1) {
                        maps[num_maps].xid.type = ID_TYPE_UID;
-                       maps[num_maps].mapped = True;
+                       maps[num_maps].status = ID_MAPPED;
                        *data->num_maps = num_maps + 1;
 
                /* Try a GID record. */
                } else
-               if (sscanf(value.dptr, "GID %u", &(maps[num_maps].xid.id)) == 1) {
+               if (sscanf((const char *)value.dptr, "GID %u", &(maps[num_maps].xid.id)) == 1) {
                        maps[num_maps].xid.type = ID_TYPE_GID;
-                       maps[num_maps].mapped = True;
+                       maps[num_maps].status = ID_MAPPED;
                        *data->num_maps = num_maps + 1;
 
                /* Unknown record type ! */
                } else {
-                       DEBUG(2, ("Found INVALID record %s -> %s\n", key.dptr, value.dptr));
+                       maps[num_maps].status = ID_UNKNOWN;
+                       DEBUG(2, ("Found INVALID record %s -> %s\n",
+                               (const char *)key.dptr, (const char *)value.dptr));
                        /* do not increment num_maps */
                }
        }
@@ -1154,9 +1166,17 @@ static NTSTATUS idmap_tdb_dump_data(struct idmap_domain *dom, struct id_map **ma
        struct dump_data *data;
        NTSTATUS ret = NT_STATUS_OK;
 
+       /* make sure we initialized */
+       if ( ! dom->initialized) {
+               ret = idmap_tdb_db_init(dom);
+               if ( ! NT_STATUS_IS_OK(ret)) {
+                       return ret;
+               }
+       }
+
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
-       data = talloc_zero(ctx, struct dump_data);
+       data = TALLOC_ZERO_P(ctx, struct dump_data);
        if ( ! data) {
                DEBUG(0, ("Out of memory!\n"));
                return NT_STATUS_NO_MEMORY;