This is the 'multiple pdb backends' patch from ctrlsoft, aka Jelmer Vernooij
authorAndrew Bartlett <abartlet@samba.org>
Sat, 13 Apr 2002 08:16:41 +0000 (08:16 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 13 Apr 2002 08:16:41 +0000 (08:16 +0000)
<jelmer@nl.linux.org>.

This patch also includes major rework of pdbedit to use popt, and the addition
of -i paramter (allowing the user to specify which PDBs is being
operated on) and -e to export a pdb - useful for backup and testing etc.

Use of -i and -e gets us pdb2pdb functionality for transition between backends,
much like the sam2sam in TNG.

Andrew Bartlett
(This used to be commit c10def37f506d3f2bab442418ac08fdb62659b02)

examples/README
examples/pdb/README
source3/include/passdb.h
source3/include/smb.h
source3/passdb/pdb_interface.c
source3/passdb/pdb_ldap.c
source3/passdb/pdb_smbpasswd.c
source3/passdb/pdb_tdb.c
source3/utils/pdbedit.c

index ba47cf912f7e7362f50ab68b7e1c2832e387b0d4..3e11ed4ad82ba223dbd1289e04b0af9f208bdc7d 100644 (file)
@@ -1,7 +1,7 @@
 Copyright(C) Samba-Team 1993-1997
 
-This directory contains example config files and related material for
-Samba. 
+This directory contains example samba extensions, example config files and 
+related material for Samba. 
 
 At a minimum please refer to the smb.conf.default file for current
 information regarding global and share parameter settings.
index ccc39248aac71bad6ab3019bfe82b305360026a0..9ca03bf59388227da10b53cc9dd218706ca37eb0 100644 (file)
@@ -7,3 +7,9 @@ a pdb plugin. It just prints the name of the function that is executed using
 DEBUG. Maybe it's nice to include some of the arguments to the function in the 
 future too..
 
+To debug passdb backends, try to run gdb on the 'pdbedit' executable. That's really much easier than restarting smbd constantly and attaching with your debugger.
+
+New passdb plugins should go into the samba lib directory, (/usr/lib/samba/ for
+most distributions) and should be prefixed with 'pdb_'. An example would be: 
+/usr/lib/samba/pdb_test.so
+
index f17b043fb27490666dcd63cde1d05b96cac43419..9e147189941791f7d650bcffb07a420fa127e6c3 100644 (file)
@@ -29,7 +29,8 @@
 
 typedef struct pdb_context 
 {
-       struct pdb_methods *pdb_selected;
+    struct pdb_methods *pdb_methods;
+       struct pdb_methods *pwent_methods;
        
        /* These functions are wrappers for the functions listed above.
           They may do extra things like re-reading a SAM_ACCOUNT on update */
@@ -59,22 +60,27 @@ typedef struct pdb_context
 typedef struct pdb_methods 
 {
        const char *name; /* What name got this module */
+    struct pdb_context *parent;
 
-       BOOL (*setsampwent)(struct pdb_context *, BOOL update);
+       /* Use macros from dlinklist.h on these two */
+       struct pdb_methods *next;
+       struct pdb_methods *prev;
+
+       BOOL (*setsampwent)(struct pdb_methods *, BOOL update);
        
-       void (*endsampwent)(struct pdb_context *);
+       void (*endsampwent)(struct pdb_methods *);
        
-       BOOL (*getsampwent)(struct pdb_context *, SAM_ACCOUNT *user);
+       BOOL (*getsampwent)(struct pdb_methods *, SAM_ACCOUNT *user);
        
-       BOOL (*getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username);
+       BOOL (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username);
        
-       BOOL (*getsampwrid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, uint32 rid);
+       BOOL (*getsampwrid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, uint32 rid);
        
-       BOOL (*add_sam_account)(struct pdb_context *, const SAM_ACCOUNT *sampass);
+       BOOL (*add_sam_account)(struct pdb_methods *, const SAM_ACCOUNT *sampass);
        
-       BOOL (*update_sam_account)(struct pdb_context *, const SAM_ACCOUNT *sampass);
+       BOOL (*update_sam_account)(struct pdb_methods *, const SAM_ACCOUNT *sampass);
        
-       BOOL (*delete_sam_account)(struct pdb_context *, const SAM_ACCOUNT *username);
+       BOOL (*delete_sam_account)(struct pdb_methods *, const SAM_ACCOUNT *username);
        
        void *private_data;  /* Private data of some kind */
        
index 8963528e9ae9af621af097f0e81f534c62367826..52b475ff272f57f440a51a68c9a3343773a1912e 100644 (file)
@@ -595,6 +595,8 @@ typedef struct sam_passwd
        
        void (*free_fn)(struct sam_passwd **);
 
+    struct pdb_methods *methods;
+
        struct user_data {
                /* initiailization flags */
                uint32 init_flag;
index 435b627da6042a283c35ddd68ba6aabe8974f332..e454bf3c25190d1070f76dbf279c9c9e2ad08da9 100644 (file)
@@ -1,18 +1,19 @@
 /* 
    Unix SMB/CIFS implementation.
    Password and authentication handling
-   Copyright (C) Andrew Bartlett                   2002
-      
+   Copyright (C) Andrew Bartlett                       2002
+   Copyright (C) Jelmer Vernooij                       2002
+
    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
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -29,102 +30,182 @@ const struct pdb_init_function_entry builtin_pdb_init_functions[] = {
        { "tdbsam_nua", pdb_init_tdbsam_nua },
        { "ldapsam", pdb_init_ldapsam },
        { "ldapsam_nua", pdb_init_ldapsam_nua },
-#if 0
-       { "nisplus", pdb_init_nisplus },        
-       { "unix", pdb_init_unix },
-#endif
        { "plugin", pdb_init_plugin },
        { NULL, NULL}
 };
 
 static BOOL context_setsampwent(struct pdb_context *context, BOOL update)
 {
-       if ((!context) || (!context->pdb_selected)) {
+       if ((!context) || (!context->pdb_methods) || (!context->pdb_methods->setsampwent)) {
                DEBUG(0, ("invalid pdb_context specified!\n"));
                return False;
        }
+
+       context->pwent_methods = context->pdb_methods;
        
-       return context->pdb_selected->setsampwent(context, update);
+       while(!(context->pwent_methods->setsampwent(context->pwent_methods, update))){
+               context->pwent_methods = context->pwent_methods->next;
+               if(context->pwent_methods == NULL)return False;
+       }
+       return True;
 }
 
 static void context_endsampwent(struct pdb_context *context)
 {
-       if ((!context) || (!context->pdb_selected)) {
+       if ((!context)){
                DEBUG(0, ("invalid pdb_context specified!\n"));
                return;
        }
-       
-       context->pdb_selected->endsampwent(context);
+
+       if(context->pwent_methods && context->pwent_methods->endsampwent)
+               context->pwent_methods->endsampwent(context->pwent_methods);
+
+       /* So we won't get strange data when calling getsampwent now */
+       context->pwent_methods = NULL;
 }
 
 static BOOL context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
 {
-       if ((!context) || (!context->pdb_selected)) {
+       if ((!context) || (!context->pwent_methods)) {
                DEBUG(0, ("invalid pdb_context specified!\n"));
                return False;
        }
+       /* Loop until we find something useful */
+       while((!context->pwent_methods->getsampwent) || 
+                 context->pwent_methods->getsampwent(context->pwent_methods, user) == False){
+
+               if(context->pwent_methods->endsampwent)
+                       context->pwent_methods->endsampwent(context->pwent_methods);
+
+               context->pwent_methods = context->pwent_methods->next;
+
+               /* All methods are checked now. There are no more entries */
+               if(context->pwent_methods == NULL)return False;
        
-       return context->pdb_selected->getsampwent(context, user);
+               if(!context->pwent_methods->setsampwent){
+                       DEBUG(0, ("invalid context->pwent_methods->setsampwent\n"));
+                       return False;
+               }
+
+               context->pwent_methods->setsampwent(context->pwent_methods, False);
+       }
+       user->methods = context->pwent_methods;
+       return True;
 }
 
 static BOOL context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
 {
-       if ((!context) || (!context->pdb_selected)) {
+       struct pdb_methods *curmethods;
+       if ((!context)) {
                DEBUG(0, ("invalid pdb_context specified!\n"));
                return False;
        }
-       
-       return context->pdb_selected->getsampwnam(context, sam_acct, username);
+       curmethods = context->pdb_methods;
+       while(curmethods){
+               if(curmethods->getsampwnam && curmethods->getsampwnam(curmethods, sam_acct, username) == True){
+                       sam_acct->methods = curmethods;
+                       return True;
+               }
+               curmethods = curmethods->next;
+       }
+
+       return False;
 }
 
 static BOOL context_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, uint32 rid)
 {
-       if ((!context) || (!context->pdb_selected)) {
+       struct pdb_methods *curmethods;
+       if ((!context)) {
                DEBUG(0, ("invalid pdb_context specified!\n"));
                return False;
        }
        
-       return context->pdb_selected->getsampwrid(context, sam_acct, rid);
+       curmethods = context->pdb_methods;
+
+       while(curmethods){
+               if(curmethods->getsampwrid && curmethods->getsampwrid(curmethods, sam_acct, rid) == True){
+                       sam_acct->methods = curmethods;
+                       return True;
+               }
+               curmethods = curmethods->next;
+       }
+
+       return False;
 }
 
 static BOOL context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
 {
-       if ((!context) || (!context->pdb_selected)) {
+       if ((!context) || (!context->pdb_methods) || (!context->pdb_methods->add_sam_account)) {
                DEBUG(0, ("invalid pdb_context specified!\n"));
                return False;
        }
-       
+
        /** @todo  This is where a 're-read on add' should be done */
-  
-       return context->pdb_selected->add_sam_account(context, sam_acct);
+       /* We now add a new account to the first database listed. 
+        * Should we? */
+
+       return context->pdb_methods->add_sam_account(context->pdb_methods, sam_acct);
 }
 
 static BOOL context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
 {
-       if ((!context) || (!context->pdb_selected)) {
+       if (!context) {
                DEBUG(0, ("invalid pdb_context specified!\n"));
                return False;
        }
-       
+
+       if(!sam_acct || !sam_acct->methods){
+               DEBUG(0, ("invalid sam_acct specified\n"));
+               return False;
+       }
+
+       if(!sam_acct->methods->update_sam_account){
+               DEBUG(0, ("invalid sam_acct->methods\n"));
+               return False;
+       }
+
        /** @todo  This is where a 're-read on update' should be done */
-       
-       return context->pdb_selected->update_sam_account(context, sam_acct);
+
+       return sam_acct->methods->update_sam_account(sam_acct->methods, sam_acct);
 }
 
 static BOOL context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
 {
-       if ((!context) || (!context->pdb_selected)) {
+       struct pdb_methods *pdb_selected;
+       if (!context) {
                DEBUG(0, ("invalid pdb_context specified!\n"));
                return False;
        }
+
+       if(!sam_acct->methods){
+               pdb_selected = context->pdb_methods;
+               /* There's no passdb backend specified for this account.
+                * Try to delete it in every passdb available */
+               while(pdb_selected){
+                       if(pdb_selected->delete_sam_account && pdb_selected->delete_sam_account(pdb_selected, sam_acct)){
+                               return True;
+                       }
+                       pdb_selected = pdb_selected->next;
+               }
+               return False;
+       }
+
+       if(!sam_acct->methods->delete_sam_account){
+               DEBUG(0,("invalid sam_acct->methods->delete_sam_account\n"));
+               return False;
+       }
        
-       return context->pdb_selected->delete_sam_account(context, sam_acct);
+       return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct);
 }
 
 static void free_pdb_context(struct pdb_context **context)
 {
-       if (((*context)->pdb_selected) && ((*context)->pdb_selected->free_private_data)) {
-               (*context)->pdb_selected->free_private_data((*context)->pdb_selected->private_data);
+       struct pdb_methods *pdb_selected = (*context)->pdb_methods;
+
+       while(pdb_selected){
+               if(pdb_selected->free_private_data)
+                       pdb_selected->free_private_data(pdb_selected->private_data);
+               pdb_selected = pdb_selected->next;
        }
 
        talloc_destroy((*context)->mem_ctx);
@@ -132,13 +213,57 @@ static void free_pdb_context(struct pdb_context **context)
 }
 
 /******************************************************************
- Make a pdb_context from scratch.
-*******************************************************************/
+  Make a pdb_methods from scratch
+ *******************************************************************/
+
+static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_context *context, const char *selected)
+{
+       char *module_name = smb_xstrdup(selected);
+       char *module_location = NULL, *p;
+       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+       int i;
+
+       p = strchr(module_name, ':');
+
+       if (p) {
+               *p = 0;
+               module_location = p+1;
+               trim_string(module_location, " ", " ");
+       }
+
+       trim_string(module_name, " ", " ");
+
+       DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
+       for (i = 0; builtin_pdb_init_functions[i].name; i++)
+       {
+               if (strequal(builtin_pdb_init_functions[i].name, module_name))
+               {
+                       DEBUG(5,("Found pdb backend %s (at pos %d)\n", module_name, i));
+                       if (NT_STATUS_IS_OK(nt_status 
+                                                               = builtin_pdb_init_functions[i].init(context, methods, module_location))) {
+                               DEBUG(5,("pdb backend %s has a valid init\n", selected));
+                       } else {
+                               DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status)));
+                       }
+                       break;
+               }
+       }
+
+       if (!*methods) {
+               DEBUG(0,("failed to select passdb backed!\n"));
+               return nt_status;
+       }
+       return NT_STATUS_OK;
+}
+
+/******************************************************************
+  Make a pdb_context from scratch.
+ *******************************************************************/
 
 static NTSTATUS make_pdb_context(struct pdb_context **context) 
 {
        TALLOC_CTX *mem_ctx;
-       
+
        mem_ctx = talloc_init_named("pdb_context internal allocation context");
 
        if (!mem_ctx) {
@@ -165,77 +290,58 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
        (*context)->pdb_update_sam_account = context_update_sam_account;
        (*context)->pdb_delete_sam_account = context_delete_sam_account;
 
+       (*context)->pdb_methods = NULL;
+       (*context)->pwent_methods = NULL;
+
        (*context)->free_fn = free_pdb_context;
-       
+
        return NT_STATUS_OK;
 }
 
 
 /******************************************************************
- Make a pdb_context, given a text string.
-*******************************************************************/
 Make a pdb_context, given a text string.
+ *******************************************************************/
 
 NTSTATUS make_pdb_context_name(struct pdb_context **context, const char *selected) 
 {
-       /* HINT: Don't store 'selected' becouse its often an lp_ string and
-          will 'go away' */
+       /* HINT: Don't store 'selected' becouse its often an lp_ string and will 'go away' */
+       char *conf = smb_xstrdup(selected);
+       char *confcur = conf, *confnext;
+       struct pdb_methods *curmethods, *tmpmethods;
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-       int i;
-       char *module_name = smb_xstrdup(selected);
-       char *module_location = NULL;
-       char *p;
 
-       p = strchr(module_name, ':');
-       
-       if (p) {
-               *p = 0;
-       
-               module_location = p+1;
-               
-               trim_string(module_location, " ", " ");
+       if(!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))){
+               return nt_status;
        }
 
-       trim_string(module_name, " ", " ");
-
-       if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context)))
-               goto done;
-       
-       DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", 
-                selected, module_name));
-
-       for (i = 0; builtin_pdb_init_functions[i].name; i++) {
-               if (strequal(builtin_pdb_init_functions[i].name, 
-                            module_name)) {
-
-                       DEBUG(5,("Found pdb backend %s (at pos %d)\n", 
-                                module_name, i));
-
-                       if (NT_STATUS_IS_OK(nt_status = builtin_pdb_init_functions[i].init(*context, &(*context)->pdb_selected, module_location))) {
-                               DEBUG(5,("pdb backend %s has a valid init\n", selected));
-                       } else {
-                               DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status)));
-                               (*context)->pdb_selected = NULL;
-                       }
-                       break;
+       while(confcur){
+               if(strchr(confcur, ' ')){
+                       confnext = strchr(confcur,' ');
+                       *confnext = '\0';
+                       confnext++;
+               }else confnext = NULL;
+
+               /* Try to initialise pdb */
+               DEBUG(5,("Trying to load: %s\n", confcur));
+               if(!NT_STATUS_IS_OK(make_pdb_methods_name(&curmethods, *context, confcur))){
+                       DEBUG(5, ("Loading %s failed!\n", confcur));
+                       SAFE_FREE(curmethods);
+                       continue;
                }
+               curmethods->parent = *context;
+               DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
+
+               if(!confnext)break;
+               confcur = confnext;
        }
