1. The most part of this patch changed the unknown_3 flag to the now known
authorSimo Sorce <idra@samba.org>
Mon, 19 Jan 2004 08:52:53 +0000 (08:52 +0000)
committerSimo Sorce <idra@samba.org>
Mon, 19 Jan 2004 08:52:53 +0000 (08:52 +0000)
meaning of fields_present bit mask. Also avoid it being saved in backends (0
is saved where removing the unit32 would have produced a format change).
Also add support in samr functions to correctly interpret the flags.
Flags still not set properly (eg. still set all flags 0xffffff as previous
code), need a tool to test this properly (I',ve done preliminary tests with
samba4 rpc torture and it seem to work properly against w2k).

2. Patch for handlig the flag user must change password at next logon
in usrmgr based on Jianliang Lu <j.lu@tiesse.com> patch
(This used to be commit 78975e9483e64412e436c5dbfe2b71e20b79de29)

20 files changed:
source3/Makefile.in
source3/include/gums.h
source3/include/passdb.h
source3/include/rpc_samr.h
source3/include/tdbsam2.h [deleted file]
source3/include/tdbsam2_parse_info.h
source3/passdb/passdb.c
source3/passdb/pdb_get_set.c
source3/passdb/pdb_gums.c
source3/passdb/pdb_ldap.c
source3/passdb/pdb_mysql.c
source3/passdb/pdb_pgsql.c
source3/passdb/pdb_sql.c
source3/passdb/pdb_xml.c
source3/rpc_parse/parse_samr.c
source3/rpc_server/srv_samr_util.c
source3/rpcclient/cmd_samr.c
source3/sam/gums_api.c
source3/sam/gums_helper.c
source3/sam/gums_tdbsam2.c

index 1bd3392f02e99bd79bf48ea1e353a693674e1b0e..6d69e03e5f8ea79dd14d01f55b1878a9ee6fe6e0 100644 (file)
@@ -1423,7 +1423,7 @@ include/tdbsam2_parse_info.h:
        @if test -n "$(PERL)"; then \
                cd $(srcdir) && @PERL@ -w script/genstruct.pl \
                -o include/tdbsam2_parse_info.h $(CC) -E -O2 -g \
-               include/tdbsam2.h; \
+               include/gums.h; \
        else \
                echo Unable to build $@, continuing; \
        fi
index 9ce2ec4e56aa891ed363c76fb096fc5efae9c563..d16a839bc4bd0a62d888128341b767ec4804d220 100644 (file)
 #define GUMS_VERSION_MAJOR     0
 #define GUMS_VERSION_MINOR     1
 #define GUMS_OBJECT_VERSION    1
+#define GUMS_PRIVILEGE_VERSION 1
 #define GUMS_INTERFACE_VERSION 1
 
 #define GUMS_OBJ_DOMAIN                        0x10
 #define GUMS_OBJ_NORMAL_USER           0x20
 #define GUMS_OBJ_GROUP                 0x30
 #define GUMS_OBJ_ALIAS                 0x31
-#define GUMS_OBJ_PRIVILEGE             0x40
 
 /* define value types */
 #define GUMS_SET_PRIMARY_GROUP         0x1
@@ -79,7 +79,7 @@
 #define GUMS_DEL_SID_LIST              0x61
 #define GUMS_SET_SID_LIST              0x62
 
-typedef struct gums_user
+GENSTRUCT struct gums_user
 {
        DOM_SID *group_sid;             /* Primary Group SID */
 
@@ -90,14 +90,14 @@ typedef struct gums_user
        NTTIME pass_can_change_time;    /* password can change time */
        NTTIME pass_must_change_time;   /* password must change time */
 
-       char *full_name;                /* user's full name string */
-       char *home_dir;                 /* home directory string */
-       char *dir_drive;                /* home directory drive string */
-       char *logon_script;             /* logon script string */
-       char *profile_path;             /* profile path string */
-       char *workstations;             /* login from workstations string */
-       char *unknown_str;              /* don't know what this is, yet. */
-       char *munged_dial;              /* munged path name and dial-back tel number */
+       char *full_name; _NULLTERM      /* user's full name string */
+       char *home_dir; _NULLTERM       /* home directory string */
+       char *dir_drive; _NULLTERM      /* home directory drive string */
+       char *logon_script; _NULLTERM   /* logon script string */
+       char *profile_path; _NULLTERM   /* profile path string */
+       char *workstations; _NULLTERM   /* login from workstations string */
+       char *unknown_str; _NULLTERM    /* don't know what this is, yet. */
+       char *munged_dial; _NULLTERM    /* munged path name and dial-back tel number */
 
        DATA_BLOB lm_pw;                /* .data is Null if no password */
        DATA_BLOB nt_pw;                /* .data is Null if no password */
@@ -105,61 +105,70 @@ typedef struct gums_user
        uint16 acct_ctrl;               /* account type & status flags */
        uint16 logon_divs;              /* 168 - number of hours in a week */
        uint32 hours_len;               /* normally 21 bytes */
-       uint8 *hours;
+       uint8 *hours; _LEN(hours_len)   /* normally 21 bytes (depends on hours_len) */
 
        uint16 bad_password_count;      /* 0 */
        uint16 logon_count;             /* 0 */
        uint32 unknown_3;               /* 0x00ff ffff */
        uint32 unknown_6;               /* 0x0000 04ec */
 
-} GUMS_USER;
+};
 
-typedef struct gums_group
+GENSTRUCT struct gums_group
 {
        uint32 count;                   /* Number of SIDs */
-       DOM_SID *members;               /* SID array */
+       DOM_SID *members; _LEN(count)   /* SID array */
 
-} GUMS_GROUP;
+};
 
-typedef struct gums_domain
+GENSTRUCT struct gums_domain
 {
        uint32 next_rid;
 
-} GUMS_DOMAIN;
+};
 
-typedef struct gums_privilege
+GENSTRUCT struct gums_object
 {
-       LUID_ATTR *privilege;           /* Privilege Type */
+       TALLOC_CTX *mem_ctx;
 
-       uint32 count;
-       DOM_SID *members;
+       uint32 type;                    /* Object Type */
+       uint32 version;                 /* Object Version */
+       uint32 seq_num;                 /* Object Sequence Number */
+
+       SEC_DESC *sec_desc;             /* Security Descriptor */
+
+       DOM_SID *sid;                   /* Object Sid */
+       char *name; _NULLTERM           /* Object Name - it should be in DOMAIN\NAME format */
+       char *description; _NULLTERM    /* Object Description */
 
-} GUMS_PRIVILEGE;
+       struct gums_user *user;
+       struct gums_group *group;
+       struct gums_domain *domain;
 
-union gums_obj_p {
-       GUMS_USER *user;
-       GUMS_GROUP *group;
-       GUMS_DOMAIN *domain;
-       GUMS_PRIVILEGE *priv;
 };
 
-typedef struct gums_object
+GENSTRUCT struct gums_privilege
 {
        TALLOC_CTX *mem_ctx;
 
-       uint32 type;                    /* Object Type */
        uint32 version;                 /* Object Version */
        uint32 seq_num;                 /* Object Sequence Number */
 
-       SEC_DESC *sec_desc;             /* Security Descriptor */
+       char *name; _NULLTERM           /* Object Name */
+       char *description; _NULLTERM    /* Object Description */
 
-       DOM_SID *sid;                   /* Object Sid */
-       char *name;                     /* Object Name */
-       char *description;              /* Object Description */
+       LUID_ATTR *privilege;           /* Privilege Type */
 
-       union gums_obj_p data;          /* Object Specific data */
+       uint32 count;
+       DOM_SID *members; _LEN(count)
+
+};
 
-} GUMS_OBJECT;
+typedef struct gums_user GUMS_USER;
+typedef struct gums_group GUMS_GROUP;
+typedef struct gums_domain GUMS_DOMAIN;
+typedef struct gums_object GUMS_OBJECT;
+typedef struct gums_privilege GUMS_PRIVILEGE;
 
 typedef struct gums_data_set
 {
@@ -210,7 +219,7 @@ typedef struct gums_functions
        NTSTATUS (*delete_object) (const DOM_SID *sid);
 
        NTSTATUS (*get_object_from_sid) (GUMS_OBJECT **object, const DOM_SID *sid, const int obj_type);
-       NTSTATUS (*get_object_from_name) (GUMS_OBJECT **object, const char *name, const int obj_type);
+       NTSTATUS (*get_object_from_name) (GUMS_OBJECT **object, const char *domain, const char *name, const int obj_type);
        /* This function is used to get the list of all objects changed since b_time, it is
           used to support PDC<->BDC synchronization */
        NTSTATUS (*get_updated_objects) (GUMS_OBJECT **objects, const NTTIME base_time);
@@ -221,7 +230,7 @@ typedef struct gums_functions
 
        /* 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);
+       NTSTATUS (*set_object) (GUMS_OBJECT *object);
 
        /* set object values function */
        NTSTATUS (*set_object_values) (DOM_SID *sid, uint32 count, GUMS_DATA_SET *data_set);
@@ -238,10 +247,11 @@ typedef struct gums_functions
 
        /* 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);
+       NTSTATUS (*get_privilege) (GUMS_OBJECT **object, const char *name);
+       NTSTATUS (*add_members_to_privilege) (const char *name, const DOM_SID **members);
+       NTSTATUS (*delete_members_from_privilege) (const char *name, const DOM_SID **members);
+       NTSTATUS (*enumerate_privilege_members) (const char *name, DOM_SID **members);
+       NTSTATUS (*get_sid_privileges) (const DOM_SID *sid, const char **privs);
 
        /* warning!: set_privilege will overwrite a prior existing privilege if such exist */
        NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv);
index c12cf10cf25a5a2e02bfcf3a5d07527492dc3260..add286816cda6dd22b8b4c86a22a2fea82e2af1f 100644 (file)
 #define _PASSDB_H
 
 
