summaryrefslogtreecommitdiff
path: root/source4/lib/samba3/tdbsam.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/samba3/tdbsam.c')
-rw-r--r--source4/lib/samba3/tdbsam.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/source4/lib/samba3/tdbsam.c b/source4/lib/samba3/tdbsam.c
new file mode 100644
index 0000000000..0b2f975441
--- /dev/null
+++ b/source4/lib/samba3/tdbsam.c
@@ -0,0 +1,266 @@
+/*
+ Unix SMB/CIFS implementation.
+ tdb passdb backend format routines
+
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Simo Sorce 2000-2003
+ Copyright (C) Gerald Carter 2000
+ Copyright (C) Jeremy Allison 2001
+ Copyright (C) Andrew Bartlett 2002
+ Copyright (C) Jelmer Vernooij 2005
+
+ 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"
+#include "system/iconv.h"
+#include "lib/tdb/include/tdbutil.h"
+#include "lib/samba3/sam.h"
+
+#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
+#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
+#define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
+#define TDBSAM_VERSION_STRING "INFO/version"
+
+/**
+ * Open the TDB passwd database, check version and convert it if needed.
+ * @param name filename of the tdbsam file.
+ * @param open_flags file access mode.
+ * @return a TDB_CONTEXT handle on the tdbsam file.
+ **/
+
+static TDB_CONTEXT * tdbsam_open (const char *name, int open_flags, int32_t *version)
+{
+ TDB_CONTEXT *pdb_tdb;
+
+ /* Try to open tdb passwd */
+ if (!(pdb_tdb = tdb_open(name, 0, TDB_DEFAULT,
+ open_flags, 0600))) {
+ DEBUG(0, ("Unable to open/create TDB passwd\n"));
+ return NULL;
+ }
+
+ /* Check the version */
+ *version = tdb_fetch_int32(pdb_tdb,
+ TDBSAM_VERSION_STRING);
+ if (*version == -1)
+ *version = 0; /* Version not found, assume version 0 */
+
+ /* Compare the version */
+ if (*version > 2) {
+ /* Version more recent than the latest known */
+ DEBUG(0, ("TDBSAM version unknown: %d\n", *version));
+ tdb_close(pdb_tdb);
+ pdb_tdb = NULL;
+ }
+
+ return pdb_tdb;
+}
+
+static BOOL init_sam_from_buffer_v0(TDB_CONTEXT *tdb, struct samba3_samaccount *sampass, uint8_t *buf, uint32_t buflen)
+{
+ uint32_t username_len, domain_len, nt_username_len,
+ dir_drive_len, unknown_str_len, munged_dial_len,
+ fullname_len, homedir_len, logon_script_len,
+ profile_path_len, acct_desc_len, workstations_len;
+
+ uint32_t remove_me;
+ uint32_t len = 0;
+ uint32_t lm_pw_len, nt_pw_len, hourslen;
+
+ if(sampass == NULL || buf == NULL) {
+ DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
+ return False;
+ }
+
+ /* unpack the buffer into variables */
+ len = tdb_unpack (tdb, (char *)buf, buflen, TDB_FORMAT_STRING_V0,
+ &sampass->logon_time, /* d */
+ &sampass->logoff_time, /* d */
+ &sampass->kickoff_time, /* d */
+ &sampass->pass_last_set_time, /* d */
+ &sampass->pass_can_change_time, /* d */
+ &sampass->pass_must_change_time, /* d */
+ &username_len, &sampass->username, /* B */
+ &domain_len, &sampass->domain, /* B */
+ &nt_username_len, &sampass->nt_username, /* B */
+ &fullname_len, &sampass->fullname, /* B */
+ &homedir_len, &sampass->homedir, /* B */
+ &dir_drive_len, &sampass->dir_drive, /* B */
+ &logon_script_len, &sampass->logon_script, /* B */
+ &profile_path_len, &sampass->profile_path, /* B */
+ &acct_desc_len, &sampass->acct_desc, /* B */
+ &workstations_len, &sampass->workstations, /* B */
+ &unknown_str_len, &sampass->unknown_str, /* B */
+ &munged_dial_len, &sampass->munged_dial, /* B */
+ &sampass->user_rid, /* d */
+ &sampass->group_rid, /* d */
+ &lm_pw_len, &sampass->lm_pw_ptr, /* B */
+ &nt_pw_len, &sampass->nt_pw_ptr, /* B */
+ &sampass->acct_ctrl, /* w */
+ &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
+ &sampass->logon_divs, /* w */
+ &sampass->hours_len, /* d */
+ &hourslen, &sampass->hours, /* B */
+ &sampass->bad_password_count, /* w */
+ &sampass->logon_count, /* w */
+ &sampass->unknown_6); /* d */
+
+ if (len == (uint32_t) -1) {
+ return False;
+ }
+
+ if (lm_pw_len != 16) {
+ sampass->lm_pw_ptr = NULL;
+ }
+
+ if (nt_pw_len != 16) {
+ sampass->nt_pw_ptr = NULL;
+ }
+
+ return True;
+}
+
+static BOOL init_sam_from_buffer_v1(TDB_CONTEXT *tdb, struct samba3_samaccount *sampass, uint8_t *buf, uint32_t buflen)
+{
+ uint32_t username_len, domain_len, nt_username_len,
+ dir_drive_len, unknown_str_len, munged_dial_len,
+ fullname_len, homedir_len, logon_script_len,
+ profile_path_len, acct_desc_len, workstations_len;
+
+ uint32_t remove_me;
+ uint32_t len = 0;
+ uint32_t lm_pw_len, nt_pw_len, hourslen;
+
+ if(sampass == NULL || buf == NULL) {
+ DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
+ return False;
+ }
+
+ /* unpack the buffer into variables */
+ len = tdb_unpack (tdb, (char *)buf, buflen, TDB_FORMAT_STRING_V1,
+ &sampass->logon_time, /* d */
+ &sampass->logoff_time, /* d */
+ &sampass->kickoff_time, /* d */
+ /* Change from V0 is addition of bad_password_time field. */
+ &sampass->bad_password_time, /* d */
+ &sampass->pass_last_set_time, /* d */
+ &sampass->pass_can_change_time, /* d */
+ &sampass->pass_must_change_time, /* d */
+ &username_len, &sampass->username, /* B */
+ &domain_len, &sampass->domain, /* B */
+ &nt_username_len, &sampass->nt_username, /* B */
+ &fullname_len, &sampass->fullname, /* B */
+ &homedir_len, &sampass->homedir, /* B */
+ &dir_drive_len, &sampass->dir_drive, /* B */
+ &logon_script_len, &sampass->logon_script, /* B */
+ &profile_path_len, &sampass->profile_path, /* B */
+ &acct_desc_len, &sampass->acct_desc, /* B */
+ &workstations_len, &sampass->workstations, /* B */
+ &unknown_str_len, &sampass->unknown_str, /* B */
+ &munged_dial_len, &sampass->munged_dial, /* B */
+ &sampass->user_rid, /* d */
+ &sampass->group_rid, /* d */
+ &lm_pw_len, &sampass->lm_pw_ptr, /* B */
+ &nt_pw_len, &sampass->nt_pw_ptr, /* B */
+ &sampass->acct_ctrl, /* w */
+ &remove_me, /* d */
+ &sampass->logon_divs, /* w */
+ &sampass->hours_len, /* d */
+ &hourslen, &sampass->hours, /* B */
+ &sampass->bad_password_count, /* w */
+ &sampass->logon_count, /* w */
+ &sampass->unknown_6); /* d */
+
+ if (len == (uint32_t) -1) {
+ return False;
+ }
+
+ if (sampass->lm_pw_ptr && lm_pw_len != 16) {
+ sampass->lm_pw_ptr = NULL;
+ }
+
+ if (sampass->nt_pw_ptr && nt_pw_len != 16) {
+ sampass->nt_pw_ptr = NULL;
+ }
+
+ return True;
+}
+
+static BOOL init_sam_from_buffer_v2(TDB_CONTEXT *tdb, struct samba3_samaccount *sampass, uint8_t *buf, uint32_t buflen)
+{
+ uint32_t username_len, domain_len, nt_username_len,
+ dir_drive_len, unknown_str_len, munged_dial_len,
+ fullname_len, homedir_len, logon_script_len,
+ profile_path_len, acct_desc_len, workstations_len;
+
+ uint32_t len = 0;
+ uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
+
+ if(sampass == NULL || buf == NULL) {
+ DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
+ return False;
+ }
+
+ /* unpack the buffer into variables */
+ len = tdb_unpack (tdb, (char *)buf, buflen, TDB_FORMAT_STRING_V2,
+ &sampass->logon_time, /* d */
+ &sampass->logoff_time, /* d */
+ &sampass->kickoff_time, /* d */
+ &sampass->bad_password_time, /* d */
+ &sampass->pass_last_set_time, /* d */
+ &sampass->pass_can_change_time, /* d */
+ &sampass->pass_must_change_time, /* d */
+ &username_len, &sampass->username, /* B */
+ &domain_len, &sampass->domain, /* B */
+ &nt_username_len, &sampass->nt_username, /* B */
+ &fullname_len, &sampass->fullname, /* B */
+ &homedir_len, &sampass->homedir, /* B */
+ &dir_drive_len, &sampass->dir_drive, /* B */
+ &logon_script_len, &sampass->logon_script, /* B */
+ &profile_path_len, &sampass->profile_path, /* B */
+ &acct_desc_len, &sampass->acct_desc, /* B */
+ &workstations_len, &sampass->workstations, /* B */
+ &unknown_str_len, &sampass->unknown_str, /* B */
+ &munged_dial_len, &sampass->munged_dial, /* B */
+ &sampass->user_rid, /* d */
+ &sampass->group_rid, /* d */
+ &lm_pw_len, &sampass->lm_pw_ptr, /* B */
+ &nt_pw_len, &sampass->nt_pw_ptr, /* B */
+ /* Change from V1 is addition of password history field. */
+ &nt_pw_hist_len, &sampass->nt_pw_hist_ptr, /* B */
+ &sampass->acct_ctrl, /* w */
+ /* Also "remove_me" field was removed. */
+ &sampass->logon_divs, /* w */
+ &sampass->hours_len, /* d */
+ &hourslen, &sampass->hours, /* B */
+ &sampass->bad_password_count, /* w */
+ &sampass->logon_count, /* w */
+ &sampass->unknown_6); /* d */
+
+ if (len == (uint32_t) -1) {
+ return False;
+ }
+
+ if (sampass->lm_pw_ptr && lm_pw_len != 16) {
+ sampass->lm_pw_ptr = NULL;
+ }
+
+ if (sampass->nt_pw_ptr && nt_pw_len != 16) {
+ sampass->nt_pw_ptr = NULL;
+ }
+
+ return True;
+}