-    
-       if (!(*context)->pdb_selected) {
-               DEBUG(0,("failed to select passdb backed!\n"));
-               talloc_destroy((*context)->mem_ctx);
-               *context = NULL;
-               goto done;
-       }
+       SAFE_FREE(conf);
 
        nt_status = NT_STATUS_OK;
 
- done:
-       SAFE_FREE(module_name);
-
        return nt_status;
 }
 
-
 /******************************************************************
  Return an already initialised pdb_context, to facilitate backward 
  compatibility (see functions below).
@@ -244,20 +350,20 @@ NTSTATUS make_pdb_context_name(struct pdb_context **context, const char *selecte
 static struct pdb_context *pdb_get_static_context(BOOL reload) 
 {
        static struct pdb_context *pdb_context = NULL;
-       
+
        if ((pdb_context) && (reload)) {
                pdb_context->free_fn(&pdb_context);
                if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) {
                        return NULL;
                }
        }
-       
+
        if (!pdb_context) {
                if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) {
                        return NULL;
                }
        }
-       
+
        return pdb_context;
 }
 
@@ -347,21 +453,21 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct)
 BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct) 
 {
        struct pdb_context *pdb_context = pdb_get_static_context(False);
-       
+
        if (!pdb_context) {
                return False;
        }
-       
+
        return pdb_context->pdb_delete_sam_account(pdb_context, sam_acct);
 }
 
 #endif /* !defined(WITH_NISPLUS_SAM) */
 
 /***************************************************************
- Initialize the static context (at smbd startup etc). 
 Initialize the static context (at smbd startup etc). 
 
- If uninitialised, context will auto-init on first use.
-***************************************************************/
 If uninitialised, context will auto-init on first use.
