Change order of parameters to smb_register_passdb()
[samba.git] / source3 / passdb / pdb_smbpasswd.c
index a6bd66eacee0731cbe1d9b87ce9b0d938e90e32c..c1421bcd53e4e0db29b02b032e7417d37b70a52e 100644 (file)
@@ -101,6 +101,10 @@ static BOOL pw_file_unlock(int fd, int *plock_depth)
 {
   BOOL ret=True;
 
+  if (fd == 0 || *plock_depth == 0) {
+         return True;
+  }
+
   if(*plock_depth == 1)
     ret = do_file_lock(fd, 5, F_UNLCK);
 
@@ -264,10 +268,13 @@ Error was %s\n.", pfile, strerror(errno) ));
 ****************************************************************/
 static void endsmbfilepwent(FILE *fp, int *lock_depth)
 {
+       if (!fp) {
+               return;
+       }
 
-  pw_file_unlock(fileno(fp), lock_depth);
-  fclose(fp);
-  DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n"));
+       pw_file_unlock(fileno(fp), lock_depth);
+       fclose(fp);
+       DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n"));
 }
 
 /*************************************************************************
@@ -400,15 +407,6 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
     /* Skip the ':' */
     p++;
 
-    if (*p == '*' || *p == 'X') {
-      /* Password deliberately invalid - end here. */
-      DEBUG(10, ("getsmbfilepwent: entry invalidated for user %s\n", user_name));
-      pw_buf->smb_nt_passwd = NULL;
-      pw_buf->smb_passwd = NULL;
-      pw_buf->acct_ctrl |= ACB_DISABLED;
-      return pw_buf;
-    }
-
     if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
       DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n"));
       continue;
@@ -423,11 +421,16 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
       pw_buf->smb_passwd = NULL;
       pw_buf->acct_ctrl |= ACB_PWNOTREQ;
     } else {
-      if (!pdb_gethexpwd((char *)p, smbpwd)) {
-        DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
-        continue;
-      }
-      pw_buf->smb_passwd = smbpwd;
+           if (*p == '*' || *p == 'X') {
+                   /* NULL LM password */
+                   pw_buf->smb_passwd = NULL;
+                   DEBUG(10, ("getsmbfilepwent: LM password for user %s invalidated\n", user_name));
+           } else if (pdb_gethexpwd((char *)p, smbpwd)) {
+                   pw_buf->smb_passwd = smbpwd;
+           } else {
+                   pw_buf->smb_passwd = NULL;
+                   DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
+           }
     }
 
     /* 
@@ -510,7 +513,6 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
   int new_entry_length;
   char *new_entry;
   char *p;
-  int i;
 
   new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;
 
@@ -520,38 +522,16 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
   }
 
   slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid);
-  p = &new_entry[strlen(new_entry)];
 
-  if(newpwd->smb_passwd != NULL) {
-    for( i = 0; i < 16; i++) {
-      slprintf((char *)&p[i*2], new_entry_length - (p - new_entry) - 1, "%02X", newpwd->smb_passwd[i]);
-    }
-  } else {
-    i=0;
-    if(newpwd->acct_ctrl & ACB_PWNOTREQ)
-      safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
-    else
-      safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
-  }
+  p = new_entry+strlen(new_entry);
   
-  p += 32;
+  pdb_sethexpwd(p, newpwd->smb_passwd, newpwd->acct_ctrl);
 
-  *p++ = ':';
+  p+=strlen(p); *p = ':'; p++;
 
-  if(newpwd->smb_nt_passwd != NULL) {
-    for( i = 0; i < 16; i++) {
-      slprintf((char *)&p[i*2], new_entry_length - 1 - (p - new_entry), "%02X", newpwd->smb_nt_passwd[i]);
-    }
-  } else {
-    if(newpwd->acct_ctrl & ACB_PWNOTREQ)
-      safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
-    else
-      safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
-  }
-
-  p += 32;
+  pdb_sethexpwd(p, newpwd->smb_nt_passwd, newpwd->acct_ctrl);
 
-  *p++ = ':';
+  p+=strlen(p); *p = ':'; p++;
 
   /* Add the account encoding and the last change time. */
   slprintf((char *)p, new_entry_length - 1 - (p - new_entry),  "%s:LCT-%08X:\n",
@@ -959,30 +939,12 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
   /* Entry is correctly formed. */
 
   /* Create the 32 byte representation of the new p16 */
-  if(pwd->smb_passwd != NULL) {
-    for (i = 0; i < 16; i++) {
-      slprintf(&ascii_p16[i*2], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_passwd[i]);
-    }
-  } else {
-    if(pwd->acct_ctrl & ACB_PWNOTREQ)
-      fstrcpy(ascii_p16, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
-    else
-      fstrcpy(ascii_p16, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
-  }
+  pdb_sethexpwd(ascii_p16, pwd->smb_passwd, pwd->acct_ctrl);
 
   /* Add on the NT md4 hash */
   ascii_p16[32] = ':';
   wr_len = 66;
-  if (pwd->smb_nt_passwd != NULL) {
-    for (i = 0; i < 16; i++) {
-      slprintf(&ascii_p16[(i*2)+33], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_nt_passwd[i]);
-    }
-  } else {
-    if(pwd->acct_ctrl & ACB_PWNOTREQ)
-      fstrcpy(&ascii_p16[33], "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
-    else
-      fstrcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
-  }
+  pdb_sethexpwd(ascii_p16+33, pwd->smb_nt_passwd, pwd->acct_ctrl);
   ascii_p16[65] = ':';
   ascii_p16[66] = '\0'; /* null-terminate the string so that strlen works */
 
@@ -1187,7 +1149,7 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
                uid = pdb_get_uid(sampass);
 
                /* If the user specified a RID, make sure its able to be both stored and retreived */
-               if (rid && uid != fallback_pdb_user_rid_to_uid(rid)) {
+               if (rid && rid != DOMAIN_USER_RID_GUEST && uid != fallback_pdb_user_rid_to_uid(rid)) {
                        DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
                        return False;
                }
@@ -1238,28 +1200,28 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
                return False;
        }
                
-       if ((smbpasswd_state->permit_non_unix_accounts) 
-           && (pw_buf->smb_userid >= smbpasswd_state->low_nua_userid) 
-           && (pw_buf->smb_userid <= smbpasswd_state->high_nua_userid)) {
-
-               pdb_set_user_rid(sam_pass, fallback_pdb_uid_to_user_rid (pw_buf->smb_userid));
-
-               /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. 
-                  
-                  This was down the bottom for machines, but it looks pretty good as
-                  a general default for non-unix users. --abartlet 2002-01-08
-               */
-               pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); 
-               pdb_set_username (sam_pass, pw_buf->smb_name);
-               pdb_set_domain (sam_pass, lp_workgroup());
-       } else {
-
-               pwfile = getpwnam_alloc(pw_buf->smb_name);
-               if (pwfile == NULL) {
+       pwfile = getpwnam_alloc(pw_buf->smb_name);
+       if (pwfile == NULL) {
+               if ((smbpasswd_state->permit_non_unix_accounts) 
+                   && (pw_buf->smb_userid >= smbpasswd_state->low_nua_userid) 
+                   && (pw_buf->smb_userid <= smbpasswd_state->high_nua_userid)) {
+
+                       pdb_set_user_sid_from_rid(sam_pass, fallback_pdb_uid_to_user_rid (pw_buf->smb_userid), PDB_SET);
+                       
+                       /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. 
+                          
+                       This was down the bottom for machines, but it looks pretty good as
+                       a general default for non-unix users. --abartlet 2002-01-08
+                       */
+                       pdb_set_group_sid_from_rid (sam_pass, DOMAIN_GROUP_RID_USERS, PDB_SET); 
+                       pdb_set_username (sam_pass, pw_buf->smb_name, PDB_SET);
+                       pdb_set_domain (sam_pass, lp_workgroup(), PDB_DEFAULT);
+                       
+               } else {
                        DEBUG(0,("build_sam_account: smbpasswd database is corrupt!  username %s with uid %u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid));
                        return False;
                }
-
+       } else {
                if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile))) {
                        return False;
                }
@@ -1267,18 +1229,18 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
                passwd_free(&pwfile);
        }
        
-       pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd);
-       pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd);                   
-       pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl);
-       pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time);
-       pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, True);
+       pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd, PDB_SET);
+       pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd, PDB_SET);                  
+       pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl, PDB_SET);
+       pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);
+       pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);
        
 #if 0  /* JERRY */
        /* the smbpasswd format doesn't have a must change time field, so
           we can't get this right. The best we can do is to set this to 
           some time in the future. 21 days seems as reasonable as any other value :) 
        */