+/*
+ * fields_present flags meanings
+ * same names as found in samba4 idl files
+ */
+
+#define ACCT_USERNAME          0x00000001
+#define ACCT_FULL_NAME         0x00000002
+#define ACCT_RID               0x00000004
+#define ACCT_PRIMARY_GID       0x00000008
+#define ACCT_ADMIN_DESC                0x00000010
+#define ACCT_DESCRIPTION       0x00000020
+#define ACCT_HOME_DIR          0x00000040
+#define ACCT_HOME_DRIVE                0x00000080
+#define ACCT_LOGON_SCRIPT      0x00000100
+#define ACCT_PROFILE           0x00000200
+#define ACCT_WORKSTATIONS      0x00000400
+#define ACCT_LAST_LOGON                0x00000800
+#define ACCT_LAST_LOGOFF       0x00001000
+#define ACCT_LOGON_HOURS       0x00002000
+#define ACCT_BAD_PWD_COUNT     0x00004000
+#define ACCT_NUM_LOGONS                0x00008000
+#define ACCT_ALLOW_PWD_CHANGE  0x00010000
+#define ACCT_FORCE_PWD_CHANGE  0x00020000
+#define ACCT_LAST_PWD_CHANGE   0x00040000
+#define ACCT_EXPIRY            0x00080000
+#define ACCT_FLAGS             0x00100000
+#define ACCT_CALLBACK          0x00200001
+#define ACCT_COUNTRY_CODE      0x00400000
+#define ACCT_CODE_PAGE         0x00800000
+#define ACCT_NT_PWD_SET                0x01000000
+#define ACCT_LM_PWD_SET                0x02000000
+#define ACCT_PRIVATEDATA       0x04000000
+#define ACCT_EXPIRED_FLAG      0x08000000
+#define ACCT_SEC_DESC          0x10000000
+#define ACCT_OWF_PWD           0x20000000
+
 /*
  * bit flags representing initialized fields in SAM_ACCOUNT
  */
@@ -140,7 +176,7 @@ typedef struct sam_passwd
                char* plaintext_pw; /* is Null if not available */
                
                uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
-               uint32 unknown_3; /* 0x00ff ffff */
+               uint32 fields_present; /* 0x00ff ffff */
                
                uint16 logon_divs; /* 168 - number of hours in a week */
                uint32 hours_len; /* normally 21 bytes */
index 787535d0e90165dc0ee82a2f049a54a46c1c37d6..a8ca504c8f9ea75d89848f3966d4480423d2737c 100644 (file)
@@ -183,7 +183,7 @@ typedef struct sam_user_info_23
 
        uint32 acb_info; /* account info (ACB_xxxx bit-mask) */
 
-       uint32 unknown_3; /* 0x09f8 27fa */
+       uint32 fields_present; /* 0x09f8 27fa */
 
        uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
        /* uint8 pad[2] */
@@ -308,7 +308,8 @@ typedef struct sam_user_info_21
 
        uint32 acb_info; /* account info (ACB_xxxx bit-mask) */
 
-       uint32 unknown_3; /* 0x00ff ffff */
+       /* Was unknown_3 */
+       uint32 fields_present; /* 0x00ff ffff */
 
        uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
        /* uint8 pad[2] */
diff --git a/source3/include/tdbsam2.h b/source3/include/tdbsam2.h
deleted file mode 100644 (file)
index b99e165..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Unix SMB/CIFS implementation. 
- * tdbsam2 genstruct enabled header file
- * Copyright (C) Simo Sorce 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.
- */
-
-/* ALL strings assumes UTF8 as encoding */
-
-#ifndef TDBSAM2_H
-#define TDBSAM2_H
-
-/* IMPORTANT: these structures must follow closely the GUMS_OBJECTs
- * structures as they will be casted over !!
- * the GUMS_OBJECT union is unrolled here into four tdbsam2
- * objects cause genstruct is not able to follow arbitrary unions */
-
-GENSTRUCT struct domain_sub_structure
-{
-       uint32 next_rid;                /* The Next free RID */
-};
-
-GENSTRUCT struct tdbsam2_domain_data
-{
-       TALLOC_CTX *mem_ctx;
-
-       uint32 type;
-       uint32 version;
-       uint32 xcounter;                /* counter to be updated at any change */
-
-       SEC_DESC *sec_desc;             /* Security Descriptor */
-       
-       DOM_SID *dom_sid;               /* The Domain SID */
-       char *name; _NULLTERM           /* NT Domain Name */
-       char *description; _NULLTERM    /* Descritpion (Gecos) */
-
-       struct domain_sub_structure *dss;
-};
-
-GENSTRUCT struct user_sub_structure
-{
-       DOM_SID *group_sid;             /* The Primary Group SID */
-
-       NTTIME logon_time;
-       NTTIME logoff_time;
-       NTTIME kickoff_time;
-       NTTIME pass_last_set_time;
-       NTTIME pass_can_change_time;
-       NTTIME pass_must_change_time;
-       
-       char *full_name; _NULLTERM      /* The Full Name */
-       char *home_dir; _NULLTERM       /* Home Directory */
-       char *dir_drive; _NULLTERM      /* Drive Letter the home should be mapped to */
-       char *logon_script; _NULLTERM   /* Logon script path */
-       char *profile_path; _NULLTERM   /* Profile is stored here */
-       char *workstations; _NULLTERM   /* List of Workstation names the user is allowed to LogIn */
-       char *unknown_str; _NULLTERM    /* Guess ... Unknown */
-       char *munged_dial; _NULLTERM    /* Callback Number */
-
-       DATA_BLOB lm_pw;                /* .data is Null if no password */
-       DATA_BLOB nt_pw;                /* .data is Null if no password */
-
-       uint16 acct_ctrl;               /* account flags */
-       uint16 logon_divs;              /* 168 - num of hours in a week */
-       uint32 hours_len;               /* normally 21 */
-       uint8 *hours; _LEN(hours_len)   /* normally 21 bytes (depends on hours_len) */
-
-       uint16 bad_password_count;      /* 0 */
-       uint16 logon_count;             /* 0 */
-       uint32 unknown_3;               /* 0x00ff ffff */
-       uint32 unknown_6;               /* 0x0000 04ec */
-};
-
-GENSTRUCT struct tdbsam2_user_data
-{
-       TALLOC_CTX *mem_ctx;
-
-       uint32 type;
-       uint32 version;
-       uint32 xcounter;                /* counter to be updated at any change */
-
-       SEC_DESC *sec_desc;             /* Security Descriptor */
-
-       DOM_SID *user_sid;              /* The User SID */
-       char *name; _NULLTERM           /* NT User Name */
-       char *description; _NULLTERM    /* Descritpion (Gecos) */
-
-       struct user_sub_structure *uss;
-};
-
-GENSTRUCT struct group_sub_structure
-{
-       uint32 count;                   /* number of sids */
-       DOM_SID *members; _LEN(count)   /* SID array */
-};
-
-GENSTRUCT struct tdbsam2_group_data
-{
-       TALLOC_CTX *mem_ctx;
-
-       uint32 type;
-       uint32 version;
-       uint32 xcounter;                /* counter to be updated at any change */
-
-       SEC_DESC *sec_desc;             /* Security Descriptor */
-
-       DOM_SID *group_sid;             /* The Group SID */
-       char *name; _NULLTERM           /* NT Group Name */
-       char *description; _NULLTERM    /* Descritpion (Gecos) */
-
-       struct group_sub_structure *gss;
-};
-
-GENSTRUCT struct priv_sub_structure
-{
-       LUID_ATTR *privilege;           /* Privilege */
-
-       uint32 count;                   /* number of sids */
-       DOM_SID *members; _LEN(count)   /* SID array */
-};
-
-GENSTRUCT struct tdbsam2_priv_data
-{
-       TALLOC_CTX *mem_ctx;
-
-       uint32 type;
-       uint32 version;
-       uint32 xcounter;                /* counter to be updated at any change */
-
-       DOM_SID *null_sid;
-       char *name; _NULLTERM           /* Privilege Name */
-       char *description; _NULLTERM    /* Descritpion (Gecos) */
-
-       struct priv_sub_structure *pss;
-};
-
-#endif /* TDBSAM2_H */
index f1b2936c476937d21cfb9e7ebfed50ed43b49e87..abaa2b142aee312d6bc3eed3cbe1090db88585ea 100644 (file)
 /* 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},
+int gen_dump_struct_gums_user(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_gums_user(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_gums_user[] = {
+{"group_sid", 1, sizeof(DOM_SID), offsetof(struct gums_user, group_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
+{"logon_time", 0, sizeof(NTTIME), offsetof(struct gums_user, logon_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"logoff_time", 0, sizeof(NTTIME), offsetof(struct gums_user, logoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"kickoff_time", 0, sizeof(NTTIME), offsetof(struct gums_user, kickoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"pass_last_set_time", 0, sizeof(NTTIME), offsetof(struct gums_user, pass_last_set_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"pass_can_change_time", 0, sizeof(NTTIME), offsetof(struct gums_user, pass_can_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"pass_must_change_time", 0, sizeof(NTTIME), offsetof(struct gums_user, pass_must_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME},
+{"full_name", 1, sizeof(char), offsetof(struct gums_user, full_name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"home_dir", 1, sizeof(char), offsetof(struct gums_user, home_dir), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"dir_drive", 1, sizeof(char), offsetof(struct gums_user, dir_drive), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"logon_script", 1, sizeof(char), offsetof(struct gums_user, logon_script), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"profile_path", 1, sizeof(char), offsetof(struct gums_user, profile_path), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"workstations", 1, sizeof(char), offsetof(struct gums_user, workstations), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"unknown_str", 1, sizeof(char), offsetof(struct gums_user, unknown_str), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"munged_dial", 1, sizeof(char), offsetof(struct gums_user, munged_dial), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"lm_pw", 0, sizeof(DATA_BLOB), offsetof(struct gums_user, lm_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB},
+{"nt_pw", 0, sizeof(DATA_BLOB), offsetof(struct gums_user, nt_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB},
+{"acct_ctrl", 0, sizeof(uint16), offsetof(struct gums_user, acct_ctrl), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
+{"logon_divs", 0, sizeof(uint16), offsetof(struct gums_user, logon_divs), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
+{"hours_len", 0, sizeof(uint32), offsetof(struct gums_user, hours_len), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"hours", 1, sizeof(uint8), offsetof(struct gums_user, hours), 0, "hours_len", 0, gen_dump_uint8, gen_parse_uint8},
+{"bad_password_count", 0, sizeof(uint16), offsetof(struct gums_user, bad_password_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
+{"logon_count", 0, sizeof(uint16), offsetof(struct gums_user, logon_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16},
+{"unknown_3", 0, sizeof(uint32), offsetof(struct gums_user, unknown_3), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"unknown_6", 0, sizeof(uint32), offsetof(struct gums_user, unknown_6), 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_dump_struct_gums_user(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_gums_user, 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_parse_struct_gums_user(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_gums_user, 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},
+int gen_dump_struct_gums_group(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_gums_group(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_gums_group[] = {
+{"count", 0, sizeof(uint32), offsetof(struct gums_group, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"members", 1, sizeof(DOM_SID), offsetof(struct gums_group, 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_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_dump_struct_gums_group(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_gums_group, 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_parse_struct_gums_group(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_gums_group, 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},
+int gen_dump_struct_gums_domain(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_gums_domain(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_gums_domain[] = {
+{"next_rid", 0, sizeof(uint32), offsetof(struct gums_domain, next_rid), 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},
+int gen_dump_struct_gums_domain(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_gums_domain, p, ptr, indent);
+}
+int gen_parse_struct_gums_domain(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_gums_domain, ptr, str);
+}
+
+int gen_dump_struct_gums_object(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_gums_object(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_gums_object[] = {
+{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct gums_object, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX},
+{"type", 0, sizeof(uint32), offsetof(struct gums_object, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"version", 0, sizeof(uint32), offsetof(struct gums_object, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"seq_num", 0, sizeof(uint32), offsetof(struct gums_object, seq_num), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"sec_desc", 1, sizeof(SEC_DESC), offsetof(struct gums_object, sec_desc), 0, NULL, 0, gen_dump_SEC_DESC, gen_parse_SEC_DESC},
+{"sid", 1, sizeof(DOM_SID), offsetof(struct gums_object, sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID},
+{"name", 1, sizeof(char), offsetof(struct gums_object, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"description", 1, sizeof(char), offsetof(struct gums_object, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"user", 1, sizeof(struct gums_user), offsetof(struct gums_object, user), 0, NULL, 0, gen_dump_struct_gums_user, gen_parse_struct_gums_user},
+{"group", 1, sizeof(struct gums_group), offsetof(struct gums_object, group), 0, NULL, 0, gen_dump_struct_gums_group, gen_parse_struct_gums_group},
+{"domain", 1, sizeof(struct gums_domain), offsetof(struct gums_object, domain), 0, NULL, 0, gen_dump_struct_gums_domain, gen_parse_struct_gums_domain},
 {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_dump_struct_gums_object(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_gums_object, 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_parse_struct_gums_object(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_gums_object, 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},
+int gen_dump_struct_gums_privilege(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned);
+int gen_parse_struct_gums_privilege(TALLOC_CTX *mem_ctx, char *, const char *);
+static const struct parse_struct pinfo_gums_privilege[] = {
+{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct gums_privilege, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX},
+{"version", 0, sizeof(uint32), offsetof(struct gums_privilege, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"seq_num", 0, sizeof(uint32), offsetof(struct gums_privilege, seq_num), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"name", 1, sizeof(char), offsetof(struct gums_privilege, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"description", 1, sizeof(char), offsetof(struct gums_privilege, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char},
+{"privilege", 1, sizeof(LUID_ATTR), offsetof(struct gums_privilege, privilege), 0, NULL, 0, gen_dump_LUID_ATTR, gen_parse_LUID_ATTR},
+{"count", 0, sizeof(uint32), offsetof(struct gums_privilege, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32},
+{"members", 1, sizeof(DOM_SID), offsetof(struct gums_privilege, 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_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_dump_struct_gums_privilege(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) {
+       return gen_dump_struct(mem_ctx, pinfo_gums_privilege, 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);
+int gen_parse_struct_gums_privilege(TALLOC_CTX *mem_ctx, char *ptr, const char *str) {
+       return gen_parse_struct(mem_ctx, pinfo_gums_privilege, ptr, str);
 }
 
index 8fbd8d4cdc62ee411dc72dc3b62eccf65e87116b..52dee801ad1ee1f64903b8a610c91d4b8587bb71 100644 (file)
@@ -79,7 +79,7 @@ void pdb_fill_default_sam(SAM_ACCOUNT *user)
        user->private.logoff_time           = 
        user->private.kickoff_time          = 
        user->private.pass_must_change_time = get_time_t_max();
-       user->private.unknown_3 = 0x00ffffff;   /* don't know */
+       user->private.fields_present = 0x00ffffff;      /* don't know */
        user->private.logon_divs = 168;         /* hours per week */
        user->private.hours_len = 21;           /* 21 times 8 bits = 168 */
        memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */
@@ -1346,7 +1346,7 @@ BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
                fullname_len, homedir_len, logon_script_len,
                profile_path_len, acct_desc_len, workstations_len;
                
-       uint32  user_rid, group_rid, unknown_3, hours_len, unknown_6;
+       uint32  user_rid, group_rid, remove_me, hours_len, unknown_6;
        uint16  acct_ctrl, logon_divs;
        uint16  bad_password_count, logon_count;
        uint8   *hours;
@@ -1385,7 +1385,7 @@ BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
                &lm_pw_len, &lm_pw_ptr,
                &nt_pw_len, &nt_pw_ptr,
                &acct_ctrl,
-               &unknown_3,
+               &remove_me, /* remove on the next TDB_FORMAT upgarde */
                &logon_divs,
                &hours_len,
                &hourslen, &hours,
@@ -1463,7 +1463,6 @@ BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
 
        pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
        pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
-       pdb_set_unknown_3(sampass, unknown_3, PDB_SET);
        pdb_set_hours_len(sampass, hours_len, PDB_SET);
        pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
        pdb_set_logon_count(sampass, logon_count, PDB_SET);
@@ -1667,7 +1666,7 @@ uint32 init_buffer_from_sam_v0 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
                lm_pw_len, lm_pw,
                nt_pw_len, nt_pw,
                pdb_get_acct_ctrl(sampass),
-               pdb_get_unknown_3(sampass),
+               0, /* was: fileds_present, to be removed on format change */
                pdb_get_logon_divs(sampass),
                pdb_get_hours_len(sampass),
                MAX_HOURS_LEN, pdb_get_hours(sampass),
@@ -1710,7 +1709,7 @@ uint32 init_buffer_from_sam_v0 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
                lm_pw_len, lm_pw,
                nt_pw_len, nt_pw,
                pdb_get_acct_ctrl(sampass),
-               pdb_get_unknown_3(sampass),
+               0, /* was: fileds_present, to be removed on format change */
                pdb_get_logon_divs(sampass),
                pdb_get_hours_len(sampass),
                MAX_HOURS_LEN, pdb_get_hours(sampass),
@@ -1762,7 +1761,7 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
                fullname_len, homedir_len, logon_script_len,
                profile_path_len, acct_desc_len, workstations_len;
                
-       uint32  user_rid, group_rid, unknown_3, hours_len, unknown_6;
+       uint32  user_rid, group_rid, remove_me, hours_len, unknown_6;
        uint16  acct_ctrl, logon_divs;
        uint16  bad_password_count, logon_count;
        uint8   *hours;
@@ -1802,7 +1801,7 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
                &lm_pw_len, &lm_pw_ptr,
                &nt_pw_len, &nt_pw_ptr,
                &acct_ctrl,
-               &unknown_3,
+               &remove_me,
                &logon_divs,
                &hours_len,
                &hourslen, &hours,
@@ -1880,7 +1879,6 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
 
        pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
        pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
-       pdb_set_unknown_3(sampass, unknown_3, PDB_SET);
        pdb_set_hours_len(sampass, hours_len, PDB_SET);
        pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
        pdb_set_logon_count(sampass, logon_count, PDB_SET);
@@ -2087,7 +2085,7 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
                lm_pw_len, lm_pw,
                nt_pw_len, nt_pw,
                pdb_get_acct_ctrl(sampass),
-               pdb_get_unknown_3(sampass),
+               0,
                pdb_get_logon_divs(sampass),
                pdb_get_hours_len(sampass),
                MAX_HOURS_LEN, pdb_get_hours(sampass),
@@ -2131,7 +2129,7 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
                lm_pw_len, lm_pw,
                nt_pw_len, nt_pw,
                pdb_get_acct_ctrl(sampass),
-               pdb_get_unknown_3(sampass),
+               0,
                pdb_get_logon_divs(sampass),
                pdb_get_hours_len(sampass),
                MAX_HOURS_LEN, pdb_get_hours(sampass),
index 4a5a5759d4f63e568bcbe77aa8e7936c59b57797..11df0ad56d71d9a4b3afea9c8b853746951470b4 100644 (file)
@@ -306,14 +306,6 @@ const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass)
                return (NULL);
 }
 
-uint32 pdb_get_unknown_3 (const SAM_ACCOUNT *sampass)
-{
-       if (sampass)
-               return (sampass->private.unknown_3);
-       else
-               return (-1);
-}
-
 uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass)
 {
        if (sampass)
@@ -982,16 +974,6 @@ BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum
        return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
 }
 
-BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag)
-{
-       if (!sampass)
-               return False;
-
-       sampass->private.unknown_3 = unkn;
-       
-       return pdb_set_init_flags(sampass, PDB_UNKNOWN3, flag);
-}
-
 BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, enum pdb_value_state flag)
 {
        if (!sampass)
@@ -1128,3 +1110,11 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
 
        return True;
 }
+
+/* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
+uint32 pdb_build_fields_present (SAM_ACCOUNT *sampass)
+{
+       /* value set to all for testing */
+       return 0x00ffffff;
+}
+
index 25dc56525320a723b2ec997dd756d87fb27ac08f..c595a51e55eb86d9fb58bef24b97706f228da36d 100644 (file)
@@ -1,7 +1,12 @@
 /*
+<<<<<<< pdb_gums.c
+ * 'Gums' password backend for samba
+ * Copyright (C) Simo Sorce 2003
+=======
  * GUMS password backend for samba
  * Copyright (C) Jelmer Vernooij 2002
  * Copyright (C) Andrew Bartlett 2003
+>>>>>>> 1.4
  * 
  * 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
@@ -95,7 +100,6 @@ static NTSTATUS gums_object_to_sam_account(SAM_ACCOUNT *sa, GUMS_OBJECT *go)
        }
        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); 
@@ -155,7 +159,6 @@ static NTSTATUS sam_account_to_gums_object(GUMS_OBJECT *go, SAM_ACCOUNT *sa)
        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);
 
index 6e8ff8350770e1ecce511c213f49afd30e706ed0..ff2b5cf762f177b393d59f6745ba9fcef658ce3c 100644 (file)
@@ -712,8 +712,6 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
 
 /*     pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */
        
-       /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
-
        if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) {
                        /* leave as default */
index acc1eff8298f3c1eeed684cc9a566b801d19108c..deed27dbe498e931d38a02c875ce1176065672dd 100644 (file)
@@ -111,7 +111,6 @@ static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u)
                pdb_set_plaintext_passwd(u, row[22]);
 
        pdb_set_acct_ctrl(u, xatol(row[23]), PDB_SET);
-       pdb_set_unknown_3(u, xatol(row[24]), PDB_SET);
        pdb_set_logon_divs(u, xatol(row[25]), PDB_SET);
        pdb_set_hours_len(u, xatol(row[26]), PDB_SET);
        pdb_set_bad_password_count(u, xatol(row[27]), PDB_SET);
index 61c620e092ec1ab16b66458a51ad61848a45549e..1731c720a21b9c0a8678d16ec26168eacc9b2085 100644 (file)
@@ -98,7 +98,6 @@ static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u )
   pdb_set_munged_dial          ( u, PQgetvalue( r, row, 17 ), PDB_SET ) ;
   
   pdb_set_acct_ctrl            ( u, PQgetlong ( r, row, 23 ), PDB_SET ) ;