+ ***************************************************************/
 
 BOOL initialize_password_db(BOOL reload)
 {      
@@ -381,11 +487,3 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
 
        return NT_STATUS_OK;
 }
-
-
-
-
-
-
-
-
index 02bb43b7ffe8b6876c8ef63671570cf8b27191c7..dc6b9f97ff497e73bcc2fc4daf586ea2d09de4e5 100644 (file)
@@ -1006,9 +1006,9 @@ static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_s
 /**********************************************************************
 Connect to LDAP server for password enumeration
 *********************************************************************/
-static BOOL ldapsam_setsampwent(struct pdb_context *context, BOOL update)
+static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
 {
-       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        int rc;
        pstring filter;
 
@@ -1054,9 +1054,9 @@ static BOOL ldapsam_setsampwent(struct pdb_context *context, BOOL update)
 /**********************************************************************
 End enumeration of the LDAP password list 
 *********************************************************************/
-static void ldapsam_endsampwent(struct pdb_context *context)
+static void ldapsam_endsampwent(struct pdb_methods *my_methods)
 {
-       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        if (ldap_state->ldap_struct && ldap_state->result)
        {
                ldap_msgfree(ldap_state->result);
@@ -1069,9 +1069,9 @@ static void ldapsam_endsampwent(struct pdb_context *context)
 /**********************************************************************
 Get the next entry in the LDAP password database 
 *********************************************************************/
-static BOOL ldapsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT * user)
+static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * user)
 {
-       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        BOOL ret = False;
 
        while (!ret) {
@@ -1093,9 +1093,9 @@ static BOOL ldapsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT * user)
 /**********************************************************************
 Get SAM_ACCOUNT entry from LDAP by username 
 *********************************************************************/
-static BOOL ldapsam_getsampwnam(struct pdb_context *context, SAM_ACCOUNT * user, const char *sname)
+static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const char *sname)
 {
-       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        LDAP *ldap_struct;
        LDAPMessage *result;
        LDAPMessage *entry;
@@ -1144,9 +1144,9 @@ static BOOL ldapsam_getsampwnam(struct pdb_context *context, SAM_ACCOUNT * user,
 /**********************************************************************
 Get SAM_ACCOUNT entry from LDAP by rid 
 *********************************************************************/
-static BOOL ldapsam_getsampwrid(struct pdb_context *context, SAM_ACCOUNT * user, uint32 rid)
+static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, uint32 rid)
 {
-       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        LDAP *ldap_struct;
        LDAPMessage *result;
        LDAPMessage *entry;
@@ -1199,9 +1199,9 @@ static BOOL ldapsam_getsampwrid(struct pdb_context *context, SAM_ACCOUNT * user,
 /**********************************************************************
 Delete entry from LDAP for username 
 *********************************************************************/
-static BOOL ldapsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT * sam_acct)
+static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, const SAM_ACCOUNT * sam_acct)
 {
-       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        const char *sname;
        int rc;
        char *dn;
@@ -1259,9 +1259,9 @@ static BOOL ldapsam_delete_sam_account(struct pdb_context *context, const SAM_AC
 /**********************************************************************
 Update SAM_ACCOUNT 
 *********************************************************************/
-static BOOL ldapsam_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd)
+static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, const SAM_ACCOUNT * newpwd)
 {
-       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        int rc;
        char *dn;
        LDAP *ldap_struct;
@@ -1326,9 +1326,9 @@ static BOOL ldapsam_update_sam_account(struct pdb_context *context, const SAM_AC
 /**********************************************************************
 Add SAM_ACCOUNT to LDAP 
 *********************************************************************/
-static BOOL ldapsam_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd)
+static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, const SAM_ACCOUNT * newpwd)
 {
-       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+       struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        int rc;
        pstring filter;
        LDAP *ldap_struct = NULL;
index 89a4217c3b1a62c5d4a3e559c29724948a63a3c9..18c949c5927baa2bd03410345a63ebdf25154fab 100644 (file)
@@ -198,7 +198,7 @@ static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int
     DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile));
 
     if((fp = sys_fopen(pfile, open_mode)) == NULL) {
-      DEBUG(2, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) ));
+      DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) ));
       return NULL;
     }
 