-       pdb_set_pass_must_change_time (sam_pass, pw_buf->pass_last_set_time + MAX_PASSWORD_AGE);
+       pdb_set_pass_must_change_time (sam_pass, pw_buf->pass_last_set_time + MAX_PASSWORD_AGE, PDB_DEFAULT);
 #endif
        return True;
 }
@@ -1286,7 +1248,7 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
 /*****************************************************************
  Functions to be implemented by the new passdb API 
  ****************************************************************/
-static BOOL smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update)
+static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update)
 {
        struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        
@@ -1313,7 +1275,10 @@ static BOOL smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update)
                                                             &(smbpasswd_state->pw_file_lock_depth));
        }
        
-       return (smbpasswd_state->pw_file != NULL);                 
+       if (smbpasswd_state->pw_file != NULL)
+               return NT_STATUS_OK;
+       else
+               return NT_STATUS_UNSUCCESSFUL;  
 }
 
 static void smbpasswd_endsampwent (struct pdb_methods *my_methods)
@@ -1324,8 +1289,9 @@ static void smbpasswd_endsampwent (struct pdb_methods *my_methods)
  
 /*****************************************************************
  ****************************************************************/
-static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
+static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
 {
+       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd *pw_buf=NULL;
        BOOL done = False;
@@ -1336,7 +1302,7 @@ static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *u
 #if 0
                smb_panic("NULL pointer passed to getsampwent (smbpasswd)\n");
 #endif
-               return False;
+               return nt_status;
        }
 
        while (!done)