-  pdb_set_unknown_3            ( u, PQgetlong ( r, row, 24 ), PDB_SET ) ;
   pdb_set_logon_divs           ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ;
   pdb_set_hours_len            ( u, PQgetlong ( r, row, 26 ), PDB_SET ) ;
   pdb_set_logon_count            ( u, PQgetlong ( r, row, 27 ), PDB_SET ) ;
index b87004e01938d74982275487e3a62e3cc7bf0aa7..d3e8b90a85d063510456a1a0ea9219f2435c9537 100644 (file)
@@ -44,7 +44,6 @@
 #define CONFIG_NT_PW_DEFAULT                           "nt_pw"
 #define CONFIG_PLAIN_PW_DEFAULT                                "NULL"
 #define CONFIG_ACCT_CTRL_DEFAULT                       "acct_ctrl"
-#define CONFIG_UNKNOWN_3_DEFAULT                       "unknown_3"
 #define CONFIG_LOGON_DIVS_DEFAULT                      "logon_divs"
 #define CONFIG_HOURS_LEN_DEFAULT                       "hours_len"
 #define CONFIG_BAD_PASSWORD_COUNT_DEFAULT              "bad_password_count"
@@ -254,8 +253,6 @@ char *sql_account_query_select(const char *data, BOOL update, enum sql_search_fi
                                                           CONFIG_PLAIN_PW_DEFAULT),
                         config_value_read(data, "acct ctrl column",
                                                           CONFIG_ACCT_CTRL_DEFAULT),