@@ -1340,9 +1340,9 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_AC
 /*****************************************************************
  Functions to be implemented by the new passdb API 
  ****************************************************************/
-static BOOL smbpasswd_setsampwent (struct pdb_context *context, BOOL update)
+static BOOL smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update)
 {
-       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        
        smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file, 
                                                       update ? PWF_UPDATE : PWF_READ, 
@@ -1370,17 +1370,17 @@ static BOOL smbpasswd_setsampwent (struct pdb_context *context, BOOL update)
        return (smbpasswd_state->pw_file != NULL);                 
 }
 
-static void smbpasswd_endsampwent (struct pdb_context *context)
+static void smbpasswd_endsampwent (struct pdb_methods *my_methods)
 {
-       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth));
 }
  
 /*****************************************************************
  ****************************************************************/
-static BOOL smbpasswd_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
+static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
 {
-       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd *pw_buf=NULL;
        BOOL done = False;
        DEBUG(5,("pdb_getsampwent\n"));
@@ -1419,9 +1419,9 @@ static BOOL smbpasswd_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user
  call getpwnam() for unix account information until we have found
  the correct entry
  ***************************************************************/
-static BOOL smbpasswd_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
+static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const char *username)
 {
-       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd *smb_pw;
        void *fp = NULL;
        char *domain = NULL;
@@ -1489,9 +1489,9 @@ static BOOL smbpasswd_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_
 }
 
 
-static BOOL smbpasswd_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct,uint32 rid)
+static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct,uint32 rid)
 {
-       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd *smb_pw;
        void *fp = NULL;
 
@@ -1533,9 +1533,9 @@ static BOOL smbpasswd_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_
        return True;
 }
 
