mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
a2e5dbb112
system header files...
Jeremy.
(This used to be commit 31e0ce310e
)
762 lines
20 KiB
C
762 lines
20 KiB
C
/*
|
|
* Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
|
|
* Copyright (C) Andrew Tridgell 1992-1998
|
|
* Copyright (C) Simo Sorce 2000
|
|
* Copyright (C) Gerald Carter 2000
|
|
*
|
|
* 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"
|
|
|
|
#ifdef WITH_TDBPWD
|
|
|
|
#define PASSDB_FILE_NAME "/passdb.tdb"
|
|
#define RIDDB_FILE_NAME "/riddb.tdb"
|
|
#define TDB_FORMAT_STRING "ddddddfffPPfPPPPffddBBwdwdBdd"
|
|
#define USERPREFIX "USER_"
|
|
#define RIDPREFIX "RID_"
|
|
|
|
extern int DEBUGLEVEL;
|
|
extern pstring samlogon_user;
|
|
extern BOOL sam_logon_in_ssb;
|
|
|
|
|
|
struct tdb_enum_info
|
|
{
|
|
TDB_CONTEXT *passwd_tdb;
|
|
TDB_DATA key;
|
|
};
|
|
|
|
static struct tdb_enum_info global_tdb_ent;
|
|
static SAM_ACCOUNT global_sam_pass;
|
|
|
|
/**********************************************************************
|
|
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 fstring username,
|
|
domain,
|
|
nt_username,
|
|
dir_drive,
|
|
unknown_str,
|
|
munged_dial;
|
|
static pstring full_name,
|
|
home_dir,
|
|
logon_script,
|
|
profile_path,
|
|
acct_desc,
|
|
workstations;
|
|
static uint8 *lm_pw_ptr,
|
|
*nt_pw_ptr,
|
|
lm_pw[16],
|
|
nt_pw[16];
|
|
uint32 len = 0;
|
|
uint32 lmpwlen, ntpwlen, hourslen;
|
|
|
|
/* using static memory for strings */
|
|
/* you set it now or you will delete any fields retrieved by tdb_unpack */
|
|
pdb_set_mem_ownership(sampass, False);
|
|
|
|
|
|
/* unpack the buffer into variables */
|
|
len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING,
|
|
&sampass->logon_time,
|
|
&sampass->logoff_time,
|
|
&sampass->kickoff_time,
|
|
&sampass->pass_last_set_time,
|
|
&sampass->pass_can_change_time,
|
|
&sampass->pass_must_change_time,
|
|
username,
|
|
domain,
|
|
nt_username,
|
|
full_name,
|
|
home_dir,
|
|
dir_drive,
|
|
logon_script,
|
|
profile_path,
|
|
acct_desc,
|
|
workstations,
|
|
unknown_str,
|
|
munged_dial,
|
|
&sampass->user_rid,
|
|
&sampass->group_rid,
|
|
&lmpwlen, &lm_pw_ptr,
|
|
&ntpwlen, &nt_pw_ptr,
|
|
&sampass->acct_ctrl,
|
|
&sampass->unknown_3,
|
|
&sampass->logon_divs,
|
|
&sampass->hours_len,
|
|
&hourslen, &sampass->hours,
|
|
&sampass->unknown_5,
|
|
&sampass->unknown_6);
|
|
|
|
if (len == -1)
|
|
return False;
|
|
|
|
/*
|
|
* We have to copy the password hashes into static memory
|
|
* and free the memory allocated by tdb_unpack. This is because
|
|
* the sampass->own_memory flag is for all pointer members.
|
|
* The remaining members are using static memory and so
|
|
* the password hashes must as well. --jerry
|
|
*/
|
|
if (lm_pw_ptr)
|
|
{
|
|
memcpy(lm_pw, lm_pw_ptr, 16);
|
|
free (lm_pw_ptr);
|
|
}
|
|
if (nt_pw_ptr)
|
|
{
|
|
memcpy(nt_pw, nt_pw_ptr, 16);
|
|
free (nt_pw_ptr);
|
|
}
|
|
|
|
pdb_set_username (sampass, username);
|
|
pdb_set_domain (sampass, domain);
|
|
pdb_set_nt_username (sampass, nt_username);
|
|
pdb_set_fullname (sampass, full_name);
|
|
pdb_set_homedir (sampass, home_dir);
|
|
pdb_set_dir_drive (sampass, dir_drive);
|
|
pdb_set_logon_script (sampass, logon_script);
|
|
pdb_set_profile_path (sampass, profile_path);
|
|
pdb_set_acct_desc (sampass, acct_desc);
|
|
pdb_set_workstations (sampass, workstations);
|
|
pdb_set_munged_dial (sampass, munged_dial);
|
|
pdb_set_lanman_passwd(sampass, lm_pw);
|
|
pdb_set_nt_passwd (sampass, nt_pw);
|
|
|
|
return True;
|
|
}
|
|
|
|
/**********************************************************************
|
|
Intialize a BYTE buffer from a SAM_ACCOUNT struct
|
|
*********************************************************************/
|
|
static uint32 init_buffer_from_sam (uint8 **buf, SAM_ACCOUNT *sampass)
|
|
{
|
|
size_t len, buflen;
|
|
|
|
fstring username,
|
|
domain,
|
|
nt_username,
|
|
dir_drive,
|
|
unknown_str,
|
|
munged_dial;
|
|
pstring full_name,
|
|
home_dir,
|
|
logon_script,
|
|
profile_path,
|
|
acct_desc,
|
|
workstations;
|
|
uint8 lm_pw[16],
|
|
nt_pw[16];
|
|
char null_pw[] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
|
|
|
|
/* do we have a valid SAM_ACCOUNT pointer? */
|
|
if (sampass == NULL)
|
|
return -1;
|
|
|
|
*buf = NULL;
|
|
buflen = 0;
|
|
|
|
fstrcpy(username, sampass->username);
|
|
fstrcpy(domain, sampass->domain);
|
|
fstrcpy(nt_username, sampass->nt_username);
|
|
fstrcpy(dir_drive, sampass->dir_drive);
|
|
fstrcpy(unknown_str, sampass->unknown_str);
|
|
fstrcpy(munged_dial, sampass->munged_dial);
|
|
|
|
pstrcpy(full_name, sampass->full_name);
|
|
pstrcpy(home_dir, sampass->home_dir);
|
|
pstrcpy(logon_script, sampass->logon_script);
|
|
pstrcpy(profile_path, sampass->profile_path);
|
|
pstrcpy(acct_desc, sampass->acct_desc);
|
|
pstrcpy(workstations, sampass->workstations);
|
|
|
|
if (sampass->lm_pw)
|
|
memcpy(lm_pw, sampass->lm_pw, 16);
|
|
else
|
|
pdb_gethexpwd (null_pw, lm_pw);
|
|
|
|
if (sampass->nt_pw)
|
|
memcpy(nt_pw, sampass->nt_pw, 16);
|
|
else
|
|
pdb_gethexpwd (null_pw, nt_pw);
|
|
|
|
|
|
/* one time to get the size needed */
|
|
len = tdb_pack(NULL, 0, TDB_FORMAT_STRING,
|
|
sampass->logon_time,
|
|
sampass->logoff_time,
|
|
sampass->kickoff_time,
|
|
sampass->pass_last_set_time,
|
|
sampass->pass_can_change_time,
|
|
sampass->pass_must_change_time,
|
|
username,
|
|
domain,
|
|
nt_username,
|
|
full_name,
|
|
home_dir,
|
|
dir_drive,
|
|
logon_script,
|
|
profile_path,
|
|
acct_desc,
|
|
workstations,
|
|
unknown_str,
|
|
munged_dial,
|
|
sampass->user_rid,
|
|
sampass->group_rid,
|
|
16, lm_pw,
|
|
16, nt_pw,
|
|
sampass->acct_ctrl,
|
|
sampass->unknown_3,
|
|
sampass->logon_divs,
|
|
sampass->hours_len,
|
|
MAX_HOURS_LEN, sampass->hours,
|
|
sampass->unknown_5,
|
|
sampass->unknown_6);
|
|
|
|
|
|
/* malloc the space needed */
|
|
if ( (*buf=(uint8*)malloc(len)) == NULL)
|
|
{
|
|
DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n"));
|
|
return (-1);
|
|
}
|
|
|
|
/* now for the real call to tdb_pack() */
|
|
/* one time to get the size needed */
|
|
buflen = tdb_pack(*buf, len, TDB_FORMAT_STRING,
|
|
sampass->logon_time,
|
|
sampass->logoff_time,
|
|
sampass->kickoff_time,
|
|
sampass->pass_last_set_time,
|
|
sampass->pass_can_change_time,
|
|
sampass->pass_must_change_time,
|
|
username,
|
|
domain,
|
|
nt_username,
|
|
full_name,
|
|
home_dir,
|
|
dir_drive,
|
|
logon_script,
|
|
profile_path,
|
|
acct_desc,
|
|
workstations,
|
|
unknown_str,
|
|
munged_dial,
|
|
sampass->user_rid,
|
|
sampass->group_rid,
|
|
16, lm_pw,
|
|
16, nt_pw,
|
|
sampass->acct_ctrl,
|
|
sampass->unknown_3,
|
|
sampass->logon_divs,
|
|
sampass->hours_len,
|
|
MAX_HOURS_LEN, sampass->hours,
|
|
sampass->unknown_5,
|
|
sampass->unknown_6);
|
|
|
|
|
|
/* check to make sure we got it correct */
|
|
if (buflen != len)
|
|
{
|
|
/* error */
|
|
free (*buf);
|
|
return (-1);
|
|
}
|
|
|
|
return (buflen);
|
|
}
|
|
|
|
/***************************************************************
|
|
Open the TDB passwd database for SAM account enumeration.
|
|
****************************************************************/
|
|
BOOL pdb_setsampwent(BOOL update)
|
|
{
|
|
pstring tdbfile;
|
|
|
|
pstrcpy (tdbfile, lp_private_dir());
|
|
pstrcat (tdbfile, PASSDB_FILE_NAME);
|
|
|
|
/* Open tdb passwd */
|
|
if (!(global_tdb_ent.passwd_tdb = tdb_open(tdbfile, 0, 0, update ? O_RDWR : O_RDONLY, 0600)))
|
|
{
|
|
DEBUG(0, ("Unable to open TDB passwd, trying create new!\n"));
|
|
if (!(global_tdb_ent.passwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600)))
|
|
{
|
|
DEBUG(0, ("Unable to create TDB passwd (passdb.tdb) !!!"));
|
|
return False;
|
|
}
|
|
}
|
|
|
|
global_tdb_ent.key = tdb_firstkey(global_tdb_ent.passwd_tdb);
|
|
|
|
return True;
|
|
}
|
|
|
|
/***************************************************************
|
|
End enumeration of the TDB passwd list.
|
|
****************************************************************/
|
|
void pdb_endsampwent(void)
|
|
{
|
|
if (global_tdb_ent.passwd_tdb)
|
|
{
|
|
tdb_close(global_tdb_ent.passwd_tdb);
|
|
global_tdb_ent.passwd_tdb = NULL;
|
|
}
|
|
|
|
DEBUG(7, ("endtdbpwent: closed password file.\n"));
|
|
}
|
|
|
|
|
|
/*****************************************************************
|
|
Get one SAM_ACCOUNT from the TDB (next in line)
|
|
*****************************************************************/
|
|
SAM_ACCOUNT* pdb_getsampwent(void)
|
|
{
|
|
TDB_DATA data;
|
|
struct passwd *pw;
|
|
uid_t uid;
|
|
gid_t gid;
|
|
|
|
/* do we have an valid interation pointer? */
|
|
if(global_tdb_ent.passwd_tdb == NULL)
|
|
{
|
|
DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
|
|
return NULL;
|
|
}
|
|
|
|
data = tdb_fetch (global_tdb_ent.passwd_tdb, global_tdb_ent.key);
|
|
if (!data.dptr)
|
|
{
|
|
DEBUG(5,("pdb_getsampwent: database entry not found.\n"));
|
|
return NULL;
|
|
}
|
|
|
|
/* unpack the buffer */
|
|
pdb_clear_sam (&global_sam_pass);
|
|
if (!init_sam_from_buffer (&global_sam_pass, data.dptr, data.dsize))
|
|
{
|
|
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
|
|
return NULL;
|
|
}
|
|
|
|
/* 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=sys_getpwnam(pdb_get_username(&global_sam_pass))) == NULL)
|
|
{
|
|
DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n",
|
|
pdb_get_username(&global_sam_pass)));
|
|
return NULL;
|
|
}
|
|
|
|
uid = pw->pw_uid;
|
|
gid = pw->pw_gid;
|
|
pdb_set_uid (&global_sam_pass, uid);
|
|
pdb_set_gid (&global_sam_pass, gid);
|
|
|
|
/* 21 days from present */
|
|
pdb_set_pass_must_change_time(&global_sam_pass, time(NULL)+1814400);
|
|
|
|
standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_logon_script(&global_sam_pass));
|
|
standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_profile_path(&global_sam_pass));
|
|
standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_homedir(&global_sam_pass));
|
|
|
|
/* increment to next in line */
|
|
global_tdb_ent.key = tdb_nextkey (global_tdb_ent.passwd_tdb, global_tdb_ent.key);
|
|
|
|
return (&global_sam_pass);
|
|
}
|
|
|
|
/******************************************************************
|
|
Lookup a name in the SAM TDB
|
|
******************************************************************/
|
|
SAM_ACCOUNT* pdb_getsampwnam (char *sname)
|
|
{
|
|
TDB_CONTEXT *pwd_tdb;
|
|
TDB_DATA data, key;
|
|
fstring keystr;
|
|
struct passwd *pw;
|
|
pstring tdbfile;
|
|
fstring name;
|
|
uid_t uid;
|
|
gid_t gid;
|
|
|
|
fstrcpy (name, sname);
|
|
strlower (name);
|
|
pstrcpy (tdbfile, lp_private_dir());
|
|
pstrcat (tdbfile, PASSDB_FILE_NAME);
|
|
|
|
/* set search key */
|
|
slprintf(keystr, sizeof(keystr), "%s%s", USERPREFIX, name);
|
|
key.dptr = keystr;
|
|
key.dsize = strlen (keystr) + 1;
|
|
|
|
/* open the accounts TDB */
|
|
if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDONLY, 0600)))
|
|
{
|
|
DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd!\n"));
|
|
return False;
|
|
}
|
|
|
|
/* get the record */
|
|
data = tdb_fetch (pwd_tdb, key);
|
|
if (!data.dptr)
|
|
{
|
|
DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
|
|
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
|
|
tdb_close (pwd_tdb);
|
|
return NULL;
|
|
}
|
|
|
|
/* unpack the buffer */
|
|
pdb_clear_sam (&global_sam_pass);
|
|
if (!init_sam_from_buffer (&global_sam_pass, data.dptr, data.dsize))
|
|
{
|
|
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
|
|
return NULL;
|
|
}
|
|
|
|
/* 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=sys_getpwnam(pdb_get_username(&global_sam_pass))) == NULL)
|
|
{
|
|
DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n",
|
|
pdb_get_username(&global_sam_pass)));
|
|
return NULL;
|
|
}
|
|
|
|
uid = pw->pw_uid;
|
|
gid = pw->pw_gid;
|
|
pdb_set_uid (&global_sam_pass, uid);
|
|
pdb_set_gid (&global_sam_pass, gid);
|
|
|
|
/* 21 days from present */
|
|
pdb_set_pass_must_change_time(&global_sam_pass, time(NULL)+1814400);
|
|
|
|
standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_logon_script(&global_sam_pass));
|
|
standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_profile_path(&global_sam_pass));
|
|
standard_sub_advanced(-1, pdb_get_username(&global_sam_pass), "", gid, pdb_get_homedir(&global_sam_pass));
|
|
|
|
/* cleanup */
|
|
tdb_close (pwd_tdb);
|
|
|
|
return (&global_sam_pass);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Search by uid
|
|
**************************************************************************/
|
|
SAM_ACCOUNT* pdb_getsampwuid (uid_t uid)
|
|
{
|
|
struct passwd *pw;
|
|
fstring name;
|
|
|
|
pw = sys_getpwuid(uid);
|
|
if (pw == NULL)
|
|
{
|
|
DEBUG(0,("pdb_getsampwuid: getpwuid(%d) return NULL. User does not exist!\n", uid));
|
|
return NULL;
|
|
}
|
|
fstrcpy (name, pw->pw_name);
|
|
|
|
return pdb_getsampwnam (name);
|
|
|
|
}
|
|
|
|
/***************************************************************************
|
|
Search by rid
|
|
**************************************************************************/
|
|
SAM_ACCOUNT* pdb_getsampwrid (uint32 rid)
|
|
{
|
|
TDB_CONTEXT *pwd_tdb;
|
|
TDB_DATA data, key;
|
|
fstring keystr;
|
|
pstring tdbfile;
|
|
fstring name;
|
|
|
|
pstrcpy (tdbfile, lp_private_dir());
|
|
pstrcat (tdbfile, RIDDB_FILE_NAME);
|
|
|
|
/* set search key */
|
|
slprintf(keystr, sizeof(keystr), "%s%.8x", RIDPREFIX, rid);
|
|
key.dptr = keystr;
|
|
key.dsize = strlen (keystr) + 1;
|
|
|
|
/* open the accounts TDB */
|
|
if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDONLY, 0600)))
|
|
{
|
|
DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n"));
|
|
return False;
|
|
}
|
|
|
|
/* get the record */
|
|
data = tdb_fetch (pwd_tdb, key);
|
|
if (!data.dptr)
|
|
{
|
|
DEBUG(5,("pdb_getsampwrid (TDB): error fetching database.\n"));
|
|
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
|
|
tdb_close (pwd_tdb);
|
|
return NULL;
|
|
}
|
|
|
|
fstrcpy (name, data.dptr);
|
|
|
|
tdb_close (pwd_tdb);
|
|
|
|
return pdb_getsampwnam (name);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Delete a SAM_ACCOUNT
|
|
****************************************************************************/
|
|
BOOL pdb_delete_sam_account(char *sname)
|
|
{
|
|
struct passwd *pwd = NULL;
|
|
TDB_CONTEXT *pwd_tdb;
|
|
TDB_DATA key, data;
|
|
fstring keystr;
|
|
pstring tdbfile;
|
|
uid_t uid;
|
|
uint32 rid;
|
|
fstring name;
|
|
|
|
fstrcpy (name, sname);
|
|
strlower (name);
|
|
|
|
pstrcpy (tdbfile, lp_private_dir());
|
|
pstrcat (tdbfile, PASSDB_FILE_NAME);
|
|
|
|
/* open the TDB */
|
|
if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600)))
|
|
{
|
|
DEBUG(0, ("Unable to open TDB passwd!"));
|
|
return False;
|
|
}
|
|
|
|
/* set the search key */
|
|
slprintf(keystr, sizeof(keystr), "%s%s", USERPREFIX, name);
|
|
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 */
|
|
pdb_clear_sam (&global_sam_pass);
|
|
if (!init_sam_from_buffer (&global_sam_pass, data.dptr, data.dsize))
|
|
{
|
|
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
|
|
return False;
|
|
}
|
|
|
|
pwd = sys_getpwnam(global_sam_pass.username);
|
|
rid = pdb_uid_to_user_rid (uid);
|
|
|
|
/* it's outaa here! 8^) */
|
|
if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS)
|
|
{
|
|
DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
|
|
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
|
|
tdb_close(pwd_tdb);
|
|
return False;
|
|
}
|
|
tdb_close(pwd_tdb);
|
|
|
|
pstrcpy (tdbfile, lp_private_dir());
|
|
pstrcat (tdbfile, RIDDB_FILE_NAME);
|
|
|
|
/* open the RID TDB */
|
|
if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600)))
|
|
{
|
|
DEBUG(0, ("Unable to open TDB rid file!"));
|
|
return False;
|
|
}
|
|
|
|
/* set the search key */
|
|
slprintf(keystr, sizeof(keystr), "%s%.8x", RIDPREFIX, rid);
|
|
key.dptr = keystr;
|
|
key.dsize = strlen (keystr) + 1;
|
|
|
|
/* it's outaa here! 8^) */
|
|
if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS)
|
|
{
|
|
DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
|
|
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
|
|
tdb_close(pwd_tdb);
|
|
return False;
|
|
}
|
|
|
|
tdb_close(pwd_tdb);
|
|
|
|
return True;
|
|
}
|
|
|
|
/***************************************************************************
|
|
Update the TDB SAM
|
|
****************************************************************************/
|
|
static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
|
|
{
|
|
TDB_CONTEXT *pwd_tdb;
|
|
TDB_DATA key, data;
|
|
uint8 *buf = NULL;
|
|
fstring keystr;
|
|
pstring tdbfile;
|
|
fstring name;
|
|
int newtdb = FALSE;
|
|
|
|
pstrcpy (tdbfile, lp_private_dir());
|
|
pstrcat (tdbfile, PASSDB_FILE_NAME);
|
|
|
|
if ( (!newpwd->uid) || (!newpwd->gid) )
|
|
DEBUG (0,("tdb_update_sam: Storing a SAM_ACCOUNT for [%s] with uid %d and gid %d!\n",
|
|
newpwd->username, newpwd->uid, newpwd->gid));
|
|
|
|
/* if we don't have a RID, then generate one */
|
|
if (!newpwd->user_rid)
|
|
pdb_set_user_rid (newpwd, pdb_uid_to_user_rid (newpwd->uid));
|
|
if (!newpwd->group_rid)
|
|
pdb_set_group_rid (newpwd, pdb_gid_to_group_rid (newpwd->gid));
|
|
|
|
/* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */
|
|
if ((data.dsize=init_buffer_from_sam (&buf, newpwd)) == -1)
|
|
{
|
|
DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n"));
|
|
return False;
|
|
}
|
|
data.dptr = buf;
|
|
|
|
fstrcpy (name, pdb_get_username(newpwd));
|
|
strlower (name);
|
|
|
|
/* setup the USER index key */
|
|
slprintf(keystr, sizeof(keystr), "%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*/
|
|
if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600)))
|
|
{
|
|
DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd!\n"));
|
|
if (flag == TDB_INSERT)
|
|
{
|
|
DEBUG(0, ("Unable to open TDB passwd, trying create new!\n"));
|
|
if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600)))
|
|
{
|
|
DEBUG(0, ("Unable to create TDB passwd (passdb.tdb) !!!\n"));
|
|
return False;
|
|
}
|
|
newtdb = TRUE;
|
|
}
|
|
}
|
|
|
|
/* add the account */
|
|
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)));
|
|
tdb_close (pwd_tdb);
|
|
return False;
|
|
}
|
|
|
|
/* cleanup */
|
|
tdb_close (pwd_tdb);
|
|
|
|
/* setup RID data */
|
|
data.dsize = sizeof(fstring);
|
|
data.dptr = name;
|
|
|
|
pstrcpy (tdbfile, lp_private_dir());
|
|
pstrcat (tdbfile, RIDDB_FILE_NAME);
|
|
|
|
/* setup the RID index key */
|
|
slprintf(keystr, sizeof(keystr), "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
|
|
key.dptr = keystr;
|
|
key.dsize = strlen (keystr) + 1;
|
|
|
|
/* open the account TDB rid file*/
|
|
if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600)))
|
|
{
|
|
DEBUG(0, ("tdb_update_sam: Unable to open TDB rid database!\n"));
|
|
if (newtdb == FALSE)
|
|
DEBUG(0, ("WARNING: rid database missing and passdb exist, check references integrity!\n"));
|
|
if (flag == TDB_INSERT)
|
|
{
|
|
DEBUG(0, ("Unable to open TDB rid file, trying create new!\n"));
|
|
if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600)))
|
|
{
|
|
DEBUG(0, ("Unable to create TDB rid (riddb.tdb) !!!\n"));
|
|
/* return False; */
|
|
}
|
|
}
|
|
}
|
|
|
|
/* add the reference */
|
|
if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS)
|
|
{
|
|
DEBUG(0, ("Unable to modify TDB rid database!"));
|
|
DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
|
|
tdb_close (pwd_tdb);
|
|
return False;
|
|
}
|
|
|
|
/* cleanup */
|
|
tdb_close (pwd_tdb);
|
|
|
|
return (True);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Modifies an existing SAM_ACCOUNT
|
|
****************************************************************************/
|
|
BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override)
|
|
{
|
|
return (tdb_update_sam(newpwd, override, TDB_MODIFY));
|
|
}
|
|
|
|
/***************************************************************************
|
|
Adds an existing SAM_ACCOUNT
|
|
****************************************************************************/
|
|
BOOL pdb_add_sam_account (SAM_ACCOUNT *newpwd)
|
|
{
|
|
return (tdb_update_sam(newpwd, True, TDB_INSERT));
|
|
}
|
|
|
|
|
|
#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_TDBPWD */
|