-                        config_value_read(data, "unknown 3 column",
-                                                          CONFIG_UNKNOWN_3_DEFAULT),
                         config_value_read(data, "logon divs column",
                                                           CONFIG_LOGON_DIVS_DEFAULT),
                         config_value_read(data, "hours len column",
index 19998a6655e95b61dbd7c5cccc0209097cd75bc9..2738ad40e2aa543703fc9a51fc2caa9c53fa33e4 100644 (file)
@@ -154,11 +154,6 @@ static BOOL parseUser(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SAM_ACCOUNT *
                                                          atol(xmlNodeListGetString
                                                                   (doc, cur->xmlChildrenNode, 1)), PDB_SET);
 
-               else if (!strcmp(cur->name, "unknown_3") && cur->ns == ns)
-                       pdb_set_unknown_3(u,
-                                                         atol(xmlNodeListGetString
-                                                                  (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
                else if (!strcmp(cur->name, "bad_password_count") && cur->ns == ns)
                        pdb_set_bad_password_count(u,
                                                          atol(xmlNodeListGetString
@@ -490,7 +485,6 @@ static NTSTATUS xmlsam_add_sam_account(struct pdb_methods *methods, SAM_ACCOUNT
        }
 
        xmlNewChild(user, data->ns, "acct_ctrl", iota(pdb_get_acct_ctrl(u)));
-       xmlNewChild(user, data->ns, "unknown_3", iota(pdb_get_unknown_3(u)));
 
        if (pdb_get_logon_divs(u))
                xmlNewChild(user, data->ns, "logon_divs",
index 607c9ecf64052c0820724cf1612dcb8643742991..e0eb2958b34418c173f9cec5c6e8e195dbf68367 100644 (file)
@@ -5315,11 +5315,6 @@ static BOOL sam_io_user_info11(const char *desc, SAM_USER_INFO_11 * usr,
 
 /*************************************************************************
  init_sam_user_infoa
-
- unknown_3 = 0x09f8 27fa
- unknown_5 = 0x0001 0000
- unknown_6 = 0x0000 04ec 
-
  *************************************************************************/
 
 void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516], uint16 pw_len)
@@ -5362,7 +5357,6 @@ static BOOL sam_io_user_info24(const char *desc, SAM_USER_INFO_24 * usr,
 /*************************************************************************
  init_sam_user_info23
 
- unknown_3 = 0x09f8 27fa
  unknown_6 = 0x0000 04ec 
 
  *************************************************************************/
@@ -5386,7 +5380,7 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
                        uint32 user_rid,        /* 0x0000 0000 */
                        uint32 group_rid,
                        uint32 acb_info,
-                       uint32 unknown_3,
+                       uint32 fields_present,
                        uint16 logon_divs,
                        LOGON_HRS * hrs,
                        uint16 bad_password_count,
@@ -5406,7 +5400,7 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
        usr->user_rid = user_rid;       /* 0x0000 0000 */
        usr->group_rid = group_rid;
        usr->acb_info = acb_info;
-       usr->unknown_3 = unknown_3;     /* 09f8 27fa */
+       usr->fields_present = fields_present;   /* 09f8 27fa */
 
        usr->logon_divs = logon_divs;   /* should be 168 (hours/week) */
        usr->ptr_logon_hrs = hrs ? 1 : 0;
@@ -5464,7 +5458,6 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
 /*************************************************************************
  init_sam_user_info23
 
- unknown_3 = 0x09f8 27fa
  unknown_6 = 0x0000 04ec 
 
  *************************************************************************/
@@ -5481,7 +5474,7 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
                           char *prof_path, const char *desc, char *wkstas,
                           char *unk_str, char *mung_dial, uint32 user_rid,     /* 0x0000 0000 */
                           uint32 group_rid, uint32 acb_info,
-                          uint32 unknown_3, uint16 logon_divs,
+                          uint32 fields_present, uint16 logon_divs,
                           LOGON_HRS * hrs, uint16 bad_password_count, uint16 logon_count,
                           char newpass[516], uint32 unknown_6)
 {
@@ -5500,7 +5493,7 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
        usr->user_rid = user_rid;       /* 0x0000 0000 */
        usr->group_rid = group_rid;
        usr->acb_info = acb_info;
-       usr->unknown_3 = unknown_3;     /* 09f8 27fa */
+       usr->fields_present = fields_present;   /* 09f8 27fa */
 
        usr->logon_divs = logon_divs;   /* should be 168 (hours/week) */
        usr->ptr_logon_hrs = hrs ? 1 : 0;
@@ -5619,7 +5612,7 @@ static BOOL sam_io_user_info23(const char *desc, SAM_USER_INFO_23 * usr,
        if(!prs_uint32("acb_info      ", ps, depth, &usr->acb_info))
                return False;
 
-       if(!prs_uint32("unknown_3     ", ps, depth, &usr->unknown_3))
+       if(!prs_uint32("fields_present ", ps, depth, &usr->fields_present))
                return False;
        if(!prs_uint16("logon_divs    ", ps, depth, &usr->logon_divs))  /* logon divisions per week */
                return False;
@@ -5816,7 +5809,6 @@ static BOOL sam_io_user_info25(const char *desc, SAM_USER_INFO_25 * usr, prs_str
 /*************************************************************************
  init_sam_user_info21W
 
- unknown_3 = 0x00ff ffff
  unknown_6 = 0x0000 04ec 
 
  *************************************************************************/
@@ -5843,7 +5835,7 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
                           uint32 user_rid,
                           uint32 group_rid,
                           uint32 acb_info,
-                          uint32 unknown_3,
+                          uint32 fields_present,
                           uint16 logon_divs,
                           LOGON_HRS * hrs,
                           uint16 bad_password_count,
@@ -5863,7 +5855,7 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
        usr->user_rid = user_rid;
        usr->group_rid = group_rid;
        usr->acb_info = acb_info;
-       usr->unknown_3 = unknown_3;     /* 0x00ff ffff */
+       usr->fields_present = fields_present;   /* 0x00ff ffff */
 
        usr->logon_divs = logon_divs;   /* should be 168 (hours/week) */
        usr->ptr_logon_hrs = hrs ? 1 : 0;
@@ -5918,7 +5910,6 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
 /*************************************************************************
  init_sam_user_info21
 
- unknown_3 = 0x00ff ffff
  unknown_6 = 0x0000 04ec 
 
  *************************************************************************/
@@ -6003,16 +5994,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
        usr->group_rid = group_rid;
        usr->acb_info  = pdb_get_acct_ctrl(pw);
 
-       /*
-         Look at a user on a real NT4 PDC with usrmgr, press
-         'ok'. Then you will see that unknown_3 is set to
-         0x08f827fa. Look at the user immediately after that again,
-         and you will see that 0x00fffff is returned. This solves
-         the problem that you get access denied after having looked
-         at the user.
-         -- Volker
-       */
-       usr->unknown_3 = 0x00ffffff;
+       usr->fields_present = pdb_build_fields_present(pw);
 
        usr->logon_divs = pdb_get_logon_divs(pw); 
        usr->ptr_logon_hrs = pdb_get_hours(pw) ? 1 : 0;
@@ -6133,7 +6115,7 @@ static BOOL sam_io_user_info21(const char *desc, SAM_USER_INFO_21 * usr,
        if(!prs_uint32("acb_info      ", ps, depth, &usr->acb_info))
                return False;
 
-       if(!prs_uint32("unknown_3     ", ps, depth, &usr->unknown_3))
+       if(!prs_uint32("fields_present ", ps, depth, &usr->fields_present))
                return False;
        if(!prs_uint16("logon_divs    ", ps, depth, &usr->logon_divs))  /* logon divisions per week */
                return False;
index 82f93a5b4c73e853dad5b6585cc27695f2bc2dcf..d54a8588782094c00e2b7b935b7f1e6049efdd14 100644 (file)
@@ -73,22 +73,24 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
 
        if (from == NULL || to == NULL) 
                return;
-       if (!nt_time_is_zero(&from->logon_time)) {
+
+       if (from->fields_present & ACCT_LAST_LOGON) {
                unix_time=nt_time_to_unix(&from->logon_time);
                stored_time = pdb_get_logon_time(to);
                DEBUG(10,("INFO_21 LOGON_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
                if (stored_time != unix_time) 
                        pdb_set_logon_time(to, unix_time, PDB_CHANGED);
-       }       
-       if (!nt_time_is_zero(&from->logoff_time)) {
+       }
+
+       if (from->fields_present & ACCT_LAST_LOGOFF) {
                unix_time=nt_time_to_unix(&from->logoff_time);
                stored_time = pdb_get_logoff_time(to);
                DEBUG(10,("INFO_21 LOGOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
                if (stored_time != unix_time) 
                        pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
        }
-       
-       if (!nt_time_is_zero(&from->kickoff_time)) {
+
+       if (from->fields_present & ACCT_EXPIRY) {
                unix_time=nt_time_to_unix(&from->kickoff_time);
                stored_time = pdb_get_kickoff_time(to);
                DEBUG(10,("INFO_21 KICKOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
@@ -96,14 +98,15 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
        }       
 
-       if (!nt_time_is_zero(&from->pass_can_change_time)) {
+       if (from->fields_present & ACCT_ALLOW_PWD_CHANGE) {
                unix_time=nt_time_to_unix(&from->pass_can_change_time);
                stored_time = pdb_get_pass_can_change_time(to);
                DEBUG(10,("INFO_21 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
                if (stored_time != unix_time) 
                        pdb_set_pass_can_change_time(to, unix_time, PDB_CHANGED);
        }
-       if (!nt_time_is_zero(&from->pass_last_set_time)) {
+
+       if (from->fields_present & ACCT_LAST_PWD_CHANGE) {
                unix_time=nt_time_to_unix(&from->pass_last_set_time);
                stored_time = pdb_get_pass_last_set_time(to);
                DEBUG(10,("INFO_21 PASS_LAST_SET: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
@@ -111,7 +114,7 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
        }
 
-       if (!nt_time_is_zero(&from->pass_must_change_time)) {
+       if (from->fields_present & ACCT_FORCE_PWD_CHANGE) {
                unix_time=nt_time_to_unix(&from->pass_must_change_time);
                stored_time=pdb_get_pass_must_change_time(to);
                DEBUG(10,("INFO_21 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
@@ -119,8 +122,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_pass_must_change_time(to, unix_time, PDB_CHANGED);
        }
 
-       /* Backend should check this for sainity */
-       if (from->hdr_user_name.buffer) {
+       if ((from->fields_present & ACCT_USERNAME) &&
+           (from->hdr_user_name.buffer)) {
                old_string = pdb_get_username(to);
                new_string = unistr2_static(&from->uni_user_name);
                DEBUG(10,("INFO_21 UNI_USER_NAME: %s -> %s\n", old_string, new_string));
@@ -128,7 +131,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                    pdb_set_username(to      , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_full_name.buffer) {
+       if ((from->fields_present & ACCT_FULL_NAME) &&
+           (from->hdr_full_name.buffer)) {
                old_string = pdb_get_fullname(to);
                new_string = unistr2_static(&from->uni_full_name);
                DEBUG(10,("INFO_21 UNI_FULL_NAME: %s -> %s\n",old_string, new_string));
@@ -136,7 +140,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_fullname(to      , new_string, PDB_CHANGED);
        }
        
-       if (from->hdr_home_dir.buffer) {
+       if ((from->fields_present & ACCT_HOME_DIR) &&
+           (from->hdr_home_dir.buffer)) {
                old_string = pdb_get_homedir(to);
                new_string = unistr2_static(&from->uni_home_dir);
                DEBUG(10,("INFO_21 UNI_HOME_DIR: %s -> %s\n",old_string,new_string));
@@ -144,7 +149,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_homedir(to       , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_dir_drive.buffer) {
+       if ((from->fields_present & ACCT_HOME_DRIVE) &&
+           (from->hdr_dir_drive.buffer)) {
                old_string = pdb_get_dir_drive(to);
                new_string = unistr2_static(&from->uni_dir_drive);
                DEBUG(10,("INFO_21 UNI_DIR_DRIVE: %s -> %s\n",old_string,new_string));
@@ -152,7 +158,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_dir_drive(to     , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_logon_script.buffer) {
+       if ((from->fields_present & ACCT_LOGON_SCRIPT) &&
+           (from->hdr_logon_script.buffer)) {
                old_string = pdb_get_logon_script(to);
                new_string = unistr2_static(&from->uni_logon_script);
                DEBUG(10,("INFO_21 UNI_LOGON_SCRIPT: %s -> %s\n",old_string,new_string));
@@ -160,7 +167,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_logon_script(to  , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_profile_path.buffer) {
+       if ((from->fields_present & ACCT_PROFILE) &&
+           (from->hdr_profile_path.buffer)) {
                old_string = pdb_get_profile_path(to);
                new_string = unistr2_static(&from->uni_profile_path);
                DEBUG(10,("INFO_21 UNI_PROFILE_PATH: %s -> %s\n",old_string, new_string));
@@ -168,7 +176,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_profile_path(to  , new_string, PDB_CHANGED);
        }
        
-       if (from->hdr_acct_desc.buffer) {
+       if ((from->fields_present & ACCT_DESCRIPTION) &&
+           (from->hdr_acct_desc.buffer)) {
                old_string = pdb_get_acct_desc(to);
                new_string = unistr2_static(&from->uni_acct_desc);
                DEBUG(10,("INFO_21 UNI_ACCT_DESC: %s -> %s\n",old_string,new_string));
@@ -176,7 +185,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_acct_desc(to     , new_string, PDB_CHANGED);
        }
        
-       if (from->hdr_workstations.buffer) {
+       if ((from->fields_present & ACCT_WORKSTATIONS) &&
+           (from->hdr_workstations.buffer)) {
                old_string = pdb_get_workstations(to);
                new_string = unistr2_static(&from->uni_workstations);
                DEBUG(10,("INFO_21 UNI_WORKSTATIONS: %s -> %s\n",old_string, new_string));
@@ -184,7 +194,9 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_workstations(to  , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_unknown_str.buffer) {
+       /* is this right? */
+       if ((from->fields_present & ACCT_ADMIN_DESC) &&
+           (from->hdr_unknown_str.buffer)) {
                old_string = pdb_get_unknown_str(to);
                new_string = unistr2_static(&from->uni_unknown_str);
                DEBUG(10,("INFO_21 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string));
@@ -192,7 +204,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                        pdb_set_unknown_str(to   , new_string, PDB_CHANGED);
        }
        
-       if (from->hdr_munged_dial.buffer) {
+       if ((from->fields_present & ACCT_CALLBACK) &&
+           (from->hdr_munged_dial.buffer)) {
                char *newstr;
                old_string = pdb_get_munged_dial(to);
                mung.length = from->hdr_munged_dial.uni_str_len;
@@ -205,7 +218,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                SAFE_FREE(newstr);
        }
        
-       if (from->user_rid == 0) {
+       if ((from->fields_present & ACCT_RID) &&
+           (from->user_rid == 0)) {
                DEBUG(10, ("INFO_21: Asked to set User RID to 0 !? Skipping change!\n"));
        } else if (from->user_rid != pdb_get_user_rid(to)) {
                DEBUG(10,("INFO_21 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid));
@@ -213,51 +227,57 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                /* pdb_set_user_sid_from_rid(to, from->user_rid, PDB_CHANGED);*/
        }
        
-       if (from->group_rid == 0) {
+       if ((from->fields_present & ACCT_PRIMARY_GID) &&
+           (from->group_rid == 0)) {
                DEBUG(10, ("INFO_21: Asked to set Group RID to 0 !? Skipping change!\n"));
        } else if (from->group_rid != pdb_get_group_rid(to)) {
                DEBUG(10,("INFO_21 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid));
                pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED);
        }
        
-       DEBUG(10,("INFO_21 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
-       if (from->acb_info != pdb_get_acct_ctrl(to)) {
-               pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
+       if (from->fields_present & ACCT_FLAGS) {
+               DEBUG(10,("INFO_21 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
+               if (from->acb_info != pdb_get_acct_ctrl(to)) {
+                       pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
+               }
        }
 
-       DEBUG(10,("INFO_21 UNKNOWN_3: %08X -> %08X\n",pdb_get_unknown_3(to),from->unknown_3));
-       if (from->unknown_3 != pdb_get_unknown_3(to)) {
-               pdb_set_unknown_3(to, from->unknown_3, PDB_CHANGED);
-       }
+       if (from->fields_present & ACCT_LOGON_HOURS) {
+               DEBUG(15,("INFO_21 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
+               if (from->logon_divs != pdb_get_logon_divs(to)) {
+                       pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED);
+               }
 
-       DEBUG(15,("INFO_21 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
-       if (from->logon_divs != pdb_get_logon_divs(to)) {
-               pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED);
-       }
+               DEBUG(15,("INFO_21 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
+               if (from->logon_hrs.len != pdb_get_hours_len(to)) {
+                       pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED);
+               }
 
-       DEBUG(15,("INFO_21 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
-       if (from->logon_hrs.len != pdb_get_hours_len(to)) {
-               pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED);
+               DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
+               /* Fix me: only update if it changes --metze */
+               pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
        }
 
-       DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
-/* Fix me: only update if it changes --metze */
-       pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
-
-       DEBUG(10,("INFO_21 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count));
-       if (from->bad_password_count != pdb_get_bad_password_count(to)) {
-               pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED);
+       if (from->fields_present & ACCT_BAD_PWD_COUNT) {
+               DEBUG(10,("INFO_21 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count));
+               if (from->bad_password_count != pdb_get_bad_password_count(to)) {
+                       pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED);
+               }
        }
 
-       DEBUG(10,("INFO_21 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count));
-       if (from->logon_count != pdb_get_logon_count(to)) {
-               pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
+       if (from->fields_present & ACCT_NUM_LOGONS) {
+               DEBUG(10,("INFO_21 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count));
+               if (from->logon_count != pdb_get_logon_count(to)) {
+                       pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
+               }
        }
 
-       DEBUG(10,("INFO_21 UNKNOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6));
-       if (from->unknown_6 != pdb_get_unknown_6(to)) {
-               pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED);
-       }
+       /* if (from->fields_present & ACCT_??) { */
+               DEBUG(10,("INFO_21 UNKNOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6));
+               if (from->unknown_6 != pdb_get_unknown_6(to)) {
+                       pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED);
+               }
+       /* } */
 
        DEBUG(10,("INFO_21 PADDING1 %02X %02X %02X %02X %02X %02X\n",
                  from->padding1[0],
@@ -269,7 +289,25 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
 
        DEBUG(10,("INFO_21 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
        if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) {
-               pdb_set_pass_must_change_time(to,0, PDB_CHANGED);               
+               pdb_set_pass_must_change_time(to,0, PDB_CHANGED);
+       } else {
+               uint32 expire;
+               time_t new_time;
+               if (pdb_get_pass_must_change_time(to) == 0) {
+                       if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
+                           || expire == (uint32)-1) {
+                               new_time = get_time_t_max();
+                       } else {
+                               time_t old_time = pdb_get_pass_last_set_time(to);
+                               new_time = old_time + expire;
+                               if ((new_time) < time(0)) {
+                                       new_time = time(0) + expire;
+                               }
+                       }
+                       if (!pdb_set_pass_must_change_time (to, new_time, PDB_CHANGED)) {
+                               DEBUG (0, ("pdb_set_pass_must_change_time failed!\n"));
+                       }
+               }
        }
 
        DEBUG(10,("INFO_21 PADDING_2: %02X\n",from->padding2));
@@ -290,14 +328,16 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
 
        if (from == NULL || to == NULL) 
                return;
-       if (!nt_time_is_zero(&from->logon_time)) {
+
+       if (from->fields_present & ACCT_LAST_LOGON) {
                unix_time=nt_time_to_unix(&from->logon_time);
                stored_time = pdb_get_logon_time(to);
                DEBUG(10,("INFO_23 LOGON_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
                if (stored_time != unix_time) 
                        pdb_set_logon_time(to, unix_time, PDB_CHANGED);
-       }       
-       if (!nt_time_is_zero(&from->logoff_time)) {
+       }
+
+       if (from->fields_present & ACCT_LAST_LOGOFF) {
                unix_time=nt_time_to_unix(&from->logoff_time);
                stored_time = pdb_get_logoff_time(to);
                DEBUG(10,("INFO_23 LOGOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
@@ -305,7 +345,7 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
        }
        
-       if (!nt_time_is_zero(&from->kickoff_time)) {
+       if (from->fields_present & ACCT_EXPIRY) {
                unix_time=nt_time_to_unix(&from->kickoff_time);
                stored_time = pdb_get_kickoff_time(to);
                DEBUG(10,("INFO_23 KICKOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
@@ -313,14 +353,15 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
        }       
 
-       if (!nt_time_is_zero(&from->pass_can_change_time)) {
+       if (from->fields_present & ACCT_ALLOW_PWD_CHANGE) {
                unix_time=nt_time_to_unix(&from->pass_can_change_time);
                stored_time = pdb_get_pass_can_change_time(to);
                DEBUG(10,("INFO_23 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
                if (stored_time != unix_time) 
                        pdb_set_pass_can_change_time(to, unix_time, PDB_CHANGED);
        }
-       if (!nt_time_is_zero(&from->pass_last_set_time)) {
+
+       if (from->fields_present & ACCT_LAST_PWD_CHANGE) {
                unix_time=nt_time_to_unix(&from->pass_last_set_time);
                stored_time = pdb_get_pass_last_set_time(to);
                DEBUG(10,("INFO_23 PASS_LAST_SET: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
@@ -328,7 +369,7 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
        }
 
-       if (!nt_time_is_zero(&from->pass_must_change_time)) {
+       if (from->fields_present & ACCT_FORCE_PWD_CHANGE) {
                unix_time=nt_time_to_unix(&from->pass_must_change_time);
                stored_time=pdb_get_pass_must_change_time(to);
                DEBUG(10,("INFO_23 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
@@ -336,8 +377,9 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_pass_must_change_time(to, unix_time, PDB_CHANGED);
        }
 
-       /* Backend should check this for sainity */
-       if (from->hdr_user_name.buffer) {
+       /* Backend should check this for sanity */
+       if ((from->fields_present & ACCT_USERNAME) &&
+           (from->hdr_user_name.buffer)) {
                old_string = pdb_get_username(to);
                new_string = unistr2_static(&from->uni_user_name);
                DEBUG(10,("INFO_23 UNI_USER_NAME: %s -> %s\n", old_string, new_string));
@@ -345,7 +387,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                    pdb_set_username(to      , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_full_name.buffer) {
+       if ((from->fields_present & ACCT_FULL_NAME) &&
+           (from->hdr_full_name.buffer)) {
                old_string = pdb_get_fullname(to);
                new_string = unistr2_static(&from->uni_full_name);
                DEBUG(10,("INFO_23 UNI_FULL_NAME: %s -> %s\n",old_string, new_string));
@@ -353,7 +396,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_fullname(to      , new_string, PDB_CHANGED);
        }
        
-       if (from->hdr_home_dir.buffer) {
+       if ((from->fields_present & ACCT_HOME_DIR) &&
+           (from->hdr_home_dir.buffer)) {
                old_string = pdb_get_homedir(to);
                new_string = unistr2_static(&from->uni_home_dir);
                DEBUG(10,("INFO_23 UNI_HOME_DIR: %s -> %s\n",old_string,new_string));
@@ -361,7 +405,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_homedir(to       , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_dir_drive.buffer) {
+       if ((from->fields_present & ACCT_HOME_DRIVE) &&
+           (from->hdr_dir_drive.buffer)) {
                old_string = pdb_get_dir_drive(to);
                new_string = unistr2_static(&from->uni_dir_drive);
                DEBUG(10,("INFO_23 UNI_DIR_DRIVE: %s -> %s\n",old_string,new_string));
@@ -369,7 +414,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_dir_drive(to     , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_logon_script.buffer) {
+       if ((from->fields_present & ACCT_LOGON_SCRIPT) &&
+           (from->hdr_logon_script.buffer)) {
                old_string = pdb_get_logon_script(to);
                new_string = unistr2_static(&from->uni_logon_script);
                DEBUG(10,("INFO_23 UNI_LOGON_SCRIPT: %s -> %s\n",old_string,new_string));
@@ -377,7 +423,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_logon_script(to  , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_profile_path.buffer) {
+       if ((from->fields_present & ACCT_PROFILE) &&
+           (from->hdr_profile_path.buffer)) {
                old_string = pdb_get_profile_path(to);
                new_string = unistr2_static(&from->uni_profile_path);
                DEBUG(10,("INFO_23 UNI_PROFILE_PATH: %s -> %s\n",old_string, new_string));
@@ -385,7 +432,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_profile_path(to  , new_string, PDB_CHANGED);
        }
        
-       if (from->hdr_acct_desc.buffer) {
+       if ((from->fields_present & ACCT_DESCRIPTION) &&
+           (from->hdr_acct_desc.buffer)) {
                old_string = pdb_get_acct_desc(to);
                new_string = unistr2_static(&from->uni_acct_desc);
                DEBUG(10,("INFO_23 UNI_ACCT_DESC: %s -> %s\n",old_string,new_string));
@@ -393,7 +441,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_acct_desc(to     , new_string, PDB_CHANGED);
        }
        
-       if (from->hdr_workstations.buffer) {
+       if ((from->fields_present & ACCT_WORKSTATIONS) &&
+           (from->hdr_workstations.buffer)) {
                old_string = pdb_get_workstations(to);
                new_string = unistr2_static(&from->uni_workstations);
                DEBUG(10,("INFO_23 UNI_WORKSTATIONS: %s -> %s\n",old_string, new_string));
@@ -401,7 +450,9 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_workstations(to  , new_string, PDB_CHANGED);
        }
 
-       if (from->hdr_unknown_str.buffer) {
+       /* is this right? */
+       if ((from->fields_present & ACCT_ADMIN_DESC) &&
+           (from->hdr_unknown_str.buffer)) {
                old_string = pdb_get_unknown_str(to);
                new_string = unistr2_static(&from->uni_unknown_str);
                DEBUG(10,("INFO_23 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string));
@@ -409,7 +460,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                        pdb_set_unknown_str(to   , new_string, PDB_CHANGED);
        }
        
-       if (from->hdr_munged_dial.buffer) {
+       if ((from->fields_present & ACCT_CALLBACK) &&
+           (from->hdr_munged_dial.buffer)) {
                char *newstr;
                old_string = pdb_get_munged_dial(to);
                mung.length = from->hdr_munged_dial.uni_str_len;
@@ -422,58 +474,66 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                SAFE_FREE(newstr);
        }
        
-       if (from->user_rid == 0) {
+       if ((from->fields_present & ACCT_RID) &&
+           (from->user_rid == 0)) {
                DEBUG(10, ("INFO_23: Asked to set User RID to 0 !? Skipping change!\n"));
        } else if (from->user_rid != pdb_get_user_rid(to)) {
                DEBUG(10,("INFO_23 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid));
                /* we really allow this ??? metze */
                /* pdb_set_user_sid_from_rid(to, from->user_rid, PDB_CHANGED);*/
        }
-       if (from->group_rid == 0) {
+
+       if ((from->fields_present & ACCT_PRIMARY_GID) &&
+           (from->group_rid == 0)) {
                DEBUG(10, ("INFO_23: Asked to set Group RID to 0 !? Skipping change!\n"));
        } else if (from->group_rid != pdb_get_group_rid(to)) {
                DEBUG(10,("INFO_23 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid));
                pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED);
        }
        
-       DEBUG(10,("INFO_23 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
-       if (from->acb_info != pdb_get_acct_ctrl(to)) {
-               pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
+       if (from->fields_present & ACCT_FLAGS) {
+               DEBUG(10,("INFO_23 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
+               if (from->acb_info != pdb_get_acct_ctrl(to)) {
+                       pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
+               }
        }
 
-       DEBUG(10,("INFO_23 UNKOWN_3: %08X -> %08X\n",pdb_get_unknown_3(to),from->unknown_3));
-       if (from->unknown_3 != pdb_get_unknown_3(to)) {
-               pdb_set_unknown_3(to, from->unknown_3, PDB_CHANGED);
-       }
+       if (from->fields_present & ACCT_LOGON_HOURS) {
+               DEBUG(15,("INFO_23 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
+               if (from->logon_divs != pdb_get_logon_divs(to)) {
+                       pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED);
+               }
 
-       DEBUG(15,("INFO_23 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
-       if (from->logon_divs != pdb_get_logon_divs(to)) {
-               pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED);
-       }
+               DEBUG(15,("INFO_23 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
+               if (from->logon_hrs.len != pdb_get_hours_len(to)) {
+                       pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED);
+               }
 
-       DEBUG(15,("INFO_23 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
-       if (from->logon_hrs.len != pdb_get_hours_len(to)) {
-               pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED);
+               DEBUG(15,("INFO_23 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
+               /* Fix me: only update if it changes --metze */
+               pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
        }
 
-       DEBUG(15,("INFO_23 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
-/* Fix me: only update if it changes --metze */
-       pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
-
-       DEBUG(10,("INFO_23 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count));
-       if (from->bad_password_count != pdb_get_bad_password_count(to)) {
-               pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED);
+       if (from->fields_present & ACCT_BAD_PWD_COUNT) {
+               DEBUG(10,("INFO_23 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count));
+               if (from->bad_password_count != pdb_get_bad_password_count(to)) {
+                       pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED);
+               }
        }
 
-       DEBUG(10,("INFO_23 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count));
-       if (from->logon_count != pdb_get_logon_count(to)) {
-               pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
+       if (from->fields_present & ACCT_NUM_LOGONS) {
+               DEBUG(10,("INFO_23 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count));
+               if (from->logon_count != pdb_get_logon_count(to)) {
+                       pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
+               }
        }
 
-       DEBUG(10,("INFO_23 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6));
-       if (from->unknown_6 != pdb_get_unknown_6(to)) {
-               pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED);
-       }
+       /* if (from->fields_present & ACCT_??) { */
+               DEBUG(10,("INFO_23 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6));
+               if (from->unknown_6 != pdb_get_unknown_6(to)) {
+                       pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED);
+               }
+       /* } */
 
        DEBUG(10,("INFO_23 PADDING1 %02X %02X %02X %02X %02X %02X\n",
                  from->padding1[0],
@@ -486,6 +546,24 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
        DEBUG(10,("INFO_23 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
        if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) {
                pdb_set_pass_must_change_time(to,0, PDB_CHANGED);               
+       } else {
+               uint32 expire;
+               time_t new_time;
+               if (pdb_get_pass_must_change_time(to) == 0) {
+                       if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
+                           || expire == (uint32)-1) {
+                               new_time = get_time_t_max();
+                       } else {
+                               time_t old_time = pdb_get_pass_last_set_time(to);
+                               new_time = old_time + expire;
+                               if ((new_time) < time(0)) {
+                                       new_time = time(0) + expire;
+                               }
+                       }
+                       if (!pdb_set_pass_must_change_time (to, new_time, PDB_CHANGED)) {
+                               DEBUG (0, ("pdb_set_pass_must_change_time failed!\n"));
+                       }
+               }
        }
 
        DEBUG(10,("INFO_23 PADDING_2: %02X\n",from->padding2));
index 34c6fc35abda4ad5bfc0108622df695bec5016db..455e5a89fccebedd08a09795efcefb9e537e9d9f 100644 (file)
@@ -83,7 +83,7 @@ static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
        printf("\tgroup_rid:\t0x%x\n"  , usr->group_rid); /* Group ID */
        printf("\tacb_info :\t0x%04x\n", usr->acb_info ); /* Account Control Info */
        
-       printf("\tunknown_3:\t0x%08x\n", usr->unknown_3); /* 0x00ff ffff */
+       printf("\tfileds_present:\t0x%08x\n", usr->fields_present); /* 0x00ff ffff */
        printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
        printf("\tbad_password_count:\t0x%08x\n", usr->bad_password_count);
        printf("\tlogon_count:\t0x%08x\n", usr->logon_count);
index 17f7d33baa9a81b563da3e25047b52698ed82a31..a76aed18fdc6bfb768ad6236e7b10473e8870822 100644 (file)
@@ -474,14 +474,6 @@ const uint8 *gums_get_user_hours(const GUMS_OBJECT *obj)
        return obj->data.user->hours;
 }
 
-uint32 gums_get_user_unknown_3(const GUMS_OBJECT *obj)
-{
-       if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
-               return 0;
-
-       return obj->data.user->unknown_3;
-}
-
 uint16 gums_get_user_bad_password_count(const GUMS_OBJECT *obj)
 {
        if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
@@ -780,18 +772,6 @@ NTSTATUS gums_set_user_hours(GUMS_OBJECT *obj, uint32 hours_len, const uint8 *ho
        return NT_STATUS_OK;
 }
 
-NTSTATUS gums_set_user_unknown_3(GUMS_OBJECT *obj, uint32 unknown_3)
-{
-       if (!obj)
-               return NT_STATUS_INVALID_PARAMETER;
-
-       if (obj->type != GUMS_OBJ_NORMAL_USER)
-               return NT_STATUS_OBJECT_TYPE_MISMATCH;
-
-       obj->data.user->unknown_3 = unknown_3;
-       return NT_STATUS_OK;
-}
-
 NTSTATUS gums_set_user_bad_password_count(GUMS_OBJECT *obj, uint16 bad_password_count)
 {
        if (!obj)
index 5bbd054be1457aa18ed6b0f692729bd87d52ace1..fcb9366cda87c73cc06f1b1a53e88d2c4b2971f1 100644 (file)
@@ -211,7 +211,7 @@ NTSTATUS gums_make_alias(DOM_SID *sid, const char *name, const char *description
        return ret;
 }
 
-NTSTATUS gums_init_domain(DOM_SID *sid, const char *name)
+NTSTATUS gums_init_domain(DOM_SID *sid, const char *name, const char * description)
 {
        NTSTATUS ret;
 
@@ -219,7 +219,7 @@ NTSTATUS gums_init_domain(DOM_SID *sid, const char *name)
        if (!NT_STATUS_IS_OK(ret = gums_make_domain(
                                        sid,
                                        name,
-                                       NULL
+                                       description
                                        ))) {
                return ret;
        }
@@ -331,7 +331,7 @@ NTSTATUS gums_init_builtin_domain(void)
        if (!NT_STATUS_IS_OK(ret = gums_make_alias(
                                        &global_sid_Builtin_Backup_Operators,
                                        "Backup Operators",
-                                        "Members can bypass file security to backup files"
+                                       "Members can bypass file security to backup files"
                                        ))) {
                return ret;
        }
index 217cf6f34eb92d9df420017436e3c8fa1df9df43..7fb9a1a997ff12c1902123427b1a24810dc8b48a 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include "includes.h"
-#include "tdbsam2.h"
 #include "tdbsam2_parse_info.h"
 
 #if 0
@@ -36,7 +35,9 @@ static int gums_tdbsam2_debug_class = DBGC_ALL;
 #define SIDPREFIX              "SID_"
 #define PRIVILEGEPREFIX                "PRIV_"
 
-#define TDB_FORMAT_STRING      "ddB"
+#define TDB_BASIC_OBJ_STRING   "ddd"
+#define TDB_FORMAT_STRING      "dddB"
+#define TDB_PRIV_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)
@@ -51,19 +52,6 @@ struct tdbsam2_enum_objs {
        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;
@@ -72,7 +60,6 @@ struct tdbsam2_private_data {
 
 static struct tdbsam2_private_data *ts2_privs;
 
-
 static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size)
 {
 
@@ -81,7 +68,7 @@ static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size
        int iret;
        char *obj_data = NULL;
        int data_size = 0;
-       int version, type;
+       int version, type, seqnum;
        int len;
 
        mem_ctx = talloc_init("init_object_from_buffer");
@@ -93,16 +80,17 @@ static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size
        len = tdb_unpack (buffer, size, TDB_FORMAT_STRING,
                          &version,
                          &type,
+                         &seqnum,
                          &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 */
+       /* 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"));
+               DEBUG(3,("init_object_from_buffer: Error, db object has wrong tdbsam version!\n"));
                goto done;
        }
 
@@ -116,20 +104,16 @@ static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size
        switch (type) {
 
                case GUMS_OBJ_DOMAIN:
-                       iret = gen_parse(mem_ctx, pinfo_tdbsam2_domain_data, (char *)(*go), obj_data);
+                       iret = gen_parse(mem_ctx, pinfo_gums_domain, (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);
+                       iret = gen_parse(mem_ctx, pinfo_gums_group, (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);
+                       iret = gen_parse(mem_ctx, pinfo_gums_user, (char *)(*go), obj_data);
                        break;
 
                default:
@@ -151,6 +135,62 @@ done:
        return ret;
 }
 
+static NTSTATUS init_privilege_from_buffer(GUMS_PRIVILEGE **priv, 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, seqnum;
+       int len;
+
+       mem_ctx = talloc_init("init_privilege_from_buffer");
+       if (!mem_ctx) {
+               DEBUG(0, ("init_privilege_from_buffer: Out of memory!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       len = tdb_unpack (buffer, size, TDB_PRIV_FORMAT_STRING,
+                         &version,
+                         &seqnum,
+                         &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_privilege_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';
+
+       *priv = (GUMS_PRIVILEGE *)talloc_zero(mem_ctx, sizeof(GUMS_PRIVILEGE));
+       TALLOC_CHECK(*priv, ret, done);
+
+       iret = gen_parse(mem_ctx, pinfo_gums_privilege, (char *)(*priv), obj_data);
+
+       if (iret != 0) {
+               DEBUG(0, ("init_privilege_from_buffer: Fatal Error! Unable to parse object!\n"));
+               DEBUG(0, ("init_privilege_from_buffer: DB Corrupt ?"));
+               goto done;
+       }
+
+       (*priv)->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)
 {
 
@@ -164,20 +204,16 @@ static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *
        switch (gums_get_object_type(object)) {
 
                case GUMS_OBJ_DOMAIN:
-                       genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_domain_data, (char *)object, 0);
+                       genbuf = gen_dump(mem_ctx, pinfo_gums_domain, (char *)object, 0);
                        break;
 
                case GUMS_OBJ_GROUP:
                case GUMS_OBJ_ALIAS:
-                       genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_group_data, (char *)object, 0);
+                       genbuf = gen_dump(mem_ctx, pinfo_gums_group, (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);
+                       genbuf = gen_dump(mem_ctx, pinfo_gums_user, (char *)object, 0);
                        break;
 
                default:
@@ -193,6 +229,7 @@ static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *
        buflen = tdb_pack(NULL, 0,  TDB_FORMAT_STRING,
                        TDBSAM_VERSION,
                        object->type,
+                       object->seq_num,
                        strlen(genbuf) + 1, genbuf);
 
        *buffer = talloc(mem_ctx, buflen);
@@ -201,6 +238,7 @@ static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *
        *len = tdb_pack(*buffer, buflen, TDB_FORMAT_STRING,
                        TDBSAM_VERSION,
                        object->type,
+                       object->seq_num,
                        strlen(genbuf) + 1, genbuf);
 
        if (*len != buflen) {
@@ -216,6 +254,49 @@ done:
        return ret;
 }
 
+static NTSTATUS init_buffer_from_privilege(char **buffer, size_t *len, TALLOC_CTX *mem_ctx, GUMS_PRIVILEGE *priv)
+{
+
+       NTSTATUS ret;
+       char *genbuf = NULL;
+       size_t buflen;
+
+       if (!buffer || !len || !mem_ctx || !priv)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       genbuf = gen_dump(mem_ctx, pinfo_gums_privilege, (char *)priv, 0);
+       
+       if (genbuf == NULL) {
+               DEBUG(0, ("init_buffer_from_privilege: Fatal Error! Unable to dump object!\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       buflen = tdb_pack(NULL, 0,  TDB_PRIV_FORMAT_STRING,
+                       TDBSAM_VERSION,
+                       priv->seq_num,
+                       strlen(genbuf) + 1, genbuf);
+
+       *buffer = talloc(mem_ctx, buflen);
+       TALLOC_CHECK(*buffer, ret, done);
+
+       *len = tdb_pack(*buffer, buflen, TDB_PRIV_FORMAT_STRING,
+                       TDBSAM_VERSION,
+                       priv->seq_num,
+                       strlen(genbuf) + 1, genbuf);
+
+       if (*len != buflen) {
+               DEBUG(0, ("init_buffer_from_privilege: 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)
@@ -266,7 +347,46 @@ done:
        return ret;
 }
 
-static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const char* name)
+static NTSTATUS make_full_object_name(TDB_CONTEXT *tdb, fstring objname, GUMS_OBJECT *object)
+{
+       NTSTATUS ret;
+
+       objname[0] = '\0';
+
+       if (gums_get_object_type(object) == GUMS_OBJ_DOMAIN) {
+
+               fstrcpy(objname, gums_get_object_name(object));
+
+       } else {
+               GUMS_OBJECT *domain_object;
+               DOM_SID domain_sid;
+               uint32 *discard_rid;
+
+               sid_copy(&domain_sid, gums_get_object_sid(object));
+               sid_split_rid(&domain_sid, discard_rid);
+
+               if (!NT_STATUS_IS_OK(get_object_by_sid(tdb,
+                                                       &domain_object,
+                                                       &domain_sid))) {
+
+                       DEBUG(3, ("Object's domain not found!\n"));
+                       ret = NT_STATUS_UNSUCCESSFUL;
+                       goto done;
+               }
+
+               fstrcpy(objname, gums_get_object_name(domain_object));
+               fstrcat(objname, "\\");
+               fstrcat(objname, gums_get_object_name(object));
+       }
+
+       ret = NT_STATUS_OK;
+
+done:
+       return ret;
+}
+
+/* name should be in DOMAIN\NAME format */
+static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const char *fullname)
 {
 
        NTSTATUS ret = NT_STATUS_OK;
@@ -277,14 +397,15 @@ static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const ch
        fstring sidstr;
        int sidstr_len;
 
-       if (!obj || !name)
+       if (!obj || !fullname)
                return NT_STATUS_INVALID_PARAMETER;
 
        /* Data is stored in all lower-case */
-       fstrcpy(objname, name);
+       fstrcpy(objname, fullname);
        strlower_m(objname);
 
        slprintf(keystr, sizeof(keystr)-1, "%s%s", NAMEPREFIX, objname);
+
        key.dptr = keystr;
        key.dsize = strlen(keystr) + 1;
 
@@ -320,13 +441,52 @@ done:
        return ret;
 }
 
-/* store a tdbsam2_object
+/* Get object's sequence number */
+
+static NTSTATUS get_object_seq_num(TDB_CONTEXT *tdb, GUMS_OBJECT *object, int *seq_num)
+{
+
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+       TDB_DATA data, key;
+       fstring keystr;
+       fstring sidstr;
+       int version, type, seqnum;
+
+       if (!object || !seq_num)
+               return NT_STATUS_INVALID_PARAMETER;
+
+       fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object)));
+       slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sidstr);
+
+       key.dptr = keystr;
+       key.dsize = strlen(keystr) + 1;
+
+       data = tdb_fetch(tdb, key);
+       if (!data.dptr) {
+               DEBUG(5, ("get_object_seq_num: 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 (tdb_unpack (data.dptr, data.dsize, TDB_BASIC_OBJ_STRING, &version, &type, &seqnum) == -1)
+               goto done;
+
+       *seq_num = seqnum;
+       ret = NT_STATUS_OK;
+
+done:
+       SAFE_FREE(data.dptr);
+       return ret;
+}
+
+/* store a gums object
  * flag: TDB_REPLACE or TDB_MODIFY or TDB_INSERT
  */
 
-static NTSTATUS store_object(TDB_CONTEXT *tdb, const GUMS_OBJECT *object, int flag)
+static NTSTATUS store_object(TDB_CONTEXT *tdb, GUMS_OBJECT *object, int flag)
 {
-
        NTSTATUS ret = NT_STATUS_OK;
        TDB_DATA data, data2, key, key2;
        TALLOC_CTX *mem_ctx;
@@ -346,308 +506,65 @@ static NTSTATUS store_object(TDB_CONTEXT *tdb, const GUMS_OBJECT *object, int fl
                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;
-       }
+       make_full_object_name(tdb, objname, object);
 
        /* 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;
+       if (flag == TDB_MODIFY) {
+               if (!NT_STATUS_IS_OK(ret = get_object_seq_num(tdb, object, &(object->seq_num))))
                        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;
+               object->seq_num += 1;
        }
 
-       /* 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;
-}
+       if (!NT_STATUS_IS_OK(ret = init_buffer_from_object(&(data.dptr), &(data.dsize), mem_ctx, object)))
+               goto done;
 
-static NTSTATUS data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_object *data)
-{
+       fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object)));
+       slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sidstr);
+       slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, objname);
 
-       NTSTATUS ret;
+       key.dptr = keystr;
+       key.dsize = strlen(keystr) + 1;
 
-       if (!object || !data) {
-               DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL structure pointers are accepted here!\n"));
-               ret = NT_STATUS_INVALID_PARAMETER;
+       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;
        }
 
-       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"));
+       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;
        }
 
-       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;
-       }
+/* TODO: update the general database counter */
+/* TODO: update this entry counter too */
 
 done:
+       talloc_destroy(mem_ctx);
        return ret;
 }
-#endif
 
 /* GUMM object functions */
 
@@ -788,26 +705,18 @@ static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj
                goto done;
        }
 
-       if (obj_type != GUMS_OBJ_PRIVILEGE) {
-               if (!sid) {
-                       ret = NT_STATUS_INVALID_PARAMETER;
+       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;
-               }
-
-               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_sid(go, sid);
        gums_set_object_name(go, name);
        gums_set_object_seq_num(go, 1);
 
-       /*obj.data.domain->sec_desc*/
+       /*obj.domain->sec_desc*/
 
        switch (obj_type) {
                case GUMS_OBJ_NORMAL_USER:
@@ -829,7 +738,6 @@ static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj
                        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);
@@ -846,10 +754,6 @@ static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj
 
                        break;  
 
-               case GUMS_OBJ_PRIVILEGE:
-
-                       break;
-
                default:
                        ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
                        goto done;
@@ -864,6 +768,8 @@ done:
        return ret;
 }
 
+/* TODO: handle privileges objects */
+
 static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid)
 {
        /* TODO: need to address privilege deletion */
@@ -882,7 +788,7 @@ static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid)
                return ret;
        }
 
-       slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sid_string_static(sid));
+       slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sid_string_static(sid));
        key.dptr = keystr;
        key.dsize = strlen(keystr) + 1;
 
@@ -909,18 +815,7 @@ static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid)
                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;
-       }
+       slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, gums_get_object_name(go));
 
        key.dptr = keystr;
        key.dsize = strlen(keystr) + 1;
@@ -956,10 +851,14 @@ static NTSTATUS tdbsam2_get_object_from_sid(GUMS_OBJECT **object, const DOM_SID
        }
 
        ret = get_object_by_sid(tdb, object, sid);
-       if (!NT_STATUS_IS_OK(ret) || (obj_type && gums_get_object_type(*object) != obj_type)) {
+       if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(0, ("tdbsam2_get_object_from_sid: %s\n", nt_errstr(ret)));
                goto error;
        }
+       if (obj_type && gums_get_object_type(*object) != obj_type) {
+               DEBUG(0, ("tdbsam2_get_object_from_sid: the object is not of the rerquested type!\n"));
+               goto error;
+       }
 
        tdb_close(tdb);
        return NT_STATUS_OK;    
@@ -970,10 +869,11 @@ error:
        return ret;
 }
 
-static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *name, const int obj_type)
+static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *domain, const char *name, const int obj_type)
 {
        NTSTATUS ret;
        TDB_CONTEXT *tdb;
+       fstring objname;
 
        if (!object || !name) {
                DEBUG(0, ("tdbsam2_get_object_from_name: no NULL pointers are accepted here!\n"));
@@ -984,12 +884,27 @@ static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *n
                return ret;
        }
 
+       if (obj_type == GUMS_OBJ_DOMAIN) {
+               fstrcpy(objname, name);
+       } else {
+               if (!domain) {
+                       domain = global_myname();
+               }
+               fstrcpy(objname, domain);
+               fstrcat(objname, "\\");
+               fstrcat(objname, name);
+       }
+
        *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)) {
+       if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(0, ("tdbsam2_get_object_from_name: %s\n", nt_errstr(ret)));
                goto error;
        }
+       if (obj_type && gums_get_object_type(*object) != obj_type) {
+               DEBUG(0, ("tdbsam2_get_object_from_name: the object is not of the rerquested type!\n"));
+               goto error;
+       }
 
        tdb_close(tdb);
        return NT_STATUS_OK;
@@ -1072,7 +987,7 @@ static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *h
        }       
 
        while ((teo->key.dptr != NULL)) {
-               int len, version, type, size;
+               int len, version, type, size, seqnum;
                char *ptr;
 
                if (strncmp(teo->key.dptr, prefix, preflen)) {
@@ -1099,6 +1014,7 @@ static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *h
                len = tdb_unpack (data.dptr, data.dsize, TDB_FORMAT_STRING,
                          &version,
                          &type,
+                         &seqnum,
                          &size, &ptr);
 
                if (len == -1) {
@@ -1166,7 +1082,7 @@ static NTSTATUS tdbsam2_enumerate_objects_stop(void *handle)
        return NT_STATUS_OK;
 }
 
-static NTSTATUS tdbsam2_set_object(const GUMS_OBJECT *go)
+static NTSTATUS tdbsam2_set_object(GUMS_OBJECT *go)
 {
        NTSTATUS ret;
        TDB_CONTEXT *tdb;
@@ -1200,12 +1116,14 @@ 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);
+static NTSTATUS (*get_privilege) (GUMS_OBJECT **object, const char *name);
+static NTSTATUS (*add_members_to_privilege) (const char *name, const DOM_SID **members);
+static NTSTATUS (*delete_members_from_privilege) (const char *name, const DOM_SID **members);
+static NTSTATUS (*enumerate_privilege_members) (const char *name, DOM_SID **members);
+static NTSTATUS (*get_sid_privileges) (const DOM_SID *sid, const char **privs);
+
        /* warning!: set_privilege will overwrite a prior existing privilege if such exist */
-static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv);
+static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv);
 #endif
 
 static void free_tdbsam2_private_data(void **vp) 
@@ -1243,6 +1161,7 @@ static NTSTATUS init_tdbsam2(GUMS_FUNCTIONS *fns, const char *storage)
        fns->get_sid_groups = tdbsam2_get_sid_groups;
        fns->lock_sid = tdbsam2_lock_sid;
        fns->unlock_sid = tdbsam2_unlock_sid;
+       fns->get_privilege = tdbsam2_get_privilege;
        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;
@@ -1280,7 +1199,7 @@ static NTSTATUS init_tdbsam2(GUMS_FUNCTIONS *fns, const char *storage)
                        gums_init_builtin_domain();
                }
 
-               gums_init_domain(get_global_sam_sid(), global_myname());
+               gums_init_domain(get_global_sam_sid(), global_myname(), "The Domain");
        }
 
        fns->private_data = &ts2_privs;