summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/passdb/pdb_tdb.c145
-rw-r--r--source3/utils/pdbedit.c6
2 files changed, 105 insertions, 46 deletions
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index c9a84f3242..e4ef51a46d 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -44,30 +44,69 @@ static int tdbsam_debug_level = DBGC_ALL;
struct tdbsam_privates {
TDB_CONTEXT *passwd_tdb;
- TDB_DATA key;
/* retrive-once info */
const char *tdbsam_location;
};
-/***************************************************************
- Open the TDB passwd database for SAM account enumeration.
-****************************************************************/
+struct pwent_list {
+ struct pwent_list *prev, *next;
+ TDB_DATA key;
+};
+static struct pwent_list *tdbsam_pwent_list;
-static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
+
+/****************************************************************************
+ creates a list of user keys
+****************************************************************************/
+
+static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
+ const char *prefix = USERPREFIX;
+ int prefixlen = strlen (prefix);
+ struct pwent_list *ptr;
- /* Open tdb passwd */
- if (!(tdb_state->passwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600)))
+ if ( strncmp(key.dptr, prefix, prefixlen) == 0 ) {
+ if ( !(ptr=(struct pwent_list*)malloc(sizeof(struct pwent_list))) ) {
+ DEBUG(0,("tdbsam_traverse_setpwent: Failed to malloc new entry for list\n"));
+
+ /* just return 0 and let the traversal continue */
+ return 0;
+ }
+ ZERO_STRUCTP(ptr);
+
+ /* save a copy of the key */
+
+ ptr->key.dptr = memdup( key.dptr, key.dsize );
+ ptr->key.dsize = key.dsize;
+
+ DLIST_ADD( tdbsam_pwent_list, ptr );
+
+ }
+
+
+ return 0;
+}
+
+/*****************************************************************************
+ Utility functions to open and close the tdb sam database
+ ****************************************************************************/
+
+static BOOL open_tdbsam( struct tdbsam_privates *tdb_state, BOOL update )
+{
+ /* check if we already have the tdbsam open */
+
+ if ( tdb_state->passwd_tdb )
+ return True;
+
+ if ( !(tdb_state->passwd_tdb = tdb_open_log(tdb_state->tdbsam_location,
+ 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600)) )
{
DEBUG(0, ("Unable to open/create TDB passwd\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ return False;
}
-
- tdb_state->key = tdb_firstkey(tdb_state->passwd_tdb);
- return NT_STATUS_OK;
+ return True;
}
static void close_tdb(struct tdbsam_privates *tdb_state)
@@ -79,15 +118,43 @@ static void close_tdb(struct tdbsam_privates *tdb_state)
}
/***************************************************************
+ Open the TDB passwd database for SAM account enumeration.
+ Save a list of user keys for iteration.
+****************************************************************/
+
+static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
+{
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
+
+ /* Open tdb passwd */
+ if ( !open_tdbsam(tdb_state, update) )
+ return NT_STATUS_UNSUCCESSFUL;
+
+ tdb_traverse( tdb_state->passwd_tdb, tdbsam_traverse_setpwent, NULL );
+
+ return NT_STATUS_OK;
+}
+
+
+/***************************************************************
End enumeration of the TDB passwd list.
****************************************************************/
static void tdbsam_endsampwent(struct pdb_methods *my_methods)
{
struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- SAFE_FREE(tdb_state->key.dptr);
+ struct pwent_list *ptr;
+
close_tdb(tdb_state);
+ /* clear out any remaining entries in the list */
+
+ for ( ptr=tdbsam_pwent_list; ptr; ptr=ptr->next ) {
+ DLIST_REMOVE( tdbsam_pwent_list, ptr );
+ SAFE_FREE( ptr->key.dptr);
+ SAFE_FREE( ptr );
+ }
+
DEBUG(7, ("endtdbpwent: closed sam database.\n"));
}
@@ -97,55 +164,45 @@ static void tdbsam_endsampwent(struct pdb_methods *my_methods)
static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_DATA data, old_key;
- const char *prefix = USERPREFIX;
- int prefixlen = strlen (prefix);
-
+ TDB_DATA data;
+ struct pwent_list *pkey;
- if (user==NULL) {
- DEBUG(0,("pdb_get_sampwent: SAM_ACCOUNT is NULL.\n"));
+ if ( !user ) {
+ DEBUG(0,("tdbsam_getsampwent: SAM_ACCOUNT is NULL.\n"));
return nt_status;
}
- /* skip all non-USER entries (eg. RIDs) */
- while ((tdb_state->key.dsize != 0) && (strncmp(tdb_state->key.dptr, prefix, prefixlen))) {
-
- old_key = tdb_state->key;
-
- /* increment to next in line */
- tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
-
- SAFE_FREE(old_key.dptr);
- }
+ if( !open_tdbsam(tdb_state, True) )
+ return nt_status;
- /* do we have an valid iteration pointer? */
- if(tdb_state->passwd_tdb == NULL) {
- DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
+ if ( !tdbsam_pwent_list ) {
+ DEBUG(4,("tdbsam_getsampwent: end of list\n"));
return nt_status;
}
- data = tdb_fetch(tdb_state->passwd_tdb, tdb_state->key);
+ /* pull the next entry */
+
+ pkey = tdbsam_pwent_list;
+ DLIST_REMOVE( tdbsam_pwent_list, pkey );
+
+ data = tdb_fetch(tdb_state->passwd_tdb, pkey->key);
+
+ SAFE_FREE( pkey->key.dptr);
+ SAFE_FREE( pkey);
+
if (!data.dptr) {
- DEBUG(5,("pdb_getsampwent: database entry not found.\n"));
+ DEBUG(5,("pdb_getsampwent: database entry not found. Was the user deleted?\n"));
return nt_status;
}
- /* unpack the buffer */
if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
- SAFE_FREE(data.dptr);
- return nt_status;
}
- SAFE_FREE(data.dptr);
- old_key = tdb_state->key;
+ SAFE_FREE( data.dptr );
- /* increment to next in line */
- tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
-
- SAFE_FREE(old_key.dptr);
return NT_STATUS_OK;
}
diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c
index f402567b74..83663c52b6 100644
--- a/source3/utils/pdbedit.c
+++ b/source3/utils/pdbedit.c
@@ -251,13 +251,15 @@ static int fix_users_list (struct pdb_context *in)
if (!(NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)))) return 1;
while (check && (ret = NT_STATUS_IS_OK(in->pdb_getsampwent (in, sam_pwent)))) {
+ printf("Updating record for user %s\n", pdb_get_username(sam_pwent));
+
if (!pdb_update_sam_account(sam_pwent)) {
- DEBUG(0, ("Update of user %s failed!\n", pdb_get_username(sam_pwent)));
+ printf("Update of user %s failed!\n", pdb_get_username(sam_pwent));
}
pdb_free_sam(&sam_pwent);
check = NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent));
if (!check) {
- DEBUG(0, ("Failed to initialise new SAM_ACCOUNT structure (out of memory?)\n"));
+ fprintf(stderr, "Failed to initialise new SAM_ACCOUNT structure (out of memory?)\n");
}
}