summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/passdb.c80
-rw-r--r--source3/passdb/pdb_interface.c368
-rw-r--r--source3/passdb/pdb_ldap.c14
-rw-r--r--source3/passdb/pdb_nisplus.c16
-rw-r--r--source3/passdb/pdb_smbpasswd.c532
-rw-r--r--source3/passdb/pdb_tdb.c421
6 files changed, 992 insertions, 439 deletions
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 4460af0545..2bb4ee0a75 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -32,28 +32,6 @@
extern DOM_SID global_sam_sid;
-struct passdb_ops *pdb_ops;
-
-#if 0 /* JERRY */
-static void* pdb_handle = NULL;
-#endif
-
-/***************************************************************
- Initialize the password db operations.
-***************************************************************/
-
-BOOL initialize_password_db(BOOL reload)
-{
- /*
- * This function is unfinished right now, so just
- * ignore the details and always return True. It
- * is here only as a placeholder --jerry
- */
- return True;
-
-}
-
-
/************************************************************
Fill the SAM_ACCOUNT with default values.
***********************************************************/
@@ -639,6 +617,7 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
DOM_SID local_sid;
fstring user;
fstring domain;
+ SAM_ACCOUNT *sam_account = NULL;
*psid_name_use = SID_NAME_UNKNOWN;
@@ -671,9 +650,20 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
(void)map_username(user);
- if((pass = Get_Pwnam(user))) {
+ if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
+ return False;
+ }
+
+ if (pdb_getsampwnam(sam_account, user)) {
+ sid_append_rid( &local_sid, pdb_get_user_rid(sam_account));
+ *psid_name_use = SID_NAME_USER;
+ pdb_free_sam(&sam_account);
+
+ } else if((pass = Get_Pwnam(user))) {
sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
*psid_name_use = SID_NAME_USER;
+ pdb_free_sam(&sam_account);
+
} else {
/*
* Maybe it was a group ?
@@ -681,6 +671,8 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
struct group *grp;
GROUP_MAP map;
+ pdb_free_sam(&sam_account);
+
/* check if it's a mapped group */
if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
if (map.gid!=-1) {
@@ -1021,29 +1013,33 @@ BOOL local_password_change(const char *user_name, int local_flags,
pdb_free_sam(&sam_pass);
if (local_flags & LOCAL_ADD_USER) {
- /*
- * Check for a local account - if we're adding only.
- */
-
- if(!(pwd = getpwnam_alloc(user_name))) {
- slprintf(err_str, err_str_len - 1, "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;
- }
+ pwd = getpwnam_alloc(user_name);
} else {
slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
return False;
}
-
- if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sam_pass, pwd))){
- slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
+
+ if (pwd) {
+ /* Local user found, so init from this */
+ if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sam_pass, pwd))){
+ slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
+ passwd_free(&pwd);
+ return False;
+ }
+
passwd_free(&pwd);
- return False;
+ } else {
+ if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_pass))){
+ slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
+ return False;
+ }
+
+ if (!pdb_set_username(sam_pass, user_name)) {
+ slprintf(err_str, err_str_len - 1, "Failed to set username for user %s.\n", user_name);
+ pdb_free_sam(&sam_pass);
+ return False;
+ }
}
-
- passwd_free(&pwd);
-
if (local_flags & LOCAL_TRUST_ACCOUNT) {
if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST)) {
slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
@@ -1135,14 +1131,14 @@ account without a valid local system user.\n", user_name);
return False;
}
} else if (local_flags & LOCAL_DELETE_USER) {
- if (!pdb_delete_sam_account(user_name)) {
+ if (!pdb_delete_sam_account(sam_pass)) {
slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
pdb_free_sam(&sam_pass);
return False;
}
slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
} else {
- if(!pdb_update_sam_account(sam_pass, True)) {
+ if(!pdb_update_sam_account(sam_pass)) {
slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
pdb_free_sam(&sam_pass);
return False;
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
new file mode 100644
index 0000000000..b5e7273520
--- /dev/null
+++ b/source3/passdb/pdb_interface.c
@@ -0,0 +1,368 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ Password and authentication handling
+ Copyright (C) Andrew Bartlett 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.
+*/
+
+#include "includes.h"
+
+/** List of various built-in passdb modules */
+
+const struct pdb_init_function builtin_pdb_init_functions[] = {
+ { "smbpasswd", pdb_init_smbpasswd },
+ { "smbpasswd_nua", pdb_init_smbpasswd_nua },
+ { "tdbsam", pdb_init_tdbsam },
+ { "tdbsam_nua", pdb_init_tdbsam_nua },
+#if 0
+ { "ldap", pdb_init_ldap },
+ { "nisplus", pdb_init_nisplus },
+ { "unix", pdb_init_unix },
+#endif
+ { NULL, NULL}
+};
+
+static BOOL context_setsampwent(struct pdb_context *context, BOOL update)
+{
+ if ((!context) || (!context->pdb_selected)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return False;
+ }
+
+ return context->pdb_selected->setsampwent(context, update);
+}
+
+static void context_endsampwent(struct pdb_context *context)
+{
+ if ((!context) || (!context->pdb_selected)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return;
+ }
+
+ context->pdb_selected->endsampwent(context);
+}
+
+static BOOL context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
+{
+ if ((!context) || (!context->pdb_selected)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return False;
+ }
+
+ return context->pdb_selected->getsampwent(context, user);
+}
+
+static BOOL context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
+{
+ if ((!context) || (!context->pdb_selected)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return False;
+ }
+
+ return context->pdb_selected->getsampwnam(context, sam_acct, username);
+}
+
+static BOOL context_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, uint32 rid)
+{
+ if ((!context) || (!context->pdb_selected)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return False;
+ }
+
+ return context->pdb_selected->getsampwrid(context, sam_acct, rid);
+}
+
+static BOOL context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
+{
+ if ((!context) || (!context->pdb_selected)) {
+ 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);
+}
+
+static BOOL context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
+{
+ if ((!context) || (!context->pdb_selected)) {
+ DEBUG(0, ("invalid pdb_context specified!\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);
+}
+
+static BOOL context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
+{
+ if ((!context) || (!context->pdb_selected)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return False;
+ }
+
+ return context->pdb_selected->delete_sam_account(context, 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);
+ }
+
+ talloc_destroy((*context)->mem_ctx);
+ *context = NULL;
+}
+
+/******************************************************************
+ 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) {
+ DEBUG(0, ("make_pdb_context: talloc init failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *context = talloc(mem_ctx, sizeof(**context));
+ if (!*context) {
+ DEBUG(0, ("make_pdb_context: talloc failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ZERO_STRUCTP(*context);
+
+ (*context)->mem_ctx = mem_ctx;
+
+ (*context)->pdb_setsampwent = context_setsampwent;
+ (*context)->pdb_endsampwent = context_endsampwent;
+ (*context)->pdb_getsampwent = context_getsampwent;
+ (*context)->pdb_getsampwnam = context_getsampwnam;
+ (*context)->pdb_getsampwrid = context_getsampwrid;
+ (*context)->pdb_add_sam_account = context_add_sam_account;
+ (*context)->pdb_update_sam_account = context_update_sam_account;
+ (*context)->pdb_delete_sam_account = context_delete_sam_account;
+
+ (*context)->free_fn = free_pdb_context;
+
+ return NT_STATUS_OK;
+}
+
+
+/******************************************************************
+ Make a pdb_context, given a text string.
+*******************************************************************/
+
+NTSTATUS make_pdb_context_name(struct pdb_context **context, char *selected)
+{
+ /* HINT: Don't store 'selected' becouse its often an lp_ string and will 'go away' */
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ int i;
+
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) {
+ return nt_status;
+ }
+
+ DEBUG(5,("Attempting to find an passdb backend to match %s\n", selected));
+ for (i = 0; builtin_pdb_init_functions[i].name; i++)
+ {
+ if (strequal(builtin_pdb_init_functions[i].name, selected))
+ {
+ DEBUG(5,("Found pdb backend %s (at pos %d)\n", selected, i));
+ if (NT_STATUS_IS_OK(nt_status
+ = builtin_pdb_init_functions[i].init(*context, &(*context)->pdb_selected, NULL))) {
+ DEBUG(5,("pdb backend %s has a valid init\n", selected));
+ (*context)->pdb_selected->name = builtin_pdb_init_functions[i].name;
+ } else {
+ DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, get_nt_error_msg(nt_status)));
+ (*context)->pdb_selected = NULL;
+ }
+ break;
+ }
+ }
+
+ if (!(*context)->pdb_selected) {
+ DEBUG(0,("failed to select passdb backed!\n"));
+ talloc_destroy((*context)->mem_ctx);
+ *context = NULL;
+ return nt_status;
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/******************************************************************
+ Return an already initilised pdb_context, to facilitate backward
+ compatiablity (see functions below).
+*******************************************************************/
+
+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;
+}
+
+#if !defined(WITH_LDAP_SAM) && !defined(WITH_NISPLUS_SAM)
+
+/******************************************************************
+ Backward compatability functions for the original passdb interface
+*******************************************************************/
+
+BOOL pdb_setsampwent(BOOL update)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return pdb_context->pdb_setsampwent(pdb_context, update);
+}
+
+void pdb_endsampwent(void)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return;
+ }
+
+ pdb_context->pdb_endsampwent(pdb_context);
+}
+
+BOOL pdb_getsampwent(SAM_ACCOUNT *user)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return pdb_context->pdb_getsampwent(pdb_context, user);
+}
+
+BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username);
+}
+
+BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct, uint32 rid)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return pdb_context->pdb_getsampwrid(pdb_context, sam_acct, rid);
+}
+
+BOOL pdb_add_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_add_sam_account(pdb_context, sam_acct);
+}
+
+BOOL pdb_update_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_update_sam_account(pdb_context, 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_LDAP_SAM) && !defined(WITH_NISPLUS_SAM) */
+
+/***************************************************************
+ Initialize the static context (at smbd startup etc).
+
+ If uninitialised, context will auto-init on first use.
+***************************************************************/
+
+BOOL initialize_password_db(BOOL reload)
+{
+ return (pdb_get_static_context(reload) != NULL);
+}
+
+
+NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
+{
+ *methods = talloc(mem_ctx, sizeof(struct pdb_methods));
+
+ if (!*methods) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ZERO_STRUCTP(*methods);
+
+ return NT_STATUS_OK;
+}
+
+
+
+
+
+
+
+
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index b687f494cc..4e602cae40 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -840,14 +840,22 @@ BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
/**********************************************************************
Delete entry from LDAP for username
*********************************************************************/
-BOOL pdb_delete_sam_account(const char *sname)
+BOOL pdb_delete_sam_account(SAM_ACCOUNT * sam_acct)
{
+ const char *sname;
int rc;
char *dn;
LDAP *ldap_struct;
LDAPMessage *entry;
LDAPMessage *result;
+ if (!sam_acct) {
+ DEBUG(0, ("sam_acct was NULL!\n"));
+ return False;
+ }
+
+ sname = pdb_get_username(sam_acct);
+
if (!ldap_open_connection (&ldap_struct))
return False;
@@ -891,7 +899,7 @@ BOOL pdb_delete_sam_account(const char *sname)
/**********************************************************************
Update SAM_ACCOUNT
*********************************************************************/
-BOOL pdb_update_sam_account(const SAM_ACCOUNT * newpwd, BOOL override)
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd)
{
int rc;
char *dn;
@@ -952,7 +960,7 @@ BOOL pdb_update_sam_account(const SAM_ACCOUNT * newpwd, BOOL override)
/**********************************************************************
Add SAM_ACCOUNT to LDAP
*********************************************************************/
-BOOL pdb_add_sam_account(const SAM_ACCOUNT * newpwd)
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
{
int rc;
pstring filter;
diff --git a/source3/passdb/pdb_nisplus.c b/source3/passdb/pdb_nisplus.c
index 446ba0ce39..687115733a 100644
--- a/source3/passdb/pdb_nisplus.c
+++ b/source3/passdb/pdb_nisplus.c
@@ -1039,14 +1039,22 @@ BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
/*************************************************************************
Routine to remove entry from the nisplus smbpasswd table
*************************************************************************/
-BOOL pdb_delete_sam_account(const char *sname)
+BOOL pdb_delete_sam_account(SAM_ACCOUNT * user)
{
+ const char *sname;
char *pfile = lp_smb_passwd_file();
pstring nisname;
nis_result *result, *delresult;
nis_object *obj;
int i;
-
+
+ if (!user) {
+ DEBUG(0, ("no SAM_ACCOUNT specified!\n"));
+ return False;
+ }
+
+ suser = pdb_get_username(user);
+
if (!*pfile)
{
DEBUG(0, ("no SMB password file set\n"));
@@ -1095,7 +1103,7 @@ BOOL pdb_delete_sam_account(const char *sname)
/************************************************************************
Routine to add an entry to the nisplus passwd file.
*************************************************************************/
-BOOL pdb_add_sam_account(const SAM_ACCOUNT * newpwd)
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
{
int local_user = 0;
char *pfile;
@@ -1290,7 +1298,7 @@ BOOL pdb_add_sam_account(const SAM_ACCOUNT * newpwd)
/************************************************************************
Routine to modify the nisplus passwd entry.
************************************************************************/
-BOOL pdb_update_sam_account(const SAM_ACCOUNT * newpwd, BOOL override)
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd)
{
nis_result *result, *addresult;
nis_object *obj;
diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c
index a464312ad6..3039e6681c 100644
--- a/source3/passdb/pdb_smbpasswd.c
+++ b/source3/passdb/pdb_smbpasswd.c
@@ -4,6 +4,7 @@
* Copyright (C) Andrew Tridgell 1992-1998
* Modified by Jeremy Allison 1995.
* Modified by Gerald (Jerry) Carter 2000-2001
+ * Modified by Andrew Bartlett 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
@@ -22,8 +23,6 @@
#include "includes.h"
-#ifdef WITH_SMBPASSWD_SAM
-
/*
smb_passwd is analogous to sam_passwd used everywhere
@@ -33,7 +32,8 @@
struct smb_passwd
{
- uid_t smb_userid; /* this is actually the unix uid_t */
+ BOOL smb_userid_set; /* this is actually the unix uid_t */
+ uint32 smb_userid; /* this is actually the unix uid_t */
const char *smb_name; /* username string */
const unsigned char *smb_passwd; /* Null if no password */
@@ -43,13 +43,29 @@ struct smb_passwd
time_t pass_last_set_time; /* password last set time */
};
+struct smbpasswd_privates
+{
+ /* used for maintain locks on the smbpasswd file */
+ int pw_file_lock_depth;
+
+ /* Global File pointer */
+ FILE *pw_file;
+
+ /* formerly static variables */
+ struct smb_passwd pw_buf;
+ pstring user_name;
+ unsigned char smbpwd[16];
+ unsigned char smbntpwd[16];
-extern struct passdb_ops pdb_ops;
+ /* retrive-once info */
+ const char *smbpasswd_file;
-/* used for maintain locks on the smbpasswd file */
-static int pw_file_lock_depth;
-static void *global_vp;
+ BOOL permit_non_unix_accounts;
+ uint32 low_nua_userid;
+ uint32 high_nua_userid;
+
+};
enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE };
@@ -116,7 +132,7 @@ static void pdb_init_smb(struct smb_passwd *user)
been granted to prevent race conditions. JRA.
****************************************************************/
-static void *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int *lock_depth)
+static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int *lock_depth)
{
FILE *fp = NULL;
const char *open_mode = NULL;
@@ -238,15 +254,14 @@ Error was %s\n.", pfile, strerror(errno) ));
}
/* We have a lock on the file. */
- return (void *)fp;
+ return fp;
}
/***************************************************************
End enumeration of the smbpasswd list.
****************************************************************/
-static void endsmbfilepwent(void *vp, int *lock_depth)
+static void endsmbfilepwent(FILE *fp, int *lock_depth)
{
- FILE *fp = (FILE *)vp;
pw_file_unlock(fileno(fp), lock_depth);
fclose(fp);
@@ -257,14 +272,13 @@ static void endsmbfilepwent(void *vp, int *lock_depth)
Routine to return the next entry in the smbpasswd list.
*************************************************************************/
-static struct smb_passwd *getsmbfilepwent(void *vp)
+static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_state, FILE *fp)
{
/* Static buffers we will return. */
- static struct smb_passwd pw_buf;
- static pstring user_name;
- static unsigned char smbpwd[16];
- static unsigned char smbntpwd[16];
- FILE *fp = (FILE *)vp;
+ struct smb_passwd *pw_buf = &smbpasswd_state->pw_buf;
+ char *user_name = smbpasswd_state->user_name;
+ unsigned char *smbpwd = smbpasswd_state->smbpwd;
+ unsigned char *smbntpwd = smbpasswd_state->smbntpwd;
char linebuf[256];
unsigned char c;
unsigned char *p;
@@ -276,9 +290,9 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
return NULL;
}
- pdb_init_smb(&pw_buf);
+ pdb_init_smb(pw_buf);
- pw_buf.acct_ctrl = ACB_NORMAL;
+ pw_buf->acct_ctrl = ACB_NORMAL;
/*
* Scan the file, a line at a time and check if the name matches.
@@ -370,8 +384,8 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
continue;
}
- pw_buf.smb_name = user_name;
- pw_buf.smb_userid = uidval;
+ pw_buf->smb_name = user_name;
+ pw_buf->smb_userid = uidval;
/*
* Now get the password value - this should be 32 hex digits
@@ -385,10 +399,10 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
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;
+ 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)) {
@@ -402,28 +416,28 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
}
if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
- pw_buf.smb_passwd = NULL;
- pw_buf.acct_ctrl |= ACB_PWNOTREQ;
+ 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;
+ pw_buf->smb_passwd = smbpwd;
}
/*
* Now check if the NT compatible password is
* available.
*/
- pw_buf.smb_nt_passwd = NULL;
+ pw_buf->smb_nt_passwd = NULL;
p += 33; /* Move to the first character of the line after
the lanman password. */
if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
if (*p != '*' && *p != 'X') {
if(pdb_gethexpwd((char *)p,smbntpwd))
- pw_buf.smb_nt_passwd = smbntpwd;
+ pw_buf->smb_nt_passwd = smbntpwd;
}
p += 33; /* Move to the first character of the line after
the NT password. */
@@ -435,11 +449,11 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
if (*p == '[')
{
unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']');
- pw_buf.acct_ctrl = pdb_decode_acct_ctrl((char*)p);
+ pw_buf->acct_ctrl = pdb_decode_acct_ctrl((char*)p);
/* Must have some account type set. */
- if(pw_buf.acct_ctrl == 0)
- pw_buf.acct_ctrl = ACB_NORMAL;
+ if(pw_buf->acct_ctrl == 0)
+ pw_buf->acct_ctrl = ACB_NORMAL;
/* Now try and get the last change time. */
if(end_p)
@@ -459,7 +473,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
* read into a time_t as the seconds since
* 1970 that the password was last changed.
*/
- pw_buf.pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
+ pw_buf->pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
}
}
}
@@ -470,13 +484,13 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
* password file as 'normal accounts'. If this changes
* we will have to fix this code. JRA.
*/
- if(pw_buf.smb_name[strlen(pw_buf.smb_name) - 1] == '$') {
- pw_buf.acct_ctrl &= ~ACB_NORMAL;
- pw_buf.acct_ctrl |= ACB_WSTRUST;
+ if(pw_buf->smb_name[strlen(pw_buf->smb_name) - 1] == '$') {
+ pw_buf->acct_ctrl &= ~ACB_NORMAL;
+ pw_buf->acct_ctrl |= ACB_WSTRUST;
}
}
- return &pw_buf;
+ return pw_buf;
}
DEBUG(5,("getsmbfilepwent: end of file reached.\n"));
@@ -547,9 +561,9 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
Routine to add an entry to the smbpasswd file.
*************************************************************************/
-static BOOL add_smbfilepwd_entry(const struct smb_passwd *newpwd)
+static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, struct smb_passwd *newpwd)
{
- char *pfile = lp_smb_passwd_file();
+ const char *pfile = smbpasswd_state->smbpasswd_file;
struct smb_passwd *pwd = NULL;
FILE *fp = NULL;
int wr_len;
@@ -557,13 +571,14 @@ static BOOL add_smbfilepwd_entry(const struct smb_passwd *newpwd)
size_t new_entry_length;
char *new_entry;
SMB_OFF_T offpos;
-
+ uint32 max_found_uid = 0;
+
/* Open the smbpassword file - for update. */
- fp = startsmbfilepwent(pfile, PWF_UPDATE, &pw_file_lock_depth);
+ fp = startsmbfilepwent(pfile, PWF_UPDATE, &(smbpasswd_state->pw_file_lock_depth));
if (fp == NULL && errno == ENOENT) {
/* Try again - create. */
- fp = startsmbfilepwent(pfile, PWF_CREATE, &pw_file_lock_depth);
+ fp = startsmbfilepwent(pfile, PWF_CREATE, &(smbpasswd_state->pw_file_lock_depth));
}
if (fp == NULL) {
@@ -575,18 +590,45 @@ static BOOL add_smbfilepwd_entry(const struct smb_passwd *newpwd)
* Scan the file, a line at a time and check if the name matches.
*/
- while ((pwd = getsmbfilepwent(fp)) != NULL)
+ while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL)
{
if (strequal(newpwd->smb_name, pwd->smb_name))
{
DEBUG(0, ("add_smbfilepwd_entry: entry with name %s already exists\n", pwd->smb_name));
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
return False;
}
- }
+
+ /* Look for a free uid for use in non-unix accounts */
+ if (pwd->smb_userid > max_found_uid) {
+ max_found_uid = pwd->smb_userid;
+ }
+ }
/* Ok - entry doesn't exist. We can add it */
+ /* Account not in /etc/passwd hack!!! */
+ if (!newpwd->smb_userid_set) {
+ if (!smbpasswd_state->permit_non_unix_accounts) {
+ DEBUG(0, ("add_smbfilepwd_entry: cannot add account %s without unix identity\n", pwd->smb_name));
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ return False;
+ }
+
+ if (max_found_uid < smbpasswd_state->low_nua_userid) {
+ newpwd->smb_userid = smbpasswd_state->low_nua_userid;
+ newpwd->smb_userid_set = True;
+ } else if (max_found_uid >= smbpasswd_state->high_nua_userid) {
+ DEBUG(0, ("add_smbfilepwd_entry: cannot add machine %s, no uids are free! \n", newpwd->smb_name));
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+ return False;
+ } else {
+ newpwd->smb_userid = max_found_uid + 1;
+ newpwd->smb_userid_set = True;
+ }
+ }
+
+
/* Create a new smb passwd entry and set it to the given password. */
/*
* The add user write needs to be atomic - so get the fd from
@@ -598,7 +640,7 @@ static BOOL add_smbfilepwd_entry(const struct smb_passwd *newpwd)
{
DEBUG(0, ("add_smbfilepwd_entry(sys_lseek): Failed to add entry for user %s to file %s. \
Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
return False;
}
@@ -606,7 +648,7 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
{
DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \
Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
return False;
}
@@ -630,13 +672,13 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
newpwd->smb_name, strerror(errno)));
}
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
free(new_entry);
return False;
}
free(new_entry);
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
return True;
}
@@ -649,10 +691,10 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
override = True, override XXXXXXXX'd out password or NO PASS
************************************************************************/
-static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
+static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd)
{
/* Static buffers we will return. */
- static pstring user_name;
+ char * user_name = smbpasswd_state->user_name;
char linebuf[256];
char readbuf[1024];
@@ -663,7 +705,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
size_t linebuf_len = 0;
FILE *fp;
int lockfd;
- char *pfile = lp_smb_passwd_file();
+ const char *pfile = smbpasswd_state->smbpasswd_file;
BOOL found_entry = False;
BOOL got_pass_last_set_time = False;
@@ -690,7 +732,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
lockfd = fileno(fp);
- if (!pw_file_lock(lockfd, F_WRLCK, 5, &pw_file_lock_depth)) {
+ if (!pw_file_lock(lockfd, F_WRLCK, 5, &(smbpasswd_state->pw_file_lock_depth))) {
DEBUG(0, ("mod_smbfilepwd_entry: unable to lock file %s\n", pfile));
fclose(fp);
return False;
@@ -710,7 +752,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
fgets(linebuf, sizeof(linebuf), fp);
if (ferror(fp)) {
- pw_file_unlock(lockfd, &pw_file_lock_depth);
+ pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
@@ -779,7 +821,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
}
if (!found_entry) {
- pw_file_unlock(lockfd, &pw_file_lock_depth);
+ pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
@@ -791,7 +833,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
if (!isdigit(*p)) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (uid not number)\n"));
- pw_file_unlock(lockfd, &pw_file_lock_depth);
+ pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
@@ -800,7 +842,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
p++;
if (*p != ':') {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no : after uid)\n"));
- pw_file_unlock(lockfd, &pw_file_lock_depth);
+ pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
@@ -815,30 +857,16 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
/* Record exact password position */
pwd_seekpos += PTR_DIFF(p, linebuf);
- if (!override && (*p == '*' || *p == 'X')) {
- /* Password deliberately invalid - end here. */
- DEBUG(10, ("mod_smbfilepwd_entry: entry invalidated for user %s\n", user_name));
- pw_file_unlock(lockfd, &pw_file_lock_depth);
- fclose(fp);
- return False;
- }
-
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return (False);
}
if (p[32] != ':') {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
- fclose(fp);
- return False;
- }
-
- if (!override && (*p == '*' || *p == 'X')) {
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
@@ -849,14 +877,14 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
the lanman password. */
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return (False);
}
if (p[32] != ':') {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
@@ -966,7 +994,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
if(wr_len > sizeof(linebuf)) {
DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return (False);
}
@@ -984,7 +1012,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
@@ -992,33 +1020,33 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
/* Sanity check - ensure the areas we are writing are framed by ':' */
if (read(fd, linebuf, wr_len+1) != wr_len+1) {
DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
if ((linebuf[0] != ':') || (linebuf[wr_len] != ':')) {
DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) {
DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
if (write(fd, ascii_p16, wr_len) != wr_len) {
DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return False;
}
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
return True;
}
@@ -1027,9 +1055,9 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
Routine to delete an entry in the smbpasswd file by name.
*************************************************************************/
-static BOOL del_smbfilepwd_entry(const char *name)
+static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const char *name)
{
- char *pfile = lp_smb_passwd_file();
+ const char *pfile = smbpasswd_state->smbpasswd_file;
pstring pfile2;
struct smb_passwd *pwd = NULL;
FILE *fp = NULL;
@@ -1044,7 +1072,7 @@ static BOOL del_smbfilepwd_entry(const char *name)
* it.
*/
- if((fp = startsmbfilepwent(pfile, PWF_UPDATE, &pw_file_lock_depth)) == NULL) {
+ if((fp = startsmbfilepwent(pfile, PWF_UPDATE, &(smbpasswd_state->pw_file_lock_depth))) == NULL) {
DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
return False;
}
@@ -1054,7 +1082,7 @@ static BOOL del_smbfilepwd_entry(const char *name)
*/
if((fp_write = startsmbfilepwent(pfile2, PWF_CREATE, &pfile2_lockdepth)) == NULL) {
DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
return False;
}
@@ -1062,7 +1090,7 @@ static BOOL del_smbfilepwd_entry(const char *name)
* Scan the file, a line at a time and check if the name matches.
*/
- while ((pwd = getsmbfilepwent(fp)) != NULL) {
+ while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) {
char *new_entry;
size_t new_entry_length;
@@ -1080,7 +1108,7 @@ static BOOL del_smbfilepwd_entry(const char *name)
DEBUG(0, ("del_smbfilepwd_entry(malloc): Failed to copy entry for user %s to file %s. \
Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
unlink(pfile2);
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
endsmbfilepwent(fp_write, &pfile2_lockdepth);
return False;
}
@@ -1092,7 +1120,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
DEBUG(0, ("del_smbfilepwd_entry(write): Failed to copy entry for user %s to file %s. \
Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
unlink(pfile2);
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
endsmbfilepwent(fp_write, &pfile2_lockdepth);
free(new_entry);
return False;
@@ -1108,7 +1136,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
if(fflush(fp_write) != 0)
{
DEBUG(0, ("del_smbfilepwd_entry: Failed to flush file %s. Error was %s\n", pfile2, strerror(errno)));
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
endsmbfilepwent(fp_write,&pfile2_lockdepth);
return False;
}
@@ -1121,7 +1149,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
unlink(pfile2);
}
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
endsmbfilepwent(fp_write,&pfile2_lockdepth);
return True;
}
@@ -1134,21 +1162,27 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass)
{
uid_t uid;
- gid_t gid;
if (sampass == NULL)
return False;
- uid = pdb_get_uid(sampass);
- gid = pdb_get_gid(sampass);
- if (!IS_SAM_UNIX_USER(sampass)) {
- DEBUG(0,("build_sam_pass: Failing attempt to store user without a UNIX uid or gid. \n"));
- return False;
- }
+ ZERO_STRUCTP(smb_pw);
+
+ if (!IS_SAM_UNIX_USER(sampass)) {
+ smb_pw->smb_userid_set = False;
+ DEBUG(5,("build_sam_pass: storing user without a UNIX uid or gid. \n"));
+ } else {
+ smb_pw->smb_userid_set = True;
+ uid = pdb_get_uid(sampass);
- ZERO_STRUCTP(smb_pw);
+ if (uid != pdb_user_rid_to_uid(pdb_get_user_rid(sampass))) {
+ DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
+ return False;
+ }
+
+ smb_pw->smb_userid=uid;
+ }
- smb_pw->smb_userid=uid;
smb_pw->smb_name=(const char*)pdb_get_username(sampass);
smb_pw->smb_passwd=pdb_get_lanman_passwd(sampass);
@@ -1157,11 +1191,6 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
smb_pw->acct_ctrl=pdb_get_acct_ctrl(sampass);
smb_pw->pass_last_set_time=pdb_get_pass_last_set_time(sampass);
- if (uid != pdb_user_rid_to_uid(pdb_get_user_rid(sampass))) {
- DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
- return False;
- }
-
#if 0
/*
* ifdef'out by JFM on 11/29/2001.
@@ -1187,7 +1216,7 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
/*********************************************************************
Create a SAM_ACCOUNT from a smb_passwd struct
********************************************************************/
-static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
+static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
{
struct passwd *pwfile;
@@ -1196,34 +1225,76 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw
return False;
}
- /* Verify in system password file...
- FIXME!!! This is where we should look up an internal
- mapping of allocated uid for machine accounts as well
- --jerry */
- pwfile = getpwnam_alloc(pw_buf->smb_name);
- if (pwfile == NULL) {
- DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s not in unix passwd database!\n", pw_buf->smb_name));
- return False;
- }
-
- pdb_set_uid (sam_pass, pwfile->pw_uid);
- pdb_set_gid (sam_pass, pwfile->pw_gid);
+ 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, 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_fullname(sam_pass, pwfile->pw_gecos);
-
- pdb_set_user_rid(sam_pass, pdb_uid_to_user_rid (pwfile->pw_uid));
+ } else {
- {
- uint32 rid;
+ uint32 grid;
GROUP_MAP map;
+ /* Verify in system password file...
+ FIXME!!! This is where we should look up an internal
+ mapping of allocated uid for machine accounts as well
+ --jerry */
+ pwfile = getpwnam_alloc(pw_buf->smb_name);
+ if (pwfile == NULL) {
+ DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s not in unix passwd database!\n", pw_buf->smb_name));
+ return False;
+ }
+
+ pdb_set_uid (sam_pass, pwfile->pw_uid);
+ pdb_set_gid (sam_pass, pwfile->pw_gid);
+
+ pdb_set_fullname(sam_pass, pwfile->pw_gecos);
+
+ pdb_set_user_rid(sam_pass, pdb_uid_to_user_rid (pwfile->pw_uid));
+
if (get_group_map_from_gid(pwfile->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
- sid_peek_rid(&map.sid, &rid);
+ sid_peek_rid(&map.sid, &grid);
+ } else {
+ grid=pdb_gid_to_group_rid(pwfile->pw_gid);
}
- else
- rid=pdb_gid_to_group_rid(pwfile->pw_gid);
- pdb_set_group_rid(sam_pass, rid);
+ pdb_set_group_rid(sam_pass, grid);
+
+ /* check if this is a user account or a machine account */
+ if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$')
+ {
+ pstring str;
+
+ pstrcpy(str, lp_logon_path());
+ standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
+ pdb_set_profile_path(sam_pass, str, False);
+
+ pstrcpy(str, lp_logon_home());
+ standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
+ pdb_set_homedir(sam_pass, str, False);
+
+ pstrcpy(str, lp_logon_drive());
+ standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
+ pdb_set_dir_drive(sam_pass, str, False);
+
+ pstrcpy(str, lp_logon_script());
+ standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
+ pdb_set_logon_script(sam_pass, str, False);
+
+ } else {
+ /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
+ /*pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); */
+ }
+
+ passwd_free(&pwfile);
}
pdb_set_username (sam_pass, pw_buf->smb_name);
@@ -1243,84 +1314,61 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw
*/
pdb_set_pass_must_change_time (sam_pass, pw_buf->pass_last_set_time + MAX_PASSWORD_AGE);
#endif
- /* check if this is a user account or a machine account */
- if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$')
- {
- pstring str;
-
- pstrcpy(str, lp_logon_path());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_profile_path(sam_pass, str, False);
-
- pstrcpy(str, lp_logon_home());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_homedir(sam_pass, str, False);
-
- pstrcpy(str, lp_logon_drive());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_dir_drive(sam_pass, str, False);
-
- pstrcpy(str, lp_logon_script());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_logon_script(sam_pass, str, False);
-
- } else {
- /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
- /*pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); */
- }
-
- passwd_free(&pwfile);
-
return True;
}
+
/*****************************************************************
Functions to be implemented by the new passdb API
****************************************************************/
-BOOL pdb_setsampwent (BOOL update)
+static BOOL smbpasswd_setsampwent (struct pdb_context *context, BOOL update)
{
- global_vp = startsmbfilepwent(lp_smb_passwd_file(),
- update ? PWF_UPDATE : PWF_READ,
- &pw_file_lock_depth);
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+
+ smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
+ update ? PWF_UPDATE : PWF_READ,
+ &(smbpasswd_state->pw_file_lock_depth));
/* did we fail? Should we try to create it? */
- if (!global_vp && update && errno == ENOENT)
+ if (!smbpasswd_state->pw_file && update && errno == ENOENT)
{
FILE *fp;
/* slprintf(msg_str,msg_str_len-1,
- "smbpasswd file did not exist - attempting to create it.\n"); */
+ "smbpasswd file did not exist - attempting to create it.\n"); */
DEBUG(0,("smbpasswd file did not exist - attempting to create it.\n"));
- fp = sys_fopen(lp_smb_passwd_file(), "w");
+ fp = sys_fopen(smbpasswd_state->smbpasswd_file, "w");
if (fp)
{
fprintf(fp, "# Samba SMB password file\n");
fclose(fp);
}
- global_vp = startsmbfilepwent(lp_smb_passwd_file(),
- update ? PWF_UPDATE : PWF_READ,
- &pw_file_lock_depth);
+ smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
+ update ? PWF_UPDATE : PWF_READ,
+ &(smbpasswd_state->pw_file_lock_depth));
}
- return (global_vp != NULL);
+ return (smbpasswd_state->pw_file != NULL);
}
-void pdb_endsampwent (void)
+static void smbpasswd_endsampwent (struct pdb_context *context)
{
- endsmbfilepwent(global_vp, &pw_file_lock_depth);
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+ endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth));
}
/*****************************************************************
****************************************************************/
-BOOL pdb_getsampwent(SAM_ACCOUNT *user)
+static BOOL smbpasswd_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
{
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
struct smb_passwd *pw_buf=NULL;
BOOL done = False;
DEBUG(5,("pdb_getsampwent\n"));
if (user==NULL) {
- DEBUG(5,("pdb_getsampwent: user is NULL\n"));
+ DEBUG(5,("pdb_getsampwent (smbpasswd): user is NULL\n"));
#if 0
- smb_panic("NULL pointer passed to pdb_getsampwent\n");
+ smb_panic("NULL pointer passed to getsampwent (smbpasswd)\n");
#endif
return False;
}
@@ -1328,18 +1376,18 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
while (!done)
{
/* do we have an entry? */
- pw_buf = getsmbfilepwent(global_vp);
+ pw_buf = getsmbfilepwent(smbpasswd_state, smbpasswd_state->pw_file);
if (pw_buf == NULL)
return False;
/* build the SAM_ACCOUNT entry from the smb_passwd struct.
We loop in case the user in the pdb does not exist in
the local system password file */
- if (build_sam_account(user, pw_buf))
+ if (build_sam_account(smbpasswd_state, user, pw_buf))
done = True;
}
- DEBUG(5,("pdb_getsampwent:done\n"));
+ DEBUG(5,("getsampwent (smbpasswd): done\n"));
/* success */
return True;
@@ -1351,15 +1399,16 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
call getpwnam() for unix account information until we have found
the correct entry
***************************************************************/
-BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
+static BOOL smbpasswd_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
{
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
struct smb_passwd *smb_pw;
void *fp = NULL;
char *domain = NULL;
char *user = NULL;
fstring name;
- DEBUG(10, ("pdb_getsampwnam: search by name: %s\n", username));
+ DEBUG(10, ("getsampwnam (smbpasswd): search by name: %s\n", username));
/* break the username from the domain if we have
@@ -1379,7 +1428,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
/* startsmbfilepwent() is used here as we don't want to lookup
the UNIX account in the local system password file until
we have a match. */
- fp = startsmbfilepwent(lp_smb_passwd_file(), PWF_READ, &pw_file_lock_depth);
+ 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"));
@@ -1391,20 +1440,20 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
if ( domain )
map_username(user);
- while ( ((smb_pw=getsmbfilepwent(fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
+ while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
/* do nothing....another loop */ ;
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
/* did we locate the username in smbpasswd */
if (smb_pw == NULL)
return False;
- DEBUG(10, ("pdb_getsampwnam: found by name: %s\n", smb_pw->smb_name));
+ DEBUG(10, ("getsampwnam (smbpasswd): found by name: %s\n", smb_pw->smb_name));
if (!sam_acct) {
- DEBUG(10,("pdb_getsampwnam:SAM_ACCOUNT is NULL\n"));
+ DEBUG(10,("getsampwnam (smbpasswd): SAM_ACCOUNT is NULL\n"));
#if 0
smb_panic("NULL pointer passed to pdb_getsampwnam\n");
#endif
@@ -1412,7 +1461,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
}
/* now build the SAM_ACCOUNT */
- if (!build_sam_account(sam_acct, smb_pw))
+ if (!build_sam_account(smbpasswd_state, sam_acct, smb_pw))
return False;
/* success */
@@ -1420,35 +1469,36 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
}
-BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct,uint32 rid)
+static BOOL smbpasswd_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct,uint32 rid)
{
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
struct smb_passwd *smb_pw;
void *fp = NULL;
DEBUG(10, ("pdb_getsampwrid: search by rid: %d\n", rid));
/* Open the sam password file - not for update. */
- fp = startsmbfilepwent(lp_smb_passwd_file(), PWF_READ, &pw_file_lock_depth);
+ 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;
}
- while ( ((smb_pw=getsmbfilepwent(fp)) != NULL) && (pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
+ while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
/* do nothing */ ;
- endsmbfilepwent(fp, &pw_file_lock_depth);
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
/* did we locate the username in smbpasswd */
if (smb_pw == NULL)
return False;
- DEBUG(10, ("pdb_getsampwrid: found by name: %s\n", smb_pw->smb_name));
+ DEBUG(10, ("getsampwrid (smbpasswd): found by name: %s\n", smb_pw->smb_name));
if (!sam_acct) {
- DEBUG(10,("pdb_getsampwrid:SAM_ACCOUNT is NULL\n"));
+ DEBUG(10,("getsampwrid: (smbpasswd) SAM_ACCOUNT is NULL\n"));
#if 0
smb_panic("NULL pointer passed to pdb_getsampwrid\n");
#endif
@@ -1456,15 +1506,16 @@ BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct,uint32 rid)
}
/* now build the SAM_ACCOUNT */
- if (!build_sam_account (sam_acct, smb_pw))
+ if (!build_sam_account (smbpasswd_state, sam_acct, smb_pw))
return False;
/* success */
return True;
}
-BOOL pdb_add_sam_account(const SAM_ACCOUNT *sampass)
+static BOOL smbpasswd_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass)
{
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
struct smb_passwd smb_pw;
/* convert the SAM_ACCOUNT */
@@ -1473,15 +1524,16 @@ BOOL pdb_add_sam_account(const SAM_ACCOUNT *sampass)
}
/* add the entry */
- if(!add_smbfilepwd_entry(&smb_pw)) {
+ if(!add_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {
return False;
}
-
+
return True;
}
-BOOL pdb_update_sam_account(const SAM_ACCOUNT *sampass, BOOL override)
+static BOOL smbpasswd_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass)
{
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
struct smb_passwd smb_pw;
/* convert the SAM_ACCOUNT */
@@ -1489,19 +1541,97 @@ BOOL pdb_update_sam_account(const SAM_ACCOUNT *sampass, BOOL override)
return False;
/* update the entry */
- if(!mod_smbfilepwd_entry(&smb_pw, override))
+ if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw))
return False;
return True;
}
-BOOL pdb_delete_sam_account (const char* username)
+static BOOL smbpasswd_delete_sam_account (struct pdb_context *context, const SAM_ACCOUNT *sampass)
{
- return del_smbfilepwd_entry(username);
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+
+ const char *username = pdb_get_username(sampass);
+
+ return del_smbfilepwd_entry(smbpasswd_state, username);
+}
+
+static void free_private_data(void **vp)
+{
+ struct smbpasswd_privates **privates = (struct smbpasswd_privates**)vp;
+
+ endsmbfilepwent((*privates)->pw_file, &((*privates)->pw_file_lock_depth));
+
+ *privates = NULL;
+ /* No need to free any further, as it is talloc()ed */
}
-#else
- /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
- void smbpass_dummy_function(void) { } /* stop some compilers complaining */
-#endif /* WTH_SMBPASSWD_SAM*/
+NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+ NTSTATUS nt_status;
+ struct smbpasswd_privates *privates;
+
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+ return nt_status;
+ }
+
+ (*pdb_method)->setsampwent = smbpasswd_setsampwent;
+ (*pdb_method)->endsampwent = smbpasswd_endsampwent;
+ (*pdb_method)->getsampwent = smbpasswd_getsampwent;
+ (*pdb_method)->getsampwnam = smbpasswd_getsampwnam;
+ (*pdb_method)->getsampwrid = smbpasswd_getsampwrid;
+ (*pdb_method)->add_sam_account = smbpasswd_add_sam_account;
+ (*pdb_method)->update_sam_account = smbpasswd_update_sam_account;
+ (*pdb_method)->delete_sam_account = smbpasswd_delete_sam_account;
+
+ /* Setup private data and free function */
+
+ privates = talloc_zero(pdb_context->mem_ctx, sizeof(struct smbpasswd_privates));
+
+ if (!privates) {
+ DEBUG(0, ("talloc() failed for smbpasswd private_data!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Store some config details */
+
+ if (location) {
+ privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, location);
+ } else {
+ privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, lp_smb_passwd_file());
+ }
+
+ if (!privates->smbpasswd_file) {
+ DEBUG(0, ("talloc_strdp() failed for storing smbpasswd location!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ (*pdb_method)->private_data = privates;
+
+
+ (*pdb_method)->free_private_data = free_private_data;
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_init_smbpasswd_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+ 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;
+ }
+
+ 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;
+}
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index b33e684c7a..0e0bf541e3 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -4,6 +4,7 @@
* Copyright (C) Simo Sorce 2000
* Copyright (C) Gerald Carter 2000
* Copyright (C) Jeremy Allison 2001
+ * Copyright (C) Andrew Bartlett 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
@@ -30,21 +31,25 @@
#define USERPREFIX "USER_"
#define RIDPREFIX "RID_"
-extern int DEBUGLEVEL;
-
-struct tdb_enum_info {
+struct tdbsam_privates {
TDB_CONTEXT *passwd_tdb;
TDB_DATA key;
-};
-static struct tdb_enum_info global_tdb_ent;
-/*static SAM_ACCOUNT global_sam_pass;*/
+ /* retrive-once info */
+ const char *tdbsam_location;
+
+ BOOL permit_non_unix_accounts;
+
+ uint32 low_nua_rid;
+ uint32 high_nua_rid;
+};
/**********************************************************************
Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
*********************************************************************/
-static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
+static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
+ SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
{
/* times are stored as 32bit integer
@@ -150,8 +155,6 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 bufle
goto done;
}
- /*pdb_set_uid(sampass, uid);
- pdb_set_gid(sampass, gid);*/
pdb_set_user_rid(sampass, user_rid);
pdb_set_group_rid(sampass, group_rid);
pdb_set_unknown_3(sampass, unknown_3);
@@ -162,6 +165,28 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 bufle
pdb_set_logon_divs(sampass, logon_divs);
pdb_set_hours(sampass, hours);
+ if ((tdb_state->permit_non_unix_accounts)
+ && (pdb_get_user_rid(sampass) >= tdb_state->low_nua_rid)
+ && (pdb_get_user_rid(sampass) <= tdb_state->high_nua_rid)) {
+
+ } else {
+ struct passwd *pw;
+ /* validate the account and fill in UNIX uid and gid. sys_getpwnam()
+ is used instaed of Get_Pwnam() as we do not need to try case
+ permutations */
+
+ if ((pw=getpwnam_alloc(pdb_get_username(sampass))) == NULL) {
+ DEBUG(0,("init_sam_from_buffer: (tdbsam) getpwnam(%s) return NULL. User does not exist!\n",
+ pdb_get_username(sampass)));
+ return False;
+ }
+
+ pdb_set_uid(sampass, pw->pw_uid);
+ pdb_set_gid(sampass, pw->pw_gid);
+
+ passwd_free(&pw);
+ }
+
done:
SAFE_FREE(username);
@@ -182,7 +207,8 @@ done:
/**********************************************************************
Intialize a BYTE buffer from a SAM_ACCOUNT struct
*********************************************************************/
-static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
+static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state, uint8 **buf,
+ const SAM_ACCOUNT *sampass, uint32 user_rid, uint32 group_rid)
{
size_t len, buflen;
@@ -321,8 +347,8 @@ static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
workstations_len, workstations,
unknown_str_len, unknown_str,
munged_dial_len, munged_dial,
- pdb_get_user_rid(sampass),
- pdb_get_group_rid(sampass),
+ user_rid,
+ group_rid,
lm_pw_len, lm_pw,
nt_pw_len, nt_pw,
pdb_get_acct_ctrl(sampass),
@@ -360,8 +386,8 @@ static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
workstations_len, workstations,
unknown_str_len, unknown_str,
munged_dial_len, munged_dial,
- pdb_get_user_rid(sampass),
- pdb_get_group_rid(sampass),
+ user_rid,
+ group_rid,
lm_pw_len, lm_pw,
nt_pw_len, nt_pw,
pdb_get_acct_ctrl(sampass),
@@ -375,6 +401,8 @@ static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
/* check to make sure we got it correct */
if (buflen != len) {
+ DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n",
+ buflen, len));
/* error */
SAFE_FREE (*buf);
return (-1);
@@ -387,35 +415,38 @@ static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
Open the TDB passwd database for SAM account enumeration.
****************************************************************/
-BOOL pdb_setsampwent(BOOL update)
+static BOOL tdbsam_setsampwent(struct pdb_context *context, BOOL update)
{
- pstring tdbfile;
-
- get_private_directory(tdbfile);
- pstrcat (tdbfile, PASSDB_FILE_NAME);
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
/* Open tdb passwd */
- if (!(global_tdb_ent.passwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600)))
+ 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 False;
}
- global_tdb_ent.key = tdb_firstkey(global_tdb_ent.passwd_tdb);
+ tdb_state->key = tdb_firstkey(tdb_state->passwd_tdb);
return True;
}
+static void close_tdb(struct tdbsam_privates *tdb_state)
+{
+ if (tdb_state->passwd_tdb) {
+ tdb_close(tdb_state->passwd_tdb);
+ tdb_state->passwd_tdb = NULL;
+ }
+}
+
/***************************************************************
End enumeration of the TDB passwd list.
****************************************************************/
-void pdb_endsampwent(void)
+static void tdbsam_endsampwent(struct pdb_context *context)
{
- if (global_tdb_ent.passwd_tdb) {
- tdb_close(global_tdb_ent.passwd_tdb);
- global_tdb_ent.passwd_tdb = NULL;
- }
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+ close_tdb(tdb_state);
DEBUG(7, ("endtdbpwent: closed sam database.\n"));
}
@@ -424,17 +455,13 @@ void pdb_endsampwent(void)
Get one SAM_ACCOUNT from the TDB (next in line)
*****************************************************************/
-BOOL pdb_getsampwent(SAM_ACCOUNT *user)
+static BOOL tdbsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
{
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
TDB_DATA data;
- struct passwd *pw;
- uid_t uid;
- gid_t gid;
char *prefix = USERPREFIX;
int prefixlen = strlen (prefix);
- const char *sam_user;
- pstring sam_subst;
if (user==NULL) {
DEBUG(0,("pdb_get_sampwent: SAM_ACCOUNT is NULL.\n"));
@@ -442,62 +469,32 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
}
/* skip all non-USER entries (eg. RIDs) */
- while ((global_tdb_ent.key.dsize != 0) && (strncmp(global_tdb_ent.key.dptr, prefix, prefixlen)))
+ while ((tdb_state->key.dsize != 0) && (strncmp(tdb_state->key.dptr, prefix, prefixlen)))
/* increment to next in line */
- global_tdb_ent.key = tdb_nextkey(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
+ tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
/* do we have an valid interation pointer? */
- if(global_tdb_ent.passwd_tdb == NULL) {
+ if(tdb_state->passwd_tdb == NULL) {
DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
return False;
}
- data = tdb_fetch(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
+ data = tdb_fetch(tdb_state->passwd_tdb, tdb_state->key);
if (!data.dptr) {
DEBUG(5,("pdb_getsampwent: database entry not found.\n"));
return False;
}
/* unpack the buffer */
- if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
+ if (!init_sam_from_buffer(tdb_state, user, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
return False;
}
SAFE_FREE(data.dptr);
- /* validate the account and fill in UNIX uid and gid. sys_getpwnam()
- is used instaed of Get_Pwnam() as we do not need to try case
- permutations */
- if ((pw=getpwnam_alloc(pdb_get_username(user))) == NULL) {
- DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n",
- pdb_get_username(user)));
- return False;
- }
-
- uid = pw->pw_uid;
- gid = pw->pw_gid;
- pdb_set_uid(user, uid);
- pdb_set_gid(user, gid);
-
- passwd_free(&pw);
-
- /* 21 days from present */
- pdb_set_pass_must_change_time(user, time(NULL)+1814400);
-
- sam_user = pdb_get_username(user);
- pstrcpy(sam_subst, pdb_get_logon_script(user));
- standard_sub_advanced(-1, sam_user, "", gid, sam_user, sam_subst);
- if (!pdb_set_logon_script(user, sam_subst, True)) return False;
- pstrcpy(sam_subst, pdb_get_profile_path(user));
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_username(user), sam_subst);
- if (!pdb_set_profile_path(user, sam_subst, True)) return False;
- pstrcpy(sam_subst, pdb_get_homedir(user));
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_username(user), sam_subst);
- if (!pdb_set_homedir(user, sam_subst, True)) return False;
-
/* increment to next in line */
- global_tdb_ent.key = tdb_nextkey(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
+ tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
return True;
}
@@ -506,19 +503,13 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
Lookup a name in the SAM TDB
******************************************************************/
-BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
+static BOOL tdbsam_getsampwnam (struct pdb_context *context, SAM_ACCOUNT *user, const char *sname)
{
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA data, key;
fstring keystr;
- struct passwd *pw;
- pstring tdbfile;
fstring name;
- uid_t uid;
- gid_t gid;
-
- const char *sam_user;
- pstring sam_subst;
if (user==NULL) {
DEBUG(0,("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n"));
@@ -528,17 +519,14 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
/* Data is stored in all lower-case */
unix_strlower(sname, -1, name, sizeof(name));
- get_private_directory(tdbfile);
- pstrcat(tdbfile, PASSDB_FILE_NAME);
-
/* set search key */
slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
/* open the accounts TDB */
- if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
- DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd!\n"));
+ if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
+ DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
return False;
}
@@ -547,12 +535,13 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
if (!data.dptr) {
DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
+ DEBUGADD(5, (" Key: %s\n", keystr));
tdb_close(pwd_tdb);
return False;
}
/* unpack the buffer */
- if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
+ if (!init_sam_from_buffer(tdb_state, user, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
tdb_close(pwd_tdb);
@@ -563,37 +552,6 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
/* no further use for database, close it now */
tdb_close(pwd_tdb);
- /* validate the account and fill in UNIX uid and gid. sys_getpwnam()
- is used instead of Get_Pwnam() as we do not need to try case
- permutations */
- if ((pw=getpwnam_alloc(pdb_get_username(user)))) {
- uid = pw->pw_uid;
- gid = pw->pw_gid;
- pdb_set_uid(user, uid);
- pdb_set_gid(user, gid);
-
- /* 21 days from present */
- pdb_set_pass_must_change_time(user, time(NULL)+1814400);
-
- sam_user = pdb_get_username(user);
- pstrcpy(sam_subst, pdb_get_logon_script(user));
- standard_sub_advanced(-1, sam_user, "", gid, sam_user, sam_subst);
- if (!pdb_set_logon_script(user, sam_subst, True)) return False;
- pstrcpy(sam_subst, pdb_get_profile_path(user));
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_username(user), sam_subst);
- if (!pdb_set_profile_path(user, sam_subst, True)) return False;
- pstrcpy(sam_subst, pdb_get_homedir(user));
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_username(user), sam_subst);
- if (!pdb_set_homedir(user, sam_subst, True)) return False;
- }
- else {
- DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n",
- pdb_get_username(user)));
- return False;
- }
-
- passwd_free(&pw);
-
return True;
}
@@ -601,12 +559,12 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
Search by rid
**************************************************************************/
-BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
+static BOOL tdbsam_getsampwrid (struct pdb_context *context, SAM_ACCOUNT *user, uint32 rid)
{
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA data, key;
fstring keystr;
- pstring tdbfile;
fstring name;
if (user==NULL) {
@@ -614,16 +572,13 @@ BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
return False;
}
- get_private_directory(tdbfile);
- pstrcat (tdbfile, PASSDB_FILE_NAME);
-
/* set search key */
slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
/* open the accounts TDB */
- if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
+ if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n"));
return False;
}
@@ -642,30 +597,26 @@ BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
tdb_close (pwd_tdb);
- return pdb_getsampwnam (user, name);
+ return tdbsam_getsampwnam (context, user, name);
}
/***************************************************************************
Delete a SAM_ACCOUNT
****************************************************************************/
-BOOL pdb_delete_sam_account(const char *sname)
+static BOOL tdbsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sam_pass)
{
- SAM_ACCOUNT *sam_pass = NULL;
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
TDB_CONTEXT *pwd_tdb;
- TDB_DATA key, data;
+ TDB_DATA key;
fstring keystr;
- pstring tdbfile;
uint32 rid;
fstring name;
- unix_strlower(sname, -1, name, sizeof(name));
+ unix_strlower(pdb_get_username(sam_pass), -1, name, sizeof(name));
- get_private_directory(tdbfile);
- pstrcat (tdbfile, PASSDB_FILE_NAME);
-
/* open the TDB */
- if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0600))) {
+ if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR, 0600))) {
DEBUG(0, ("Unable to open TDB passwd!"));
return False;
}
@@ -675,33 +626,8 @@ BOOL pdb_delete_sam_account(const char *sname)
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
- /* get the record */
- data = tdb_fetch (pwd_tdb, key);
- if (!data.dptr) {
- DEBUG(5,("pdb_delete_sam_account (TDB): error fetching database.\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
- tdb_close (pwd_tdb);
- return False;
- }
-
- /* unpack the buffer */
- if (!NT_STATUS_IS_OK(pdb_init_sam (&sam_pass))) {
- tdb_close (pwd_tdb);
- return False;
- }
-
- if (!init_sam_from_buffer (sam_pass, data.dptr, data.dsize)) {
- DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
- tdb_close (pwd_tdb);
- SAFE_FREE(data.dptr);
- return False;
- }
- SAFE_FREE(data.dptr);
-
rid = pdb_get_user_rid(sam_pass);
- pdb_free_sam (&sam_pass);
-
/* it's outaa here! 8^) */
if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) {
DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
@@ -734,27 +660,62 @@ BOOL pdb_delete_sam_account(const char *sname)
Update the TDB SAM
****************************************************************************/
-static BOOL tdb_update_sam(const SAM_ACCOUNT* newpwd, BOOL override, int flag)
+static BOOL tdb_update_sam(struct pdb_context *context, const SAM_ACCOUNT* newpwd, int flag)
{
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
TDB_CONTEXT *pwd_tdb = NULL;
TDB_DATA key, data;
uint8 *buf = NULL;
fstring keystr;
- pstring tdbfile;
fstring name;
BOOL ret = True;
-
- get_private_directory(tdbfile);
- pstrcat (tdbfile, PASSDB_FILE_NAME);
-
- /* if we don't have a RID, then FAIL */
- if (!pdb_get_user_rid(newpwd))
- DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd)));
- if (!pdb_get_group_rid(newpwd))
- DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd)));
+ uint32 user_rid;
+ uint32 group_rid;
+ int32 tdb_ret;
+
+ /* invalidate the existing TDB iterator if it is open */
+ if (tdb_state->passwd_tdb) {
+ tdb_close(tdb_state->passwd_tdb);
+ tdb_state->passwd_tdb = NULL;
+ }
+
+ /* open the account TDB passwd*/
+ pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
+ if (!pwd_tdb)
+ {
+ DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
+ return False;
+ }
+
+ /* if we don't have a RID, then make them up. */
+ if (!(user_rid = pdb_get_user_rid(newpwd))) {
+ if (!tdb_state->permit_non_unix_accounts) {
+ DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd)));
+ ret = False;
+ goto done;
+ } else {
+ user_rid = tdb_state->low_nua_rid;
+ tdb_ret = tdb_change_int32_atomic(pwd_tdb, "NUA_NEXT_RID", &user_rid, RID_MULTIPLIER);
+ if (tdb_ret == -1) {
+ ret = False;
+ goto done;
+ }
+ }
+ }
+
+ if (!(group_rid = pdb_get_group_rid(newpwd))) {
+ if (!tdb_state->permit_non_unix_accounts) {
+ DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd)));
+ ret = False;
+ goto done;
+ } else {
+ /* This seems like a good default choice for non-unix users */
+ group_rid = DOMAIN_GROUP_RID_USERS;
+ }
+ }
/* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */
- if ((data.dsize=init_buffer_from_sam (&buf, newpwd)) == -1) {
+ if ((data.dsize=init_buffer_from_sam (tdb_state, &buf, newpwd, user_rid, group_rid)) == -1) {
DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n"));
ret = False;
goto done;
@@ -763,29 +724,18 @@ static BOOL tdb_update_sam(const SAM_ACCOUNT* newpwd, BOOL override, int flag)
unix_strlower(pdb_get_username(newpwd), -1, name, sizeof(name));
+ DEBUG(5, ("Storing %saccount %s with RID %d\n", flag == TDB_INSERT ? "(new) " : "", name, user_rid));
+
/* setup the USER index key */
slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
- /* invalidate the existing TDB iterator if it is open */
- if (global_tdb_ent.passwd_tdb) {
- tdb_close(global_tdb_ent.passwd_tdb);
- global_tdb_ent.passwd_tdb = NULL;
- }
-
- /* open the account TDB passwd*/
- pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
- if (!pwd_tdb)
- {
- DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd!\n"));
- return False;
- }
-
/* add the account */
if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
DEBUG(0, ("Unable to modify passwd TDB!"));
- DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
+ DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb)));
+ DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr));
ret = False;
goto done;
}
@@ -795,7 +745,7 @@ static BOOL tdb_update_sam(const SAM_ACCOUNT* newpwd, BOOL override, int flag)
data.dptr = name;
/* setup the RID index key */
- slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
+ slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, user_rid);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
@@ -803,6 +753,7 @@ static BOOL tdb_update_sam(const SAM_ACCOUNT* newpwd, BOOL override, int flag)
if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
DEBUG(0, ("Unable to modify TDB passwd !"));
DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
+ DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr));
ret = False;
goto done;
}
@@ -819,21 +770,113 @@ done:
Modifies an existing SAM_ACCOUNT
****************************************************************************/
-BOOL pdb_update_sam_account (const SAM_ACCOUNT *newpwd, BOOL override)
+static BOOL tdbsam_update_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd)
{
- return (tdb_update_sam(newpwd, override, TDB_MODIFY));
+ return (tdb_update_sam(context, newpwd, TDB_MODIFY));
}
/***************************************************************************
Adds an existing SAM_ACCOUNT
****************************************************************************/
-BOOL pdb_add_sam_account (const SAM_ACCOUNT *newpwd)
+static BOOL tdbsam_add_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd)
+{
+ return (tdb_update_sam(context, newpwd, TDB_INSERT));
+}
+
+static void free_private_data(void **vp)
{
- return (tdb_update_sam(newpwd, True, TDB_INSERT));
+ struct tdbsam_privates **tdb_state = (struct tdbsam_privates **)vp;
+ close_tdb(*tdb_state);
+ *tdb_state = NULL;
+
+ /* No need to free any further, as it is talloc()ed */
}
+
+NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+ NTSTATUS nt_status;
+ struct tdbsam_privates *tdb_state;
+
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+ return nt_status;
+ }
+
+ (*pdb_method)->setsampwent = tdbsam_setsampwent;
+ (*pdb_method)->endsampwent = tdbsam_endsampwent;
+ (*pdb_method)->getsampwent = tdbsam_getsampwent;
+ (*pdb_method)->getsampwnam = tdbsam_getsampwnam;
+ (*pdb_method)->getsampwrid = tdbsam_getsampwrid;
+ (*pdb_method)->add_sam_account = tdbsam_add_sam_account;
+ (*pdb_method)->update_sam_account = tdbsam_update_sam_account;
+ (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account;
+
+ /* TODO: Setup private data and free */
+
+ tdb_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct tdbsam_privates));
+
+ if (!tdb_state) {
+ DEBUG(0, ("talloc() failed for tdbsam private_data!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (location) {
+ tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, location);
+ } else {
+ pstring tdbfile;
+ get_private_directory(tdbfile);
+ pstrcat (tdbfile, PASSDB_FILE_NAME);
+ tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, tdbfile);
+ }
+
+ (*pdb_method)->private_data = tdb_state;
+
+ (*pdb_method)->free_private_data = free_private_data;
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+ NTSTATUS nt_status;
+ struct tdbsam_privates *tdb_state;
+ uint32 low_nua_uid, high_nua_uid;
+
+ if (!NT_STATUS_IS_OK(nt_status = pdb_init_tdbsam(pdb_context, pdb_method, location))) {
+ return nt_status;
+ }
+
+ tdb_state = (*pdb_method)->private_data;
+
+ tdb_state->permit_non_unix_accounts = True;
+
+ if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
+ DEBUG(0, ("cannot use tdbsam_nua without 'non unix account range' in smb.conf!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ tdb_state->low_nua_rid=pdb_uid_to_user_rid(low_nua_uid);
+
+ tdb_state->high_nua_rid=pdb_uid_to_user_rid(high_nua_uid);
+
+ return NT_STATUS_OK;
+}
+
+
#else
- /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
- void samtdb_dummy_function(void) { } /* stop some compilers complaining */
-#endif /* WITH_TDB_SAM */
+
+NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+ DEBUG(0, ("tdbsam not compiled in!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+ DEBUG(0, ("tdbsam_nua not compiled in!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+
+#endif