*
* 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)
+ * Software Foundation; either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* 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.
+ * this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
else. However, smb_passwd is limited to the information
stored by an smbpasswd entry
*/
-
+
struct smb_passwd
{
uint32 smb_userid; /* this is actually the unix uid_t */
{
/* 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;
+ fstring user_name;
unsigned char smbpwd[16];
unsigned char smbntpwd[16];
enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE };
+static SIG_ATOMIC_T gotalarm;
+
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+
+static void gotalarm_sig(int signum)
+{
+ gotalarm = 1;
+}
+
+/***************************************************************
+ Lock or unlock a fd for a known lock type. Abandon after waitsecs
+ seconds.
+****************************************************************/
+
+static bool do_file_lock(int fd, int waitsecs, int type)
+{
+ SMB_STRUCT_FLOCK lock;
+ int ret;
+ void (*oldsig_handler)(int);
+
+ gotalarm = 0;
+ oldsig_handler = CatchSignal(SIGALRM, gotalarm_sig);
+
+ lock.l_type = type;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 1;
+ lock.l_pid = 0;
+
+ alarm(waitsecs);
+ /* Note we must *NOT* use sys_fcntl here ! JRA */
+ ret = fcntl(fd, SMB_F_SETLKW, &lock);
+ alarm(0);
+ CatchSignal(SIGALRM, oldsig_handler);
+
+ if (gotalarm && ret == -1) {
+ DEBUG(0, ("do_file_lock: failed to %s file.\n",
+ type == F_UNLCK ? "unlock" : "lock"));
+ return False;
+ }
+
+ return (ret == 0);
+}
+
/***************************************************************
Lock an fd. Abandon after waitsecs seconds.
****************************************************************/
-static BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
+static bool pw_file_lock(int fd, int type, int secs, int *plock_depth)
{
if (fd < 0) {
return False;
Unlock an fd. Abandon after waitsecs seconds.
****************************************************************/
-static BOOL pw_file_unlock(int fd, int *plock_depth)
+static bool pw_file_unlock(int fd, int *plock_depth)
{
- BOOL ret=True;
+ bool ret=True;
if (fd == 0 || *plock_depth == 0) {
return True;
if (user == NULL)
return;
ZERO_STRUCTP (user);
-
+
user->pass_last_set_time = (time_t)0;
}
break;
}
}
-
+
for(race_loop = 0; race_loop < 5; race_loop++) {
DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile));
* prevent infinate loops. JRA.
*/
- if (sys_stat(pfile,&sbuf1) != 0) {
+ if (sys_stat(pfile, &sbuf1, false) != 0) {
DEBUG(0, ("startsmbfilepwent_internal: unable to stat file %s. \
Error was %s\n", pfile, strerror(errno)));
pw_file_unlock(fileno(fp), lock_depth);
return NULL;
}
- if (sys_fstat(fileno(fp),&sbuf2) != 0) {
+ if (sys_fstat(fileno(fp), &sbuf2, false) != 0) {
DEBUG(0, ("startsmbfilepwent_internal: unable to fstat file %s. \
Error was %s\n", pfile, strerror(errno)));
pw_file_unlock(fileno(fp), lock_depth);
return NULL;
}
- if( sbuf1.st_ino == sbuf2.st_ino) {
+ if( sbuf1.st_ex_ino == sbuf2.st_ex_ino) {
/* No race. */
break;
}
continue;
}
- /*
- * As 256 is shorter than a pstring we don't need to check
- * length here - if this ever changes....
- */
- SMB_ASSERT(sizeof(pstring) > sizeof(linebuf));
-
strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
user_name[PTR_DIFF(p, linebuf)] = '\0';
Routine to add an entry to the smbpasswd file.
*************************************************************************/
-static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, struct smb_passwd *newpwd)
+static NTSTATUS add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state,
+ struct smb_passwd *newpwd)
{
const char *pfile = smbpasswd_state->smbpasswd_file;
struct smb_passwd *pwd = NULL;
if (fp == NULL) {
DEBUG(0, ("add_smbfilepwd_entry: unable to open file.\n"));
- return False;
+ return map_nt_error_from_unix(errno);
}
/*
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, &smbpasswd_state->pw_file_lock_depth);
- return False;
+ return NT_STATUS_USER_EXISTS;
}
}
fd = fileno(fp);
if((offpos = sys_lseek(fd, 0, SEEK_END)) == -1) {
+ NTSTATUS result = map_nt_error_from_unix(errno);
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, &smbpasswd_state->pw_file_lock_depth);
- return False;
+ return result;
}
if((new_entry = format_new_smbpasswd_entry(newpwd)) == NULL) {
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, &smbpasswd_state->pw_file_lock_depth);
- return False;
+ return NT_STATUS_NO_MEMORY;
}
new_entry_length = strlen(new_entry);
#endif
if ((wr_len = write(fd, new_entry, new_entry_length)) != new_entry_length) {
+ NTSTATUS result = map_nt_error_from_unix(errno);
DEBUG(0, ("add_smbfilepwd_entry(write): %d Failed to add entry for user %s to file %s. \
Error was %s\n", wr_len, newpwd->smb_name, pfile, strerror(errno)));
endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
free(new_entry);
- return False;
+ return result;
}
free(new_entry);
endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
- return True;
+ return NT_STATUS_OK;
}
/************************************************************************
override = True, override XXXXXXXX'd out password or NO PASS
************************************************************************/
-static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd)
+static bool mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd)
{
/* Static buffers we will return. */
- pstring user_name;
+ fstring user_name;
char *status;
char linebuf[256];
FILE *fp;
int lockfd;
const char *pfile = smbpasswd_state->smbpasswd_file;
- BOOL found_entry = False;
- BOOL got_pass_last_set_time = False;
+ bool found_entry = False;
+ bool got_pass_last_set_time = False;
SMB_OFF_T pwd_seekpos = 0;
continue;
}
- /*
- * As 256 is shorter than a pstring we don't need to check
- * length here - if this ever changes....
- */
-
- SMB_ASSERT(sizeof(user_name) > sizeof(linebuf));
-
strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
user_name[PTR_DIFF(p, linebuf)] = '\0';
if (strequal(user_name, pwd->smb_name)) {
#ifdef DEBUG_PASSWORD
DEBUG(100,("mod_smbfilepwd_entry: "));
- dump_data(100, ascii_p16, wr_len);
+ dump_data(100, (uint8 *)ascii_p16, wr_len);
#endif
if(wr_len > sizeof(linebuf)) {
Routine to delete an entry in the smbpasswd file by name.
*************************************************************************/
-static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const char *name)
+static bool del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const char *name)
{
const char *pfile = smbpasswd_state->smbpasswd_file;
- pstring pfile2;
+ char *pfile2 = NULL;
struct smb_passwd *pwd = NULL;
FILE *fp = NULL;
FILE *fp_write = NULL;
int pfile2_lockdepth = 0;
- slprintf(pfile2, sizeof(pfile2)-1, "%s.%u", pfile, (unsigned)sys_getpid() );
+ pfile2 = talloc_asprintf(talloc_tos(),
+ "%s.%u",
+ pfile, (unsigned)sys_getpid());
+ if (!pfile2) {
+ return false;
+ }
/*
* Open the smbpassword file - for update. It needs to be update
size_t new_entry_length;
if (strequal(name, pwd->smb_name)) {
- DEBUG(10, ("add_smbfilepwd_entry: found entry with name %s - deleting it.\n", name));
+ DEBUG(10, ("del_smbfilepwd_entry: found entry with "
+ "name %s - deleting it.\n", name));
continue;
}
if(rename(pfile2,pfile) != 0) {
unlink(pfile2);
}
-
+
endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
endsmbfilepwent(fp_write,&pfile2_lockdepth);
return True;
should only stay around as long as the struct samu does.
********************************************************************/
-static BOOL build_smb_pass (struct smb_passwd *smb_pw, const struct samu *sampass)
+static bool build_smb_pass (struct smb_passwd *smb_pw, const struct samu *sampass)
{
uint32 rid;
if (!IS_SAM_DEFAULT(sampass, PDB_USERSID)) {
rid = pdb_get_user_rid(sampass);
-
+
/* If the user specified a RID, make sure its able to be both stored and retreived */
if (rid == DOMAIN_USER_RID_GUEST) {
struct passwd *passwd = getpwnam_alloc(NULL, lp_guestaccount());
if (!passwd) {
- DEBUG(0, ("Could not find gest account via getpwnam()! (%s)\n", lp_guestaccount()));
+ DEBUG(0, ("Could not find guest account via getpwnam()! (%s)\n", lp_guestaccount()));
return False;
}
smb_pw->smb_userid=passwd->pw_uid;
Create a struct samu from a smb_passwd struct
********************************************************************/
-static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
+static bool build_sam_account(struct smbpasswd_privates *smbpasswd_state,
struct samu *sam_pass, const struct smb_passwd *pw_buf)
{
struct passwd *pwfile;
-
+
if ( !sam_pass ) {
DEBUG(5,("build_sam_account: struct samu is NULL\n"));
return False;
}
/* verify the user account exists */
-
- if ( !(pwfile = getpwnam_alloc(NULL, pw_buf->smb_name)) ) {
+
+ if ( !(pwfile = Get_Pwnam_alloc(NULL, pw_buf->smb_name )) ) {
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;
}
-
+
if ( !NT_STATUS_IS_OK( samu_set_unix(sam_pass, pwfile )) )
return False;
-
+
TALLOC_FREE(pwfile);
/* set remaining fields */
-
- 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);
+
+ if (!pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd, PDB_SET))
+ return False;
+ if (!pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd, PDB_SET))
+ return False;
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);
-
+
return True;
}
Functions to be implemented by the new passdb API
****************************************************************/
-static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update, uint32 acb_mask)
-{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
-
- smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
- update ? PWF_UPDATE : PWF_READ,
- &(smbpasswd_state->pw_file_lock_depth));
-
- /* did we fail? Should we try to create it? */
- 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"); */
- DEBUG(0,("smbpasswd file did not exist - attempting to create it.\n"));
- fp = sys_fopen(smbpasswd_state->smbpasswd_file, "w");
- if (fp) {
- fprintf(fp, "# Samba SMB password file\n");
- fclose(fp);
- }
-
- smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
- update ? PWF_UPDATE : PWF_READ,
- &(smbpasswd_state->pw_file_lock_depth));
- }
-
- if (smbpasswd_state->pw_file != NULL)
- return NT_STATUS_OK;
- else
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-static void smbpasswd_endsampwent (struct pdb_methods *my_methods)
-{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
- endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth));
-}
-
-/*****************************************************************
- ****************************************************************/
-
-static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, struct samu *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;
-
- DEBUG(5,("pdb_getsampwent\n"));
-
- if ( !user ) {
- DEBUG(5,("pdb_getsampwent (smbpasswd): user is NULL\n"));
- return nt_status;
- }
-
- while (!done) {
- /* do we have an entry? */
- pw_buf = getsmbfilepwent(smbpasswd_state, smbpasswd_state->pw_file);
- if (pw_buf == NULL)
- return nt_status;
-
- /* build the struct samu 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(smbpasswd_state, user, pw_buf))
- done = True;
- }
-
- DEBUG(5,("getsampwent (smbpasswd): done\n"));
-
- /* success */
- return NT_STATUS_OK;
-}
-
/****************************************************************
Search smbpasswd file by iterating over the entries. Do not
call getpwnam() for unix account information until we have found
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;
+ FILE *fp = NULL;
DEBUG(10, ("getsampwnam (smbpasswd): search by name: %s\n", username));
while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
/* do nothing....another loop */ ;
-
+
endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
/* did we locate the username in smbpasswd */
if (smb_pw == NULL)
return nt_status;
-
+
DEBUG(10, ("getsampwnam (smbpasswd): found by name: %s\n", smb_pw->smb_name));
if (!sam_acct) {
DEBUG(10,("getsampwnam (smbpasswd): struct samu is NULL\n"));
return nt_status;
}
-
+
/* now build the struct samu */
if (!build_sam_account(smbpasswd_state, sam_acct, smb_pw))
return nt_status;
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;
+ FILE *fp = NULL;
uint32 rid;
-
- DEBUG(10, ("smbpasswd_getsampwrid: search by sid: %s\n", sid_to_string(sid_str, sid)));
+
+ DEBUG(10, ("smbpasswd_getsampwrid: search by sid: %s\n",
+ sid_string_dbg(sid)));
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
return NT_STATUS_UNSUCCESSFUL;
/* did we locate the username in smbpasswd */
if (smb_pw == NULL)
return nt_status;
-
+
DEBUG(10, ("getsampwrid (smbpasswd): found by name: %s\n", smb_pw->smb_name));
-
+
if (!sam_acct) {
DEBUG(10,("getsampwrid: (smbpasswd) struct samu is NULL\n"));
return nt_status;
/* 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)));
+ DEBUG(1, ("looking for user with sid %s instead returned %s "
+ "for account %s!?!\n", sid_string_dbg(sid),
+ sid_string_dbg(pdb_get_user_sid(sam_acct)),
+ pdb_get_username(sam_acct)));
return NT_STATUS_NO_SUCH_USER;
}
{
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd smb_pw;
-
+
/* convert the struct samu */
if (!build_smb_pass(&smb_pw, sampass)) {
return NT_STATUS_UNSUCCESSFUL;
}
-
+
/* add the entry */
- if(!add_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return NT_STATUS_OK;
+ return add_smbfilepwd_entry(smbpasswd_state, &smb_pw);
}
static NTSTATUS smbpasswd_update_sam_account(struct pdb_methods *my_methods, struct samu *sampass)
{
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd smb_pw;
-
+
/* convert the struct samu */
if (!build_smb_pass(&smb_pw, sampass)) {
DEBUG(0, ("smbpasswd_update_sam_account: build_smb_pass failed!\n"));
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 NT_STATUS_UNSUCCESSFUL;
}
-
+
return NT_STATUS_OK;
}
struct samu *old_acct,
const char *newname)
{
- pstring rename_script;
+ char *rename_script = NULL;
struct samu *new_acct = NULL;
- BOOL interim_account = False;
+ bool interim_account = False;
+ TALLOC_CTX *ctx = talloc_tos();
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
if (!*(lp_renameuser_script()))
if ( !(new_acct = samu_new( NULL )) ) {
return NT_STATUS_NO_MEMORY;
}
-
+
if ( !pdb_copy_sam_account( new_acct, old_acct )
|| !pdb_set_username(new_acct, newname, PDB_CHANGED))
{
goto done;
}
-
+
ret = smbpasswd_add_sam_account(my_methods, new_acct);
if (!NT_STATUS_IS_OK(ret))
goto done;
interim_account = True;
/* rename the posix user */
- pstrcpy(rename_script, lp_renameuser_script());
+ rename_script = talloc_strdup(ctx,
+ lp_renameuser_script());
+ if (!rename_script) {
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
if (*rename_script) {
int rename_ret;
- string_sub2(rename_script, "%unew", newname, sizeof(pstring),
- True, False, True);
- string_sub2(rename_script, "%uold", pdb_get_username(old_acct),
- sizeof(pstring), True, False, True);
+ rename_script = talloc_string_sub2(ctx,
+ rename_script,
+ "%unew",
+ newname,
+ true,
+ false,
+ true);
+ if (!rename_script) {
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ rename_script = talloc_string_sub2(ctx,
+ rename_script,
+ "%uold",
+ pdb_get_username(old_acct),
+ true,
+ false,
+ true);
+ if (!rename_script) {
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
rename_ret = smbrun(rename_script, NULL);
DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
- if (rename_ret)
- goto done;
+ if (rename_ret == 0) {
+ smb_nscd_flush_user_cache();
+ }
+
+ if (rename_ret)
+ goto done;
} else {
goto done;
}
smbpasswd_delete_sam_account(my_methods, old_acct);
interim_account = False;
-done:
+done:
/* cleanup */
if (interim_account)
smbpasswd_delete_sam_account(my_methods, new_acct);
if (new_acct)
TALLOC_FREE(new_acct);
-
+
return (ret);
}
-static BOOL smbpasswd_rid_algorithm(struct pdb_methods *methods)
+static uint32_t smbpasswd_capabilities(struct pdb_methods *methods)
{
- return True;
+ return 0;
}
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 */
}
+struct smbpasswd_search_state {
+ uint32_t acct_flags;
+
+ struct samr_displayentry *entries;
+ uint32_t num_entries;
+ ssize_t array_size;
+ uint32_t current;
+};
+
+static void smbpasswd_search_end(struct pdb_search *search)
+{
+ struct smbpasswd_search_state *state = talloc_get_type_abort(
+ search->private_data, struct smbpasswd_search_state);
+ TALLOC_FREE(state);
+}
+
+static bool smbpasswd_search_next_entry(struct pdb_search *search,
+ struct samr_displayentry *entry)
+{
+ struct smbpasswd_search_state *state = talloc_get_type_abort(
+ search->private_data, struct smbpasswd_search_state);
+
+ if (state->current == state->num_entries) {
+ return false;
+ }
+
+ entry->idx = state->entries[state->current].idx;
+ entry->rid = state->entries[state->current].rid;
+ entry->acct_flags = state->entries[state->current].acct_flags;
+
+ entry->account_name = talloc_strdup(
+ search, state->entries[state->current].account_name);
+ entry->fullname = talloc_strdup(
+ search, state->entries[state->current].fullname);
+ entry->description = talloc_strdup(
+ search, state->entries[state->current].description);
+
+ if ((entry->account_name == NULL) || (entry->fullname == NULL)
+ || (entry->description == NULL)) {
+ DEBUG(0, ("talloc_strdup failed\n"));
+ return false;
+ }
+
+ state->current += 1;
+ return true;
+}
+
+static bool smbpasswd_search_users(struct pdb_methods *methods,
+ struct pdb_search *search,
+ uint32_t acct_flags)
+{
+ struct smbpasswd_privates *smbpasswd_state =
+ (struct smbpasswd_privates*)methods->private_data;
+
+ struct smbpasswd_search_state *search_state;
+ struct smb_passwd *pwd;
+ FILE *fp;
+
+ search_state = talloc_zero(search, struct smbpasswd_search_state);
+ if (search_state == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return false;
+ }
+ search_state->acct_flags = acct_flags;
+
+ fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ,
+ &smbpasswd_state->pw_file_lock_depth);
+
+ if (fp == NULL) {
+ DEBUG(10, ("Unable to open smbpasswd file.\n"));
+ TALLOC_FREE(search_state);
+ return false;
+ }
+
+ while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) {
+ struct samr_displayentry entry;
+ struct samu *user;
+
+ if ((acct_flags != 0)
+ && ((acct_flags & pwd->acct_ctrl) == 0)) {
+ continue;
+ }
+
+ user = samu_new(talloc_tos());
+ if (user == NULL) {
+ DEBUG(0, ("samu_new failed\n"));
+ break;
+ }
+
+ if (!build_sam_account(smbpasswd_state, user, pwd)) {
+ /* Already got debug msgs... */
+ break;
+ }
+
+ ZERO_STRUCT(entry);
+
+ entry.acct_flags = pdb_get_acct_ctrl(user);
+ sid_peek_rid(pdb_get_user_sid(user), &entry.rid);
+ entry.account_name = talloc_strdup(
+ search_state, pdb_get_username(user));
+ entry.fullname = talloc_strdup(
+ search_state, pdb_get_fullname(user));
+ entry.description = talloc_strdup(
+ search_state, pdb_get_acct_desc(user));
+
+ TALLOC_FREE(user);
+
+ if ((entry.account_name == NULL) || (entry.fullname == NULL)
+ || (entry.description == NULL)) {
+ DEBUG(0, ("talloc_strdup failed\n"));
+ break;
+ }
+
+ ADD_TO_LARGE_ARRAY(search_state, struct samr_displayentry,
+ entry, &search_state->entries,
+ &search_state->num_entries,
+ &search_state->array_size);
+ }
+
+ endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+
+ search->private_data = search_state;
+ search->next_entry = smbpasswd_search_next_entry;
+ search->search_end = smbpasswd_search_end;
+
+ return true;
+}
+
static NTSTATUS pdb_init_smbpasswd( struct pdb_methods **pdb_method, const char *location )
{
NTSTATUS nt_status;
(*pdb_method)->name = "smbpasswd";
- (*pdb_method)->setsampwent = smbpasswd_setsampwent;
- (*pdb_method)->endsampwent = smbpasswd_endsampwent;
- (*pdb_method)->getsampwent = smbpasswd_getsampwent;
(*pdb_method)->getsampwnam = smbpasswd_getsampwnam;
(*pdb_method)->getsampwsid = smbpasswd_getsampwsid;
(*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;
(*pdb_method)->rename_sam_account = smbpasswd_rename_sam_account;
+ (*pdb_method)->search_users = smbpasswd_search_users;
- (*pdb_method)->rid_algorithm = smbpasswd_rid_algorithm;
+ (*pdb_method)->capabilities = smbpasswd_capabilities;
/* Setup private data and free function */
} else {
privates->smbpasswd_file = talloc_strdup(*pdb_method, lp_smb_passwd_file());
}
-
+
if (!privates->smbpasswd_file) {
DEBUG(0, ("talloc_strdp() failed for storing smbpasswd location!\n"));
return NT_STATUS_NO_MEMORY;