@@ -1344,7 +1310,7 @@ static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *u
                /* do we have an entry? */
                pw_buf = getsmbfilepwent(smbpasswd_state, smbpasswd_state->pw_file);
                if (pw_buf == NULL) 
-                       return False;
+                       return nt_status;
 
                /* build the SAM_ACCOUNT entry from the smb_passwd struct. 
                   We loop in case the user in the pdb does not exist in 
@@ -1356,7 +1322,7 @@ static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *u
        DEBUG(5,("getsampwent (smbpasswd): done\n"));
 
        /* success */
-       return True;
+       return NT_STATUS_OK;
 }
 
 
@@ -1365,8 +1331,10 @@ static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *u
  call getpwnam() for unix account information until we have found
  the correct entry
  ***************************************************************/
-static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const char *username)
+static NTSTATUS smbpasswd_getsampwnam(struct pdb_methods *my_methods, 
+                                 SAM_ACCOUNT *sam_acct, const char *username)
 {
+       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd *smb_pw;
        void *fp = NULL;
@@ -1380,7 +1348,7 @@ static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *s
 
        if (fp == NULL) {
                DEBUG(0, ("unable to open passdb database.\n"));
-               return False;
+               return nt_status;
        }
 
        while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
@@ -1391,7 +1359,7 @@ static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *s
 
        /* did we locate the username in smbpasswd  */
        if (smb_pw == NULL)
-               return False;
+               return nt_status;
        
        DEBUG(10, ("getsampwnam (smbpasswd): found by name: %s\n", smb_pw->smb_name));
 
@@ -1400,31 +1368,47 @@ static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *s
 #if 0
                smb_panic("NULL pointer passed to pdb_getsampwnam\n");
 #endif
-               return False;
+               return nt_status;
        }
                
        /* now build the SAM_ACCOUNT */
        if (!build_sam_account(smbpasswd_state, sam_acct, smb_pw))
-               return False;
+               return nt_status;
 
        /* success */
-       return True;
+       return NT_STATUS_OK;
 }
 
-static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct,uint32 rid)
+static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
 {
+       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd *smb_pw;
        void *fp = NULL;
+       fstring sid_str;
+       uint32 rid;
+       
+       DEBUG(10, ("smbpasswd_getsampwrid: search by sid: %s\n", sid_to_string(sid_str, sid)));
 
-       DEBUG(10, ("pdb_getsampwrid: search by rid: %d\n", rid));
+       if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
+               return NT_STATUS_UNSUCCESSFUL;
+
+       /* More special case 'guest account' hacks... */
+       if (rid == DOMAIN_USER_RID_GUEST) {
+               const char *guest_account = lp_guestaccount();
+               if (!(guest_account && *guest_account)) {
+                       DEBUG(1, ("Guest account not specfied!\n"));
+                       return nt_status;
+               }
+               return smbpasswd_getsampwnam(my_methods, sam_acct, guest_account);
+       }
 
        /* Open the sam password file - not for update. */
        fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth));
 
        if (fp == NULL) {
                DEBUG(0, ("unable to open passdb database.\n"));
-               return False;
+               return nt_status;
        }
 
        while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (fallback_pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
@@ -1435,7 +1419,7 @@ static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *s
 
        /* did we locate the username in smbpasswd  */
        if (smb_pw == NULL)
-               return False;
+               return nt_status;
        
        DEBUG(10, ("getsampwrid (smbpasswd): found by name: %s\n", smb_pw->smb_name));
                
@@ -1444,43 +1428,44 @@ static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *s
 #if 0
                smb_panic("NULL pointer passed to pdb_getsampwrid\n");
 #endif
-               return False;
+               return nt_status;
        }
 
        /* now build the SAM_ACCOUNT */
        if (!build_sam_account (smbpasswd_state, sam_acct, smb_pw))