-static BOOL smbpasswd_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass)
+static BOOL smbpasswd_add_sam_account(struct pdb_methods *my_methods, const SAM_ACCOUNT *sampass)
 {
-       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd smb_pw;
        
        /* convert the SAM_ACCOUNT */
@@ -1551,9 +1551,9 @@ static BOOL smbpasswd_add_sam_account(struct pdb_context *context, const SAM_ACC
        return True;
 }
 
-static BOOL smbpasswd_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass)
+static BOOL smbpasswd_update_sam_account(struct pdb_methods *my_methods, const SAM_ACCOUNT *sampass)
 {
-       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd smb_pw;
        
        /* convert the SAM_ACCOUNT */
@@ -1567,9 +1567,9 @@ static BOOL smbpasswd_update_sam_account(struct pdb_context *context, const SAM_
        return True;
 }
 
-static BOOL smbpasswd_delete_sam_account (struct pdb_context *context, const SAM_ACCOUNT *sampass)
+static BOOL smbpasswd_delete_sam_account (struct pdb_methods *my_methods, const SAM_ACCOUNT *sampass)
 {
-       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
 
        const char *username = pdb_get_username(sampass);
 
index a8edac917e28e0c9372fd342a294c318df7bea31..7092caa15ef557fce936719fad331111cfcca37e 100644 (file)
@@ -462,9 +462,9 @@ static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state,
  Open the TDB passwd database for SAM account enumeration.
 ****************************************************************/
 
-static BOOL tdbsam_setsampwent(struct pdb_context *context, BOOL update)
+static BOOL tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
 {
-       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
        
        /* 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)))
@@ -490,9 +490,9 @@ static void close_tdb(struct tdbsam_privates *tdb_state)
  End enumeration of the TDB passwd list.
 ****************************************************************/
 
-static void tdbsam_endsampwent(struct pdb_context *context)
+static void tdbsam_endsampwent(struct pdb_methods *my_methods)
 {
-       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
        close_tdb(tdb_state);
        
        DEBUG(7, ("endtdbpwent: closed sam database.\n"));
@@ -502,9 +502,9 @@ static void tdbsam_endsampwent(struct pdb_context *context)
  Get one SAM_ACCOUNT from the TDB (next in line)
 *****************************************************************/
 
-static BOOL tdbsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
+static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
 {
-       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
        TDB_DATA        data;
        char *prefix = USERPREFIX;
        int  prefixlen = strlen (prefix);
@@ -550,9 +550,9 @@ static BOOL tdbsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
  Lookup a name in the SAM TDB
 ******************************************************************/
 
-static BOOL tdbsam_getsampwnam (struct pdb_context *context, SAM_ACCOUNT *user, const char *sname)
+static BOOL tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
 {
-       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
        TDB_CONTEXT     *pwd_tdb;
        TDB_DATA        data, key;
        fstring         keystr;
@@ -606,9 +606,9 @@ static BOOL tdbsam_getsampwnam (struct pdb_context *context, SAM_ACCOUNT *user,
  Search by rid
  **************************************************************************/
 
-static BOOL tdbsam_getsampwrid (struct pdb_context *context, SAM_ACCOUNT *user, uint32 rid)
+static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
 {
-       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
        TDB_CONTEXT             *pwd_tdb;
        TDB_DATA                data, key;
        fstring                 keystr;
@@ -644,16 +644,16 @@ static BOOL tdbsam_getsampwrid (struct pdb_context *context, SAM_ACCOUNT *user,
        
        tdb_close (pwd_tdb);
        
-       return tdbsam_getsampwnam (context, user, name);
+       return tdbsam_getsampwnam (my_methods, user, name);
 }
 
 /***************************************************************************
  Delete a SAM_ACCOUNT
 ****************************************************************************/
 
-static BOOL tdbsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sam_pass)
+static BOOL tdbsam_delete_sam_account(struct pdb_methods *my_methods, const SAM_ACCOUNT *sam_pass)
 {
-       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
        TDB_CONTEXT     *pwd_tdb;
        TDB_DATA        key;
        fstring         keystr;
@@ -707,9 +707,9 @@ static BOOL tdbsam_delete_sam_account(struct pdb_context *context, const SAM_ACC
  Update the TDB SAM
 ****************************************************************************/
 
-static BOOL tdb_update_sam(struct pdb_context *context, const SAM_ACCOUNT* newpwd, int flag)
+static BOOL tdb_update_sam(struct pdb_methods *my_methods, const SAM_ACCOUNT* newpwd, int flag)
 {
-       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
        TDB_CONTEXT     *pwd_tdb = NULL;
        TDB_DATA        key, data;
        uint8           *buf = NULL;
@@ -823,18 +823,18 @@ done:
  Modifies an existing SAM_ACCOUNT
 ****************************************************************************/
 
-static BOOL tdbsam_update_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd)
+static BOOL tdbsam_update_sam_account (struct pdb_methods *my_methods, const SAM_ACCOUNT *newpwd)
 {
-       return (tdb_update_sam(context, newpwd, TDB_MODIFY));
+       return (tdb_update_sam(my_methods, newpwd, TDB_MODIFY));
 }
 
 /***************************************************************************
  Adds an existing SAM_ACCOUNT
 ****************************************************************************/
 
-static BOOL tdbsam_add_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd)
+static BOOL tdbsam_add_sam_account (struct pdb_methods *my_methods, const SAM_ACCOUNT *newpwd)
 {
-       return (tdb_update_sam(context, newpwd, TDB_INSERT));
+       return (tdb_update_sam(my_methods, newpwd, TDB_INSERT));
 }
 
 static void free_private_data(void **vp) 
index 1fb1f2355b6596faf6cbb7ee090cdf792b8e5bbf..421a72923aa7d8a2e5512cfcc520eec0fbea43fe 100644 (file)
@@ -4,6 +4,7 @@
    
    Copyright (C) Simo Sorce      2000
    Copyright (C) Andrew Bartlett 2001   
+   Copyright (C) Jelmer Vernooij 2002
 
    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
 extern pstring global_myname;
 extern BOOL AllowDebugChange;
 
-/*
- * Next two lines needed for SunOS and don't
- * hurt anything else...
- */
-extern char *optarg;
-extern int optind;
-
 /*********************************************************
- Print command usage on stderr and die.
-**********************************************************/
-static void usage(void)
-{
-       if (getuid() == 0) {
-               printf("pdbedit options\n");
-       } else {
-               printf("You need to be root to use this tool!\n");
+ Add all currently available users to another db
+ ********************************************************/
+
+int export_database (struct pdb_context *in, char *db){
+       struct pdb_context *context;
+       SAM_ACCOUNT *user = NULL;
+
+       if(!NT_STATUS_IS_OK(make_pdb_context_name(&context, db))){
+               fprintf(stderr, "Can't initialize %s.\n", db);
+               return 1;
+       }
+
+       if(!in->pdb_setsampwent(in, 0)){
+               fprintf(stderr, "Can't sampwent!\n");
+               return 1;
+       }
+
+       if(!NT_STATUS_IS_OK(pdb_init_sam(&user))){
+               fprintf(stderr, "Can't initialize new SAM_ACCOUNT!\n");
+               return 1;
        }
-       printf("(actually to add a user you need to use smbpasswd)\n");
-       printf("options:\n");
-       printf("  -l                   list usernames\n");
-       printf("     -v                verbose output\n");
-       printf("     -w                smbpasswd file style\n");
-       printf("  -u username          print user's info\n");
-       printf("     -f fullname       set Full Name\n");
-       printf("     -h homedir        set home directory\n");
-       printf("     -d drive          set home dir drive\n");
-       printf("     -s script         set logon script\n");
-       printf("     -p profile        set profile path\n");
-       printf("  -a                   create new account\n");
-       printf("     -m                it is a machine trust\n");
-       printf("  -x                   delete this user\n");
-       printf("  -i file              import account from file (smbpasswd style)\n");
-       printf("  -D debuglevel        set DEBUGELEVEL (default = 1)\n");
-       exit(1);
+
+       while(in->pdb_getsampwent(in,user)){
+               context->pdb_add_sam_account(context,user);
+               if(!NT_STATUS_IS_OK(pdb_reset_sam(user))){
+                       fprintf(stderr, "Can't reset SAM_ACCOUNT!\n");
+                       return 1;
+               }
+       }
+
+       in->pdb_endsampwent(in);
+
+       return 0;
 }
 
 /*********************************************************
@@ -126,7 +127,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst
  Get an Print User Info
 **********************************************************/
 
-static int print_user_info (char *username, BOOL verbosity, BOOL smbpwdstyle)
+static int print_user_info (struct pdb_context *in, char *username, BOOL verbosity, BOOL smbpwdstyle)
 {
        SAM_ACCOUNT *sam_pwent=NULL;
        BOOL ret;
@@ -135,7 +136,7 @@ static int print_user_info (char *username, BOOL verbosity, BOOL smbpwdstyle)
                return -1;
        }
        
-       ret = pdb_getsampwnam (sam_pwent, username);
+       ret = in->pdb_getsampwnam (in, sam_pwent, username);
 
        if (ret==False) {
                fprintf (stderr, "Username not found!\n");
@@ -152,13 +153,13 @@ static int print_user_info (char *username, BOOL verbosity, BOOL smbpwdstyle)
 /*********************************************************
  List Users
 **********************************************************/
-static int print_users_list (BOOL verbosity, BOOL smbpwdstyle)
+static int print_users_list (struct pdb_context *in, BOOL verbosity, BOOL smbpwdstyle)
 {
        SAM_ACCOUNT *sam_pwent=NULL;
        BOOL check, ret;
        
        errno = 0; /* testing --simo */
-       check = pdb_setsampwent(False);
+       check = in->pdb_setsampwent(in, False);
        if (check && errno == ENOENT) {
                fprintf (stderr,"Password database not found!\n");
                exit(1);
@@ -167,7 +168,7 @@ static int print_users_list (BOOL verbosity, BOOL smbpwdstyle)
        check = True;
        if (!(NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)))) return 1;
 
-       while (check && (ret = pdb_getsampwent (sam_pwent))) {
+       while (check && (ret = in->pdb_getsampwent (in, sam_pwent))) {
                if (verbosity)
                        printf ("---------------\n");
                print_sam_info (sam_pwent, verbosity, smbpwdstyle);
@@ -176,7 +177,7 @@ static int print_users_list (BOOL verbosity, BOOL smbpwdstyle)
        }
        if (check) pdb_free_sam(&sam_pwent);
        
-       pdb_endsampwent();
+       in->pdb_endsampwent(in);
        return 0;
 }
 
@@ -184,14 +185,14 @@ static int print_users_list (BOOL verbosity, BOOL smbpwdstyle)
  Set User Info
 **********************************************************/
 
-static int set_user_info (char *username, char *fullname, char *homedir, char *drive, char *script, char *profile)
+static int set_user_info (struct pdb_context *in, char *username, char *fullname, char *homedir, char *drive, char *script, char *profile)
 {
        SAM_ACCOUNT *sam_pwent=NULL;
        BOOL ret;
        
        pdb_init_sam(&sam_pwent);
        
-       ret = pdb_getsampwnam (sam_pwent, username);
+       ret = in->pdb_getsampwnam (in, sam_pwent, username);
        if (ret==False) {
                fprintf (stderr, "Username not found!\n");
                pdb_free_sam(&sam_pwent);
@@ -209,8 +210,8 @@ static int set_user_info (char *username, char *fullname, char *homedir, char *d
        if (profile)
                pdb_set_profile_path (sam_pwent, profile, True);
        
-       if (pdb_update_sam_account (sam_pwent))
-               print_user_info (username, True, False);
+       if (in->pdb_update_sam_account (in, sam_pwent))
+               print_user_info (in, username, True, False);
        else {
                fprintf (stderr, "Unable to modify entry!\n");
                pdb_free_sam(&sam_pwent);
@@ -223,7 +224,7 @@ static int set_user_info (char *username, char *fullname, char *homedir, char *d
 /*********************************************************
  Add New User
 **********************************************************/
-static int new_user (char *username, char *fullname, char *homedir, char *drive, char *script, char *profile)
+static int new_user (struct pdb_context *in, char *username, char *fullname, char *homedir, char *drive, char *script, char *profile)
 {
        SAM_ACCOUNT *sam_pwent=NULL;
        struct passwd  *pwd = NULL;
@@ -265,8 +266,8 @@ static int new_user (char *username, char *fullname, char *homedir, char *drive,
        
        pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL);
        
-       if (pdb_add_sam_account (sam_pwent)) { 
-               print_user_info (username, True, False);
+       if (in->pdb_add_sam_account (in, sam_pwent)) { 
+               print_user_info (in, username, True, False);
        } else {
                fprintf (stderr, "Unable to add user! (does it alredy exist?)\n");
                pdb_free_sam (&sam_pwent);
@@ -280,7 +281,7 @@ static int new_user (char *username, char *fullname, char *homedir, char *drive,
  Add New Machine
 **********************************************************/
 
-static int new_machine (char *machinename)
+static int new_machine (struct pdb_context *in, char *machinename)
 {
        SAM_ACCOUNT *sam_pwent=NULL;
        char name[16];
@@ -307,8 +308,8 @@ static int new_machine (char *machinename)
        
        pdb_set_group_rid(sam_pwent, DOMAIN_GROUP_RID_COMPUTERS);
        
-       if (pdb_add_sam_account (sam_pwent)) {
-               print_user_info (name, True, False);
+       if (in->pdb_add_sam_account (in, sam_pwent)) {
+               print_user_info (in, name, True, False);
        } else {
                fprintf (stderr, "Unable to add machine! (does it already exist?)\n");
                pdb_free_sam (&sam_pwent);
@@ -322,7 +323,7 @@ static int new_machine (char *machinename)
  Delete user entry
 **********************************************************/
 
-static int delete_user_entry (char *username)
+static int delete_user_entry (struct pdb_context *in, char *username)
 {
        SAM_ACCOUNT *samaccount = NULL;
 
@@ -330,19 +331,19 @@ static int delete_user_entry (char *username)
                return -1;
        }
 
-       if (!pdb_getsampwnam(samaccount, username)) {
+       if (!in->pdb_getsampwnam(in, samaccount, username)) {
                fprintf (stderr, "user %s does not exist in the passdb\n", username);
                return -1;
        }
 
-       return pdb_delete_sam_account (samaccount);
+       return in->pdb_delete_sam_account (in, samaccount);
 }
 
 /*********************************************************
  Delete machine entry
 **********************************************************/
 
-static int delete_machine_entry (char *machinename)
+static int delete_machine_entry (struct pdb_context *in, char *machinename)
 {
        char name[16];
        SAM_ACCOUNT *samaccount = NULL;
@@ -355,189 +356,12 @@ static int delete_machine_entry (char *machinename)
                return -1;
        }
 
-       if (!pdb_getsampwnam(samaccount, name)) {
+       if (!in->pdb_getsampwnam(in, samaccount, name)) {
                fprintf (stderr, "user %s does not exist in the passdb\n", name);
                return -1;
        }
 
-       return pdb_delete_sam_account (samaccount);
-}
-
-/*********************************************************
- Import smbpasswd style file
-**********************************************************/
-
-static int import_users (char *filename)
-{
-       FILE *fp = NULL;
-       SAM_ACCOUNT *sam_pwent = NULL;
-       static pstring  user_name;
-       static unsigned char smbpwd[16];
-       static unsigned char smbntpwd[16];
-       char linebuf[256];
-       size_t linebuf_len;
-       unsigned char c;
-       unsigned char *p;
-       long uidval;
-       int line = 0;
-       int good = 0;
-       struct passwd *pwd;
-
-       if((fp = sys_fopen(filename, "rb")) == NULL) {
-               fprintf (stderr, "%s\n", strerror (ferror (fp)));
-               return -1;
-       }
-       
-       while (!feof(fp)) {
-               /*Get a new line*/
-               linebuf[0] = '\0';
-               fgets(linebuf, 256, fp);
-               if (ferror(fp)) {
-                       fprintf (stderr, "%s\n", strerror (ferror (fp)));
-                       return -1;
-               }
-               if ((linebuf_len = strlen(linebuf)) == 0) {
-                       line++;
-                       continue;
-               }
-               if (linebuf[linebuf_len - 1] != '\n') {
-                       c = '\0';
-                       while (!ferror(fp) && !feof(fp)) {
-                               c = fgetc(fp);
-                               if (c == '\n') break;
-                       }
-               } else
-                       linebuf[linebuf_len - 1] = '\0';
-               linebuf[linebuf_len] = '\0';
-               if ((linebuf[0] == 0) && feof(fp)) {
-                       /*end of file!!*/
-                       return 0;
-               }
-               line++;
-               if (linebuf[0] == '#' || linebuf[0] == '\0')
-                       continue;
-               
-               /* Get user name */
-               p = (unsigned char *) strchr_m(linebuf, ':');
-               if (p == NULL) {
-                       fprintf (stderr, "Error: malformed password entry at line %d !!\n", line);
-                       continue;
-               }
-               strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
-               user_name[PTR_DIFF(p, linebuf)] = '\0';
-
-               /* Get smb uid. */
-               p++;
-               if(*p == '-') {
-                       fprintf (stderr, "Error: negative uid at line %d\n", line);
-                       continue;
-               }
-               if (!isdigit(*p)) {
-                       fprintf (stderr, "Error: malformed password entry at line %d (uid not number)\n", line);
-                       continue;
-               }
-               uidval = atoi((char *) p);
-               while (*p && isdigit(*p)) p++;
-               if (*p != ':') {
-                       fprintf (stderr, "Error: malformed password entry at line %d (no : after uid)\n", line);
-                       continue;
-               }
-               if(!(pwd = sys_getpwnam(user_name))) {
-                       fprintf(stderr, "User %s does not \
-exist in system password file (usually /etc/passwd). Cannot add \
-account without a valid local system user.\n", user_name);
-                       return False;
-               }
-
-               if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sam_pwent, pwd))) {
-                       fprintf(stderr, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
-                       return False;
-               }
-
-               /* Get passwords */
-               p++;
-               if (*p == '*' || *p == 'X') {
-                       /* Password deliberately invalid */
-                       fprintf (stderr, "Warning: entry invalidated for user %s\n", user_name);
-                       pdb_set_lanman_passwd(sam_pwent, NULL);
-                       pdb_set_nt_passwd(sam_pwent,NULL);
-                       pdb_set_acct_ctrl(sam_pwent, pdb_get_acct_ctrl(sam_pwent) | ACB_DISABLED);
-               } else {
-                       if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
-                               fprintf (stderr, "Error: malformed password entry at line %d (password too short)\n",line);
-                               pdb_free_sam (&sam_pwent);
-                               continue;
-                       }
-                       if (p[32] != ':') {
-                               fprintf (stderr, "Error: malformed password entry at line %d (no terminating :)\n",line);
-                               pdb_free_sam (&sam_pwent);
-                               continue;
-                       }
-                       if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
-                               pdb_set_lanman_passwd(sam_pwent, NULL);
-                               pdb_set_acct_ctrl(sam_pwent, pdb_get_acct_ctrl(sam_pwent) | ACB_PWNOTREQ);
-                       } else {
-                               if (!pdb_gethexpwd((char *)p, smbpwd)) {
-                                       fprintf (stderr, "Error: malformed Lanman password entry at line %d (non hex chars)\n", line);
-                                       pdb_free_sam (&sam_pwent);
-                                       continue;
-                               }
-                               pdb_set_lanman_passwd(sam_pwent, smbpwd);
-                       }
-                       /* NT password */
-                       p += 33;
-                       if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
-                               if (*p != '*' && *p != 'X') {
-                                       if (pdb_gethexpwd((char *)p,smbntpwd)) {
-                                               pdb_set_nt_passwd(sam_pwent, smbntpwd);
-                                       }
-                               }
-                               p += 33;
-                       }
-               }
-
-               /* Get ACCT_CTRL field if any */
-               if (*p == '[') {
-                       uint16 acct_ctrl;
-                       unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']');
-                       
-                       acct_ctrl = pdb_decode_acct_ctrl((char*)p);
-                       if (acct_ctrl)
-                               acct_ctrl = ACB_NORMAL;
-
-                       pdb_set_acct_ctrl(sam_pwent, acct_ctrl);
-                       
-                       /* Get last change time */
-                       if(end_p)
-                               p = end_p + 1;
-                       if(*p == ':') {
-                               p++;
-                               if(*p && (StrnCaseCmp((char *)p, "LCT-", 4)==0)) {
-                                       int i;
-                                       
-                                       p += 4;
-                                       for(i = 0; i < 8; i++) {
-                                               if(p[i] == '\0' || !isxdigit(p[i])) break;
-                                       }
-                                       if(i == 8) {
-                                                pdb_set_pass_last_set_time (sam_pwent, (time_t)strtol((char *)p, NULL, 16));
-                                       }
-                               }
-                       }
-               }
-
-                /* Now ADD the entry */
-               if (!(pdb_add_sam_account (sam_pwent))) {
-                       fprintf (stderr, "Unable to add user entry!\n");
-                       pdb_free_sam (&sam_pwent);
-                       continue;
-               }
-               printf ("%s imported!\n", user_name);
-               good++;
-               pdb_free_sam (&sam_pwent);
-       }
-       printf ("%d lines read.\n%d entryes imported\n", line, good);
-       return 0;
+       return in->pdb_delete_sam_account (in, samaccount);
 }
 
 /*********************************************************
@@ -546,7 +370,7 @@ account without a valid local system user.\n", user_name);
 
 int main (int argc, char **argv)
 {
-       int ch;
+       struct pdb_context *in;
        BOOL list_users = False;
        BOOL verbose = False;
        BOOL spstyle = False;
@@ -555,93 +379,64 @@ int main (int argc, char **argv)
        BOOL add_user = False;
        BOOL delete_user = False;
        BOOL import = False;
-       char *user_name = NULL;
+       int opt;
        char *full_name = NULL;
+       char *user_name = NULL;
        char *home_dir = NULL;
        char *home_drive = NULL;
+       char *backend_in = NULL;
+       char *backend_out = NULL;
        char *logon_script = NULL;
        char *profile_path = NULL;
-       char *smbpasswd = NULL;
-
-       setup_logging("pdbedit", True);
-
-       if (argc < 2) {
-               usage();
-               return 0;
-       }
+       poptContext pc;
+       struct poptOption long_options[] = {
+               POPT_AUTOHELP
+               {"list",        'l',POPT_ARG_VAL, &list_users, 1, "list all users", NULL},
+               {"verbose",     'v',POPT_ARG_VAL, &verbose, 1, "be verbose", NULL },
+               {"smbpasswd-style",     'w',POPT_ARG_VAL, &spstyle, 1, "give output in smbpasswd style", NULL},
+               {"user",        'u',POPT_ARG_STRING,&user_name, 0, "use username", "USER" },
+               {"fullname",    'f',POPT_ARG_STRING,&full_name, 0, "set full name", NULL},
+               {"homedir",     'h',POPT_ARG_STRING,&home_dir, 0, "set home directory", NULL},
+               {"drive",       'd',POPT_ARG_STRING,&home_drive, 0, "set home drive", NULL},
+               {"script",      's',POPT_ARG_STRING,&logon_script, 0, "set logon script", NULL},
+               {"profile",     'p',POPT_ARG_STRING,&profile_path, 0, "set profile path", NULL},
+               {"create",      'a',POPT_ARG_VAL,&add_user, 1, "create user", NULL},
+               {"machine",     'm',POPT_ARG_VAL,&machine, 1,"account is a machine account",NULL},
+               {"delete",      'x',POPT_ARG_VAL,&delete_user,1,"delete user",NULL},
+               {"import",      'i',POPT_ARG_STRING,&backend_in,0,"use different passdb backend",NULL},
+               {"export",      'e',POPT_ARG_STRING,&backend_out,0,"export user accounts to backend", NULL},
+               {"debuglevel",'D',POPT_ARG_INT,&DEBUGLEVEL,0,"set debuglevel",NULL},
+               {0,0,0,0}
+       };
        
        DEBUGLEVEL = 1;
+       setup_logging("pdbedit", True);
        AllowDebugChange = False;
-
+       
        if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
                fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
                        dyn_CONFIGFILE);
                exit(1);
        }
-       
-       if(!initialize_password_db(True)) {
-               fprintf(stderr, "Can't setup password database vectors.\n");
+
+       backend_in = lp_passdb_backend();
+
+       pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
+                                               POPT_CONTEXT_KEEP_FIRST);
+
+       while((opt = poptGetNextOpt(pc)) != -1);
+
+       setparms = (full_name || home_dir || home_drive || logon_script || profile_path);
+
+       if (((add_user?1:0) + (delete_user?1:0) + (list_users?1:0) + (import?1:0) + (setparms?1:0)) + (backend_out?1:0) > 1) {
+               fprintf (stderr, "Incompatible options on command line!\n");
                exit(1);
        }
        
-       while ((ch = getopt(argc, argv, "ad:f:h:i:lmp:s:u:vwxD:")) != EOF) {
-               switch(ch) {
-               case 'a':
-                       add_user = True;
-                       break;
-               case 'm':
-                       machine = True;
-                       break;
-               case 'l':
-                       list_users = True;
-                       break;
-               case 'v':
-                       verbose = True;
-                       break;
-               case 'w':
-                       spstyle = True;
-                       break;
-               case 'u':
-                       user_name = optarg;
-                       break;
-               case 'f':
-                       setparms = True;
-                       full_name = optarg;
-                       break;
-               case 'h':
-                       setparms = True;
-                       home_dir = optarg;
-                       break;
-               case 'd':
-                       setparms = True;
-                       home_drive = optarg;
-                       break;
-               case 's':
-                       setparms = True;
-                       logon_script = optarg;
-                       break;
-               case 'p':
-                       setparms = True;
-                       profile_path = optarg;
-                       break;
-               case 'x':
-                       delete_user = True;
-                       break;
-               case 'i':
-                       import = True;
-                       smbpasswd = optarg;
-                       break;
-               case 'D':
-                       DEBUGLEVEL = atoi(optarg);
-                       break;
-               default:
-                       usage();
-               }
-       }
-       if (((add_user?1:0) + (delete_user?1:0) + (list_users?1:0) + (import?1:0) + (setparms?1:0)) > 1) {
-               fprintf (stderr, "Incompatible options on command line!\n");
-               usage();
-               exit(1);
+
+       if(!NT_STATUS_IS_OK(make_pdb_context_name(&in, backend_in))){
+               fprintf(stderr, "Can't initialize %s.\n", backend_in);
+               return 1;
        }
 
        if (add_user) {
@@ -650,9 +445,9 @@ int main (int argc, char **argv)
                        return -1;
                }
                if (machine)
-                       return new_machine (user_name);
+                       return new_machine (in, user_name);
                else
-                       return new_user (user_name, full_name, home_dir, home_drive, logon_script, profile_path);
+                       return new_user (in, user_name, full_name, home_dir, home_drive, logon_script, profile_path);
        }
 
        if (delete_user) {
@@ -661,32 +456,29 @@ int main (int argc, char **argv)
                        return -1;
                }
                if (machine)
-                       return delete_machine_entry (user_name);
+                       return delete_machine_entry (in, user_name);
                else
-                       return delete_user_entry (user_name);
+                       return delete_user_entry (in, user_name);
        }
        
        if (user_name) {
                if (setparms)
-                       set_user_info ( user_name, full_name,
+                       return set_user_info (in,       user_name, full_name,
                                                home_dir,
                                                home_drive,
                                                logon_script,
                                                profile_path);
                else
-                       return print_user_info (user_name, verbose, spstyle);
-               
-               return 0;
+                       return print_user_info (in, user_name, verbose, spstyle);
        }
 
-       
        if (list_users) 
-               return print_users_list (verbose, spstyle);
+               return print_users_list (in, verbose, spstyle);
+
+       if (backend_out)
+               return export_database(in, backend_out);
        
-       if (import) 
-               return import_users (smbpasswd); 
+       poptPrintHelp(pc, stderr, 0);
        
-       usage();
-
-       return 0;
+       return 1;
 }