sorry folks, forgot to cvs add/remove before commit.
authorSimo Sorce <idra@samba.org>
Tue, 14 Oct 2003 07:43:41 +0000 (07:43 +0000)
committerSimo Sorce <idra@samba.org>
Tue, 14 Oct 2003 07:43:41 +0000 (07:43 +0000)
(This used to be commit 0ed85e6a2dff0953dbbd5ff4723ef6941ec32850)

source3/include/tdbsam2_parse_info.h [new file with mode: 0644]
source3/passdb/pdb_gums.c [new file with mode: 0644]
source3/sam/gumm_tdb.c [deleted file]
source3/sam/gums_tdbsam2.c [new file with mode: 0644]

diff --git a/source3/include/tdbsam2_parse_info.h b/source3/include/tdbsam2_parse_info.h
new file mode 100644 (file)
index 0000000..f1b2936
--- /dev/null
@@ -0,0 +1,164 @@
+/* This is an automatically generated file - DO NOT EDIT! */
+
+int gen_dump_struct_domain_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_domain_sub_structure(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_domain_sub_structure[] = {
+{"next_rid", 0, sizeof(uint32), offsetof(struct domain_sub_structure, next_rid), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
+
+int gen_dump_struct_domain_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_domain_sub_structure, p, ptr, indent);
+}
+int gen_parse_struct_domain_sub_structure(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_domain_sub_structure, ptr, str);
+}
+
+int gen_dump_struct_tdbsam2_domain_data(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_tdbsam2_domain_data(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_tdbsam2_domain_data[] = {
+{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct tdbsam2_domain_data, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX},
+{"type", 0, sizeof(uint32), offsetof(struct tdbsam2_domain_data, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"version", 0, sizeof(uint32), offsetof(struct tdbsam2_domain_data, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"xcounter", 0, sizeof(uint32), offsetof(struct tdbsam2_domain_data, xcounter), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"sec_desc", 1, sizeof(SEC_DESC), offsetof(struct tdbsam2_domain_data, sec_desc), 0, NULL, 0, gen_dump_SEC_DESC, gen_parse_SEC_DESC},
+{"dom_sid", 1, sizeof(DOM_SID), offsetof(struct tdbsam2_domain_data, dom_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
+{"name", 1, sizeof(char), offsetof(struct tdbsam2_domain_data, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"description", 1, sizeof(char), offsetof(struct tdbsam2_domain_data, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"dss", 1, sizeof(struct domain_sub_structure), offsetof(struct tdbsam2_domain_data, dss), 0, NULL, 0, gen_dump_struct_domain_sub_structure, gen_parse_struct_domain_sub_structure},
+{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
+
+int gen_dump_struct_tdbsam2_domain_data(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_tdbsam2_domain_data, p, ptr, indent);
+}
+int gen_parse_struct_tdbsam2_domain_data(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_tdbsam2_domain_data, ptr, str);
+}
+
+int gen_dump_struct_user_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_user_sub_structure(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_user_sub_structure[] = {
+{"group_sid", 1, sizeof(DOM_SID), offsetof(struct user_sub_structure, group_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
+{"logon_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, logon_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"logoff_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, logoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"kickoff_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, kickoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"pass_last_set_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, pass_last_set_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"pass_can_change_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, pass_can_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"pass_must_change_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, pass_must_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"full_name", 1, sizeof(char), offsetof(struct user_sub_structure, full_name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"home_dir", 1, sizeof(char), offsetof(struct user_sub_structure, home_dir), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"dir_drive", 1, sizeof(char), offsetof(struct user_sub_structure, dir_drive), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"logon_script", 1, sizeof(char), offsetof(struct user_sub_structure, logon_script), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"profile_path", 1, sizeof(char), offsetof(struct user_sub_structure, profile_path), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"workstations", 1, sizeof(char), offsetof(struct user_sub_structure, workstations), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"unknown_str", 1, sizeof(char), offsetof(struct user_sub_structure, unknown_str), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"munged_dial", 1, sizeof(char), offsetof(struct user_sub_structure, munged_dial), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"lm_pw", 0, sizeof(DATA_BLOB), offsetof(struct user_sub_structure, lm_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB},
+{"nt_pw", 0, sizeof(DATA_BLOB), offsetof(struct user_sub_structure, nt_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB},
+{"acct_ctrl", 0, sizeof(uint16), offsetof(struct user_sub_structure, acct_ctrl), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
+{"logon_divs", 0, sizeof(uint16), offsetof(struct user_sub_structure, logon_divs), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
+{"hours_len", 0, sizeof(uint32), offsetof(struct user_sub_structure, hours_len), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"hours", 1, sizeof(uint8), offsetof(struct user_sub_structure, hours), 0, "hours_len", 0, gen_dump_uint8, gen_parse_uint8},
+{"bad_password_count", 0, sizeof(uint16), offsetof(struct user_sub_structure, bad_password_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
+{"logon_count", 0, sizeof(uint16), offsetof(struct user_sub_structure, logon_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
+{"unknown_3", 0, sizeof(uint32), offsetof(struct user_sub_structure, unknown_3), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"unknown_6", 0, sizeof(uint32), offsetof(struct user_sub_structure, unknown_6), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
+
+int gen_dump_struct_user_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_user_sub_structure, p, ptr, indent);
+}
+int gen_parse_struct_user_sub_structure(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_user_sub_structure, ptr, str);
+}
+
+int gen_dump_struct_tdbsam2_user_data(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_tdbsam2_user_data(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_tdbsam2_user_data[] = {
+{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct tdbsam2_user_data, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX},
+{"type", 0, sizeof(uint32), offsetof(struct tdbsam2_user_data, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"version", 0, sizeof(uint32), offsetof(struct tdbsam2_user_data, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"xcounter", 0, sizeof(uint32), offsetof(struct tdbsam2_user_data, xcounter), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"sec_desc", 1, sizeof(SEC_DESC), offsetof(struct tdbsam2_user_data, sec_desc), 0, NULL, 0, gen_dump_SEC_DESC, gen_parse_SEC_DESC},
+{"user_sid", 1, sizeof(DOM_SID), offsetof(struct tdbsam2_user_data, user_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
+{"name", 1, sizeof(char), offsetof(struct tdbsam2_user_data, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"description", 1, sizeof(char), offsetof(struct tdbsam2_user_data, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"uss", 1, sizeof(struct user_sub_structure), offsetof(struct tdbsam2_user_data, uss), 0, NULL, 0, gen_dump_struct_user_sub_structure, gen_parse_struct_user_sub_structure},
+{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
+
+int gen_dump_struct_tdbsam2_user_data(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_tdbsam2_user_data, p, ptr, indent);
+}
+int gen_parse_struct_tdbsam2_user_data(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_tdbsam2_user_data, ptr, str);
+}
+
+int gen_dump_struct_group_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_group_sub_structure(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_group_sub_structure[] = {
+{"count", 0, sizeof(uint32), offsetof(struct group_sub_structure, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"members", 1, sizeof(DOM_SID), offsetof(struct group_sub_structure, members), 0, "count", 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
+{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
+
+int gen_dump_struct_group_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_group_sub_structure, p, ptr, indent);
+}
+int gen_parse_struct_group_sub_structure(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_group_sub_structure, ptr, str);
+}
+
+int gen_dump_struct_tdbsam2_group_data(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_tdbsam2_group_data(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_tdbsam2_group_data[] = {
+{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct tdbsam2_group_data, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX},
+{"type", 0, sizeof(uint32), offsetof(struct tdbsam2_group_data, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"version", 0, sizeof(uint32), offsetof(struct tdbsam2_group_data, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"xcounter", 0, sizeof(uint32), offsetof(struct tdbsam2_group_data, xcounter), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"sec_desc", 1, sizeof(SEC_DESC), offsetof(struct tdbsam2_group_data, sec_desc), 0, NULL, 0, gen_dump_SEC_DESC, gen_parse_SEC_DESC},
+{"group_sid", 1, sizeof(DOM_SID), offsetof(struct tdbsam2_group_data, group_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
+{"name", 1, sizeof(char), offsetof(struct tdbsam2_group_data, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"description", 1, sizeof(char), offsetof(struct tdbsam2_group_data, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"gss", 1, sizeof(struct group_sub_structure), offsetof(struct tdbsam2_group_data, gss), 0, NULL, 0, gen_dump_struct_group_sub_structure, gen_parse_struct_group_sub_structure},
+{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
+
+int gen_dump_struct_tdbsam2_group_data(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_tdbsam2_group_data, p, ptr, indent);
+}
+int gen_parse_struct_tdbsam2_group_data(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_tdbsam2_group_data, ptr, str);
+}
+
+int gen_dump_struct_priv_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_priv_sub_structure(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_priv_sub_structure[] = {
+{"privilege", 1, sizeof(LUID_ATTR), offsetof(struct priv_sub_structure, privilege), 0, NULL, 0, gen_dump_LUID_ATTR, gen_parse_LUID_ATTR},
+{"count", 0, sizeof(uint32), offsetof(struct priv_sub_structure, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"members", 1, sizeof(DOM_SID), offsetof(struct priv_sub_structure, members), 0, "count", 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
+{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
+
+int gen_dump_struct_priv_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_priv_sub_structure, p, ptr, indent);
+}
+int gen_parse_struct_priv_sub_structure(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_priv_sub_structure, ptr, str);
+}
+
+int gen_dump_struct_tdbsam2_priv_data(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_tdbsam2_priv_data(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_tdbsam2_priv_data[] = {
+{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct tdbsam2_priv_data, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX},
+{"type", 0, sizeof(uint32), offsetof(struct tdbsam2_priv_data, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"version", 0, sizeof(uint32), offsetof(struct tdbsam2_priv_data, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"xcounter", 0, sizeof(uint32), offsetof(struct tdbsam2_priv_data, xcounter), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"null_sid", 1, sizeof(DOM_SID), offsetof(struct tdbsam2_priv_data, null_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
+{"name", 1, sizeof(char), offsetof(struct tdbsam2_priv_data, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"description", 1, sizeof(char), offsetof(struct tdbsam2_priv_data, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"pss", 1, sizeof(struct priv_sub_structure), offsetof(struct tdbsam2_priv_data, pss), 0, NULL, 0, gen_dump_struct_priv_sub_structure, gen_parse_struct_priv_sub_structure},
+{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};
+
+int gen_dump_struct_tdbsam2_priv_data(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_tdbsam2_priv_data, p, ptr, indent);
+}
+int gen_parse_struct_tdbsam2_priv_data(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_tdbsam2_priv_data, ptr, str);
+}
+
diff --git a/source3/passdb/pdb_gums.c b/source3/passdb/pdb_gums.c
new file mode 100644 (file)
index 0000000..dd6e682
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * 'Guest' password backend for samba
+ * Copyright (C) Jelmer Vernooij 2002
+ * Copyright (C) Andrew Bartlett 2003
+ * 
+ * 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"
+
+#define SET_OR_FAIL(func, label) do { if (!NT_STATUS_IS_OK(func)) { DEBUG(0, ("%s: Setting gums object data failed!\n", FUNCTION_MACRO)); goto label; } } while(0)
+#define BOOL_SET_OR_FAIL(func, label) do { if (!func) { DEBUG(0, ("%s: Setting sam object data failed!\n", FUNCTION_MACRO)); goto label; } } while(0)
+
+struct gums_gw_data {
+       GUMS_FUNCTIONS *fns;
+       void *handle;
+};
+
+static NTSTATUS gums_object_to_sam_account(SAM_ACCOUNT *sa, GUMS_OBJECT *go)
+{
+       NTSTATUS ret;
+       NTTIME nt_time;
+       DATA_BLOB pwd;
+
+       if (!go || !sa)
+               return NT_STATUS_INVALID_PARAMETER;
+/*
+       if (!NT_STATUS_IS_OK(ret = pdb_init_sam(sa))) {
+               DEBUG(0, ("gums_object_to_sam_account: error occurred while creating sam_account object!\n"));
+               goto error;
+       }
+*/
+       if (gums_get_object_type(go) != GUMS_OBJ_NORMAL_USER)
+               return NT_STATUS_OBJECT_TYPE_MISMATCH;
+
+       BOOL_SET_OR_FAIL(pdb_set_acct_ctrl(sa, gums_get_user_acct_ctrl(go), PDB_SET), error);
+
+       /* domain */
+       /* unix_homedir ? */
+
+       nt_time = gums_get_user_logon_time(go);
+       BOOL_SET_OR_FAIL(pdb_set_logon_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
+       nt_time = gums_get_user_logoff_time(go);
+       BOOL_SET_OR_FAIL(pdb_set_logoff_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
+       nt_time = gums_get_user_kickoff_time(go);
+       BOOL_SET_OR_FAIL(pdb_set_kickoff_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
+       nt_time = gums_get_user_pass_last_set_time(go);
+       BOOL_SET_OR_FAIL(pdb_set_pass_last_set_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
+       nt_time = gums_get_user_pass_can_change_time(go);
+       BOOL_SET_OR_FAIL(pdb_set_pass_can_change_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
+       nt_time = gums_get_user_pass_must_change_time(go);
+       BOOL_SET_OR_FAIL(pdb_set_pass_must_change_time(sa, nt_time_to_unix(&nt_time), PDB_SET), error);
+       BOOL_SET_OR_FAIL(pdb_set_hours_len(sa, gums_get_user_hours_len(go), PDB_SET), error);
+       BOOL_SET_OR_FAIL(pdb_set_logon_divs(sa, gums_get_user_logon_divs(go), PDB_SET), error);
+       BOOL_SET_OR_FAIL(pdb_set_user_sid(sa, gums_get_object_sid(go), PDB_SET), error);
+       BOOL_SET_OR_FAIL(pdb_set_group_sid(sa, gums_get_user_pri_group(go), PDB_SET), error);
+       BOOL_SET_OR_FAIL(pdb_set_username(sa, gums_get_object_name(go), PDB_SET), error);
+       BOOL_SET_OR_FAIL(pdb_set_nt_username(sa, gums_get_object_name(go), PDB_SET), error);
+       BOOL_SET_OR_FAIL(pdb_set_fullname(sa, gums_get_user_fullname(go), PDB_SET), error);
+       BOOL_SET_OR_FAIL(pdb_set_logon_script(sa, gums_get_user_logon_script(go), PDB_SET), error);
+       BOOL_SET_OR_FAIL(pdb_set_profile_path(sa, gums_get_user_profile_path(go), PDB_SET), error); 
+       BOOL_SET_OR_FAIL(pdb_set_dir_drive(sa, gums_get_user_dir_drive(go), PDB_SET), error); 
+       BOOL_SET_OR_FAIL(pdb_set_homedir(sa, gums_get_user_homedir(go), PDB_SET), error); 
+       BOOL_SET_OR_FAIL(pdb_set_acct_desc(sa, gums_get_object_description(go), PDB_SET), error); 
+       BOOL_SET_OR_FAIL(pdb_set_workstations(sa, gums_get_user_workstations(go), PDB_SET), error); 
+       BOOL_SET_OR_FAIL(pdb_set_unknown_str(sa, gums_get_user_unknown_str(go), PDB_SET), error); 
+       BOOL_SET_OR_FAIL(pdb_set_munged_dial(sa, gums_get_user_munged_dial(go), PDB_SET), error); 
+
+       pwd = gums_get_user_nt_pwd(go);
+       if (!pdb_set_nt_passwd(sa, pwd.data, PDB_SET)) {
+               DEBUG(5, ("gums_object_to_sam_account: unable to set nt password"));
+               data_blob_clear_free(&pwd);
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto error;
+       }
+       data_blob_clear_free(&pwd);
+       pwd = gums_get_user_lm_pwd(go);
+       if (!pdb_set_lanman_passwd(sa, pwd.data, PDB_SET)) {
+               DEBUG(5, ("gums_object_to_sam_account: unable to set lanman password"));
+               data_blob_clear_free(&pwd);
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto error;
+       }
+       data_blob_clear_free(&pwd);
+
+       BOOL_SET_OR_FAIL(pdb_set_unknown_3(sa, gums_get_user_unknown_3(go), PDB_SET), error); 
+       BOOL_SET_OR_FAIL(pdb_set_bad_password_count(sa, gums_get_user_bad_password_count(go), PDB_SET), error); 
+       BOOL_SET_OR_FAIL(pdb_set_unknown_6(sa, gums_get_user_unknown_6(go), PDB_SET), error); 
+       BOOL_SET_OR_FAIL(pdb_set_hours(sa, gums_get_user_hours(go), PDB_SET), error); 
+
+       return NT_STATUS_OK;
+
+error:
+       if (sa && (sa->free_fn)) {
+               sa->free_fn(&sa);
+       }
+
+       return ret;
+}
+
+static NTSTATUS sam_account_to_gums_object(GUMS_OBJECT *go, SAM_ACCOUNT *sa)
+{
+       NTSTATUS ret;
+       NTTIME nt_time;
+       DATA_BLOB pwd;
+
+       if (!go || !sa)
+               return NT_STATUS_INVALID_PARAMETER;
+
+/*
+       ret = gums_create_object(go, GUMS_OBJ_NORMAL_USER);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(0, ("sam_account_to_gums_object: error occurred while creating gums object!\n"));
+               goto error;
+       }
+*/
+
+       /* sec_desc */
+
+       SET_OR_FAIL(gums_set_object_name(go, pdb_get_username(sa)), error);
+
+       SET_OR_FAIL(gums_set_object_sid(go, pdb_get_user_sid(sa)), error);
+       SET_OR_FAIL(gums_set_user_pri_group(go, pdb_get_group_sid(sa)), error);
+
+       if (pdb_get_acct_desc(sa))
+               SET_OR_FAIL(gums_set_object_description(go, pdb_get_acct_desc(sa)), error);
+       if (pdb_get_fullname(sa))
+               SET_OR_FAIL(gums_set_user_fullname(go, pdb_get_fullname(sa)), error);
+       if (pdb_get_homedir(sa))
+               SET_OR_FAIL(gums_set_user_homedir(go, pdb_get_homedir(sa)), error);
+       if (pdb_get_dir_drive(sa))
+               SET_OR_FAIL(gums_set_user_dir_drive(go, pdb_get_dir_drive(sa)), error);
+       if (pdb_get_logon_script(sa))
+               SET_OR_FAIL(gums_set_user_logon_script(go, pdb_get_logon_script(sa)), error);
+       if (pdb_get_profile_path(sa))
+               SET_OR_FAIL(gums_set_user_profile_path(go, pdb_get_profile_path(sa)), error);
+       if (pdb_get_workstations(sa))
+               SET_OR_FAIL(gums_set_user_workstations(go, pdb_get_workstations(sa)), error);
+       if (pdb_get_unknown_str(sa))
+               SET_OR_FAIL(gums_set_user_unknown_str(go, pdb_get_unknown_str(sa)), error);
+       if (pdb_get_munged_dial(sa))
+               SET_OR_FAIL(gums_set_user_munged_dial(go, pdb_get_munged_dial(sa)), error);
+       SET_OR_FAIL(gums_set_user_logon_divs(go, pdb_get_logon_divs(sa)), error);
+       if (pdb_get_hours(sa))
+               SET_OR_FAIL(gums_set_user_hours(go, pdb_get_hours_len(sa), pdb_get_hours(sa)), error);
+       SET_OR_FAIL(gums_set_user_unknown_3(go, pdb_get_unknown_3(sa)), error);
+       SET_OR_FAIL(gums_set_user_bad_password_count(go, pdb_get_bad_password_count(sa)), error);
+       SET_OR_FAIL(gums_set_user_unknown_6(go, pdb_get_unknown_6(sa)), error);
+
+       unix_to_nt_time(&nt_time, pdb_get_logon_time(sa));
+       SET_OR_FAIL(gums_set_user_logon_time(go, nt_time), error);
+       unix_to_nt_time(&nt_time, pdb_get_logoff_time(sa));
+       SET_OR_FAIL(gums_set_user_logoff_time(go, nt_time), error);
+       unix_to_nt_time(&nt_time, pdb_get_kickoff_time(sa));
+       SET_OR_FAIL(gums_set_user_kickoff_time(go, nt_time), error);
+       unix_to_nt_time(&nt_time, pdb_get_pass_last_set_time(sa));
+       SET_OR_FAIL(gums_set_user_pass_last_set_time(go, nt_time), error);
+       unix_to_nt_time(&nt_time, pdb_get_pass_can_change_time(sa));
+       SET_OR_FAIL(gums_set_user_pass_can_change_time(go, nt_time), error);
+       unix_to_nt_time(&nt_time, pdb_get_pass_must_change_time(sa));
+       SET_OR_FAIL(gums_set_user_pass_must_change_time(go, nt_time), error);
+
+       pwd = data_blob(pdb_get_nt_passwd(sa), NT_HASH_LEN);
+       ret = gums_set_user_nt_pwd(go, pwd);
+       data_blob_clear_free(&pwd);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(5, ("sam_account_to_gums_object: failed to set nt password!\n"));
+               goto error;
+       }
+       pwd = data_blob(pdb_get_lanman_passwd(sa), LM_HASH_LEN);
+       ret = gums_set_user_lm_pwd(go, pwd);
+       data_blob_clear_free(&pwd);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(5, ("sam_account_to_gums_object: failed to set lanman password!\n"));
+               goto error;
+       }
+
+       SET_OR_FAIL(gums_set_user_acct_ctrl(go, pdb_get_acct_ctrl(sa)), error);
+
+       return NT_STATUS_OK;
+
+error:
+       gums_reset_object(go);
+       return ret;
+}
+
+static NTSTATUS gums_setsampwent(struct pdb_methods *methods, BOOL update)
+{
+       struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
+
+       return ggwd->fns->enumerate_objects_start(&(ggwd->handle), NULL, GUMS_OBJ_NORMAL_USER);
+}
+
+static NTSTATUS gums_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *account)
+{
+       NTSTATUS ret;
+       GUMS_OBJECT *go;
+       struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
+
+       if (!NT_STATUS_IS_OK(ret = ggwd->fns->enumerate_objects_get_next(&go, ggwd->handle))) {
+               return ret;
+       }
+
+       ret = gums_object_to_sam_account(account, go);
+
+       gums_destroy_object(&go);
+       return ret;
+}
+
+static void gums_endsampwent(struct pdb_methods *methods)
+{
+       struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
+
+       ggwd->fns->enumerate_objects_stop(ggwd->handle);
+}
+
+/******************************************************************
+  Lookup a name in the SAM database
+ ******************************************************************/
+
+static NTSTATUS gums_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *account, const char *name)
+{
+       NTSTATUS ret;
+       GUMS_OBJECT *go;
+       struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
+
+       if (!account || !name)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       if (!NT_STATUS_IS_OK(ret = ggwd->fns->get_object_from_name(&go, name, GUMS_OBJ_NORMAL_USER))) {
+               DEBUG(10, ("gums_getsampwnam: unable to find account with name %s", name));
+               return ret;
+       }
+
+       ret = gums_object_to_sam_account(account, go);
+
+       gums_destroy_object(&go);
+       return ret;
+}
+
+/***************************************************************************
+  Search by SID
+ **************************************************************************/
+
+static NTSTATUS gums_getsampwsid(struct pdb_methods *methods, SAM_ACCOUNT *account, const DOM_SID *sid)
+{
+       NTSTATUS ret;
+       GUMS_OBJECT *go;
+       struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
+
+       if (!account || !sid)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       if (!NT_STATUS_IS_OK(ret = ggwd->fns->get_object_from_sid(&go, sid, GUMS_OBJ_NORMAL_USER))) {
+               DEBUG(10, ("gums_getsampwsid: unable to find account with sid %s", sid_string_static(sid)));
+               return ret;
+       }
+
+       ret = gums_object_to_sam_account(account, go);
+
+       gums_destroy_object(&go);
+       return ret;
+}
+
+/***************************************************************************
+  Search by rid
+ **************************************************************************/
+
+static NTSTATUS gums_getsampwrid (struct pdb_methods *methods, 
+                                SAM_ACCOUNT *account, uint32 rid)
+{
+       DOM_SID sid;
+
+       sid_copy(&sid, get_global_sam_sid());
+       sid_append_rid(&sid, rid);
+       gums_getsampwsid(methods, account, &sid);
+}
+
+
+/***************************************************************************
+  Updates a SAM_ACCOUNT
+
+  This isn't a particulary practical option for pdb_guest.  We certainly don't
+  want to twidde the filesystem, so what should we do?
+
+  Current plan is to transparently add the account.  It should appear
+  as if the pdb_guest version was modified, but its actually stored somehwere.
+ ****************************************************************************/
+
+static NTSTATUS gums_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *account)
+{
+       NTSTATUS ret;
+       GUMS_OBJECT *go;
+       struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
+
+       if (!account)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       if (!NT_STATUS_IS_OK(ret = gums_create_object(&go, GUMS_OBJ_NORMAL_USER))) {
+               DEBUG(0, ("gums_add_sam_account: error occurred while creating gums object!\n"));
+               return ret;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = sam_account_to_gums_object(go, account))) {
+               DEBUG(0, ("gums_add_sam_account: error occurred while converting object!\n"));
+               goto done;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = ggwd->fns->set_object(go))) {
+               DEBUG(0, ("gums_add_sam_account: unable to store account!\n"));
+               goto done;
+       }
+
+done:
+       gums_destroy_object(&go);
+       return ret;
+}
+
+static NTSTATUS gums_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *account)
+{
+       NTSTATUS ret;
+       GUMS_OBJECT *go;
+       struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
+
+       if (!account)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       if (!NT_STATUS_IS_OK(ret = ggwd->fns->get_object_from_sid(&go, pdb_get_user_sid(account), GUMS_OBJ_NORMAL_USER))) {
+               DEBUG(0, ("gums_update_sam_account: update on invalid account!\n"));
+               return ret;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = sam_account_to_gums_object(go, account))) {
+               DEBUG(0, ("gums_update_sam_account: error occurred while converting object!\n"));
+               goto done;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = ggwd->fns->set_object(go))) {
+               DEBUG(0, ("gums_update_sam_account: unable to store account!\n"));
+               goto done;
+       }
+
+done:
+       gums_destroy_object(&go);
+       return ret;
+}
+
+static NTSTATUS gums_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *account)
+{
+       NTSTATUS ret;
+       struct gums_gw_data *ggwd = (struct gums_gw_data *)(methods->private_data);
+
+       if (!account)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       if (!NT_STATUS_IS_OK(ret = ggwd->fns->delete_object(pdb_get_user_sid(account)))) {
+               DEBUG(0, ("gums_add_sam_account: unable to store account!\n"));
+       }
+
+       return ret;
+}
+
+
+static void free_gw_private_data(void **vp)
+{
+       struct gums_gw_data *ggwd = (struct gums_gw_data *)vp;
+       ggwd->fns->free_private_data(&(ggwd->fns->private_data));
+       ggwd->fns = NULL;
+       ggwd->handle = NULL;
+       SAFE_FREE(vp);
+}
+
+NTSTATUS pdb_init_gums_gateway(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+       NTSTATUS ret;
+       struct gums_gw_data *ggwd;
+       
+       if (!pdb_context) {
+               DEBUG(0, ("invalid pdb_context specified\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = gums_setup_backend(lp_gums_backend()))) {
+               DEBUG(0, ("pdb_init_gums_gateway: initialization error!\n"));
+               return ret;
+       }
+       
+       ggwd = (struct gums_gw_data *)malloc(sizeof(struct gums_gw_data));
+       if (!ggwd)
+               return NT_STATUS_NO_MEMORY;
+       memset(ggwd, 0, sizeof(struct gums_gw_data));
+
+       if (!NT_STATUS_IS_OK(ret = get_gums_fns(&(ggwd->fns)))) {
+               goto error;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+               goto error;
+       }
+       
+       (*pdb_method)->name = "gums_gateway";
+       
+       (*pdb_method)->setsampwent = gums_setsampwent;
+       (*pdb_method)->getsampwent = gums_getsampwent;
+       (*pdb_method)->endsampwent = gums_endsampwent;
+       (*pdb_method)->getsampwnam = gums_getsampwnam;
+       (*pdb_method)->getsampwsid = gums_getsampwsid;
+       (*pdb_method)->add_sam_account = gums_add_sam_account;
+       (*pdb_method)->update_sam_account = gums_update_sam_account;
+       (*pdb_method)->delete_sam_account = gums_delete_sam_account;
+       
+       /* we should do no group mapping here */
+/*     (*pdb_method)->getgrsid = gums_getgrsid;
+       (*pdb_method)->getgrgid = gums_getgrgid;
+       (*pdb_method)->getgrnam = gums_getgrnam;
+       (*pdb_method)->add_group_mapping_entry = gums_add_group_mapping_entry;
+       (*pdb_method)->update_group_mapping_entry = gums_update_group_mapping_entry;
+       (*pdb_method)->delete_group_mapping_entry = gums_delete_group_mapping_entry;
+       (*pdb_method)->enum_group_mapping = gums_enum_group_mapping;*/
+       
+       /* we do not handle groups in guest backend */
+/*     FIXME
+       (*pdb_method)->get_group_info_by_sid = gums_get_group_info_by_sid;
+       (*pdb_method)->get_group_list = gums_get_group_list;
+       (*pdb_method)->get_group_sids = gums_get_group_sids;
+       (*pdb_method)->add_group = gums_add_group;
+       (*pdb_method)->update_group = gums_update_group;
+       (*pdb_method)->delete_group = gums_delete_group;
+       (*pdb_method)->add_sid_to_group = gums_add_sid_to_group;
+       (*pdb_method)->remove_sid_from_group = gums_remove_sid_from_group;
+       (*pdb_method)->get_group_info_by_name = gums_get_group_info_by_name;
+       (*pdb_method)->get_group_info_by_nt_name = gums_get_group_info_by_nt_name;
+       (*pdb_method)->get_group_uids = gums_get_group_uids;
+*/     
+
+       (*pdb_method)->private_data = ggwd;
+       (*pdb_method)->free_private_data = free_gw_private_data;
+       
+       return NT_STATUS_OK;
+
+error:
+       SAFE_FREE(ggwd);
+       return ret;
+}
+
+NTSTATUS pdb_gums_init(void)
+{
+       return smb_register_passdb(PASSDB_INTERFACE_VERSION, "gums", pdb_init_gums_gateway);
+}
+
diff --git a/source3/sam/gumm_tdb.c b/source3/sam/gumm_tdb.c
deleted file mode 100644 (file)
index 2623180..0000000
+++ /dev/null
@@ -1,1196 +0,0 @@
-/*
- * Unix SMB/CIFS implementation. 
- * SMB parameters and setup
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Simo Sorce 2000-2002
- * 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
- * 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 "tdbsam2.h"
-#include "tdbsam2_parse_info.h"
-
-static int tdbgumm_debug_level = DBGC_ALL;
-#undef DBGC_CLASS
-#define DBGC_CLASS tdbgumm_debug_level
-
-#define TDBSAM_VERSION         20021215
-#define TDB_FILE_NAME          "tdbsam2.tdb"
-#define NAMEPREFIX             "NAME_"
-#define SIDPREFIX              "SID_"
-#define PRIVILEGEPREFIX                "PRIV_"
-
-#define TDB_FORMAT_STRING      "ddB"
-
-#define TALLOC_CHECK(ptr, err, label) do { if ((ptr) == NULL) { DEBUG(0, ("%s: Out of memory!\n", FUNCTION_MACRO)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0)
-#define SET_OR_FAIL(func, label) do { if (NT_STATUS_IS_ERR(func)) { DEBUG(0, ("%s: Setting gums object data failed!\n", FUNCTION_MACRO)); goto label; } } while(0)
-
-struct tdbsam2_enum_objs {
-       uint32 type;
-       fstring dom_sid;
-       TDB_CONTEXT *db;
-       TDB_DATA key;
-       struct tdbsam2_enum_objs *next;
-};
-
-union tdbsam2_data {
-       struct tdbsam2_domain_data *domain;
-       struct tdbsam2_user_data *user;
-       struct tdbsam2_group_data *group;
-};
-
-struct tdbsam2_object {
-       uint32 type;
-       uint32 version;
-       union tdbsam2_data data;
-};
-
-static TDB_CONTEXT *tdbsam2_db;
-
-struct tdbsam2_enum_objs **teo_handlers;
-
-static NTSTATUS init_tdbsam2_object_from_buffer(struct tdbsam2_object *object, TALLOC_CTX *mem_ctx, char *buffer, int size)
-{
-
-       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-       int iret;
-       char *obj_data;
-       int data_size = 0;
-       int len;
-       
-       len = tdb_unpack (buffer, size, TDB_FORMAT_STRING,
-                         &(object->version),
-                         &(object->type),
-                         &data_size, &obj_data);
-
-       if (len == -1)
-               goto done;
-
-       /* version is checked inside this function so that backward compatibility code can be
-          called eventually.
-          this way we can easily handle database format upgrades */
-       if (object->version != TDBSAM_VERSION) {
-               DEBUG(3,("init_tdbsam2_object_from_buffer: Error, db object has wrong tdbsam version!\n"));
-               goto done;
-       }
-
-       /* be sure the string is terminated before trying to parse it */
-       if (obj_data[data_size - 1] != '\0')
-               obj_data[data_size - 1] = '\0';
-
-       switch (object->type) {
-               case GUMS_OBJ_DOMAIN:
-                       object->data.domain = (struct tdbsam2_domain_data *)talloc(mem_ctx, sizeof(struct tdbsam2_domain_data));
-                       TALLOC_CHECK(object->data.domain, ret, done);
-                       memset(object->data.domain, 0, sizeof(struct tdbsam2_domain_data));
-
-                       iret = gen_parse(mem_ctx, pinfo_tdbsam2_domain_data, (char *)(object->data.domain), obj_data);
-                       break;
-               case GUMS_OBJ_GROUP:
-               case GUMS_OBJ_ALIAS:
-                       object->data.group = (struct tdbsam2_group_data *)talloc(mem_ctx, sizeof(struct tdbsam2_group_data));
-                       TALLOC_CHECK(object->data.group, ret, done);
-                       memset(object->data.group, 0, sizeof(struct tdbsam2_group_data));
-
-                       iret = gen_parse(mem_ctx, pinfo_tdbsam2_group_data, (char *)(object->data.group), obj_data);
-                       break;
-               case GUMS_OBJ_NORMAL_USER:
-                       object->data.user = (struct tdbsam2_user_data *)talloc(mem_ctx, sizeof(struct tdbsam2_user_data));
-                       TALLOC_CHECK(object->data.user, ret, done);
-                       memset(object->data.user, 0, sizeof(struct tdbsam2_user_data));
-
-                       iret = gen_parse(mem_ctx, pinfo_tdbsam2_user_data, (char *)(object->data.user), obj_data);
-                       break;
-               default:
-                       DEBUG(3,("init_tdbsam2_object_from_buffer: Error, wrong object type number!\n"));
-                       goto done;
-       }
-
-       if (iret != 0) {
-               DEBUG(0,("init_tdbsam2_object_from_buffer: Fatal Error! Unable to parse object!\n"));
-               DEBUG(0,("init_tdbsam2_object_from_buffer: DB Corrupted ?"));
-               goto done;
-       }
-
-       ret = NT_STATUS_OK;
-done:
-       SAFE_FREE(obj_data);
-       return ret;
-}
-
-static NTSTATUS init_buffer_from_tdbsam2_object(char **buffer, size_t *len, TALLOC_CTX *mem_ctx, struct tdbsam2_object *object)
-{
-
-       NTSTATUS ret;
-       char *buf1 = NULL;
-       size_t buflen;
-
-       if (!buffer)
-               return NT_STATUS_INVALID_PARAMETER;
-
-       switch (object->type) {
-               case GUMS_OBJ_DOMAIN:
-                       buf1 = gen_dump(mem_ctx, pinfo_tdbsam2_domain_data, (char *)(object->data.domain), 0);
-                       break;
-               case GUMS_OBJ_GROUP:
-               case GUMS_OBJ_ALIAS:
-                       buf1 = gen_dump(mem_ctx, pinfo_tdbsam2_group_data, (char *)(object->data.group), 0);
-                       break;
-               case GUMS_OBJ_NORMAL_USER:
-                       buf1 = gen_dump(mem_ctx, pinfo_tdbsam2_user_data, (char *)(object->data.user), 0);
-                       break;
-               default:
-                       DEBUG(3,("init_buffer_from_tdbsam2_object: Error, wrong object type number!\n"));
-                       return NT_STATUS_UNSUCCESSFUL;  
-       }
-       
-       if (buf1 == NULL) {
-               DEBUG(0, ("init_buffer_from_tdbsam2_object: Fatal Error! Unable to dump object!\n"));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       buflen = tdb_pack(NULL, 0,  TDB_FORMAT_STRING,
-                       TDBSAM_VERSION,
-                       object->type,
-                       strlen(buf1) + 1, buf1);
-
-       *buffer = talloc(mem_ctx, buflen);
-       TALLOC_CHECK(*buffer, ret, done);
-
-       *len = tdb_pack(*buffer, buflen, TDB_FORMAT_STRING,
-                       TDBSAM_VERSION,
-                       object->type,
-                       strlen(buf1) + 1, buf1);
-
-       if (*len != buflen) {
-               DEBUG(0, ("init_tdb_data_from_tdbsam2_object: somthing odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n", 
-                         buflen, *len));
-               *buffer = NULL;
-               ret = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }
-
-       ret = NT_STATUS_OK;
-done:
-       return ret;
-}
-
-static NTSTATUS opentdb(void)
-{
-       if (!tdbsam2_db) {
-               pstring tdbfile;
-               get_private_directory(tdbfile);
-               pstrcat(tdbfile, "/");
-               pstrcat(tdbfile, TDB_FILE_NAME);
-
-               tdbsam2_db = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
-               if (!tdbsam2_db)
-               {
-                       DEBUG(0, ("opentdb: Unable to open database (%s)!\n", tdbfile));
-                       return NT_STATUS_UNSUCCESSFUL;
-               }
-       }
-
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS get_object_by_sid(TALLOC_CTX *mem_ctx, struct tdbsam2_object *obj, const DOM_SID *sid)
-{
-       NTSTATUS ret;
-       TDB_DATA data, key;
-       fstring keystr;
-
-       if (!obj || !mem_ctx || !sid)
-               return NT_STATUS_INVALID_PARAMETER;
-
-       if (NT_STATUS_IS_ERR(ret = opentdb())) {
-               return ret;
-       }
-
-       slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sid_string_static(sid));
-       key.dptr = keystr;
-       key.dsize = strlen(keystr) + 1;
-
-       data = tdb_fetch(tdbsam2_db, key);
-       if (!data.dptr) {
-               DEBUG(5, ("get_object_by_sid: Error fetching database, domain entry not found!\n"));
-               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam2_db)));
-               DEBUGADD(5, (" Key: %s\n", keystr));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       if (NT_STATUS_IS_ERR(init_tdbsam2_object_from_buffer(obj, mem_ctx, data.dptr, data.dsize))) {
-               SAFE_FREE(data.dptr);
-               DEBUG(0, ("get_object_by_sid: Error fetching database, malformed entry!\n"));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-       SAFE_FREE(data.dptr);
-
-       return NT_STATUS_OK;
-       
-}
-
-static NTSTATUS get_object_by_name(TALLOC_CTX *mem_ctx, struct tdbsam2_object *obj, const char* name)
-{
-
-       NTSTATUS ret;
-       TDB_DATA data, key;
-       fstring keystr;
-       fstring objname;
-       DOM_SID sid;
-       char *obj_sidstr;
-       int obj_version, obj_type, obj_sidstr_len, len;
-
-       if (!obj || !mem_ctx || !name)
-               return NT_STATUS_INVALID_PARAMETER;
-
-       if (NT_STATUS_IS_ERR(ret = opentdb())) {
-               return ret;
-       }
-
-       fstrcpy(objname, name);
-       strlower(objname);
-
-       slprintf(keystr, sizeof(keystr)-1, "%s%s", NAMEPREFIX, objname);
-       key.dptr = keystr;
-       key.dsize = strlen(keystr) + 1;
-
-       data = tdb_fetch(tdbsam2_db, key);
-       if (!data.dptr) {
-               DEBUG(5, ("get_object_by_name: Error fetching database, domain entry not found!\n"));
-               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam2_db)));
-               DEBUGADD(5, (" Key: %s\n", keystr));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       len = tdb_unpack(data.dptr, data.dsize, TDB_FORMAT_STRING,
-               &obj_version,
-               &obj_type,
-               &obj_sidstr_len, &obj_sidstr);
-
-       SAFE_FREE(data.dptr);
-
-       if (len == -1 || obj_version != TDBSAM_VERSION || obj_sidstr_len <= 0) {
-               DEBUG(5, ("get_object_by_name: Error unpacking database object!\n"));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       if (!string_to_sid(&sid, obj_sidstr)) {
-               DEBUG(5, ("get_object_by_name: Error invalid sid string found in database object!\n"));
-               SAFE_FREE(obj_sidstr);
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-       SAFE_FREE(obj_sidstr);
-       
-       return get_object_by_sid(mem_ctx, obj, &sid);
-}
-
-static NTSTATUS store_object(TALLOC_CTX *mem_ctx, struct tdbsam2_object *object, BOOL new_obj)
-{
-
-       NTSTATUS ret;
-       TDB_DATA data, key, key2;
-       fstring keystr;
-       fstring namestr;
-       int flag, r;
-
-       if (NT_STATUS_IS_ERR(ret = opentdb())) {
-               return ret;
-       }
-
-       if (new_obj) {
-               flag = TDB_INSERT;
-       } else {
-               flag = TDB_MODIFY;
-       }
-
-       ret = init_buffer_from_tdbsam2_object(&(data.dptr), &(data.dsize), mem_ctx, object);
-       if (NT_STATUS_IS_ERR(ret))
-               return ret;
-
-       switch (object->type) {
-               case GUMS_OBJ_DOMAIN:
-                       slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sid_string_static(object->data.domain->dom_sid));
-                       slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, object->data.domain->name);
-                       break;
-               case GUMS_OBJ_GROUP:
-               case GUMS_OBJ_ALIAS:
-                       slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sid_string_static(object->data.group->group_sid));
-                       slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, object->data.group->name);
-                       break;
-               case GUMS_OBJ_NORMAL_USER:
-                       slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sid_string_static(object->data.user->user_sid));
-                       slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, object->data.user->name);
-                       break;
-               default:
-                       return NT_STATUS_UNSUCCESSFUL;  
-       }
-
-       key.dptr = keystr;
-       key.dsize = strlen(keystr) + 1;
-
-       if ((r = tdb_store(tdbsam2_db, key, data, flag)) != TDB_SUCCESS) {
-               DEBUG(0, ("store_object: Unable to modify SAM!\n"));
-               DEBUGADD(0, (" Error: %s", tdb_errorstr(tdbsam2_db)));
-               DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr));
-               if (r == TDB_ERR_EXISTS) return NT_STATUS_UNSUCCESSFUL;
-               return NT_STATUS_INTERNAL_DB_ERROR;
-       }
-
-       key2.dptr = namestr;
-       key2.dsize = strlen(namestr) + 1;
-
-       if ((r = tdb_store(tdbsam2_db, key2, key, flag)) != TDB_SUCCESS) {
-               DEBUG(0, ("store_object: Unable to modify SAM!\n"));
-               DEBUGADD(0, (" Error: %s", tdb_errorstr(tdbsam2_db)));
-               DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr));
-               if (r == TDB_ERR_EXISTS) return NT_STATUS_UNSUCCESSFUL;
-               return NT_STATUS_INTERNAL_DB_ERROR;
-       }
-/* TODO: update the general database counter */
-/* TODO: update this entry counter too */
-
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS get_next_sid(TALLOC_CTX *mem_ctx, DOM_SID **sid)
-{
-       NTSTATUS ret;
-       struct tdbsam2_object obj;
-       DOM_SID *dom_sid = get_global_sam_sid();
-       uint32 new_rid;
-
-/* TODO: LOCK DOMAIN OBJECT */
-       ret = get_object_by_sid(mem_ctx, &obj, dom_sid);
-       if (NT_STATUS_IS_ERR(ret)) {
-               DEBUG(0, ("get_next_sid: unable to get root Domain object!\n"));
-               ret = NT_STATUS_INTERNAL_DB_ERROR;
-               goto error;
-       }
-
-       new_rid = obj.data.domain->next_rid;
-       
-       /* Increment the RID Counter */
-       obj.data.domain->next_rid++;
-       
-       /* Store back Domain object */
-       ret = store_object(mem_ctx, &obj, False);
-       if (NT_STATUS_IS_ERR(ret)) {
-               DEBUG(0, ("get_next_sid: unable to update root Domain object!\n"));
-               ret = NT_STATUS_INTERNAL_DB_ERROR;
-               goto error;
-       }
-/* TODO: UNLOCK DOMAIN OBJECT */
-
-       *sid = sid_dup_talloc(mem_ctx, dom_sid);
-       TALLOC_CHECK(*sid, ret, error);
-       
-       if (!sid_append_rid(*sid, new_rid)) {
-               DEBUG(0, ("get_next_sid: unable to build new SID !?!\n"));
-               ret = NT_STATUS_UNSUCCESSFUL;
-               goto error;
-       }
-
-       return NT_STATUS_OK;
-
-error:
-       return ret;
-}
-
-static NTSTATUS user_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_user_data *userdata)
-{
-       NTSTATUS ret;
-
-       if (!object || !userdata) {
-               DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL pointers are accepted here!\n"));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       /* userdata->xcounter */
-       /* userdata->sec_desc */
-
-       SET_OR_FAIL(gums_set_object_sid(*object, userdata->user_sid), error);
-       SET_OR_FAIL(gums_set_object_name(*object, userdata->name), error);
-
-       SET_OR_FAIL(gums_set_user_pri_group(*object, userdata->group_sid), error);
-
-       if (userdata->description)
-               SET_OR_FAIL(gums_set_object_description(*object, userdata->description), error);
-
-       if (userdata->full_name)
-               SET_OR_FAIL(gums_set_user_fullname(*object, userdata->full_name), error);
-       
-       if (userdata->home_dir)
-               SET_OR_FAIL(gums_set_user_homedir(*object, userdata->home_dir), error);
-
-       if (userdata->dir_drive)
-               SET_OR_FAIL(gums_set_user_dir_drive(*object, userdata->dir_drive), error);
-
-       if (userdata->logon_script)
-               SET_OR_FAIL(gums_set_user_logon_script(*object, userdata->logon_script), error);
-       
-       if (userdata->profile_path) 
-               SET_OR_FAIL(gums_set_user_profile_path(*object, userdata->profile_path), error);
-
-       if (userdata->workstations)
-               SET_OR_FAIL(gums_set_user_workstations(*object, userdata->workstations), error);
-
-       if (userdata->unknown_str)
-               SET_OR_FAIL(gums_set_user_unknown_str(*object, userdata->unknown_str), error);
-
-       if (userdata->munged_dial)
-               SET_OR_FAIL(gums_set_user_munged_dial(*object, userdata->munged_dial), error);
-
-       SET_OR_FAIL(gums_set_user_logon_divs(*object, userdata->logon_divs), error);
-       SET_OR_FAIL(gums_set_user_hours_len(*object, userdata->hours_len), error);
-
-       if (userdata->hours)
-               SET_OR_FAIL(gums_set_user_hours(*object, userdata->hours), error);
-
-       SET_OR_FAIL(gums_set_user_unknown_3(*object, userdata->unknown_3), error);
-       SET_OR_FAIL(gums_set_user_bad_password_count(*object, userdata->bad_password_count), error);
-       SET_OR_FAIL(gums_set_user_unknown_6(*object, userdata->unknown_6), error);
-
-       SET_OR_FAIL(gums_set_user_logon_time(*object, *(userdata->logon_time)), error);
-       SET_OR_FAIL(gums_set_user_logoff_time(*object, *(userdata->logoff_time)), error);
-       SET_OR_FAIL(gums_set_user_kickoff_time(*object, *(userdata->kickoff_time)), error);
-       SET_OR_FAIL(gums_set_user_pass_last_set_time(*object, *(userdata->pass_last_set_time)), error);
-       SET_OR_FAIL(gums_set_user_pass_can_change_time(*object, *(userdata->pass_can_change_time)), error);
-       SET_OR_FAIL(gums_set_user_pass_must_change_time(*object, *(userdata->pass_must_change_time)), error);
-
-       ret = NT_STATUS_OK;
-       return ret;
-       
-error:
-       talloc_destroy((*object)->mem_ctx);
-       *object = NULL;
-       return ret;
-}
-
-static NTSTATUS group_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_group_data *groupdata)
-{
-       NTSTATUS ret;
-
-       if (!object || !groupdata) {
-               DEBUG(0, ("tdbsam2_group_data_to_gums_object: no NULL pointers are accepted here!\n"));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       /* groupdata->xcounter */
-       /* groupdata->sec_desc */
-
-       SET_OR_FAIL(gums_set_object_sid(*object, groupdata->group_sid), error);
-       SET_OR_FAIL(gums_set_object_name(*object, groupdata->name), error);
-
-       if (groupdata->description)
-               SET_OR_FAIL(gums_set_object_description(*object, groupdata->description), error);
-
-       if (groupdata->count)
-               SET_OR_FAIL(gums_set_group_members(*object, groupdata->count, groupdata->members), error);
-
-       ret = NT_STATUS_OK;
-       return ret;
-       
-error:
-       talloc_destroy((*object)->mem_ctx);
-       *object = NULL;
-       return ret;
-}
-
-static NTSTATUS domain_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_domain_data *domdata)
-{
-
-       NTSTATUS ret;
-
-       if (!object || !*object || !domdata) {
-               DEBUG(0, ("tdbsam2_domain_data_to_gums_object: no NULL pointers are accepted here!\n"));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       /* domdata->xcounter */
-       /* domdata->sec_desc */
-
-       SET_OR_FAIL(gums_set_object_sid(*object, domdata->dom_sid), error);
-       SET_OR_FAIL(gums_set_object_name(*object, domdata->name), error);
-
-       if (domdata->description)
-               SET_OR_FAIL(gums_set_object_description(*object, domdata->description), error);
-
-       ret = NT_STATUS_OK;
-       return ret;
-       
-error:
-       talloc_destroy((*object)->mem_ctx);
-       *object = NULL;
-       return ret;
-}
-
-static NTSTATUS data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_object *data)
-{
-
-       NTSTATUS ret;
-
-       if (!object || !data) {
-               DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL structure pointers are accepted here!\n"));
-               ret = NT_STATUS_INVALID_PARAMETER;
-               goto done;
-       }
-
-       ret = gums_create_object(object, data->type);
-       if (NT_STATUS_IS_ERR(ret)) {
-               DEBUG(5, ("tdbsam2_user_data_to_gums_object: error creating gums object!\n"));
-               goto done;
-       }
-
-       switch (data->type) {
-               case GUMS_OBJ_DOMAIN:
-                       ret = domain_data_to_gums_object(object, data->data.domain);
-                       break;
-
-               case GUMS_OBJ_NORMAL_USER:
-                       ret = user_data_to_gums_object(object, data->data.user);
-                       break;
-
-               case GUMS_OBJ_GROUP:
-               case GUMS_OBJ_ALIAS:
-                       ret = group_data_to_gums_object(object, data->data.group);
-                       break;
-
-               default:
-                       ret = NT_STATUS_UNSUCCESSFUL;
-       }
-
-done:
-       return ret;
-}
-
-
-/* GUMM object functions */
-
-static NTSTATUS tdbsam2_get_domain_sid(DOM_SID *sid, const char* name)
-{
-
-       NTSTATUS ret;
-       struct tdbsam2_object obj;
-       TALLOC_CTX *mem_ctx;
-       fstring domname;
-
-       if (!sid || !name)
-               return NT_STATUS_INVALID_PARAMETER;
-
-       mem_ctx = talloc_init("tdbsam2_get_domain_sid");
-       if (!mem_ctx) {
-               DEBUG(0, ("tdbsam2_new_object: Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (NT_STATUS_IS_ERR(ret = opentdb())) {
-               goto done;
-       }
-
-       fstrcpy(domname, name);
-       strlower(domname);
-
-       ret = get_object_by_name(mem_ctx, &obj, domname);
-
-       if (NT_STATUS_IS_ERR(ret)) {
-               DEBUG(0, ("tdbsam2_get_domain_sid: Error fetching database!\n"));
-               goto done;
-       }
-
-       if (obj.type != GUMS_OBJ_DOMAIN) {
-               DEBUG(5, ("tdbsam2_get_domain_sid: Requested object is not a domain!\n"));
-               ret = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }
-
-       sid_copy(sid, obj.data.domain->dom_sid);
-
-       ret = NT_STATUS_OK;
-
-done:
-       talloc_destroy(mem_ctx);
-       return ret;
-}
-
-static NTSTATUS tdbsam2_set_domain_sid (const DOM_SID *sid, const char *name)
-{
-
-       NTSTATUS ret;
-       struct tdbsam2_object obj;
-       TALLOC_CTX *mem_ctx;
-       fstring domname;
-
-       if (!sid || !name)
-               return NT_STATUS_INVALID_PARAMETER;
-
-       mem_ctx = talloc_init("tdbsam2_set_domain_sid");
-       if (!mem_ctx) {
-               DEBUG(0, ("tdbsam2_new_object: Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (tdbsam2_db == NULL) {
-               if (NT_STATUS_IS_ERR(ret = opentdb())) {
-                       goto done;
-               }
-       }
-
-       fstrcpy(domname, name);
-       strlower(domname);
-
-/* TODO: we need to lock this entry until updated! */
-
-       ret = get_object_by_name(mem_ctx, &obj, domname);
-
-       if (NT_STATUS_IS_ERR(ret)) {
-               DEBUG(0, ("tdbsam2_get_domain_sid: Error fetching database!\n"));
-               goto done;
-       }
-
-       if (obj.type != GUMS_OBJ_DOMAIN) {
-               DEBUG(5, ("tdbsam2_get_domain_sid: Requested object is not a domain!\n"));
-               ret = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }
-
-       sid_copy(obj.data.domain->dom_sid, sid);
-
-       ret = store_object(mem_ctx, &obj, False);
-
-done:
-/* TODO: unlock here */
-       if (mem_ctx) talloc_destroy(mem_ctx);
-       return ret;
-}
-
-/* TODO */
-       NTSTATUS (*get_sequence_number) (void);
-
-
-extern DOM_SID global_sid_NULL;
-
-static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj_type)
-{
-
-       NTSTATUS ret;
-       struct tdbsam2_object obj;
-       TALLOC_CTX *mem_ctx;
-       NTTIME zero_time = {0,0};
-       const char *defpw = "NOPASSWORDXXXXXX";
-       uint8 defhours[21] = {255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
-
-       if (!sid || !name) {
-               DEBUG(0, ("tdbsam2_new_object: no NULL pointers are accepted here!\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       mem_ctx = talloc_init("tdbsam2_new_object");
-       if (!mem_ctx) {
-               DEBUG(0, ("tdbsam2_new_object: Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       obj.type = obj_type;
-       obj.version = TDBSAM_VERSION;
-
-       switch (obj_type) {
-               case GUMS_OBJ_NORMAL_USER:
-                       obj.data.user = (struct tdbsam2_user_data *)talloc_zero(mem_ctx, sizeof(struct tdbsam2_user_data));
-                       TALLOC_CHECK(obj.data.user, ret, done);
-
-                       get_next_sid(mem_ctx, &(obj.data.user->user_sid));
-                       TALLOC_CHECK(obj.data.user->user_sid, ret, done);
-                       sid_copy(sid, obj.data.user->user_sid);
-
-                       obj.data.user->name = talloc_strdup(mem_ctx, name);
-                       TALLOC_CHECK(obj.data.user, ret, done);
-
-                       obj.data.user->xcounter = 1;
-                       /*obj.data.user->sec_desc*/
-                       obj.data.user->description = "";
-                       obj.data.user->group_sid = &global_sid_NULL;
-                       obj.data.user->logon_time = &zero_time;
-                       obj.data.user->logoff_time = &zero_time;
-                       obj.data.user->kickoff_time = &zero_time;
-                       obj.data.user->pass_last_set_time = &zero_time;
-                       obj.data.user->pass_can_change_time = &zero_time;
-                       obj.data.user->pass_must_change_time = &zero_time;
-
-                       obj.data.user->full_name = "";          
-                       obj.data.user->home_dir = "";           
-                       obj.data.user->dir_drive = "";          
-                       obj.data.user->logon_script = "";               
-                       obj.data.user->profile_path = "";               
-                       obj.data.user->workstations = "";               
-                       obj.data.user->unknown_str = "";                
-                       obj.data.user->munged_dial = "";                
-
-                       obj.data.user->lm_pw_ptr = defpw;
-                       obj.data.user->nt_pw_ptr = defpw;
-
-                       obj.data.user->logon_divs = 168;
-                       obj.data.user->hours_len = 21;
-                       obj.data.user->hours = &defhours;
-
-                       obj.data.user->unknown_3 = 0x00ffffff;
-                       obj.data.user->bad_password_count = 0x00020000;
-                       obj.data.user->unknown_6 = 0x000004ec;
-                       break;
-
-               case GUMS_OBJ_GROUP:
-               case GUMS_OBJ_ALIAS:
-                       obj.data.group = (struct tdbsam2_group_data *)talloc_zero(mem_ctx, sizeof(struct tdbsam2_group_data));
-                       TALLOC_CHECK(obj.data.group, ret, done);
-
-                       get_next_sid(mem_ctx, &(obj.data.group->group_sid));
-                       TALLOC_CHECK(obj.data.group->group_sid, ret, done);
-                       sid_copy(sid, obj.data.group->group_sid);
-
-                       obj.data.group->name = talloc_strdup(mem_ctx, name);
-                       TALLOC_CHECK(obj.data.group, ret, done);
-
-                       obj.data.group->xcounter = 1;
-                       /*obj.data.group->sec_desc*/
-                       obj.data.group->description = "";
-
-                       break;
-
-               case GUMS_OBJ_DOMAIN:
-
-                       /* FIXME: should we check against global_sam_sid to make it impossible
-                                 to store more than one domain ? */ 
-
-                       obj.data.domain = (struct tdbsam2_domain_data *)talloc_zero(mem_ctx, sizeof(struct tdbsam2_domain_data));
-                       TALLOC_CHECK(obj.data.domain, ret, done);
-
-                       obj.data.domain->dom_sid = sid_dup_talloc(mem_ctx, get_global_sam_sid());
-                       TALLOC_CHECK(obj.data.domain->dom_sid, ret, done);
-                       sid_copy(sid, obj.data.domain->dom_sid);
-
-                       obj.data.domain->name = talloc_strdup(mem_ctx, name);
-                       TALLOC_CHECK(obj.data.domain, ret, done);
-
-                       obj.data.domain->xcounter = 1;
-                       /*obj.data.domain->sec_desc*/
-                       obj.data.domain->next_rid = 0x3e9;
-                       obj.data.domain->description = "";
-
-                       ret = NT_STATUS_OK;
-                       break;  
-
-               default:
-                       ret = NT_STATUS_UNSUCCESSFUL;
-                       goto done;
-       }
-
-       ret = store_object(mem_ctx, &obj, True);
-
-done:
-       talloc_destroy(mem_ctx);
-       return ret;
-}
-
-static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid)
-{
-       NTSTATUS ret;
-       struct tdbsam2_object obj;
-       TALLOC_CTX *mem_ctx;
-       TDB_DATA data, key;
-       fstring keystr;
-
-       if (!sid) {
-               DEBUG(0, ("tdbsam2_delete_object: no NULL pointers are accepted here!\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       mem_ctx = talloc_init("tdbsam2_delete_object");
-       if (!mem_ctx) {
-               DEBUG(0, ("tdbsam2_delete_object: Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (tdbsam2_db == NULL) {
-               if (NT_STATUS_IS_ERR(ret = opentdb())) {
-                       goto done;
-               }
-       }
-
-       slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sid_string_static(sid));
-       key.dptr = keystr;
-       key.dsize = strlen(keystr) + 1;
-
-       data = tdb_fetch(tdbsam2_db, key);
-       if (!data.dptr) {
-               DEBUG(5, ("tdbsam2_delete_object: Error fetching database, SID entry not found!\n"));
-               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam2_db)));
-               DEBUGADD(5, (" Key: %s\n", keystr));
-               ret = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }
-
-       if (tdb_delete(tdbsam2_db, key) != TDB_SUCCESS) {
-               DEBUG(5, ("tdbsam2_delete_object: Error deleting object!\n"));
-               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam2_db)));
-               DEBUGADD(5, (" Key: %s\n", keystr));
-               ret = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }       
-
-       if (NT_STATUS_IS_ERR(init_tdbsam2_object_from_buffer(&obj, mem_ctx, data.dptr, data.dsize))) {
-               SAFE_FREE(data.dptr);
-               DEBUG(0, ("tdbsam2_delete_object: Error fetching database, malformed entry!\n"));
-               ret = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }
-
-       switch (obj.type) {
-               case GUMS_OBJ_DOMAIN:
-                       /* TODO: SHOULD WE ALLOW TO DELETE DOMAINS ? */
-                       slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, obj.data.domain->name);
-                       break;
-               case GUMS_OBJ_GROUP:
-               case GUMS_OBJ_ALIAS:
-                       slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, obj.data.group->name);
-                       break;
-               case GUMS_OBJ_NORMAL_USER:
-                       slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, obj.data.user->name);
-                       break;
-               default:
-                       ret = NT_STATUS_UNSUCCESSFUL;
-                       goto done;
-       }
-
-       key.dptr = keystr;
-       key.dsize = strlen(keystr) + 1;
-
-       if (tdb_delete(tdbsam2_db, key) != TDB_SUCCESS) {
-               DEBUG(5, ("tdbsam2_delete_object: Error deleting object!\n"));
-               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam2_db)));
-               DEBUGADD(5, (" Key: %s\n", keystr));
-               ret = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }
-
-/* TODO: update the general database counter */
-
-done:
-       SAFE_FREE(data.dptr);
-       talloc_destroy(mem_ctx);
-       return ret;
-}
-
-static NTSTATUS tdbsam2_get_object_from_sid(GUMS_OBJECT **object, const DOM_SID *sid, const int obj_type)
-{
-       NTSTATUS ret;
-       struct tdbsam2_object obj;
-       TALLOC_CTX *mem_ctx;
-
-       if (!object || !sid) {
-               DEBUG(0, ("tdbsam2_get_object_from_sid: no NULL pointers are accepted here!\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       mem_ctx = talloc_init("tdbsam2_get_object_from_sid");
-       if (!mem_ctx) {
-               DEBUG(0, ("tdbsam2_get_object_from_sid: Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       ret = get_object_by_sid(mem_ctx, &obj, sid);
-       if (NT_STATUS_IS_ERR(ret) || (obj_type && obj.type != obj_type)) {
-               DEBUG(0, ("tdbsam2_get_object_from_sid: error fetching object or wrong object type!\n"));
-               goto done;
-       }
-
-       ret = data_to_gums_object(object, &obj);
-       if (NT_STATUS_IS_ERR(ret)) {
-               DEBUG(0, ("tdbsam2_get_object_from_sid: error setting object data!\n"));
-               goto done;
-       }
-       
-done:
-       talloc_destroy(mem_ctx);
-       return ret;
-}
-
-static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *name, const int obj_type)
-{
-       NTSTATUS ret;
-       struct tdbsam2_object obj;
-       TALLOC_CTX *mem_ctx;
-
-       if (!object || !name) {
-               DEBUG(0, ("tdbsam2_get_object_from_sid: no NULL pointers are accepted here!\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       mem_ctx = talloc_init("tdbsam2_get_object_from_sid");
-       if (!mem_ctx) {
-               DEBUG(0, ("tdbsam2_get_object_from_sid: Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       ret = get_object_by_name(mem_ctx, &obj, name);
-       if (NT_STATUS_IS_ERR(ret) || (obj_type && obj.type != obj_type)) {
-               DEBUG(0, ("tdbsam2_get_object_from_sid: error fetching object or wrong object type!\n"));
-               goto done;
-       }
-
-       ret = data_to_gums_object(object, &obj);
-       if (NT_STATUS_IS_ERR(ret)) {
-               DEBUG(0, ("tdbsam2_get_object_from_sid: error setting object data!\n"));
-               goto done;
-       }
-       
-done:
-       talloc_destroy(mem_ctx);
-       return ret;
-}
-
-       /* This function is used to get the list of all objects changed since base_time, it is
-          used to support PDC<->BDC synchronization */
-       NTSTATUS (*get_updated_objects) (GUMS_OBJECT **objects, const NTTIME base_time);
-
-static NTSTATUS tdbsam2_enumerate_objects_start(void *handle, const DOM_SID *sid, const int obj_type)
-{
-       struct tdbsam2_enum_objs *teo, *t;
-       pstring tdbfile;
-
-       teo = (struct tdbsam2_enum_objs *)calloc(1, sizeof(struct tdbsam2_enum_objs));
-       if (!teo) {
-               DEBUG(0, ("tdbsam2_enumerate_objects_start: Out of Memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       teo->type = obj_type;
-       if (sid) {
-               sid_to_string(teo->dom_sid, sid);
-       }
-
-       get_private_directory(tdbfile);
-       pstrcat(tdbfile, "/");
-       pstrcat(tdbfile, TDB_FILE_NAME);
-
-       teo->db = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600);
-       if (!teo->db)
-       {
-               DEBUG(0, ("tdbsam2_enumerate_objects_start: Unable to open database (%s)!\n", tdbfile));
-               SAFE_FREE(teo);
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       if (!teo_handlers) {
-               *teo_handlers = teo;
-       } else {
-               t = *teo_handlers;
-               while (t->next) {
-                       t = t->next;
-               }
-               t->next = teo;
-       }
-
-       handle = teo;
-
-       teo->key = tdb_firstkey(teo->db);
-
-       return NT_STATUS_OK;    
-}
-
-static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *handle)
-{
-       NTSTATUS ret;
-       TALLOC_CTX *mem_ctx;
-       TDB_DATA data;
-       struct tdbsam2_enum_objs *teo;
-       struct tdbsam2_object obj;
-       const char *prefix = SIDPREFIX;
-       const int preflen = strlen(prefix);
-
-       if (!object || !handle) {
-               DEBUG(0, ("tdbsam2_get_object_from_sid: no NULL pointers are accepted here!\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       teo = (struct tdbsam2_enum_objs *)handle;
-
-       mem_ctx = talloc_init("tdbsam2_enumerate_objects_get_next");
-       if (!mem_ctx) {
-               DEBUG(0, ("tdbsam2_enumerate_objects_get_next: Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       while ((teo->key.dsize != 0)) {
-               int len, version, type, size;
-               char *ptr;
-
-               if (strncmp(teo->key.dptr, prefix, preflen)) {
-                       teo->key = tdb_nextkey(teo->db, teo->key);
-                       continue;
-               }
-
-               if (teo->dom_sid) {
-                       if (strncmp(&(teo->key.dptr[preflen]), teo->dom_sid, strlen(teo->dom_sid))) {
-                               teo->key = tdb_nextkey(teo->db, teo->key);
-                               continue;
-                       }
-               }
-
-               data = tdb_fetch(teo->db, teo->key);
-               if (!data.dptr) {
-                       DEBUG(5, ("tdbsam2_enumerate_objects_get_next: Error fetching database, SID entry not found!\n"));
-                       DEBUGADD(5, (" Error: %s\n", tdb_errorstr(teo->db)));
-                       DEBUGADD(5, (" Key: %s\n", teo->key.dptr));
-                       ret = NT_STATUS_UNSUCCESSFUL;
-                       goto done;
-               }
-
-               len = tdb_unpack (data.dptr, data.dsize, TDB_FORMAT_STRING,
-                         &version,
-                         &type,
-                         &size, &ptr);
-
-               if (len == -1) {
-                       DEBUG(5, ("tdbsam2_enumerate_objects_get_next: Error unable to unpack data!\n"));
-                       ret = NT_STATUS_UNSUCCESSFUL;
-                       goto done;
-               }
-               SAFE_FREE(ptr);
-
-               if (teo->type && type != teo->type) {
-                       SAFE_FREE(data.dptr);
-                       data.dsize = 0;
-                       teo->key = tdb_nextkey(teo->db, teo->key);
-                       continue;
-               }
-               
-               break;
-       }
-
-       if (data.dsize != 0) {
-               if (NT_STATUS_IS_ERR(init_tdbsam2_object_from_buffer(&obj, mem_ctx, data.dptr, data.dsize))) {
-                       SAFE_FREE(data.dptr);
-                       DEBUG(0, ("tdbsam2_enumerate_objects_get_next: Error fetching database, malformed entry!\n"));
-                       ret = NT_STATUS_UNSUCCESSFUL;
-                       goto done;
-               }
-               SAFE_FREE(data.dptr);
-       }
-
-       ret = data_to_gums_object(object, &obj);
-
-done:
-       talloc_destroy(mem_ctx);
-       return ret;
-}
-
-static NTSTATUS tdbsam2_enumerate_objects_stop(void *handle)
-{
-       struct tdbsam2_enum_objs *teo, *t, *p;
-
-       teo = (struct tdbsam2_enum_objs *)handle;
-
-       if (*teo_handlers == teo) {
-               *teo_handlers = teo->next;
-       } else {
-               t = *teo_handlers;
-               while (t != teo) {
-                       p = t;
-                       t = t->next;
-                       if (t == NULL) {
-                               DEBUG(0, ("tdbsam2_enumerate_objects_stop: Error, handle not found!\n"));
-                               return NT_STATUS_UNSUCCESSFUL;
-                       }
-               }
-               p = t->next;
-       }
-
-       tdb_close(teo->db);
-       SAFE_FREE(teo);
-
-       return NT_STATUS_OK;
-}
-
-       /* This function MUST be used ONLY by PDC<->BDC replication code or recovery tools.
-          Never use this function to update an object in the database, use set_object_values() */
-       NTSTATUS (*set_object) (const GUMS_OBJECT *object);
-
-       /* set object values function */
-       NTSTATUS (*set_object_values) (DOM_SID *sid, uint32 count, GUMS_DATA_SET *data_set);
-
-       /* Group related functions */
-       NTSTATUS (*add_memberss_to_group) (const DOM_SID *group, const DOM_SID **members);
-       NTSTATUS (*delete_members_from_group) (const DOM_SID *group, const DOM_SID **members);
-       NTSTATUS (*enumerate_group_members) (DOM_SID **members, const DOM_SID *sid, const int type);
-
-       NTSTATUS (*get_sid_groups) (DOM_SID **groups, const DOM_SID *sid);
-
-       NTSTATUS (*lock_sid) (const DOM_SID *sid);
-       NTSTATUS (*unlock_sid) (const DOM_SID *sid);
-
-       /* privileges related functions */
-
-       NTSTATUS (*add_members_to_privilege) (const LUID_ATTR *priv, const DOM_SID **members);
-       NTSTATUS (*delete_members_from_privilege) (const LUID_ATTR *priv, const DOM_SID **members);
-       NTSTATUS (*enumerate_privilege_members) (DOM_SID **members, const LUID_ATTR *priv);
-       NTSTATUS (*get_sid_privileges) (DOM_SID **privs, const DOM_SID *sid);
-       /* warning!: set_privilege will overwrite a prior existing privilege if such exist */
-       NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv);
-
-
-int gumm_init(GUMS_FUNCTIONS **storage)
-{
-       tdbsam2_db = NULL;
-       teo_handlers = 0;
-
-       return 0;
-}
-
-#if 0
-int main(int argc, char *argv[])
-{
-       NTSTATUS ret;
-       DOM_SID dsid;
-
-       if (argc < 2) {
-               printf ("not enough arguments!\n");
-               exit(0);
-       }
-
-       if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
-               fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
-               exit(1);
-       }
-
-       ret = tdbsam2_new_object(&dsid, "_domain_", GUMS_OBJ_DOMAIN);
-       if (NT_STATUS_IS_OK(ret)) {
-               printf ("_domain_ created, sid=%s\n", sid_string_static(&dsid));
-       } else {
-               printf ("_domain_ creation error n. 0x%08x\n", ret.v);
-       }
-       ret = tdbsam2_new_object(&dsid, argv[1], GUMS_OBJ_NORMAL_USER);
-       if (NT_STATUS_IS_OK(ret)) {
-               printf ("%s user created, sid=%s\n", argv[1], sid_string_static(&dsid));
-       } else {
-               printf ("%s user creation error n. 0x%08x\n", argv[1], ret.v);
-       }
-       
-       exit(0);
-}
-#endif
diff --git a/source3/sam/gums_tdbsam2.c b/source3/sam/gums_tdbsam2.c
new file mode 100644 (file)
index 0000000..82e3923
--- /dev/null
@@ -0,0 +1,1297 @@
+/*
+ * Unix SMB/CIFS implementation. 
+ * tdbsam2 - sam backend
+ * Copyright (C) Simo Sorce 2002-2003
+ * 
+ * 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 "tdbsam2.h"
+#include "tdbsam2_parse_info.h"
+
+static int gums_tdbsam2_debug_class = DBGC_ALL;
+/*
+#undef DBGC_CLASS
+#define DBGC_CLASS gums_tdbsam2_debug_class
+*/
+
+#define TDBSAM_VERSION         20021215
+#define TDB_FILE_NAME          "tdbsam2.tdb"
+#define NAMEPREFIX             "NAME_"
+#define SIDPREFIX              "SID_"
+#define PRIVILEGEPREFIX                "PRIV_"
+
+#define TDB_FORMAT_STRING      "ddB"
+
+#define TALLOC_CHECK(ptr, err, label) do { if ((ptr) == NULL) { DEBUG(0, ("%s: Out of memory!\n", FUNCTION_MACRO)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0)
+#define SET_OR_FAIL(func, label) do { if (!NT_STATUS_IS_OK(func)) { DEBUG(0, ("%s: Setting gums object data failed!\n", FUNCTION_MACRO)); goto label; } } while(0)
+
+
+
+struct tdbsam2_enum_objs {
+       uint32 type;
+       DOM_SID *dom_sid;
+       TDB_CONTEXT *db;
+       TDB_DATA key;
+       struct tdbsam2_enum_objs *next;
+};
+
+union tdbsam2_data {
+       struct tdbsam2_domain_data *domain;
+       struct tdbsam2_user_data *user;
+       struct tdbsam2_group_data *group;
+       struct tdbsam2_priv_data *priv;
+};
+
+struct tdbsam2_object {
+       uint32 type;
+       uint32 version;
+       union tdbsam2_data data;
+};
+
+struct tdbsam2_private_data {
+
+       const char *storage;
+       struct tdbsam2_enum_objs *teo_handlers;
+};
+
+static struct tdbsam2_private_data *ts2_privs;
+
+
+static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size)
+{
+
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+       TALLOC_CTX *mem_ctx;
+       int iret;
+       char *obj_data = NULL;
+       int data_size = 0;
+       int version, type;
+       int len;
+
+       mem_ctx = talloc_init("init_object_from_buffer");
+       if (!mem_ctx) {
+               DEBUG(0, ("init_object_from_buffer: Out of memory!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       len = tdb_unpack (buffer, size, TDB_FORMAT_STRING,
+                         &version,
+                         &type,
+                         &data_size, &obj_data);
+
+       if (len == -1 || data_size <= 0)
+               goto done;
+
+       /* version is checked inside this function so that backward compatibility code can be
+          called eventually.
+          this way we can easily handle database format upgrades */
+       if (version != TDBSAM_VERSION) {
+               DEBUG(3,("init_tdbsam2_object_from_buffer: Error, db object has wrong tdbsam version!\n"));
+               goto done;
+       }
+
+       /* be sure the string is terminated before trying to parse it */
+       if (obj_data[data_size - 1] != '\0')
+               obj_data[data_size - 1] = '\0';
+
+       *go = (GUMS_OBJECT *)talloc_zero(mem_ctx, sizeof(GUMS_OBJECT));
+       TALLOC_CHECK(*go, ret, done);
+
+       switch (type) {
+
+               case GUMS_OBJ_DOMAIN:
+                       iret = gen_parse(mem_ctx, pinfo_tdbsam2_domain_data, (char *)(*go), obj_data);
+                       break;
+
+               case GUMS_OBJ_GROUP:
+               case GUMS_OBJ_ALIAS:
+                       iret = gen_parse(mem_ctx, pinfo_tdbsam2_group_data, (char *)(*go), obj_data);
+                       break;
+
+               case GUMS_OBJ_NORMAL_USER:
+                       iret = gen_parse(mem_ctx, pinfo_tdbsam2_user_data, (char *)(*go), obj_data);
+                       break;
+
+               case GUMS_OBJ_PRIVILEGE:
+                       iret = gen_parse(mem_ctx, pinfo_tdbsam2_priv_data, (char *)(*go), obj_data);
+                       break;
+
+               default:
+                       DEBUG(3,("init_object_from_buffer: Error, wrong object type number!\n"));
+                       goto done;
+       }
+
+       if (iret != 0) {
+               DEBUG(0, ("init_object_from_buffer: Fatal Error! Unable to parse object!\n"));
+               DEBUG(0, ("init_object_from_buffer: DB Corrupt ?"));
+               goto done;
+       }
+
+       (*go)->mem_ctx = mem_ctx;
+
+       ret = NT_STATUS_OK;
+done:
+       SAFE_FREE(obj_data);
+       return ret;
+}
+
+static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *mem_ctx, GUMS_OBJECT *object)
+{
+
+       NTSTATUS ret;
+       char *genbuf = NULL;
+       size_t buflen;
+
+       if (!buffer)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       switch (gums_get_object_type(object)) {
+
+               case GUMS_OBJ_DOMAIN:
+                       genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_domain_data, (char *)object, 0);
+                       break;
+
+               case GUMS_OBJ_GROUP:
+               case GUMS_OBJ_ALIAS:
+                       genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_group_data, (char *)object, 0);
+                       break;
+
+               case GUMS_OBJ_NORMAL_USER:
+                       genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_user_data, (char *)object, 0);
+                       break;
+
+               case GUMS_OBJ_PRIVILEGE:
+                       genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_priv_data, (char *)object, 0);
+                       break;
+
+               default:
+                       DEBUG(3,("init_buffer_from_object: Error, wrong object type number!\n"));
+                       return NT_STATUS_UNSUCCESSFUL;  
+       }
+       
+       if (genbuf == NULL) {
+               DEBUG(0, ("init_buffer_from_object: Fatal Error! Unable to dump object!\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       buflen = tdb_pack(NULL, 0,  TDB_FORMAT_STRING,
+                       TDBSAM_VERSION,
+                       object->type,
+                       strlen(genbuf) + 1, genbuf);
+
+       *buffer = talloc(mem_ctx, buflen);
+       TALLOC_CHECK(*buffer, ret, done);
+
+       *len = tdb_pack(*buffer, buflen, TDB_FORMAT_STRING,
+                       TDBSAM_VERSION,
+                       object->type,
+                       strlen(genbuf) + 1, genbuf);
+
+       if (*len != buflen) {
+               DEBUG(0, ("init_buffer_from_object: something odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n", 
+                         buflen, *len));
+               *buffer = NULL;
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+       ret = NT_STATUS_OK;
+done:
+       return ret;
+}
+
+static NTSTATUS opentdb(TDB_CONTEXT **tdb, BOOL readonly)
+{
+       if (!tdb)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       *tdb = tdb_open_log(ts2_privs->storage, 0, TDB_DEFAULT, readonly?(O_RDONLY):(O_RDWR | O_CREAT), 0600);
+       if (!(*tdb))
+       {
+               DEBUG(0, ("opentdb: Unable to open database (%s)!\n", ts2_privs->storage));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS get_object_by_sid(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const DOM_SID *sid)
+{
+       NTSTATUS ret;
+       TDB_DATA data, key;
+       fstring keystr;
+
+       if (!obj || !sid)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sid_string_static(sid));
+       key.dptr = keystr;
+       key.dsize = strlen(keystr) + 1;
+
+       data = tdb_fetch(tdb, key);
+       if (!data.dptr) {
+               DEBUG(5, ("get_object_by_sid: Entry not found!\n"));
+               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
+               DEBUGADD(5, (" Key: %s\n", keystr));
+               ret = NT_STATUS_NOT_FOUND;
+               goto done;
+       }
+
+       if (!NT_STATUS_IS_OK(init_object_from_buffer(obj, data.dptr, data.dsize))) {
+               DEBUG(0, ("get_object_by_sid: Error fetching database, malformed entry!\n"));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+       ret = NT_STATUS_OK;
+
+done:
+       SAFE_FREE(data.dptr);
+       return ret;
+}
+
+static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const char* name)
+{
+
+       NTSTATUS ret = NT_STATUS_OK;
+       TDB_DATA data, key;
+       fstring keystr;
+       fstring objname;
+       DOM_SID sid;
+       fstring sidstr;
+       int sidstr_len;
+
+       if (!obj || !name)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       /* Data is stored in all lower-case */
+       fstrcpy(objname, name);
+       strlower_m(objname);
+
+       slprintf(keystr, sizeof(keystr)-1, "%s%s", NAMEPREFIX, objname);
+       key.dptr = keystr;
+       key.dsize = strlen(keystr) + 1;
+
+       data = tdb_fetch(tdb, key);
+       if (!data.dptr) {
+               DEBUG(5, ("get_object_by_name: Entry not found!\n"));
+               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
+               DEBUGADD(5, (" Key: %s\n", keystr));
+               ret = NT_STATUS_NOT_FOUND;
+               goto done;
+       }
+
+       fstrcpy(sidstr, data.dptr);
+       sidstr_len = data.dsize;
+
+       SAFE_FREE(data.dptr);
+
+       if (sidstr_len <= 0) {
+               DEBUG(5, ("get_object_by_name: Error unpacking database object!\n"));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+       if (!string_to_sid(&sid, sidstr)) {
+               DEBUG(5, ("get_object_by_name: Error invalid sid string found in database object!\n"));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+done:
+       if (NT_STATUS_IS_OK(ret))
+               return get_object_by_sid(tdb, obj, &sid);
+       return ret;
+}
+
+/* store a tdbsam2_object
+ * flag: TDB_REPLACE or TDB_MODIFY or TDB_INSERT
+ */
+
+static NTSTATUS store_object(TDB_CONTEXT *tdb, const GUMS_OBJECT *object, int flag)
+{
+
+       NTSTATUS ret = NT_STATUS_OK;
+       TDB_DATA data, data2, key, key2;
+       TALLOC_CTX *mem_ctx;
+       fstring keystr;
+       fstring sidstr;
+       fstring namestr;
+       fstring objname;
+       int r;
+
+       /* TODO: on object renaming/replacing this function should
+        * check name->sid record and delete the old one
+        */
+
+       mem_ctx = talloc_init("store_object");
+       if (!mem_ctx) {
+               DEBUG(0, ("store_object: Out of memory!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = init_buffer_from_object(&(data.dptr), &(data.dsize), mem_ctx, object)))
+               goto done;
+
+       switch (object->type) {
+
+               case GUMS_OBJ_DOMAIN:
+               case GUMS_OBJ_GROUP:
+               case GUMS_OBJ_ALIAS:
+               case GUMS_OBJ_NORMAL_USER:
+
+                       fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object)));
+                       slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sidstr);
+                       break;
+
+               default:
+                       ret = NT_STATUS_UNSUCCESSFUL;
+                       goto done;
+       }
+
+       /* Data is stored in all lower-case */
+       fstrcpy(objname, gums_get_object_name(object));
+       strlower_m(objname);
+
+       slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, objname);
+
+       if (object->type != GUMS_OBJ_PRIVILEGE) {
+               key.dptr = keystr;
+               key.dsize = strlen(keystr) + 1;
+
+               if ((r = tdb_store(tdb, key, data, flag)) != TDB_SUCCESS) {
+                       DEBUG(0, ("store_object: Unable to modify TDBSAM!\n"));
+                       DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb)));
+                       DEBUGADD(0, (" occured while storing sid record (%s)\n", keystr));
+                       if (r == TDB_ERR_EXISTS)
+                               ret = NT_STATUS_UNSUCCESSFUL;
+                       else
+                               ret = NT_STATUS_INTERNAL_DB_ERROR;
+                       goto done;
+               }
+
+               data2.dptr = sidstr;
+               data2.dsize = strlen(sidstr) + 1;
+               key2.dptr = namestr;
+               key2.dsize = strlen(namestr) + 1;
+
+               if ((r = tdb_store(tdb, key2, data2, flag)) != TDB_SUCCESS) {
+                       DEBUG(0, ("store_object: Unable to modify TDBSAM!\n"));
+                       DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb)));
+                       DEBUGADD(0, (" occured while storing name record (%s)\n", keystr));
+                       DEBUGADD(0, (" attempting rollback operation.\n"));
+                       if ((tdb_delete(tdb, key)) != TDB_SUCCESS) {
+                               DEBUG(0, ("store_object: Unable to rollback! Check database consitency!\n"));
+                       }
+                       if (r == TDB_ERR_EXISTS)
+                               ret = NT_STATUS_UNSUCCESSFUL;
+                       else
+                               ret = NT_STATUS_INTERNAL_DB_ERROR;
+                       goto done;
+               }
+       } else {
+               key.dptr = namestr;
+               key.dsize = strlen(keystr) + 1;
+
+               if ((r = tdb_store(tdb, key, data, flag)) != TDB_SUCCESS) {
+                       DEBUG(0, ("store_object: Unable to modify TDBSAM!\n"));
+                       DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb)));
+                       DEBUGADD(0, (" occured while storing sid record (%s)\n", keystr));
+                       if (r == TDB_ERR_EXISTS)
+                               ret = NT_STATUS_UNSUCCESSFUL;
+                       else
+                               ret = NT_STATUS_INTERNAL_DB_ERROR;
+                       goto done;
+               }
+       }
+
+/* TODO: update the general database counter */
+/* TODO: update this entry counter too */
+
+done:
+       talloc_destroy(mem_ctx);
+       return ret;
+}
+
+#if 0
+static NTSTATUS user_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_user_data *userdata)
+{
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+       DATA_BLOB pwd;
+
+       if (!object || !userdata) {
+               DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL pointers are accepted here!\n"));
+               return ret;
+       }
+
+       /* userdata->xcounter */
+       /* userdata->sec_desc */
+
+       SET_OR_FAIL(gums_set_object_sid(*object, userdata->user_sid), error);
+       SET_OR_FAIL(gums_set_object_name(*object, userdata->name), error);
+
+       SET_OR_FAIL(gums_set_user_pri_group(*object, userdata->group_sid), error);
+
+       if (userdata->description)
+               SET_OR_FAIL(gums_set_object_description(*object, userdata->description), error);
+
+       if (userdata->full_name)
+               SET_OR_FAIL(gums_set_user_fullname(*object, userdata->full_name), error);
+       
+       if (userdata->home_dir)
+               SET_OR_FAIL(gums_set_user_homedir(*object, userdata->home_dir), error);
+
+       if (userdata->dir_drive)
+               SET_OR_FAIL(gums_set_user_dir_drive(*object, userdata->dir_drive), error);
+
+       if (userdata->logon_script)
+               SET_OR_FAIL(gums_set_user_logon_script(*object, userdata->logon_script), error);
+       
+       if (userdata->profile_path) 
+               SET_OR_FAIL(gums_set_user_profile_path(*object, userdata->profile_path), error);
+
+       if (userdata->workstations)
+               SET_OR_FAIL(gums_set_user_workstations(*object, userdata->workstations), error);
+
+       if (userdata->unknown_str)
+               SET_OR_FAIL(gums_set_user_unknown_str(*object, userdata->unknown_str), error);
+
+       if (userdata->munged_dial)
+               SET_OR_FAIL(gums_set_user_munged_dial(*object, userdata->munged_dial), error);
+
+       SET_OR_FAIL(gums_set_user_logon_divs(*object, userdata->logon_divs), error);
+
+       if (userdata->hours)
+               SET_OR_FAIL(gums_set_user_hours(*object, userdata->hours_len, userdata->hours), error);
+
+       SET_OR_FAIL(gums_set_user_unknown_3(*object, userdata->unknown_3), error);
+       SET_OR_FAIL(gums_set_user_unknown_5(*object, userdata->unknown_5), error);
+       SET_OR_FAIL(gums_set_user_unknown_6(*object, userdata->unknown_6), error);
+
+       SET_OR_FAIL(gums_set_user_logon_time(*object, *(userdata->logon_time)), error);
+       SET_OR_FAIL(gums_set_user_logoff_time(*object, *(userdata->logoff_time)), error);
+       SET_OR_FAIL(gums_set_user_kickoff_time(*object, *(userdata->kickoff_time)), error);
+       SET_OR_FAIL(gums_set_user_pass_last_set_time(*object, *(userdata->pass_last_set_time)), error);
+       SET_OR_FAIL(gums_set_user_pass_can_change_time(*object, *(userdata->pass_can_change_time)), error);
+       SET_OR_FAIL(gums_set_user_pass_must_change_time(*object, *(userdata->pass_must_change_time)), error);
+
+       pwd = data_blob(userdata->nt_pw_ptr, NT_HASH_LEN);
+       ret = gums_set_user_nt_pwd(*object, pwd);
+       data_blob_clear_free(&pwd);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(5, ("user_data_to_gums_object: failed to set nt password!\n"));
+               goto error;
+       }
+       pwd = data_blob(userdata->lm_pw_ptr, LM_HASH_LEN);
+       ret = gums_set_user_lm_pwd(*object, pwd);
+       data_blob_clear_free(&pwd);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(5, ("user_data_to_gums_object: failed to set lanman password!\n"));
+               goto error;
+       }
+
+       ret = NT_STATUS_OK;
+       return ret;
+       
+error:
+       talloc_destroy((*object)->mem_ctx);
+       *object = NULL;
+       return ret;
+}
+
+static NTSTATUS group_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_group_data *groupdata)
+{
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+       if (!object || !groupdata) {
+               DEBUG(0, ("tdbsam2_group_data_to_gums_object: no NULL pointers are accepted here!\n"));
+               return ret;
+       }
+
+       /* groupdata->xcounter */
+       /* groupdata->sec_desc */
+
+       SET_OR_FAIL(gums_set_object_sid(*object, groupdata->group_sid), error);
+       SET_OR_FAIL(gums_set_object_name(*object, groupdata->name), error);
+
+       if (groupdata->description)
+               SET_OR_FAIL(gums_set_object_description(*object, groupdata->description), error);
+
+       if (groupdata->count)
+               SET_OR_FAIL(gums_set_group_members(*object, groupdata->count, groupdata->members), error);
+
+       ret = NT_STATUS_OK;
+       return ret;
+       
+error:
+       talloc_destroy((*object)->mem_ctx);
+       *object = NULL;
+       return ret;
+}
+
+static NTSTATUS domain_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_domain_data *domdata)
+{
+
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+       if (!object || !*object || !domdata) {
+               DEBUG(0, ("tdbsam2_domain_data_to_gums_object: no NULL pointers are accepted here!\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /* domdata->xcounter */
+       /* domdata->sec_desc */
+
+       SET_OR_FAIL(gums_set_object_sid(*object, domdata->dom_sid), error);
+       SET_OR_FAIL(gums_set_object_name(*object, domdata->name), error);
+
+       if (domdata->description)
+               SET_OR_FAIL(gums_set_object_description(*object, domdata->description), error);
+
+       ret = NT_STATUS_OK;
+       return ret;
+       
+error:
+       talloc_destroy((*object)->mem_ctx);
+       *object = NULL;
+       return ret;
+}
+
+static NTSTATUS priv_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_priv_data *privdata)
+{
+
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+       if (!object || !*object || !privdata) {
+               DEBUG(0, ("tdbsam2_priv_data_to_gums_object: no NULL pointers are accepted here!\n"));
+               return ret;
+       }
+
+       /* domdata->xcounter */
+       /* domdata->sec_desc */
+
+       SET_OR_FAIL(gums_set_priv_luid_attr(*object, privdata->privilege), error);
+       SET_OR_FAIL(gums_set_object_name(*object, privdata->name), error);
+
+       if (privdata->description)
+               SET_OR_FAIL(gums_set_object_description(*object, privdata->description), error);
+
+       if (privdata->count)
+               SET_OR_FAIL(gums_set_priv_members(*object, privdata->count, privdata->members), error);
+
+       ret = NT_STATUS_OK;
+       return ret;
+       
+error:
+       talloc_destroy((*object)->mem_ctx);
+       *object = NULL;
+       return ret;
+}
+
+static NTSTATUS data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_object *data)
+{
+
+       NTSTATUS ret;
+
+       if (!object || !data) {
+               DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL structure pointers are accepted here!\n"));
+               ret = NT_STATUS_INVALID_PARAMETER;
+               goto done;
+       }
+
+       ret = gums_create_object(object, data->type);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(5, ("tdbsam2_user_data_to_gums_object: error creating gums object!\n"));
+               goto done;
+       }
+
+       switch (data->type) {
+
+               case GUMS_OBJ_DOMAIN:
+                       ret = domain_data_to_gums_object(object, data->data.domain);
+                       break;
+
+               case GUMS_OBJ_NORMAL_USER:
+                       ret = user_data_to_gums_object(object, data->data.user);
+                       break;
+
+               case GUMS_OBJ_GROUP:
+               case GUMS_OBJ_ALIAS:
+                       ret = group_data_to_gums_object(object, data->data.group);
+                       break;
+
+               case GUMS_OBJ_PRIVILEGE:
+                       ret = priv_data_to_gums_object(object, data->data.priv);
+                       break;
+
+               default:
+                       ret = NT_STATUS_UNSUCCESSFUL;
+       }
+
+done:
+       return ret;
+}
+#endif
+
+/* GUMM object functions */
+
+static NTSTATUS tdbsam2_get_domain_sid(DOM_SID *sid, const char* name)
+{
+
+       NTSTATUS ret;
+       TDB_CONTEXT *tdb;
+       GUMS_OBJECT *go;
+       fstring domname;
+
+       if (!sid || !name)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, True))) {
+               return ret;
+       }
+
+       /* Data is stored in all lower-case */
+       fstrcpy(domname, name);
+       strlower_m(domname);
+
+       if (!NT_STATUS_IS_OK(ret = get_object_by_name(tdb, &go, domname))) {
+               go = NULL;
+               DEBUG(0, ("tdbsam2_get_domain_sid: Error fetching database!\n"));
+               goto done;
+       }
+
+       if (gums_get_object_type(go) != GUMS_OBJ_DOMAIN) {
+               DEBUG(5, ("tdbsam2_get_domain_sid: Requested object is not a domain!\n"));
+               ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
+               goto done;
+       }
+
+       sid_copy(sid, gums_get_object_sid(go));
+
+       ret = NT_STATUS_OK;
+
+done:
+       if (go)
+               gums_destroy_object(&go);
+       tdb_close(tdb);
+       return ret;
+}
+
+static NTSTATUS get_next_sid(TDB_CONTEXT *tdb, DOM_SID *sid)
+{
+       NTSTATUS ret;
+       GUMS_OBJECT *go;
+       DOM_SID dom_sid;
+       TDB_DATA dom_sid_key;
+       fstring dom_sid_str;
+       uint32 new_rid;
+
+       /* Find the domain SID */
+               if (!NT_STATUS_IS_OK(tdbsam2_get_domain_sid(&dom_sid, global_myname()))) {
+               DEBUG(0, ("get_next_sid: cannot found the domain sid!!\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       /* Lock the domain record */
+       sid_to_string(dom_sid_str, &dom_sid);
+       dom_sid_key.dptr = dom_sid_str;
+       dom_sid_key.dsize = strlen(dom_sid_key.dptr) + 1;
+       
+       if(tdb_chainlock(tdb, dom_sid_key) != 0) {
+               DEBUG(0, ("get_next_sid: unable to lock domain record!\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       /* Get the domain object */
+       ret = get_object_by_sid(tdb, &go, &dom_sid);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(0, ("get_next_sid: unable to get root Domain object!\n"));
+               ret = NT_STATUS_INTERNAL_DB_ERROR;
+               goto done;
+       }
+
+       new_rid = gums_get_domain_next_rid(go);
+       
+       /* Increment the RID Counter */
+       gums_set_domain_next_rid(go, new_rid+1);
+       
+       /* Store back Domain object */
+       ret = store_object(tdb, go, TDB_MODIFY);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(0, ("get_next_sid: unable to update root Domain object!\n"));
+               ret = NT_STATUS_INTERNAL_DB_ERROR;
+               goto done;
+       }
+
+       /* Build the Domain SID to return */
+       sid_copy(sid, &dom_sid);
+       
+       if (!sid_append_rid(sid, new_rid)) {
+               DEBUG(0, ("get_next_sid: unable to build new SID !?!\n"));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+       ret = NT_STATUS_OK;
+
+done:
+       /* Unlock the Domain object */
+       tdb_chainunlock(tdb, dom_sid_key);
+
+       return ret;
+}
+
+/* TODO */
+       NTSTATUS (*get_sequence_number) (void);
+
+
+extern DOM_SID global_sid_NULL;
+
+static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj_type)
+{
+
+       NTSTATUS ret = NT_STATUS_OK;
+       TDB_CONTEXT *tdb;
+       GUMS_OBJECT *go;
+       NTTIME null_time;
+       DATA_BLOB pw;
+       const char *defpw = "NOPASSWORDXXXXXX";
+       uint8 defhours[21] = {255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
+
+       if (!name) {
+               DEBUG(0, ("tdbsam2_new_object: no NULL pointers are accepted here!\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) {
+               return ret;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = gums_create_object(&go, obj_type))) {
+               go = NULL;
+               goto done;
+       }
+
+       if (obj_type != GUMS_OBJ_PRIVILEGE) {
+               if (!sid) {
+                       ret = NT_STATUS_INVALID_PARAMETER;
+                       goto done;
+               }
+
+               if (obj_type == GUMS_OBJ_DOMAIN) {
+                       sid_copy(sid, get_global_sam_sid());
+               } else {
+                       if (!NT_STATUS_IS_OK(ret = get_next_sid(tdb, sid)))
+                               goto done;
+               }
+
+               gums_set_object_sid(go, sid);
+       }
+
+       gums_set_object_name(go, name);
+       gums_set_object_seq_num(go, 1);
+
+       /*obj.data.domain->sec_desc*/
+
+       switch (obj_type) {
+               case GUMS_OBJ_NORMAL_USER:
+
+                       init_nt_time(&null_time);
+
+                       gums_set_user_logon_time(go, null_time);
+                       gums_set_user_logoff_time(go, null_time);
+                       gums_set_user_kickoff_time(go, null_time);
+                       gums_set_user_pass_last_set_time(go, null_time);
+                       gums_set_user_pass_can_change_time(go, null_time);
+                       gums_set_user_pass_must_change_time(go, null_time);
+
+                       pw = data_blob(defpw, NT_HASH_LEN);
+                       gums_set_user_nt_pwd(go, pw);
+                       gums_set_user_lm_pwd(go, pw);
+                       data_blob_free(&pw);
+
+                       gums_set_user_logon_divs(go, 168);
+                       gums_set_user_hours(go, 21, defhours);
+
+                       gums_set_user_unknown_3(go, 0x00ffffff);
+                       gums_set_user_bad_password_count(go, 0);
+                       gums_set_user_logon_count(go, 0);
+                       gums_set_user_unknown_6(go, 0x000004ec);
+                       break;
+
+               case GUMS_OBJ_GROUP:
+               case GUMS_OBJ_ALIAS:
+
+                       break;
+
+               case GUMS_OBJ_DOMAIN:
+
+                       gums_set_domain_next_rid(go, 0x3e9);
+
+                       break;  
+
+               case GUMS_OBJ_PRIVILEGE:
+
+                       break;
+
+               default:
+                       ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
+                       goto done;
+       }
+
+       ret = store_object(tdb, go, TDB_INSERT);
+
+done:
+       if (go)
+               gums_destroy_object(&go);
+       tdb_close(tdb);
+       return ret;
+}
+
+static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid)
+{
+       /* TODO: need to address privilege deletion */
+       NTSTATUS ret = NT_STATUS_OK;
+       TDB_CONTEXT *tdb;
+       GUMS_OBJECT *go;
+       TDB_DATA data, key;
+       fstring keystr;
+
+       if (!sid) {
+               DEBUG(0, ("tdbsam2_delete_object: no NULL pointers are accepted here!\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) {
+               return ret;
+       }
+
+       slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sid_string_static(sid));
+       key.dptr = keystr;
+       key.dsize = strlen(keystr) + 1;
+
+       data = tdb_fetch(tdb, key);
+       if (!data.dptr) {
+               DEBUG(5, ("tdbsam2_delete_object: Error fetching database, SID entry not found!\n"));
+               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
+               DEBUGADD(5, (" Key: %s\n", keystr));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+       if (tdb_delete(tdb, key) != TDB_SUCCESS) {
+               DEBUG(5, ("tdbsam2_delete_object: Error deleting object!\n"));
+               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
+               DEBUGADD(5, (" Key: %s\n", keystr));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }       
+
+       if (!NT_STATUS_IS_OK(init_object_from_buffer(&go, data.dptr, data.dsize))) {
+               DEBUG(0, ("tdbsam2_delete_object: Error fetching database, malformed entry!\n"));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+       switch (go->type) {
+               case GUMS_OBJ_DOMAIN:
+                       /* FIXME: SHOULD WE ALLOW TO DELETE DOMAINS ? */
+               case GUMS_OBJ_GROUP:
+               case GUMS_OBJ_ALIAS:
+               case GUMS_OBJ_NORMAL_USER:
+                       slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, gums_get_object_name(go));
+                       break;
+               default:
+                       ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
+                       goto done;
+       }
+
+       key.dptr = keystr;
+       key.dsize = strlen(keystr) + 1;
+
+       if (tdb_delete(tdb, key) != TDB_SUCCESS) {
+               DEBUG(5, ("tdbsam2_delete_object: Error deleting object!\n"));
+               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb)));
+               DEBUGADD(5, (" Key: %s\n", keystr));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+/* TODO: update the general database counter */
+
+done:
+       gums_destroy_object(&go);
+       SAFE_FREE(data.dptr);
+       return ret;
+}
+
+static NTSTATUS tdbsam2_get_object_from_sid(GUMS_OBJECT **object, const DOM_SID *sid, const int obj_type)
+{
+       NTSTATUS ret;
+       TDB_CONTEXT *tdb;
+
+       if (!object || !sid) {
+               DEBUG(0, ("tdbsam2_get_object_from_sid: no NULL pointers are accepted here!\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, True))) {
+               return ret;
+       }
+
+       ret = get_object_by_sid(tdb, object, sid);
+       if (!NT_STATUS_IS_OK(ret) || (obj_type && gums_get_object_type(*object) != obj_type)) {
+               DEBUG(0, ("tdbsam2_get_object_from_sid: %s\n", nt_errstr(ret)));
+               goto error;
+       }
+
+       tdb_close(tdb);
+       return NT_STATUS_OK;    
+
+error:
+       gums_destroy_object(object);
+       tdb_close(tdb);
+       return ret;
+}
+
+static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *name, const int obj_type)
+{
+       NTSTATUS ret;
+       TDB_CONTEXT *tdb;
+
+       if (!object || !name) {
+               DEBUG(0, ("tdbsam2_get_object_from_name: no NULL pointers are accepted here!\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, True))) {
+               return ret;
+       }
+
+       *object = NULL;
+       ret = get_object_by_name(tdb, object, name);
+       if (!NT_STATUS_IS_OK(ret) || (obj_type && gums_get_object_type(*object) != obj_type)) {
+               DEBUG(0, ("tdbsam2_get_object_from_name: %s\n", nt_errstr(ret)));
+               goto error;
+       }
+
+       tdb_close(tdb);
+       return NT_STATUS_OK;
+
+error:
+       gums_destroy_object(object);
+       tdb_close(tdb);
+       return ret;
+}
+
+       /* This function is used to get the list of all objects changed since base_time, it is
+          used to support PDC<->BDC synchronization */
+       NTSTATUS (*get_updated_objects) (GUMS_OBJECT **objects, const NTTIME base_time);
+
+static NTSTATUS tdbsam2_enumerate_objects_start(void **handle, const DOM_SID *sid, const int obj_type)
+{
+       struct tdbsam2_enum_objs *teo, *t;
+
+       teo = (struct tdbsam2_enum_objs *)malloc(sizeof(struct tdbsam2_enum_objs));
+       if (!teo) {
+               DEBUG(0, ("tdbsam2_enumerate_objects_start: Out of Memory!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+       memset(teo, 0, sizeof(struct tdbsam2_enum_objs));
+
+       teo->type = obj_type;
+       if (sid) {
+               teo->dom_sid = (DOM_SID *)malloc(sizeof(DOM_SID));
+               if (!teo->dom_sid) {
+                       DEBUG(0, ("tdbsam2_enumerate_objects_start: Out of Memory!\n"));
+                       return NT_STATUS_NO_MEMORY;
+               }
+               sid_copy(teo->dom_sid, sid);
+       }
+
+       if (!NT_STATUS_IS_OK(opentdb(&(teo->db), True)))
+       {
+               DEBUG(0, ("tdbsam2_enumerate_objects_start: Unable to open database (%s)!\n", ts2_privs->storage));
+               SAFE_FREE(teo);
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!ts2_privs->teo_handlers) {
+               ts2_privs->teo_handlers = teo;
+       } else {
+               t = ts2_privs->teo_handlers;
+               while (t->next) {
+                       t = t->next;
+               }
+               t->next = teo;
+       }
+
+       *handle = teo;
+
+       teo->key = tdb_firstkey(teo->db);
+
+       return NT_STATUS_OK;    
+}
+
+static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *handle)
+{
+       NTSTATUS ret;
+       TDB_DATA data;
+       struct tdbsam2_enum_objs *teo;
+       const char *prefix = SIDPREFIX;
+       const int preflen = strlen(prefix);
+       fstring dom_sid_str;
+       int dom_sid_str_len = 0;
+
+       if (!object || !handle) {
+               DEBUG(0, ("tdbsam2_get_object_from_sid: no NULL pointers are accepted here!\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       teo = (struct tdbsam2_enum_objs *)handle;
+
+       if (teo->dom_sid) {
+               sid_to_string(dom_sid_str, teo->dom_sid);
+               dom_sid_str_len = strlen(dom_sid_str);
+       }       
+
+       while ((teo->key.dptr != NULL)) {
+               int len, version, type, size;
+               char *ptr;
+
+               if (strncmp(teo->key.dptr, prefix, preflen)) {
+                       teo->key = tdb_nextkey(teo->db, teo->key);
+                       continue;
+               }
+
+               if (dom_sid_str_len != 0) {
+                       if (strncmp(&(teo->key.dptr[preflen]), dom_sid_str, dom_sid_str_len)) {
+                               teo->key = tdb_nextkey(teo->db, teo->key);
+                               continue;
+                       }
+               }
+
+               data = tdb_fetch(teo->db, teo->key);
+               if (!data.dptr) {
+                       DEBUG(5, ("tdbsam2_enumerate_objects_get_next: Error fetching database, SID entry not found!\n"));
+                       DEBUGADD(5, (" Error: %s\n", tdb_errorstr(teo->db)));
+                       DEBUGADD(5, (" Key: %s\n", teo->key.dptr));
+                       ret = NT_STATUS_UNSUCCESSFUL;
+                       goto done;
+               }
+
+               len = tdb_unpack (data.dptr, data.dsize, TDB_FORMAT_STRING,
+                         &version,
+                         &type,
+                         &size, &ptr);
+
+               if (len == -1) {
+                       DEBUG(5, ("tdbsam2_enumerate_objects_get_next: Error unable to unpack data!\n"));
+                       ret = NT_STATUS_UNSUCCESSFUL;
+                       goto done;
+               }
+               SAFE_FREE(ptr);
+
+               if (teo->type && type != teo->type) {
+                       SAFE_FREE(data.dptr);
+                       data.dsize = 0;
+                       teo->key = tdb_nextkey(teo->db, teo->key);
+                       continue;
+               }
+               
+               break;
+       }
+
+       if (teo->key.dptr == NULL) { /* no more objs */
+               ret = NT_STATUS_NO_MORE_ENTRIES;
+               goto done;
+       }
+
+       if (!NT_STATUS_IS_OK(ret = init_object_from_buffer(object, data.dptr, data.dsize))) {
+               SAFE_FREE(data.dptr);
+               DEBUG(0, ("tdbsam2_enumerate_objects_get_next: Error fetching database, malformed entry!\n"));
+               ret = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+       SAFE_FREE(data.dptr);
+
+       /* prepare next run */
+       teo->key = tdb_nextkey(teo->db, teo->key);
+
+done:
+       return ret;
+}
+
+static NTSTATUS tdbsam2_enumerate_objects_stop(void *handle)
+{
+       struct tdbsam2_enum_objs *teo, *t, *p;
+
+       teo = (struct tdbsam2_enum_objs *)handle;
+
+       if (ts2_privs->teo_handlers == teo) {
+               ts2_privs->teo_handlers = teo->next;
+       } else {
+               t = ts2_privs->teo_handlers;
+               while (t != teo) {
+                       p = t;
+                       t = t->next;
+                       if (t == NULL) {
+                               DEBUG(0, ("tdbsam2_enumerate_objects_stop: Error, handle not found!\n"));
+                               return NT_STATUS_UNSUCCESSFUL;
+                       }
+               }
+               p = t->next;
+       }
+
+       tdb_close(teo->db);
+       SAFE_FREE(teo->dom_sid);
+       SAFE_FREE(teo);
+
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS tdbsam2_set_object(const GUMS_OBJECT *go)
+{
+       NTSTATUS ret;
+       TDB_CONTEXT *tdb;
+
+       if (!go)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) {
+               return ret;
+       }
+
+       ret = store_object(tdb, go, TDB_REPLACE);
+
+       tdb_close(tdb);
+       return ret;
+}
+
+       /* set object values function */
+static NTSTATUS (*set_object_values) (DOM_SID *sid, uint32 count, GUMS_DATA_SET *data_set);
+
+       /* Group related functions */
+static NTSTATUS (*add_memberss_to_group) (const DOM_SID *group, const DOM_SID **members);
+       NTSTATUS (*delete_members_from_group) (const DOM_SID *group, const DOM_SID **members);
+static NTSTATUS (*enumerate_group_members) (DOM_SID **members, const DOM_SID *sid, const int type);
+
+static NTSTATUS (*get_sid_groups) (DOM_SID **groups, const DOM_SID *sid);
+
+static NTSTATUS (*lock_sid) (const DOM_SID *sid);
+static NTSTATUS (*unlock_sid) (const DOM_SID *sid);
+
+       /* privileges related functions */
+
+static NTSTATUS (*add_members_to_privilege) (const LUID_ATTR *priv, const DOM_SID **members);
+static NTSTATUS (*delete_members_from_privilege) (const LUID_ATTR *priv, const DOM_SID **members);
+static NTSTATUS (*enumerate_privilege_members) (DOM_SID **members, const LUID_ATTR *priv);
+static NTSTATUS (*get_sid_privileges) (DOM_SID **privs, const DOM_SID *sid);
+       /* warning!: set_privilege will overwrite a prior existing privilege if such exist */
+static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv);
+
+static void free_tdbsam2_private_data(void **vp) 
+{
+       struct tdbsam2_private_data **tdb_privs = (struct tdbsam2_private_data **)vp;
+       while (ts2_privs->teo_handlers)
+               tdbsam2_enumerate_objects_stop(ts2_privs->teo_handlers);
+       *tdb_privs = NULL;
+       /* No need to free any further, as it is talloc()ed */
+}
+
+static NTSTATUS init_tdbsam2(GUMS_FUNCTIONS *fns, const char *storage)
+{
+       NTSTATUS ret;
+       TDB_CONTEXT *tdb;
+       DOM_SID dom_sid;
+
+       fns->name = talloc_strdup(fns->mem_ctx, "tdbsam2");
+
+       fns->get_domain_sid = tdbsam2_get_domain_sid;
+       /* fns->get_sequence_number = tdbsam2_get_sequence_number; */
+       fns->new_object = tdbsam2_new_object;
+       fns->delete_object = tdbsam2_delete_object;
+       fns->get_object_from_sid = tdbsam2_get_object_from_sid;
+       fns->get_object_from_name = tdbsam2_get_object_from_name;
+       /* fns->get_updated_objects = tdbsam2_get_updated_objects; */
+       fns->enumerate_objects_start = tdbsam2_enumerate_objects_start;
+       fns->enumerate_objects_get_next = tdbsam2_enumerate_objects_get_next;
+       fns->enumerate_objects_stop = tdbsam2_enumerate_objects_stop;
+       fns->set_object = tdbsam2_set_object;
+       /* fns->set_object_values = tdbsam2_set_object_values;
+       fns->add_members_to_group = tdbsam2_add_members_to_group;
+       fns->delete_members_from_group = tdbsam2_delete_members_from_group;
+       fns->enumerate_group_members = tdbsam2_enumerate_group_members;
+       fns->get_sid_groups = tdbsam2_get_sid_groups;
+       fns->lock_sid = tdbsam2_lock_sid;
+       fns->unlock_sid = tdbsam2_unlock_sid;
+       fns->add_members_to_privilege = tdbsam2_add_members_to_privilege;
+       fns->delete_members_from_privilege = tdbsam2_delete_members_from_privilege;
+       fns->enumerate_privilege_members = tdbsam2_enumerate_privilege_members;
+       fns->get_sid_privileges = tdbsam2_get_sid_privileges;
+       fns->set_privilege = tdbsam2_set_privilege; */
+
+       ts2_privs = talloc_zero(fns->mem_ctx, sizeof(struct tdbsam2_private_data));
+       if (!ts2_privs) {
+               DEBUG(0, ("talloc() failed for tdbsam2 private_data!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (storage) {
+               ts2_privs->storage = talloc_strdup(fns->mem_ctx, storage);
+       } else {
+               pstring tdbfile;
+               get_private_directory(tdbfile);
+               pstrcat(tdbfile, "/");
+               pstrcat(tdbfile, TDB_FILE_NAME);
+               ts2_privs->storage = talloc_strdup(fns->mem_ctx, tdbfile);
+       }
+
+       /* check tdb exist (or create it) */
+
+               /* Find the domain SID */
+               if (!NT_STATUS_IS_OK(tdbsam2_get_domain_sid(&dom_sid, global_myname()))) {
+               /* db file does not exist or it is not inited */
+                       /* make the tdb file */
+               if (!NT_STATUS_IS_OK(ret = opentdb(&tdb, False))) {
+                       return ret;
+               }
+               tdb_close(tdb);
+
+               if (!NT_STATUS_IS_OK(tdbsam2_get_domain_sid(&dom_sid, "BUILTIN"))) {
+                       gums_init_builtin_domain();
+               }
+
+               gums_init_domain(get_global_sam_sid(), global_myname());
+       }
+
+       fns->private_data = &ts2_privs;
+       fns->free_private_data = free_tdbsam2_private_data;
+
+       return NT_STATUS_OK;
+}
+
+NTSTATUS gums_tdbsam2_init(void)
+{
+       /*
+       if ((gums_tdbsam2_debug_class = debug_add_class("gums_tdbsam2")) == -1) {
+               DEBUG(0, ("gums_tdbsam2: unable to register my own debug class! going on ...\n"));
+               gums_tdbsam2_debug_class = DBGC_ALL;
+       } 
+       */
+       return gums_register_module(GUMS_INTERFACE_VERSION, "tdbsam2", init_tdbsam2);
+}