-               return False;
+               return nt_status;
 
-       /* success */
-       return True;
-}
+       /* build_sam_account might change the SID on us, if the name was for the guest account */
+       if (NT_STATUS_IS_OK(nt_status) && !sid_equal(pdb_get_user_sid(sam_acct), sid)) {
+               fstring sid_string1, sid_string2;
+               DEBUG(1, ("looking for user with sid %s instead returned %s for account %s!?!\n",
+                         sid_to_string(sid_string1, sid), sid_to_string(sid_string2, pdb_get_user_sid(sam_acct)), pdb_get_username(sam_acct)));
+               return NT_STATUS_NO_SUCH_USER;
+       }
 
-static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
-{
-       uint32 rid;
-       sid_peek_rid(sid, &rid);
-       return smbpasswd_getsampwrid(my_methods, user, rid);
+       /* success */
+       return NT_STATUS_OK;
 }
 
-static BOOL smbpasswd_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
+static NTSTATUS smbpasswd_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
 {
        struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd smb_pw;
        
        /* convert the SAM_ACCOUNT */
        if (!build_smb_pass(&smb_pw, sampass)) {
-               return False;
+               return NT_STATUS_UNSUCCESSFUL;
        }
        
        /* add the entry */
        if(!add_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {
-               return False;
+               return NT_STATUS_UNSUCCESSFUL;
        }
        
-       return True;
+       return NT_STATUS_OK;
 }
 
-static BOOL smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
+static NTSTATUS smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
 {
        struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        struct smb_passwd smb_pw;
@@ -1488,25 +1473,28 @@ static BOOL smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM_ACC
        /* convert the SAM_ACCOUNT */
        if (!build_smb_pass(&smb_pw, sampass)) {
                DEBUG(0, ("smbpasswd_update_sam_account: build_smb_pass failed!\n"));
-               return False;
+               return NT_STATUS_UNSUCCESSFUL;
        }
        
        /* update the entry */
        if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {
                DEBUG(0, ("smbpasswd_update_sam_account: mod_smbfilepwd_entry failed!\n"));
-               return False;
+               return NT_STATUS_UNSUCCESSFUL;
        }
        
-       return True;
+       return NT_STATUS_OK;
 }
 
-static BOOL smbpasswd_delete_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
+static NTSTATUS smbpasswd_delete_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
 {
        struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
 
        const char *username = pdb_get_username(sampass);
 
-       return del_smbfilepwd_entry(smbpasswd_state, username);
+       if (del_smbfilepwd_entry(smbpasswd_state, username))
+               return NT_STATUS_OK;
+
+       return NT_STATUS_UNSUCCESSFUL;
 }
 
 static void free_private_data(void **vp) 
@@ -1519,7 +1507,6 @@ static void free_private_data(void **vp)
        /* No need to free any further, as it is talloc()ed */
 }
 
-
 NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
 {
        NTSTATUS nt_status;
@@ -1566,28 +1553,16 @@ NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
 
        (*pdb_method)->free_private_data = free_private_data;
 
+       if (lp_idmap_uid(&privates->low_nua_userid, &privates->high_nua_userid)) {
+               DEBUG(0, ("idmap uid range defined, non unix accounts enabled\n"));
+               privates->permit_non_unix_accounts = True;
+       }
+
        return NT_STATUS_OK;
 }
 
-NTSTATUS pdb_init_smbpasswd_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+int pdb_smbpasswd_init(void) 
 {
-       NTSTATUS nt_status;
-       struct smbpasswd_privates *privates;
-
-       if (!NT_STATUS_IS_OK(nt_status = pdb_init_smbpasswd(pdb_context, pdb_method, location))) {
-               return nt_status;
-       }
-
-       (*pdb_method)->name = "smbpasswd_nua";
-
-       privates = (*pdb_method)->private_data;
-       
-       privates->permit_non_unix_accounts = True;
-
-       if (!lp_non_unix_account_range(&privates->low_nua_userid, &privates->high_nua_userid)) {
-               DEBUG(0, ("cannot use smbpasswd_nua without 'non unix account range' in smb.conf!\n"));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       return NT_STATUS_OK;
+       smb_register_passdb(PASSDB_INTERFACE_VERSION, "smbpasswd", pdb_init_smbpasswd);
+       return True;
 }