docs: fix a typo in history file
[bbaumbach/samba-autobuild/.git] / source3 / passdb / pdb_tdb.c
index 565dd5d309826cdafa121a4ffac62ed7036a63a4..161030fed8b9aba4096a75f9191b6e9998b25a94 100644 (file)
@@ -30,6 +30,8 @@
 #include "../libcli/security/security.h"
 #include "util_tdb.h"
 #include "passdb/pdb_tdb.h"
+#include "lib/util/smb_strtox.h"
+#include "lib/util/string_wrappers.h"
 
 #if 0 /* when made a module use this */
 
@@ -59,6 +61,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;
@@ -100,27 +103,27 @@ static int tdbsam_convert_one(struct db_record *rec, void *priv)
        switch (state->from) {
        case 0:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V0,
-                                           (uint8 *)value.dptr,
+                                           (uint8_t *)value.dptr,
                                            value.dsize);
                break;
        case 1:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V1,
-                                           (uint8 *)value.dptr,
+                                           (uint8_t *)value.dptr,
                                            value.dsize);
                break;
        case 2:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V2,
-                                           (uint8 *)value.dptr,
+                                           (uint8_t *)value.dptr,
                                            value.dsize);
                break;
        case 3:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V3,
-                                           (uint8 *)value.dptr,
+                                           (uint8_t *)value.dptr,
                                            value.dsize);
                break;
        case 4:
                ret = init_samu_from_buffer(user, SAMU_BUFFER_V4,
-                                           (uint8 *)value.dptr,
+                                           (uint8_t *)value.dptr,
                                            value.dsize);
                break;
        default:
@@ -224,7 +227,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));
@@ -290,7 +294,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));
@@ -323,17 +328,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(talloc_tos(), "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) {
@@ -344,14 +356,15 @@ 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;
@@ -388,15 +401,19 @@ 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;
        }
 
@@ -422,8 +439,8 @@ 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 */
@@ -434,7 +451,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));
@@ -442,14 +460,15 @@ static bool tdbsam_open( const char *name )
        }
 
        /* Check the version */
-       status = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING, &version);
+       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 */
-       status = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING,
-                                   &minor_version);
+       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 */
        }
@@ -484,15 +503,15 @@ static bool tdbsam_open( const char *name )
                }
 
                /* Re-check the version */
-               status = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING,
-                                           &version);
+               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 */
-               status = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING,
-                                           &minor_version);
+               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 */
                }
@@ -562,10 +581,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 */
 
@@ -583,11 +604,17 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods,
                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;
        }
 
@@ -603,7 +630,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;
@@ -617,7 +644,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 */
 
@@ -643,7 +670,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;
@@ -658,11 +685,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 ) ) {
@@ -688,9 +717,9 @@ static bool tdb_delete_samacct_only( struct samu *sam_pass )
 static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods,
                                          struct samu *sam_pass)
 {
-       NTSTATUS        nt_status = NT_STATUS_UNSUCCESSFUL;
+       NTSTATUS        nt_status;
        fstring         keystr;
-       uint32          rid;
+       uint32_t        rid;
        fstring         name;
 
        /* open the database */
@@ -702,11 +731,13 @@ 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);
 
@@ -726,7 +757,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^) */
 
@@ -760,7 +791,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;
@@ -775,14 +806,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 */
 
@@ -813,14 +846,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);
@@ -900,7 +934,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;
@@ -969,6 +1003,8 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
                                          struct samu *old_acct,
                                          const char *newname)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        struct samu      *new_acct = NULL;
        char *rename_script = NULL;
        int              rename_ret;
@@ -981,7 +1017,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, lp_sub);
        if (!rename_script) {
                TALLOC_FREE(new_acct);
                return NT_STATUS_NO_MEMORY;
@@ -1022,10 +1058,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,
@@ -1047,7 +1087,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));
@@ -1095,9 +1135,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 */
@@ -1108,8 +1148,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)));
@@ -1136,7 +1176,8 @@ 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;
+       int error = 0;
        TDB_DATA key;
 
        key = dbwrap_record_get_key(rec);
@@ -1146,9 +1187,16 @@ static int tdbsam_collect_rids(struct db_record *rec, void *private_data)
                return 0;
        }
 
-       rid = strtoul((char *)key.dptr+prefixlen, NULL, 16);
+       rid = smb_strtoul((char *)key.dptr+prefixlen,
+                         NULL,
+                         16,
+                         &error,
+                         SMB_STR_STANDARD);
+       if (error != 0) {
+               return 0;
+       }
 
-       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;
@@ -1179,6 +1227,7 @@ static bool tdbsam_search_next_entry(struct pdb_search *search,
        }
 
        if (state->current == state->num_rids) {
+               TALLOC_FREE(user);
                return false;
        }
 
@@ -1224,7 +1273,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;
 
@@ -1251,6 +1300,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...
@@ -1279,6 +1333,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) {
@@ -1302,7 +1360,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);
 }