Merge branch 'master' of ssh://git.samba.org/data/git/samba
authorJelmer Vernooij <jelmer@samba.org>
Tue, 11 Nov 2008 16:11:57 +0000 (17:11 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Tue, 11 Nov 2008 16:11:57 +0000 (17:11 +0100)
42 files changed:
libcli/util/ntstatus.h
librpc/idl/netlogon.idl
librpc/idl/samr.idl [moved from source3/librpc/idl/samr.idl with 99% similarity]
pidl/lib/Parse/Pidl/Samba4/Python.pm
source3/Makefile.in
source3/libnet/libnet_samsync_passdb.c
source3/librpc/gen_ndr/cli_samr.c
source3/librpc/gen_ndr/cli_samr.h
source3/librpc/gen_ndr/ndr_netlogon.c
source3/librpc/gen_ndr/ndr_samr.c
source3/librpc/gen_ndr/netlogon.h
source3/librpc/gen_ndr/samr.h
source3/librpc/gen_ndr/srv_samr.c
source3/libsmb/nterr.c
source3/rpc_server/srv_samr_nt.c
source3/winbindd/winbindd_rpc.c
source4/dsdb/common/util.c
source4/libcli/util/nterr.c
source4/libnet/groupinfo.c
source4/libnet/groupman.c
source4/libnet/libnet_domain.c
source4/libnet/libnet_group.c
source4/libnet/libnet_join.c
source4/libnet/libnet_passwd.c
source4/libnet/libnet_samsync_ldb.c
source4/libnet/libnet_user.c
source4/libnet/userinfo.c
source4/libnet/userman.c
source4/librpc/idl/samr.idl [deleted file]
source4/rpc_server/samr/dcesrv_samr.c
source4/rpc_server/samr/samr_password.c
source4/torture/libnet/libnet_domain.c
source4/torture/libnet/libnet_group.c
source4/torture/libnet/libnet_user.c
source4/torture/libnet/utils.c
source4/torture/rpc/samba3rpc.c
source4/torture/rpc/samr.c
source4/torture/rpc/samr_accessmask.c
source4/torture/rpc/samsync.c
source4/torture/rpc/schannel.c
source4/torture/rpc/testjoin.c
source4/winbind/wb_async_helpers.c

index fa4553df1e0b173540aa671bad346208b5aaa52d..139562d8c29b07e551515daba062f6556611b2c3 100644 (file)
@@ -592,6 +592,7 @@ typedef uint32_t NTSTATUS;
 #define NT_STATUS_TOO_MANY_LINKS NT_STATUS(0xC0000000 | 0x0265)
 #define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266)
 #define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267)
+#define NT_STATUS_DS_BUSY NT_STATUS(0xC0000000 | 0x02a5)
 #define NT_STATUS_DS_NO_MORE_RIDS NT_STATUS(0xC0000000 | 0x02a8)
 #define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275)
 #define NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED NT_STATUS(0xC0000000 | 0x02E9)
index 764958937f11c8dd3d7ac126342be68d9b7423df..e9b5170e9d3871765a05035db9b287bceeb2e3c1 100644 (file)
@@ -436,7 +436,7 @@ interface netlogon
                boolean8 lm_password_present;
                boolean8 password_expired;
                lsa_String comment;
-               lsa_String parameters;
+               lsa_BinaryString parameters;
                uint16 country_code;
                uint16 code_page;
                netr_USER_PRIVATE_INFO user_private_info;
similarity index 99%
rename from source3/librpc/idl/samr.idl
rename to librpc/idl/samr.idl
index f47e0994dc232a5588082ce538b3ad52c47348c8..ee179407d4e8c8230d223d3071e54caa831d7362 100644 (file)
@@ -417,7 +417,7 @@ import "misc.idl", "lsa.idl", "security.idl";
        /************************/
        /* Function    0x09     */
        /*
-         only levels 1, 3, 4, 6, 7, 9, 12 are valid for this 
+         only levels 1, 3, 4, 6, 7, 9, 12 are valid for this
          call in w2k3
        */
        NTSTATUS samr_SetDomainInfo(
@@ -436,14 +436,10 @@ import "misc.idl", "lsa.idl", "security.idl";
                [out,ref]     policy_handle *group_handle,
                [out,ref]     uint32 *rid
                );
-               
+
 
        /************************/
        /* Function    0x0b     */
-
-       const int MAX_SAM_ENTRIES_W2K = 0x400; /* 1024 */
-       const int MAX_SAM_ENTRIES_W95 = 50;
-
        NTSTATUS samr_EnumDomainGroups(
                [in]          policy_handle *domain_handle,
                [in,out,ref]  uint32 *resume_handle,
@@ -853,7 +849,7 @@ import "misc.idl", "lsa.idl", "security.idl";
        typedef struct {
                samr_AcctFlags acct_flags;
        } samr_UserInfo16;
-       
+
        typedef struct {
                NTTIME acct_expiry;
        } samr_UserInfo17;
@@ -1135,7 +1131,7 @@ import "misc.idl", "lsa.idl", "security.idl";
          this seems to be an alphabetic search function. The returned index
          is the index for samr_QueryDisplayInfo needed to get names occurring
          after the specified name. The supplied name does not need to exist
-         in the database (for example you can supply just a first letter for 
+         in the database (for example you can supply just a first letter for
          searching starting at that letter)
 
          The level corresponds to the samr_QueryDisplayInfo level
@@ -1330,7 +1326,7 @@ import "misc.idl", "lsa.idl", "security.idl";
        /************************/
        /* Function    0x3a     */
        /*
-         seems to be an exact alias for samr_SetUserInfo() 
+         seems to be an exact alias for samr_SetUserInfo()
        */
        [public] NTSTATUS samr_SetUserInfo2(
                [in,ref]                   policy_handle *user_handle,
@@ -1434,10 +1430,9 @@ import "misc.idl", "lsa.idl", "security.idl";
        NTSTATUS samr_RidToSid(
                [in,ref]    policy_handle *domain_handle,
                [in]        uint32        rid,
-               [out,ref]   dom_sid2      *sid
+               [out,ref]   dom_sid2      **sid
                );
 
-
        /************************/
        /* Function    0x42     */
 
index 38aee2c9d16cd1d30bacb14fac3a943918457a33..a3107d4672fcf61e5823e82906778dfb74954fdc 100644 (file)
@@ -702,7 +702,7 @@ sub Interface($$$)
                $self->pidl("if (!NT_STATUS_IS_OK(status)) {");
                $self->indent;
                $self->pidl("PyErr_SetNTSTATUS(status);");
-               $self->pidl("return;");
+               $self->pidl("return NULL;");
                $self->deindent;
                $self->pidl("}");
 
@@ -1181,7 +1181,6 @@ sub Parse($$$$$)
        $self->pidl("{");
        $self->indent;
        $self->pidl("PyObject *m;");
-       $self->pidl("NTSTATUS status;");
        $self->pidl("");
 
        foreach (@{$self->{ready_types}}) {
index be075ad6856589f2c3125ace6521a16a4310156a..c048e193a6103615a38d9a58876b0bf26e208b3d 100644 (file)
@@ -1225,7 +1225,7 @@ samba3-idl::
                ../librpc/idl/initshutdown.idl ../librpc/idl/srvsvc.idl ../librpc/idl/svcctl.idl \
                ../librpc/idl/eventlog.idl ../librpc/idl/wkssvc.idl ../librpc/idl/netlogon.idl \
                ../librpc/idl/notify.idl ../librpc/idl/epmapper.idl librpc/idl/messaging.idl \
-               ../librpc/idl/xattr.idl ../librpc/idl/misc.idl librpc/idl/samr.idl \
+               ../librpc/idl/xattr.idl ../librpc/idl/misc.idl ../librpc/idl/samr.idl \
                ../librpc/idl/security.idl ../librpc/idl/dssetup.idl ../librpc/idl/krb5pac.idl \
                ../librpc/idl/ntsvcs.idl librpc/idl/libnetapi.idl ../librpc/idl/drsuapi.idl \
                ../librpc/idl/drsblobs.idl ../librpc/idl/nbt.idl \
index 1faef7b3eb1064253d09566969afce520052da41..7ace77caceb8b640b3993ae91435ef13bdf07f6a 100644 (file)
@@ -118,12 +118,12 @@ static NTSTATUS sam_account_from_delta(struct samu *account,
                        pdb_set_profile_path(account, new_string, PDB_CHANGED);
        }
 
-       if (r->parameters.string) {
+       if (r->parameters.array) {
                DATA_BLOB mung;
                char *newstr;
                old_string = pdb_get_munged_dial(account);
-               mung.length = r->parameters.length;
-               mung.data = (uint8 *) r->parameters.string;
+               mung.length = r->parameters.length * 2;
+               mung.data = (uint8_t *) r->parameters.array;
                newstr = (mung.length == 0) ? NULL :
                        base64_encode_data_blob(talloc_tos(), mung);
 
index 179bd0007f0b4c84f993d8f09c471df3af0a7a3b..7edb790286d91acf18fdcb2fd1c7e44cd6a8e263 100644 (file)
@@ -2838,7 +2838,7 @@ NTSTATUS rpccli_samr_RidToSid(struct rpc_pipe_client *cli,
                              TALLOC_CTX *mem_ctx,
                              struct policy_handle *domain_handle /* [in] [ref] */,
                              uint32_t rid /* [in]  */,
-                             struct dom_sid2 *sid /* [out] [ref] */)
+                             struct dom_sid2 **sid /* [out] [ref] */)
 {
        struct samr_RidToSid r;
        NTSTATUS status;
index 7216d0cf3ded0b679925a92428272a3d56dcb86f..b57d63334e35723dc55d630aa73409974b5004b1 100644 (file)
@@ -375,7 +375,7 @@ NTSTATUS rpccli_samr_RidToSid(struct rpc_pipe_client *cli,
                              TALLOC_CTX *mem_ctx,
                              struct policy_handle *domain_handle /* [in] [ref] */,
                              uint32_t rid /* [in]  */,
-                             struct dom_sid2 *sid /* [out] [ref] */);
+                             struct dom_sid2 **sid /* [out] [ref] */);
 NTSTATUS rpccli_samr_SetDsrmPassword(struct rpc_pipe_client *cli,
                                     TALLOC_CTX *mem_ctx,
                                     struct lsa_String *name /* [in] [unique] */,
index 6575dbcb913ff290acf285154d187905783bd6a9..ac23c36a7c74580b442cc9394b8e5d9e1fc7da90 100644 (file)
@@ -2513,7 +2513,7 @@ static enum ndr_err_code ndr_push_netr_DELTA_USER(struct ndr_push *ndr, int ndr_
                NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->lm_password_present));
                NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->password_expired));
                NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS, &r->comment));
-               NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS, &r->parameters));
+               NDR_CHECK(ndr_push_lsa_BinaryString(ndr, NDR_SCALARS, &r->parameters));
                NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->country_code));
                NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->code_page));
                NDR_CHECK(ndr_push_netr_USER_PRIVATE_INFO(ndr, NDR_SCALARS, &r->user_private_info));
@@ -2540,7 +2540,7 @@ static enum ndr_err_code ndr_push_netr_DELTA_USER(struct ndr_push *ndr, int ndr_
                NDR_CHECK(ndr_push_samr_Password(ndr, NDR_BUFFERS, &r->lmpassword));
                NDR_CHECK(ndr_push_samr_Password(ndr, NDR_BUFFERS, &r->ntpassword));
                NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->comment));
-               NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->parameters));
+               NDR_CHECK(ndr_push_lsa_BinaryString(ndr, NDR_BUFFERS, &r->parameters));
                NDR_CHECK(ndr_push_netr_USER_PRIVATE_INFO(ndr, NDR_BUFFERS, &r->user_private_info));
                NDR_CHECK(ndr_push_sec_desc_buf(ndr, NDR_BUFFERS, &r->sdbuf));
                NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->profile_path));
@@ -2578,7 +2578,7 @@ static enum ndr_err_code ndr_pull_netr_DELTA_USER(struct ndr_pull *ndr, int ndr_
                NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->lm_password_present));
                NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->password_expired));
                NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS, &r->comment));
-               NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS, &r->parameters));
+               NDR_CHECK(ndr_pull_lsa_BinaryString(ndr, NDR_SCALARS, &r->parameters));
                NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->country_code));
                NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->code_page));
                NDR_CHECK(ndr_pull_netr_USER_PRIVATE_INFO(ndr, NDR_SCALARS, &r->user_private_info));
@@ -2605,7 +2605,7 @@ static enum ndr_err_code ndr_pull_netr_DELTA_USER(struct ndr_pull *ndr, int ndr_
                NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_BUFFERS, &r->lmpassword));
                NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_BUFFERS, &r->ntpassword));
                NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->comment));
-               NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->parameters));
+               NDR_CHECK(ndr_pull_lsa_BinaryString(ndr, NDR_BUFFERS, &r->parameters));
                NDR_CHECK(ndr_pull_netr_USER_PRIVATE_INFO(ndr, NDR_BUFFERS, &r->user_private_info));
                NDR_CHECK(ndr_pull_sec_desc_buf(ndr, NDR_BUFFERS, &r->sdbuf));
                NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->profile_path));
@@ -2643,7 +2643,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_USER(struct ndr_print *ndr, const char *name,
        ndr_print_uint8(ndr, "lm_password_present", r->lm_password_present);
        ndr_print_uint8(ndr, "password_expired", r->password_expired);
        ndr_print_lsa_String(ndr, "comment", &r->comment);
-       ndr_print_lsa_String(ndr, "parameters", &r->parameters);
+       ndr_print_lsa_BinaryString(ndr, "parameters", &r->parameters);
        ndr_print_uint16(ndr, "country_code", r->country_code);
        ndr_print_uint16(ndr, "code_page", r->code_page);
        ndr_print_netr_USER_PRIVATE_INFO(ndr, "user_private_info", &r->user_private_info);
index f83d0f0875540bb7eaeaf8fa9c9404d44a53ddab..e1b8fd17f9d7a726be821000aa15b05dd95cbf57 100644 (file)
@@ -11907,7 +11907,10 @@ static enum ndr_err_code ndr_push_samr_RidToSid(struct ndr_push *ndr, int flags,
                if (r->out.sid == NULL) {
                        return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
                }
-               NDR_CHECK(ndr_push_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid));
+               NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.sid));
+               if (*r->out.sid) {
+                       NDR_CHECK(ndr_push_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.sid));
+               }
                NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
        }
        return NDR_ERR_SUCCESS;
@@ -11915,8 +11918,10 @@ static enum ndr_err_code ndr_push_samr_RidToSid(struct ndr_push *ndr, int flags,
 
 static enum ndr_err_code ndr_pull_samr_RidToSid(struct ndr_pull *ndr, int flags, struct samr_RidToSid *r)
 {
+       uint32_t _ptr_sid;
        TALLOC_CTX *_mem_save_domain_handle_0;
        TALLOC_CTX *_mem_save_sid_0;
+       TALLOC_CTX *_mem_save_sid_1;
        if (flags & NDR_IN) {
                ZERO_STRUCT(r->out);
 
@@ -11937,7 +11942,18 @@ static enum ndr_err_code ndr_pull_samr_RidToSid(struct ndr_pull *ndr, int flags,
                }
                _mem_save_sid_0 = NDR_PULL_GET_MEM_CTX(ndr);
                NDR_PULL_SET_MEM_CTX(ndr, r->out.sid, LIBNDR_FLAG_REF_ALLOC);
-               NDR_CHECK(ndr_pull_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid));
+               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sid));
+               if (_ptr_sid) {
+                       NDR_PULL_ALLOC(ndr, *r->out.sid);
+               } else {
+                       *r->out.sid = NULL;
+               }
+               if (*r->out.sid) {
+                       _mem_save_sid_1 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, *r->out.sid, 0);
+                       NDR_CHECK(ndr_pull_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.sid));
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sid_1, 0);
+               }
                NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sid_0, LIBNDR_FLAG_REF_ALLOC);
                NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
        }
@@ -11966,7 +11982,12 @@ _PUBLIC_ void ndr_print_samr_RidToSid(struct ndr_print *ndr, const char *name, i
                ndr->depth++;
                ndr_print_ptr(ndr, "sid", r->out.sid);
                ndr->depth++;
-               ndr_print_dom_sid2(ndr, "sid", r->out.sid);
+               ndr_print_ptr(ndr, "sid", *r->out.sid);
+               ndr->depth++;
+               if (*r->out.sid) {
+                       ndr_print_dom_sid2(ndr, "sid", *r->out.sid);
+               }
+               ndr->depth--;
                ndr->depth--;
                ndr_print_NTSTATUS(ndr, "result", r->out.result);
                ndr->depth--;
index e1dc69cca03f02d51732c297f0336be1d8dbc8b7..51cca4083b47236c00073f530f5e8c3d0be5df93 100644 (file)
@@ -327,7 +327,7 @@ struct netr_DELTA_USER {
        uint8_t lm_password_present;
        uint8_t password_expired;
        struct lsa_String comment;
-       struct lsa_String parameters;
+       struct lsa_BinaryString parameters;
        uint16_t country_code;
        uint16_t code_page;
        struct netr_USER_PRIVATE_INFO user_private_info;
index 8c8f3f70f96df8f767e585e5880748d144cb00cf..d900c29d5e150b835895c9e0999194df7927ac28 100644 (file)
@@ -33,8 +33,6 @@
 #define GENERIC_RIGHTS_ALIAS_READ      ( (STANDARD_RIGHTS_READ_ACCESS|SAMR_ALIAS_ACCESS_GET_MEMBERS) )
 #define GENERIC_RIGHTS_ALIAS_WRITE     ( (STANDARD_RIGHTS_WRITE_ACCESS|SAMR_ALIAS_ACCESS_REMOVE_MEMBER|SAMR_ALIAS_ACCESS_ADD_MEMBER|SAMR_ALIAS_ACCESS_SET_INFO) )
 #define GENERIC_RIGHTS_ALIAS_EXECUTE   ( (STANDARD_RIGHTS_EXECUTE_ACCESS|SAMR_ALIAS_ACCESS_LOOKUP_INFO) )
-#define MAX_SAM_ENTRIES_W2K    ( 0x400 )
-#define MAX_SAM_ENTRIES_W95    ( 50 )
 #define SAMR_ENUM_USERS_MULTIPLIER     ( 54 )
 #define PASS_MUST_CHANGE_AT_NEXT_LOGON ( 0x01 )
 #define PASS_DONT_CHANGE_AT_NEXT_LOGON ( 0x00 )
@@ -1747,7 +1745,7 @@ struct samr_RidToSid {
        } in;
 
        struct {
-               struct dom_sid2 *sid;/* [ref] */
+               struct dom_sid2 **sid;/* [ref] */
                NTSTATUS result;
        } out;
 
index 3e3a1cc6c1fcedb6e097c31943e1c7807f58ec85..f4facd2914c32a54d35ac30c6311b4b87bb17c9c 100644 (file)
@@ -5202,7 +5202,7 @@ static bool api_samr_RidToSid(pipes_struct *p)
        }
 
        ZERO_STRUCT(r->out);
-       r->out.sid = talloc_zero(r, struct dom_sid2);
+       r->out.sid = talloc_zero(r, struct dom_sid2 *);
        if (r->out.sid == NULL) {
                talloc_free(r);
                return false;
index 1ba230cefeda060334695cc030675343a38780dc..465d88a9b6f4d99c425be6fa5057b91a79e98f61 100644 (file)
@@ -532,6 +532,7 @@ static const nt_err_code_struct nt_errs[] =
        { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS },
        { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT },
        { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE },
+       { "NT_STATUS_DS_BUSY", NT_STATUS_DS_BUSY },
        { "NT_STATUS_DS_NO_MORE_RIDS", NT_STATUS_DS_NO_MORE_RIDS },
        { "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT },
        { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED },
index c573173900929c3edf11ae91d150af2ccff54c8e..62ac1cb5c363ceef096426acdd4557a674a962cf 100644 (file)
@@ -45,6 +45,9 @@
 
 #define DISP_INFO_CACHE_TIMEOUT 10
 
+#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
+#define MAX_SAM_ENTRIES_W95 50
+
 typedef struct disp_info {
        DOM_SID sid; /* identify which domain this is. */
        bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
index d966e50159516560a162d0bd2616f0fdaf948f2a..7dea342a53af3004dc80f2c27c7cf9a125098e31 100644 (file)
@@ -636,6 +636,8 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
        return NT_STATUS_OK;
 }
 
+#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
+
 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
                                  TALLOC_CTX *mem_ctx,
                                  uint32 num_sids, const DOM_SID *sids,
index 69e456274c8ce756b0f8add96ff23835e59bf3e4..2161286e08c6816f90069b537c6ffd23abdeacf5 100644 (file)
@@ -657,6 +657,28 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
        return acct_flags;
 }
 
+struct lsa_BinaryString samdb_result_parameters(TALLOC_CTX *mem_ctx,
+                                               struct ldb_message *msg,
+                                               const char *attr)
+{
+       struct lsa_BinaryString s;
+       const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
+
+       ZERO_STRUCT(s);
+
+       if (!val) {
+               return s;
+       }
+
+       s.array = talloc_array(mem_ctx, uint16_t, val->length/2);
+       if (!s.array) {
+               return s;
+       }
+       s.length = s.size = val->length/2;
+       memcpy(s.array, val->data, val->length);
+
+       return s;
+}
 
 /* Find an attribute, with a particular value */
 
@@ -896,6 +918,17 @@ int samdb_msg_add_logon_hours(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
        return ldb_msg_add_value(msg, attr_name, &val, NULL);
 }
 
+/*
+  add a parameters element to a message
+*/
+int samdb_msg_add_parameters(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
+                            const char *attr_name, struct lsa_BinaryString *parameters)
+{
+       struct ldb_val val;
+       val.length = parameters->length * 2;
+       val.data = (uint8_t *)parameters->array;
+       return ldb_msg_add_value(msg, attr_name, &val, NULL);
+}
 /*
   add a general value element to a message
 */
index e95f0228c1d9fdae524e2149750abc3d4be07e3c..e94ed36d39779f73e94e47a0225e79b07aed97e7 100644 (file)
@@ -548,6 +548,7 @@ static const nt_err_code_struct nt_errs[] =
        { "NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED", NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED },
        { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND },
        { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED },
+       { "NT_STATUS_DS_BUSY", NT_STATUS_DS_BUSY },
        { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES },
        { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED },
        { "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP },
index 1da6646702836bd61fad3d58e9e93066793f381f..5c94c34b1dd8dfc1064622c22a117d06072afa4c 100644 (file)
@@ -83,8 +83,8 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
        if (s->monitor_fn) {
                msg.type = mon_SamrLookupName;
                msg_lookup = talloc(s, struct msg_rpc_lookup_name);
-               msg_lookup->rid = s->lookup.out.rids.ids;
-               msg_lookup->count = s->lookup.out.rids.count;
+               msg_lookup->rid = s->lookup.out.rids->ids;
+               msg_lookup->count = s->lookup.out.rids->count;
                msg.data = (void*)msg_lookup;
                msg.data_size = sizeof(*msg_lookup);
                
@@ -94,7 +94,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
 
        /* have we actually got name resolved
           - we're looking for only one at the moment */
-       if (s->lookup.out.rids.count == 0) {
+       if (s->lookup.out.rids->count == 0) {
                composite_error(c, NT_STATUS_NO_SUCH_USER);
        }
 
@@ -103,7 +103,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
        /* prepare parameters for LookupNames */
        s->opengroup.in.domain_handle   = &s->domain_handle;
        s->opengroup.in.access_mask     = SEC_FLAG_MAXIMUM_ALLOWED;
-       s->opengroup.in.rid             = s->lookup.out.rids.ids[0];
+       s->opengroup.in.rid             = s->lookup.out.rids->ids[0];
        s->opengroup.out.group_handle   = &s->group_handle;
 
        /* send request */
@@ -152,6 +152,8 @@ static void continue_groupinfo_opengroup(struct rpc_request *req)
        /* prepare parameters for QueryGroupInfo call */
        s->querygroupinfo.in.group_handle = &s->group_handle;
        s->querygroupinfo.in.level        = s->level;
+       s->querygroupinfo.out.info        = talloc(s, union samr_GroupInfo *);
+       if (composite_nomem(s->querygroupinfo.out.info, c)) return;
        
        /* queue rpc call, set event handling and new state */
        querygroup_req = dcerpc_samr_QueryGroupInfo_send(s->pipe, c, &s->querygroupinfo);
@@ -185,7 +187,7 @@ static void continue_groupinfo_getgroup(struct rpc_request *req)
                return;
        }
 
-       s->info = talloc_steal(s, s->querygroupinfo.out.info);
+       s->info = talloc_steal(s, *s->querygroupinfo.out.info);
 
        /* issue a monitor message */
        if (s->monitor_fn) {
@@ -301,7 +303,11 @@ struct composite_context *libnet_rpc_groupinfo_send(struct dcerpc_pipe *p,
 
                s->lookup.in.names[0].string  = talloc_strdup(s, io->in.groupname);
                if (composite_nomem(s->lookup.in.names[0].string, c)) return c;
-               
+               s->lookup.out.rids         = talloc_zero(s, struct samr_Ids);
+               s->lookup.out.types        = talloc_zero(s, struct samr_Ids);
+               if (composite_nomem(s->lookup.out.rids, c)) return c;
+               if (composite_nomem(s->lookup.out.types, c)) return c;
+
                /* send request */
                lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookup);
                if (composite_nomem(lookup_req, c)) return c;
index 58d574233601928923144950f6bda0683e5e7eb6..4dfb2d8aabc3a2a071c7f09d5f64116200a0eae3 100644 (file)
@@ -174,6 +174,10 @@ struct composite_context* libnet_rpc_groupdel_send(struct dcerpc_pipe *p,
        s->lookupname.in.num_names     = 1;
        s->lookupname.in.names         = talloc_zero(s, struct lsa_String);
        s->lookupname.in.names->string = io->in.groupname;
+       s->lookupname.out.rids         = talloc_zero(s, struct samr_Ids);
+       s->lookupname.out.types        = talloc_zero(s, struct samr_Ids);
+       if (composite_nomem(s->lookupname.out.rids, c)) return c;
+       if (composite_nomem(s->lookupname.out.types, c)) return c;
 
        /* send the request */
        lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
@@ -205,12 +209,12 @@ static void continue_groupdel_name_found(struct rpc_request *req)
 
        /* what to do when there's no group account to delete
           and what if there's more than one rid resolved */
-       if (!s->lookupname.out.rids.count) {
+       if (!s->lookupname.out.rids->count) {
                c->status = NT_STATUS_NO_SUCH_GROUP;
                composite_error(c, c->status);
                return;
 
-       } else if (!s->lookupname.out.rids.count > 1) {
+       } else if (!s->lookupname.out.rids->count > 1) {
                c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
                composite_error(c, c->status);
                return;
@@ -218,7 +222,7 @@ static void continue_groupdel_name_found(struct rpc_request *req)
 
        /* prepare the arguments for rpc call */
        s->opengroup.in.domain_handle = &s->domain_handle;
-       s->opengroup.in.rid           = s->lookupname.out.rids.ids[0];
+       s->opengroup.in.rid           = s->lookupname.out.rids->ids[0];
        s->opengroup.in.access_mask   = SEC_FLAG_MAXIMUM_ALLOWED;
        s->opengroup.out.group_handle  = &s->group_handle;
 
index ccdfdaf13489bbe1df8f6fa74b61389168500814..eb6920d88ef62ac68c68a1ab58d5201e41b28110 100644 (file)
@@ -40,6 +40,7 @@ struct domain_open_samr_state {
        uint32_t                  access_mask;
        struct policy_handle      connect_handle;
        struct policy_handle      domain_handle;
+       struct dom_sid2           *domain_sid;
 
        /* information about the progress */
        void (*monitor_fn)(struct monitor_msg*);
@@ -159,6 +160,8 @@ static void continue_domain_open_connect(struct rpc_request *req)
        /* prepare for samr_LookupDomain call */
        r->in.connect_handle = &s->connect_handle;
        r->in.domain_name    = &s->domain_name;
+       r->out.sid           = talloc(s, struct dom_sid2 *);
+       if (composite_nomem(r->out.sid, c)) return;
 
        lookup_req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);
        if (composite_nomem(lookup_req, c)) return;
@@ -209,7 +212,7 @@ static void continue_domain_open_lookup(struct rpc_request *req)
        /* prepare for samr_OpenDomain call */
        r->in.connect_handle = &s->connect_handle;
        r->in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;
-       r->in.sid            = s->lookup.out.sid;
+       r->in.sid            = *s->lookup.out.sid;
        r->out.domain_handle = &s->domain_handle;
 
        opendom_req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);
@@ -361,7 +364,7 @@ NTSTATUS libnet_DomainOpenSamr_recv(struct composite_context *c, struct libnet_c
                   libnet functions */
                ctx->samr.connect_handle = s->connect_handle;
                ctx->samr.handle      = s->domain_handle;
-               ctx->samr.sid         = talloc_steal(ctx, s->lookup.out.sid);
+               ctx->samr.sid         = talloc_steal(ctx, *s->lookup.out.sid);
                ctx->samr.name        = talloc_steal(ctx, s->domain_name.string);
                ctx->samr.access_mask = s->access_mask;
        }
@@ -998,6 +1001,10 @@ static void continue_samr_connect(struct rpc_request *req)
        s->enumdom.in.resume_handle  = &s->resume_handle;
        s->enumdom.in.buf_size       = s->buf_size;
        s->enumdom.out.resume_handle = &s->resume_handle;
+       s->enumdom.out.num_entries   = talloc(s, uint32_t);
+       if (composite_nomem(s->enumdom.out.num_entries, c)) return;
+       s->enumdom.out.sam           = talloc(s, struct samr_SamArray *);
+       if (composite_nomem(s->enumdom.out.sam, c)) return;
 
        enumdom_req = dcerpc_samr_EnumDomains_send(s->ctx->samr.pipe, c, &s->enumdom);
        if (composite_nomem(enumdom_req, c)) return;
@@ -1113,16 +1120,16 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis
        /* prepare domains array */
        if (s->domains == NULL) {
                s->domains = talloc_array(mem_ctx, struct domainlist,
-                                         s->enumdom.out.num_entries);
+                                         *s->enumdom.out.num_entries);
        } else {
                s->domains = talloc_realloc(mem_ctx, s->domains, struct domainlist,
-                                           s->count + s->enumdom.out.num_entries);
+                                           s->count + *s->enumdom.out.num_entries);
        }
 
        /* copy domain names returned from samr_EnumDomains call */
-       for (i = s->count; i < s->count + s->enumdom.out.num_entries; i++)
+       for (i = s->count; i < s->count + *s->enumdom.out.num_entries; i++)
        {
-               struct lsa_String *domain_name = &s->enumdom.out.sam->entries[i - s->count].name;
+               struct lsa_String *domain_name = &(*s->enumdom.out.sam)->entries[i - s->count].name;
 
                /* strdup name as a child of allocated array to make it follow the array
                   in case of talloc_steal or talloc_free */
@@ -1131,7 +1138,7 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis
        }
 
        /* number of entries returned (domains enumerated) */
-       s->count += s->enumdom.out.num_entries;
+       s->count += *s->enumdom.out.num_entries;
        
        return s->domains;
 }
index eded3785110aae555144d76e8180ad0393909a46..af5fe4d5d375ed18d9f16ad2746e73766f002f7b 100644 (file)
@@ -518,6 +518,10 @@ static void continue_domain_queried(struct rpc_request *req)
        s->group_list.in.max_size       = s->page_size;
        s->group_list.in.resume_handle  = &s->resume_index;
        s->group_list.out.resume_handle = &s->resume_index;
+       s->group_list.out.num_entries   = talloc(s, uint32_t);
+       if (composite_nomem(s->group_list.out.num_entries, c)) return;
+       s->group_list.out.sam           = talloc(s, struct samr_SamArray *);
+       if (composite_nomem(s->group_list.out.sam, c)) return;
 
        /* send the request */
        enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list);
@@ -549,6 +553,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx)
        s->group_list.in.max_size       = s->page_size;
        s->group_list.in.resume_handle  = &s->resume_index;
        s->group_list.out.resume_handle = &s->resume_index;
+       s->group_list.out.num_entries   = talloc(s, uint32_t);
+       if (composite_nomem(s->group_list.out.num_entries, c)) return;
+       s->group_list.out.sam           = talloc(s, struct samr_SamArray *);
+       if (composite_nomem(s->group_list.out.sam, c)) return;
 
        /* send the request */
        enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list);
@@ -587,15 +595,15 @@ static void continue_groups_enumerated(struct rpc_request *req)
                /* get enumerated accounts counter and resume handle (the latter allows
                   making subsequent call to continue enumeration) */
                s->resume_index = *s->group_list.out.resume_handle;
-               s->count        = s->group_list.out.num_entries;
+               s->count        = *s->group_list.out.num_entries;
 
                /* prepare returned group accounts array */
-               s->groups       = talloc_array(c, struct grouplist, s->group_list.out.sam->count);
+               s->groups       = talloc_array(c, struct grouplist, (*s->group_list.out.sam)->count);
                if (composite_nomem(s->groups, c)) return;
 
-               for (i = 0; i < s->group_list.out.sam->count; i++) {
+               for (i = 0; i < (*s->group_list.out.sam)->count; i++) {
                        struct dom_sid *group_sid;
-                       struct samr_SamEntry *entry = &s->group_list.out.sam->entries[i];
+                       struct samr_SamEntry *entry = &(*s->group_list.out.sam)->entries[i];
                        struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid;
                        
                        /* construct group sid from returned rid and queried domain sid */
index 0ed5e8ae2623b9d44e8045aa515314f472079829..70fcb4a894eac46bc86a1a6208f27c2fe2b0daf6 100644 (file)
@@ -444,13 +444,16 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        struct samr_OpenDomain od;
        struct policy_handle d_handle;
        struct samr_LookupNames ln;
+       struct samr_Ids rids, types;
        struct samr_OpenUser ou;
        struct samr_CreateUser2 cu;
        struct policy_handle *u_handle = NULL;
        struct samr_QueryUserInfo qui;
+       union samr_UserInfo *uinfo;
        struct samr_UserInfo21 u_info21;
        union libnet_SetPassword r2;
        struct samr_GetUserPwInfo pwp;
+       struct samr_PwInfo info;
        struct lsa_String samr_account_name;
        
        uint32_t acct_flags, old_acct_flags;
@@ -559,9 +562,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        if (!connect_with_info->out.domain_sid) {
                struct lsa_String name;
                struct samr_LookupDomain l;
+               struct dom_sid2 *sid = NULL;
                name.string = connect_with_info->out.domain_name;
                l.in.connect_handle = &p_handle;
                l.in.domain_name = &name;
+               l.out.sid = &sid;
                
                status = dcerpc_samr_LookupDomain(samr_pipe, tmp_ctx, &l);
                if (!NT_STATUS_IS_OK(status)) {
@@ -571,7 +576,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                        talloc_free(tmp_ctx);
                        return status;
                }
-               connect_with_info->out.domain_sid = l.out.sid;
+               connect_with_info->out.domain_sid = *l.out.sid;
        }
 
        /* prepare samr_OpenDomain */
@@ -611,6 +616,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                ln.in.domain_handle = &d_handle;
                ln.in.num_names = 1;
                ln.in.names = talloc_array(tmp_ctx, struct lsa_String, 1);
+               ln.out.rids = &rids;
+               ln.out.types = &types;
                if (!ln.in.names) {
                        r->out.error_string = NULL;
                        talloc_free(tmp_ctx);
@@ -630,10 +637,10 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                }
                
                /* check if we got one RID for the user */
-               if (ln.out.rids.count != 1) {
+               if (ln.out.rids->count != 1) {
                        r->out.error_string = talloc_asprintf(mem_ctx,
                                                              "samr_LookupNames for [%s] returns %d RIDs",
-                                                             r->in.account_name, ln.out.rids.count);
+                                                             r->in.account_name, ln.out.rids->count);
                        talloc_free(tmp_ctx);
                        return NT_STATUS_INVALID_PARAMETER;
                }
@@ -642,7 +649,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                ZERO_STRUCTP(u_handle);
                ou.in.domain_handle = &d_handle;
                ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-               ou.in.rid = ln.out.rids.ids[0];
+               ou.in.rid = ln.out.rids->ids[0];
                rid = ou.in.rid;
                ou.out.user_handle = u_handle;
                
@@ -694,6 +701,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
        /* prepare samr_QueryUserInfo (get flags) */
        qui.in.user_handle = u_handle;
        qui.in.level = 16;
+       qui.out.info = &uinfo;
        
        status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
        if (!NT_STATUS_IS_OK(status)) {
@@ -705,7 +713,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                return status;
        }
        
-       if (!qui.out.info) {
+       if (!uinfo) {
                status = NT_STATUS_INVALID_PARAMETER;
                r->out.error_string
                        = talloc_asprintf(mem_ctx,
@@ -715,7 +723,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                return status;
        }
 
-       old_acct_flags = (qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
+       old_acct_flags = (uinfo->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
        /* Possibly bail if the account is of the wrong type */
        if (old_acct_flags
            != r->in.acct_type) {
@@ -771,17 +779,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
                        return NT_STATUS_USER_EXISTS;
                }
        } else {
-               acct_flags = qui.out.info->info16.acct_flags;
+               acct_flags = uinfo->info16.acct_flags;
        }
        
        acct_flags = (acct_flags & ~(ACB_DISABLED|ACB_PWNOTREQ));
 
        /* Find out what password policy this user has */
        pwp.in.user_handle = u_handle;
+       pwp.out.info = &info;
 
        status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp);                           
        if (NT_STATUS_IS_OK(status)) {
-               policy_min_pw_len = pwp.out.info.min_password_length;
+               policy_min_pw_len = pwp.out.info->min_password_length;
        }
        
        /* Grab a password of that minimum length */
index de2ed01abd8690218f32052e4eb6c26b92fb5968..976606e72cf5f7cd3ef574fcdb02ed39ab9ae170 100644 (file)
@@ -50,6 +50,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
        struct samr_Password nt_verifier, lm_verifier;
        uint8_t old_nt_hash[16], new_nt_hash[16];
        uint8_t old_lm_hash[16], new_lm_hash[16];
+       struct samr_DomInfo1 *dominfo = NULL;
+       struct samr_ChangeReject *reject = NULL;
 
        /* prepare connect to the SAMR pipe of the users domain PDC */
        c.level                    = LIBNET_RPC_CONNECT_PDC;
@@ -92,6 +94,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
        pw3.in.lm_password = &lm_pass;
        pw3.in.lm_verifier = &lm_verifier;
        pw3.in.password3 = NULL;
+       pw3.out.dominfo = &dominfo;
+       pw3.out.reject = &reject;
 
        /* 2. try samr_ChangePasswordUser3 */
        status = dcerpc_samr_ChangePasswordUser3(c.out.dcerpc_pipe, mem_ctx, &pw3);
@@ -527,10 +531,12 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        struct samr_Connect sc;
        struct policy_handle p_handle;
        struct samr_LookupDomain ld;
+       struct dom_sid2 *sid = NULL;
        struct lsa_String d_name;
        struct samr_OpenDomain od;
        struct policy_handle d_handle;
        struct samr_LookupNames ln;
+       struct samr_Ids rids, types;
        struct samr_OpenUser ou;
        struct policy_handle u_handle;
        union libnet_SetPassword r2;
@@ -568,6 +574,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        d_name.string = r->samr.in.domain_name;
        ld.in.connect_handle = &p_handle;
        ld.in.domain_name = &d_name;
+       ld.out.sid = &sid;
 
        /* 3. do a samr_LookupDomain to get the domain sid */
        status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld);
@@ -582,7 +589,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        ZERO_STRUCT(d_handle);
        od.in.connect_handle = &p_handle;
        od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       od.in.sid = ld.out.sid;
+       od.in.sid = *ld.out.sid;
        od.out.domain_handle = &d_handle;
 
        /* 4. do a samr_OpenDomain to get a domain handle */
@@ -598,6 +605,8 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        ln.in.domain_handle = &d_handle;
        ln.in.num_names = 1;
        ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
+       ln.out.rids = &rids;
+       ln.out.types = &types;
        if (!ln.in.names) {
                r->samr.out.error_string = "Out of Memory";
                return NT_STATUS_NO_MEMORY;
@@ -614,10 +623,10 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        }
 
        /* check if we got one RID for the user */
-       if (ln.out.rids.count != 1) {
+       if (ln.out.rids->count != 1) {
                r->samr.out.error_string = talloc_asprintf(mem_ctx,
                                                "samr_LookupNames for [%s] returns %d RIDs",
-                                               r->samr.in.account_name, ln.out.rids.count);
+                                               r->samr.in.account_name, ln.out.rids->count);
                status = NT_STATUS_INVALID_PARAMETER;
                goto disconnect;        
        }
@@ -626,7 +635,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
        ZERO_STRUCT(u_handle);
        ou.in.domain_handle = &d_handle;
        ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       ou.in.rid = ln.out.rids.ids[0];
+       ou.in.rid = ln.out.rids->ids[0];
        ou.out.user_handle = &u_handle;
 
        /* 6. do a samr_OpenUser to get a user handle */
index 8b7dd1f59891beec4fc29007c5d04f79ee04b87a..160b4b3e19c893a3f06a50ac1656ace32701c634 100644 (file)
@@ -384,7 +384,11 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
        }
            
        ADD_OR_DEL(string, "comment", comment.string);
-       ADD_OR_DEL(string, "userParameters", parameters.string);
+
+       if (samdb_msg_add_parameters(state->sam_ldb, mem_ctx, msg, "userParameters", &user->parameters) != 0) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        ADD_OR_DEL(uint, "countryCode", country_code);
        ADD_OR_DEL(uint, "codePage", code_page);
 
index c76831945218211dbbe591520850a4c7be6b4192..8606d0856e20cc73fc29faa7d79078a48db04d88 100644 (file)
@@ -1032,6 +1032,10 @@ static void continue_domain_queried(struct rpc_request *req)
        s->user_list.in.resume_handle = &s->resume_index;
        s->user_list.in.acct_flags = ACB_NORMAL;
        s->user_list.out.resume_handle = &s->resume_index;
+       s->user_list.out.num_entries = talloc(s, uint32_t);
+       if (composite_nomem(s->user_list.out.num_entries, c)) return;
+       s->user_list.out.sam = talloc(s, struct samr_SamArray *);
+       if (composite_nomem(s->user_list.out.sam, c)) return;
 
        /* send the request */
        enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);
@@ -1064,6 +1068,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx)
        s->user_list.in.resume_handle = &s->resume_index;
        s->user_list.in.acct_flags = ACB_NORMAL;
        s->user_list.out.resume_handle = &s->resume_index;
+       s->user_list.out.sam = talloc(s, struct samr_SamArray *);
+       if (composite_nomem(s->user_list.out.sam, c)) return;
+       s->user_list.out.num_entries = talloc(s, uint32_t);
+       if (composite_nomem(s->user_list.out.num_entries, c)) return;
        
        /* send the request */
        enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);
@@ -1102,15 +1110,15 @@ static void continue_users_enumerated(struct rpc_request *req)
                /* get enumerated accounts counter and resume handle (the latter allows
                   making subsequent call to continue enumeration) */
                s->resume_index = *s->user_list.out.resume_handle;
-               s->count        = s->user_list.out.num_entries;
+               s->count        = *s->user_list.out.num_entries;
                
                /* prepare returned user accounts array */
-               s->users        = talloc_array(c, struct userlist, s->user_list.out.sam->count);
+               s->users        = talloc_array(c, struct userlist, (*s->user_list.out.sam)->count);
                if (composite_nomem(s->users, c)) return;
 
-               for (i = 0; i < s->user_list.out.sam->count; i++) {
+               for (i = 0; i < (*s->user_list.out.sam)->count; i++) {
                        struct dom_sid *user_sid;
-                       struct samr_SamEntry *entry = &s->user_list.out.sam->entries[i];
+                       struct samr_SamEntry *entry = &(*s->user_list.out.sam)->entries[i];
                        struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid;
                        
                        /* construct user sid from returned rid and queried domain sid */
index e8b6b090c7c8ef3a50ca1633fcb8b74bf0c6cc7d..710154d41e195eddd5e3983dbdeb0725d19227c1 100644 (file)
@@ -82,8 +82,8 @@ static void continue_userinfo_lookup(struct rpc_request *req)
        if (s->monitor_fn) {
                msg.type = mon_SamrLookupName;
                msg_lookup = talloc(s, struct msg_rpc_lookup_name);
-               msg_lookup->rid = s->lookup.out.rids.ids;
-               msg_lookup->count = s->lookup.out.rids.count;
+               msg_lookup->rid = s->lookup.out.rids->ids;
+               msg_lookup->count = s->lookup.out.rids->count;
                msg.data = (void*)msg_lookup;
                msg.data_size = sizeof(*msg_lookup);
                
@@ -93,7 +93,7 @@ static void continue_userinfo_lookup(struct rpc_request *req)
 
        /* have we actually got name resolved
           - we're looking for only one at the moment */
-       if (s->lookup.out.rids.count == 0) {
+       if (s->lookup.out.rids->count == 0) {
                composite_error(c, NT_STATUS_NO_SUCH_USER);
        }
 
@@ -102,7 +102,7 @@ static void continue_userinfo_lookup(struct rpc_request *req)
        /* prepare parameters for LookupNames */
        s->openuser.in.domain_handle  = &s->domain_handle;
        s->openuser.in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;
-       s->openuser.in.rid            = s->lookup.out.rids.ids[0];
+       s->openuser.in.rid            = s->lookup.out.rids->ids[0];
        s->openuser.out.user_handle   = &s->user_handle;
 
        /* send request */
@@ -151,6 +151,8 @@ static void continue_userinfo_openuser(struct rpc_request *req)
        /* prepare parameters for QueryUserInfo call */
        s->queryuserinfo.in.user_handle = &s->user_handle;
        s->queryuserinfo.in.level       = s->level;
+       s->queryuserinfo.out.info       = talloc(s, union samr_UserInfo *);
+       if (composite_nomem(s->queryuserinfo.out.info, c)) return;
        
        /* queue rpc call, set event handling and new state */
        queryuser_req = dcerpc_samr_QueryUserInfo_send(s->pipe, c, &s->queryuserinfo);
@@ -184,7 +186,7 @@ static void continue_userinfo_getuser(struct rpc_request *req)
                return;
        }
 
-       s->info = talloc_steal(s, s->queryuserinfo.out.info);
+       s->info = talloc_steal(s, *(s->queryuserinfo.out.info));
 
        /* issue a monitor message */
        if (s->monitor_fn) {
@@ -297,6 +299,10 @@ struct composite_context *libnet_rpc_userinfo_send(struct dcerpc_pipe *p,
                s->lookup.in.num_names        = 1;
                s->lookup.in.names            = talloc_array(s, struct lsa_String, 1);
                if (composite_nomem(s->lookup.in.names, c)) return c;
+               s->lookup.out.rids         = talloc_zero(s, struct samr_Ids);
+               s->lookup.out.types        = talloc_zero(s, struct samr_Ids);
+               if (composite_nomem(s->lookup.out.rids, c)) return c;
+               if (composite_nomem(s->lookup.out.types, c)) return c;
 
                s->lookup.in.names[0].string  = talloc_strdup(s, io->in.username);
                if (composite_nomem(s->lookup.in.names[0].string, c)) return c;
index 398d9f2cb044eca244dc8ce2d0c6dd7543d04e0d..c638d8af32115aaf2c7baeb6e07b409e4c88c03e 100644 (file)
@@ -236,12 +236,12 @@ static void continue_userdel_name_found(struct rpc_request *req)
 
        /* what to do when there's no user account to delete
           and what if there's more than one rid resolved */
-       if (!s->lookupname.out.rids.count) {
+       if (!s->lookupname.out.rids->count) {
                c->status = NT_STATUS_NO_SUCH_USER;
                composite_error(c, c->status);
                return;
 
-       } else if (!s->lookupname.out.rids.count > 1) {
+       } else if (!s->lookupname.out.rids->count > 1) {
                c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
                composite_error(c, c->status);
                return;
@@ -251,8 +251,8 @@ static void continue_userdel_name_found(struct rpc_request *req)
        if (s->monitor_fn) {
                struct msg_rpc_lookup_name msg_lookup;
 
-               msg_lookup.rid   = s->lookupname.out.rids.ids;
-               msg_lookup.count = s->lookupname.out.rids.count;
+               msg_lookup.rid   = s->lookupname.out.rids->ids;
+               msg_lookup.count = s->lookupname.out.rids->count;
 
                msg.type      = mon_SamrLookupName;
                msg.data      = (void*)&msg_lookup;
@@ -262,7 +262,7 @@ static void continue_userdel_name_found(struct rpc_request *req)
 
        /* prepare the arguments for rpc call */
        s->openuser.in.domain_handle = &s->domain_handle;
-       s->openuser.in.rid           = s->lookupname.out.rids.ids[0];
+       s->openuser.in.rid           = s->lookupname.out.rids->ids[0];
        s->openuser.in.access_mask   = SEC_FLAG_MAXIMUM_ALLOWED;
        s->openuser.out.user_handle  = &s->user_handle;
 
@@ -393,6 +393,10 @@ struct composite_context *libnet_rpc_userdel_send(struct dcerpc_pipe *p,
        s->lookupname.in.num_names     = 1;
        s->lookupname.in.names         = talloc_zero(s, struct lsa_String);
        s->lookupname.in.names->string = io->in.username;
+       s->lookupname.out.rids         = talloc_zero(s, struct samr_Ids);
+       s->lookupname.out.types        = talloc_zero(s, struct samr_Ids);
+       if (composite_nomem(s->lookupname.out.rids, c)) return c;
+       if (composite_nomem(s->lookupname.out.types, c)) return c;
 
        /* send the request */
        lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
@@ -500,12 +504,12 @@ static void continue_usermod_name_found(struct rpc_request *req)
 
        /* what to do when there's no user account to delete
           and what if there's more than one rid resolved */
-       if (!s->lookupname.out.rids.count) {
+       if (!s->lookupname.out.rids->count) {
                c->status = NT_STATUS_NO_SUCH_USER;
                composite_error(c, c->status);
                return;
 
-       } else if (!s->lookupname.out.rids.count > 1) {
+       } else if (!s->lookupname.out.rids->count > 1) {
                c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
                composite_error(c, c->status);
                return;
@@ -515,8 +519,8 @@ static void continue_usermod_name_found(struct rpc_request *req)
        if (s->monitor_fn) {
                struct msg_rpc_lookup_name msg_lookup;
 
-               msg_lookup.rid   = s->lookupname.out.rids.ids;
-               msg_lookup.count = s->lookupname.out.rids.count;
+               msg_lookup.rid   = s->lookupname.out.rids->ids;
+               msg_lookup.count = s->lookupname.out.rids->count;
 
                msg.type      = mon_SamrLookupName;
                msg.data      = (void*)&msg_lookup;
@@ -526,7 +530,7 @@ static void continue_usermod_name_found(struct rpc_request *req)
 
        /* prepare the next rpc call */
        s->openuser.in.domain_handle = &s->domain_handle;
-       s->openuser.in.rid           = s->lookupname.out.rids.ids[0];
+       s->openuser.in.rid           = s->lookupname.out.rids->ids[0];
        s->openuser.in.access_mask   = SEC_FLAG_MAXIMUM_ALLOWED;
        s->openuser.out.user_handle  = &s->user_handle;
 
@@ -679,6 +683,9 @@ static NTSTATUS usermod_change(struct composite_context *c,
        if (!do_set) {
                s->queryuser.in.user_handle = &s->user_handle;
                s->queryuser.in.level       = level;
+               s->queryuser.out.info       = talloc(s, union samr_UserInfo *);
+               if (composite_nomem(s->queryuser.out.info, c)) return;
+
 
                /* send query user info request to retrieve complete data of
                   a particular info level */
@@ -751,7 +758,7 @@ static void continue_usermod_user_queried(struct rpc_request *req)
 
        /* get returned user data and make a change (potentially one
           of many) */
-       s->info = *s->queryuser.out.info;
+       s->info = *(*s->queryuser.out.info);
 
        usermod_setfields(s, &level, i, true);
 
@@ -834,6 +841,10 @@ struct composite_context *libnet_rpc_usermod_send(struct dcerpc_pipe *p,
        s->lookupname.in.num_names     = 1;
        s->lookupname.in.names         = talloc_zero(s, struct lsa_String);
        s->lookupname.in.names->string = io->in.username;
+       s->lookupname.out.rids         = talloc_zero(s, struct samr_Ids);
+       s->lookupname.out.types        = talloc_zero(s, struct samr_Ids);
+       if (composite_nomem(s->lookupname.out.rids, c)) return c;
+       if (composite_nomem(s->lookupname.out.types, c)) return c;
 
        /* send the rpc request */
        lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl
deleted file mode 100644 (file)
index 47882df..0000000
+++ /dev/null
@@ -1,1424 +0,0 @@
-#include "idl_types.h"
-
-/*
-  samr interface definition
-*/
-import "misc.idl", "lsa.idl", "security.idl";
-
-/*
-  Thanks to Todd Sabin for some information from his samr.idl in acltools
-*/
-
-[ uuid("12345778-1234-abcd-ef00-0123456789ac"),
-  version(1.0),
-  endpoint("ncacn_np:[\\pipe\\samr]","ncacn_ip_tcp:", "ncalrpc:"),
-  pointer_default(unique)
-] interface samr
-{
-       typedef bitmap security_secinfo security_secinfo;
-
-       /* account control (acct_flags) bits */
-       typedef [public,bitmap32bit] bitmap {
-               ACB_DISABLED                    = 0x00000001,  /* 1 = User account disabled */
-               ACB_HOMDIRREQ                   = 0x00000002,  /* 1 = Home directory required */
-               ACB_PWNOTREQ                    = 0x00000004,  /* 1 = User password not required */
-               ACB_TEMPDUP                     = 0x00000008,  /* 1 = Temporary duplicate account */
-               ACB_NORMAL                      = 0x00000010,  /* 1 = Normal user account */
-               ACB_MNS                         = 0x00000020,  /* 1 = MNS logon user account */
-               ACB_DOMTRUST                    = 0x00000040,  /* 1 = Interdomain trust account */
-               ACB_WSTRUST                     = 0x00000080,  /* 1 = Workstation trust account */
-               ACB_SVRTRUST                    = 0x00000100,  /* 1 = Server trust account */
-               ACB_PWNOEXP                     = 0x00000200,  /* 1 = User password does not expire */
-               ACB_AUTOLOCK                    = 0x00000400,  /* 1 = Account auto locked */
-               ACB_ENC_TXT_PWD_ALLOWED         = 0x00000800,  /* 1 = Encryped text password is allowed */
-               ACB_SMARTCARD_REQUIRED          = 0x00001000,  /* 1 = Smart Card required */
-               ACB_TRUSTED_FOR_DELEGATION      = 0x00002000,  /* 1 = Trusted for Delegation */
-               ACB_NOT_DELEGATED               = 0x00004000,  /* 1 = Not delegated */
-               ACB_USE_DES_KEY_ONLY            = 0x00008000,  /* 1 = Use DES key only */
-               ACB_DONT_REQUIRE_PREAUTH        = 0x00010000,  /* 1 = Preauth not required */
-               ACB_PW_EXPIRED                  = 0x00020000,  /* 1 = Password Expired */
-               ACB_NO_AUTH_DATA_REQD           = 0x00080000   /* 1 = No authorization data required */
-       } samr_AcctFlags;
-
-       typedef [bitmap32bit] bitmap {
-               SAMR_ACCESS_CONNECT_TO_SERVER   = 0x00000001,
-               SAMR_ACCESS_SHUTDOWN_SERVER     = 0x00000002,
-               SAMR_ACCESS_INITIALIZE_SERVER   = 0x00000004,
-               SAMR_ACCESS_CREATE_DOMAIN       = 0x00000008,
-               SAMR_ACCESS_ENUM_DOMAINS        = 0x00000010,
-               SAMR_ACCESS_OPEN_DOMAIN         = 0x00000020
-       } samr_ConnectAccessMask;
-
-       typedef [bitmap32bit] bitmap {
-               SAMR_USER_ACCESS_GET_NAME_ETC             = 0x00000001,
-               SAMR_USER_ACCESS_GET_LOCALE               = 0x00000002,
-               SAMR_USER_ACCESS_SET_LOC_COM              = 0x00000004,
-               SAMR_USER_ACCESS_GET_LOGONINFO            = 0x00000008,
-               SAMR_USER_ACCESS_GET_ATTRIBUTES           = 0x00000010,
-               SAMR_USER_ACCESS_SET_ATTRIBUTES           = 0x00000020,
-               SAMR_USER_ACCESS_CHANGE_PASSWORD          = 0x00000040,
-               SAMR_USER_ACCESS_SET_PASSWORD             = 0x00000080,
-               SAMR_USER_ACCESS_GET_GROUPS               = 0x00000100,
-               SAMR_USER_ACCESS_GET_GROUP_MEMBERSHIP     = 0x00000200,
-               SAMR_USER_ACCESS_CHANGE_GROUP_MEMBERSHIP  = 0x00000400
-       } samr_UserAccessMask;
-
-       typedef [bitmap32bit] bitmap {
-               SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1  = 0x00000001,
-               SAMR_DOMAIN_ACCESS_SET_INFO_1     = 0x00000002,
-               SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2  = 0x00000004,
-               SAMR_DOMAIN_ACCESS_SET_INFO_2     = 0x00000008,
-               SAMR_DOMAIN_ACCESS_CREATE_USER    = 0x00000010,
-               SAMR_DOMAIN_ACCESS_CREATE_GROUP   = 0x00000020,
-               SAMR_DOMAIN_ACCESS_CREATE_ALIAS   = 0x00000040,
-               SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS   = 0x00000080,
-               SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS  = 0x00000100,
-               SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT   = 0x00000200,
-               SAMR_DOMAIN_ACCESS_SET_INFO_3     = 0x00000400
-       } samr_DomainAccessMask;
-
-       typedef [bitmap32bit] bitmap {
-               SAMR_GROUP_ACCESS_LOOKUP_INFO     = 0x00000001,
-               SAMR_GROUP_ACCESS_SET_INFO        = 0x00000002,
-               SAMR_GROUP_ACCESS_ADD_MEMBER      = 0x00000004,
-               SAMR_GROUP_ACCESS_REMOVE_MEMBER   = 0x00000008,
-               SAMR_GROUP_ACCESS_GET_MEMBERS     = 0x00000010
-       } samr_GroupAccessMask;
-
-       typedef [bitmap32bit] bitmap {
-               SAMR_ALIAS_ACCESS_ADD_MEMBER      = 0x00000001,
-               SAMR_ALIAS_ACCESS_REMOVE_MEMBER   = 0x00000002,
-               SAMR_ALIAS_ACCESS_GET_MEMBERS     = 0x00000004,
-               SAMR_ALIAS_ACCESS_LOOKUP_INFO     = 0x00000008,
-               SAMR_ALIAS_ACCESS_SET_INFO        = 0x00000010
-       } samr_AliasAccessMask;
-
-       /******************/
-       /* Function: 0x00 */
-       NTSTATUS samr_Connect (
-               /* notice the lack of [string] */
-               [in,unique] uint16 *system_name,
-               [in]       samr_ConnectAccessMask access_mask,
-               [out,ref]  policy_handle *connect_handle
-               );
-
-
-       /******************/
-       /* Function: 0x01 */
-       [public] NTSTATUS samr_Close (
-               [in,out,ref]  policy_handle *handle
-               );
-
-       /******************/
-       /* Function: 0x02 */
-
-       NTSTATUS samr_SetSecurity (
-               [in,ref]          policy_handle *handle,
-               [in]              security_secinfo sec_info,
-               [in,ref]          sec_desc_buf *sdbuf
-               );
-
-       /******************/
-       /* Function: 0x03 */
-
-       NTSTATUS samr_QuerySecurity (
-               [in,ref]          policy_handle *handle,
-               [in]              security_secinfo sec_info,
-               [out,unique]      sec_desc_buf *sdbuf
-               );
-
-       /******************/
-       /* Function: 0x04 */
-
-       /*
-         shutdown the SAM - once you call this the SAM will be dead
-       */
-       NTSTATUS samr_Shutdown (
-               [in,ref]   policy_handle *connect_handle
-               );
-
-       /******************/
-       /* Function: 0x05 */
-       NTSTATUS samr_LookupDomain (
-               [in,ref]  policy_handle *connect_handle,                
-               [in,ref]  lsa_String *domain_name,
-               [out,unique] dom_sid2 *sid
-               );
-
-
-       /******************/
-       /* Function: 0x06 */
-
-       typedef struct {
-               uint32 idx;
-               lsa_String name;
-       } samr_SamEntry;
-
-       typedef struct {
-               uint32 count;
-               [size_is(count)] samr_SamEntry *entries;
-       } samr_SamArray;
-
-       NTSTATUS samr_EnumDomains (
-               [in,ref]      policy_handle *connect_handle,
-               [in,out,ref]  uint32 *resume_handle,
-               [in]          uint32 buf_size,
-               [out,unique]  samr_SamArray *sam,
-               [out]         uint32 num_entries
-               );
-
-
-       /************************/
-       /* Function    0x07     */
-       [public] NTSTATUS samr_OpenDomain(
-               [in,ref]      policy_handle *connect_handle,
-               [in]          samr_DomainAccessMask access_mask,
-               [in,ref]      dom_sid2 *sid,
-               [out,ref]     policy_handle *domain_handle
-               );
-
-       /************************/
-       /* Function    0x08     */
-       /* server roles */
-       typedef [v1_enum] enum {
-               SAMR_ROLE_STANDALONE    = 0,
-               SAMR_ROLE_DOMAIN_MEMBER = 1,
-               SAMR_ROLE_DOMAIN_BDC    = 2,
-               SAMR_ROLE_DOMAIN_PDC    = 3
-       } samr_Role;
-
-       /* password properties flags */
-       typedef [public,bitmap32bit] bitmap {
-               DOMAIN_PASSWORD_COMPLEX         = 0x00000001,
-               DOMAIN_PASSWORD_NO_ANON_CHANGE  = 0x00000002,
-               DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004,
-               DOMAIN_PASSWORD_LOCKOUT_ADMINS  = 0x00000008,
-               DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010,
-               DOMAIN_REFUSE_PASSWORD_CHANGE   = 0x00000020
-       } samr_PasswordProperties;
-
-       typedef struct {
-               uint16 min_password_length;
-               uint16 password_history_length;
-               samr_PasswordProperties password_properties;
-               /* yes, these are signed. They are in negative 100ns */
-               dlong  max_password_age;
-               dlong  min_password_age;
-       } samr_DomInfo1;
-
-       typedef struct {
-               NTTIME force_logoff_time;
-               lsa_String oem_information; /* comment */
-               lsa_String domain_name;
-               lsa_String primary; /* PDC name if this is a BDC */
-               udlong sequence_num;
-               uint32 unknown2;
-               samr_Role role;
-               uint32 unknown3;
-               uint32 num_users;
-               uint32 num_groups;
-               uint32 num_aliases;
-       } samr_DomGeneralInformation;
-
-       typedef struct {
-               NTTIME force_logoff_time;
-       } samr_DomInfo3;
-
-       typedef struct {
-               lsa_String oem_information; /* comment */
-       } samr_DomOEMInformation;
-
-       typedef struct {
-               lsa_String domain_name;
-       } samr_DomInfo5;
-
-       typedef struct {
-               lsa_String primary;
-       } samr_DomInfo6;
-
-       typedef struct {
-               samr_Role role;
-       } samr_DomInfo7;
-
-       typedef struct {
-               hyper sequence_num;
-               NTTIME domain_create_time;
-       } samr_DomInfo8;
-
-       typedef struct {
-               uint32 unknown; /* w2k3 returns 1 */
-       } samr_DomInfo9;
-
-       typedef struct {
-               samr_DomGeneralInformation general;
-               hyper lockout_duration;
-               hyper lockout_window;
-               uint16 lockout_threshold;
-       } samr_DomGeneralInformation2;
-
-       typedef struct {
-               hyper lockout_duration;
-               hyper lockout_window;
-               uint16 lockout_threshold;
-       } samr_DomInfo12;
-
-       typedef struct {
-               hyper sequence_num;
-               NTTIME domain_create_time;
-               uint32 unknown1;
-               uint32 unknown2;
-       } samr_DomInfo13;
-
-       typedef [switch_type(uint16)] union {
-               [case(1)] samr_DomInfo1 info1;
-               [case(2)] samr_DomGeneralInformation general;
-               [case(3)] samr_DomInfo3 info3;
-               [case(4)] samr_DomOEMInformation oem;
-               [case(5)] samr_DomInfo5 info5;
-               [case(6)] samr_DomInfo6 info6;
-               [case(7)] samr_DomInfo7 info7;
-               [case(8)] samr_DomInfo8 info8;
-               [case(9)] samr_DomInfo9 info9;
-               [case(11)] samr_DomGeneralInformation2 general2;
-               [case(12)] samr_DomInfo12 info12;
-               [case(13)] samr_DomInfo13 info13;
-       } samr_DomainInfo;
-
-       NTSTATUS samr_QueryDomainInfo(
-               [in,ref]      policy_handle *domain_handle,
-               [in]          uint16 level,
-               [out,switch_is(level),unique] samr_DomainInfo *info
-               );
-
-       /************************/
-       /* Function    0x09     */
-       /*
-         only levels 1, 3, 4, 6, 7, 9, 12 are valid for this 
-         call in w2k3
-       */
-       NTSTATUS samr_SetDomainInfo(
-               [in,ref]      policy_handle *domain_handle,
-               [in]          uint16 level,
-               [in,switch_is(level),ref] samr_DomainInfo *info
-               );
-
-
-       /************************/
-       /* Function    0x0a     */
-       NTSTATUS samr_CreateDomainGroup(
-               [in,ref]      policy_handle *domain_handle,
-               [in,ref]      lsa_String *name,
-               [in]          samr_GroupAccessMask access_mask,
-               [out,ref]     policy_handle *group_handle,
-               [out,ref]     uint32 *rid
-               );
-               
-
-       /************************/
-       /* Function    0x0b     */
-       NTSTATUS samr_EnumDomainGroups(
-               [in,ref]      policy_handle *domain_handle,
-               [in,out,ref]  uint32 *resume_handle,
-               [in]          uint32 max_size,
-               [out,unique]  samr_SamArray *sam,
-               [out]         uint32 num_entries
-               );
-
-       /************************/
-       /* Function    0x0c     */
-       NTSTATUS samr_CreateUser(
-               [in,ref]      policy_handle *domain_handle,
-               [in,ref]      lsa_String *account_name,
-               [in]          samr_UserAccessMask access_mask,
-               [out,ref]     policy_handle *user_handle,
-               [out,ref]     uint32 *rid
-               );
-
-       /************************/
-       /* Function    0x0d     */
-
-
-       /* w2k3 treats max_size as max_users*54 and sets the
-          resume_handle as the rid of the last user sent
-       */
-       const int SAMR_ENUM_USERS_MULTIPLIER = 54;
-
-       NTSTATUS samr_EnumDomainUsers(
-               [in,ref]      policy_handle *domain_handle,
-               [in,out,ref]  uint32 *resume_handle,
-               [in]          samr_AcctFlags acct_flags,
-               [in]          uint32 max_size,
-               [out,unique]  samr_SamArray *sam,
-               [out]         uint32 num_entries
-               );
-
-       /************************/
-       /* Function    0x0e     */
-       NTSTATUS samr_CreateDomAlias(
-               [in,ref]      policy_handle *domain_handle,
-               [in,ref]      lsa_String   *alias_name,
-               [in]          samr_AliasAccessMask access_mask,
-               [out,ref]     policy_handle *alias_handle,
-               [out,ref]     uint32        *rid
-               );
-
-       /************************/
-       /* Function    0x0f     */
-       NTSTATUS samr_EnumDomainAliases(
-               [in,ref]      policy_handle *domain_handle,
-               [in,out,ref]  uint32 *resume_handle,
-               [in]          samr_AcctFlags acct_flags,
-               [out,unique]  samr_SamArray *sam,
-               [out]         uint32 num_entries
-               );
-
-       /************************/
-       /* Function    0x10     */
-
-       typedef struct {
-               [range(0,1024)]  uint32 count;
-               [size_is(count)] uint32 *ids;
-       } samr_Ids;
-
-       NTSTATUS samr_GetAliasMembership(
-               [in,ref]      policy_handle *domain_handle,
-               [in,ref]      lsa_SidArray  *sids,
-               [out,ref]     samr_Ids *rids
-               );
-
-       /************************/
-       /* Function    0x11     */
-
-       [public] NTSTATUS samr_LookupNames(
-               [in,ref]      policy_handle *domain_handle,
-               [in,range(0,1000)] uint32 num_names,
-               [in,size_is(1000),length_is(num_names)] lsa_String names[],
-               [out]         samr_Ids rids,
-               [out]         samr_Ids types
-               );
-
-
-       /************************/
-       /* Function    0x12     */
-       NTSTATUS samr_LookupRids(
-               [in,ref]      policy_handle *domain_handle,
-               [in,range(0,1000)] uint32 num_rids,
-               [in,size_is(1000),length_is(num_rids)] uint32 rids[],
-               [out]         lsa_Strings names,
-               [out]         samr_Ids types
-               );
-
-       /************************/
-       /* Function    0x13     */
-       NTSTATUS samr_OpenGroup(
-               [in,ref]      policy_handle *domain_handle,
-               [in]          samr_GroupAccessMask access_mask,
-               [in]          uint32 rid,
-               [out,ref]     policy_handle *group_handle
-               );
-
-       /* Group attributes */
-       typedef [public,bitmap32bit] bitmap {
-               SE_GROUP_MANDATORY              = 0x00000001,
-               SE_GROUP_ENABLED_BY_DEFAULT     = 0x00000002,
-               SE_GROUP_ENABLED                = 0x00000004,
-               SE_GROUP_OWNER                  = 0x00000008,
-               SE_GROUP_USE_FOR_DENY_ONLY      = 0x00000010,
-               SE_GROUP_RESOURCE               = 0x20000000,
-               SE_GROUP_LOGON_ID               = 0xC0000000
-       } samr_GroupAttrs;
-
-       /************************/
-       /* Function    0x14     */
-
-       typedef struct {
-               lsa_String name;
-               samr_GroupAttrs attributes;
-               uint32 num_members;
-               lsa_String description;
-       } samr_GroupInfoAll;
-
-       typedef struct {
-               samr_GroupAttrs attributes;
-       } samr_GroupInfoAttributes;
-
-       typedef struct {
-               lsa_String description;
-       } samr_GroupInfoDescription;
-
-       typedef enum {
-               GROUPINFOALL          = 1,
-               GROUPINFONAME         = 2,
-               GROUPINFOATTRIBUTES   = 3,
-               GROUPINFODESCRIPTION  = 4,
-               GROUPINFOALL2         = 5
-       } samr_GroupInfoEnum;
-
-       typedef [switch_type(samr_GroupInfoEnum)] union {
-               [case(GROUPINFOALL)]         samr_GroupInfoAll        all;
-               [case(GROUPINFONAME)]        lsa_String               name;
-               [case(GROUPINFOATTRIBUTES)]  samr_GroupInfoAttributes attributes;
-               [case(GROUPINFODESCRIPTION)] lsa_String               description;
-               [case(GROUPINFOALL2)]        samr_GroupInfoAll        all2;
-       } samr_GroupInfo;
-
-       NTSTATUS samr_QueryGroupInfo(
-               [in,ref]                  policy_handle *group_handle,
-               [in]                      samr_GroupInfoEnum level,
-               [out,switch_is(level),unique] samr_GroupInfo *info
-               );
-
-       /************************/
-       /* Function    0x15     */
-       NTSTATUS samr_SetGroupInfo(
-               [in,ref]                  policy_handle *group_handle,
-               [in]                      samr_GroupInfoEnum level,
-               [in,switch_is(level),ref] samr_GroupInfo *info
-               );
-
-       /************************/
-       /* Function    0x16     */
-       NTSTATUS samr_AddGroupMember(
-               [in,ref]                  policy_handle *group_handle,
-               [in]                      uint32 rid,
-               [in]                      uint32 flags
-               );
-
-       /************************/
-       /* Function    0x17     */
-       NTSTATUS samr_DeleteDomainGroup(
-               [in,out,ref]   policy_handle *group_handle
-               );
-
-       /************************/
-       /* Function    0x18     */
-       NTSTATUS samr_DeleteGroupMember(
-               [in,ref]                  policy_handle *group_handle,
-               [in]                      uint32 rid
-               );
-
-
-       /************************/
-       /* Function    0x19     */
-       typedef struct {
-               uint32 count;
-               [size_is(count)] uint32 *rids;
-               [size_is(count)] uint32 *types;
-       } samr_RidTypeArray;
-
-       NTSTATUS samr_QueryGroupMember(
-               [in,ref]  policy_handle *group_handle,
-               [out,unique] samr_RidTypeArray *rids
-               );
-
-
-       /************************/
-       /* Function    0x1a     */
-
-       /*
-         win2003 seems to accept any data at all for the two integers
-         below, and doesn't seem to do anything with them that I can
-         see. Weird. I really expected the first integer to be a rid
-         and the second to be the attributes for that rid member.
-       */
-       NTSTATUS samr_SetMemberAttributesOfGroup(
-               [in,ref]  policy_handle *group_handle,
-               [in]      uint32 unknown1,
-               [in]      uint32 unknown2
-               );
-
-
-       /************************/
-       /* Function    0x1b     */
-       NTSTATUS samr_OpenAlias (
-               [in,ref]      policy_handle *domain_handle,
-               [in]          samr_AliasAccessMask access_mask,
-               [in]          uint32 rid,
-               [out,ref]     policy_handle *alias_handle
-               );
-
-
-       /************************/
-       /* Function    0x1c     */
-
-       typedef struct {
-               lsa_String name;
-               uint32 num_members;
-               lsa_String description;
-       } samr_AliasInfoAll;
-
-       typedef enum {
-               ALIASINFOALL          = 1,
-               ALIASINFONAME         = 2,
-               ALIASINFODESCRIPTION  = 3
-       } samr_AliasInfoEnum;
-
-       typedef [switch_type(samr_AliasInfoEnum)] union {
-               [case(ALIASINFOALL)] samr_AliasInfoAll all;
-               [case(ALIASINFONAME)] lsa_String name;
-               [case(ALIASINFODESCRIPTION)] lsa_String description;
-       } samr_AliasInfo;
-
-       NTSTATUS samr_QueryAliasInfo(
-               [in,ref]                  policy_handle  *alias_handle,
-               [in]                      samr_AliasInfoEnum      level,
-               [out,switch_is(level),unique] samr_AliasInfo *info
-               );
-
-       /************************/
-       /* Function    0x1d     */
-       NTSTATUS samr_SetAliasInfo(
-               [in,ref]                  policy_handle  *alias_handle,
-               [in]                      samr_AliasInfoEnum      level,
-               [in,switch_is(level),ref] samr_AliasInfo *info
-               );
-
-       /************************/
-       /* Function    0x1e     */
-       NTSTATUS samr_DeleteDomAlias(
-               [in,out,ref]  policy_handle *alias_handle
-               );
-
-       /************************/
-       /* Function    0x1f     */
-       NTSTATUS samr_AddAliasMember(
-               [in,ref]  policy_handle *alias_handle,
-               [in,ref]  dom_sid2      *sid
-               );
-
-       /************************/
-       /* Function    0x20     */
-       NTSTATUS samr_DeleteAliasMember(
-               [in,ref] policy_handle *alias_handle,
-               [in,ref] dom_sid2      *sid
-               );
-
-       /************************/
-       /* Function    0x21     */
-       NTSTATUS samr_GetMembersInAlias(
-               [in,ref]   policy_handle *alias_handle,
-               [out,ref]  lsa_SidArray    *sids
-               );
-
-       /************************/
-       /* Function    0x22     */
-       [public] NTSTATUS samr_OpenUser(
-               [in,ref]      policy_handle *domain_handle,
-               [in]          samr_UserAccessMask access_mask,
-               [in]          uint32 rid,
-               [out,ref]     policy_handle *user_handle
-               );
-
-       /************************/
-       /* Function    0x23     */
-       NTSTATUS samr_DeleteUser(
-               [in,out,ref]   policy_handle *user_handle
-               );
-
-       /************************/
-       /* Function    0x24     */
-       typedef struct {
-               lsa_String account_name;
-               lsa_String full_name;
-               uint32 primary_gid;
-               lsa_String description;
-               lsa_String comment;
-       } samr_UserInfo1;
-
-       typedef struct {
-               lsa_String comment;
-               lsa_String unknown; /* settable, but doesn't stick. probably obsolete */
-               uint16 country_code;
-               uint16 code_page;
-       } samr_UserInfo2;
-
-       /* this is also used in samr and netlogon */
-       typedef [public, flag(NDR_PAHEX)] struct {
-               uint16 units_per_week;
-               [size_is(1260), length_is(units_per_week/8)] uint8 *bits;
-       } samr_LogonHours;
-
-       typedef struct {
-               lsa_String account_name;
-               lsa_String full_name;
-               uint32 rid;
-               uint32 primary_gid;
-               lsa_String home_directory;
-               lsa_String home_drive;
-               lsa_String logon_script;
-               lsa_String profile_path;
-               lsa_String workstations;
-               NTTIME last_logon;
-               NTTIME last_logoff;
-               NTTIME last_password_change;
-               NTTIME allow_password_change;
-               NTTIME force_password_change;
-               samr_LogonHours logon_hours;
-               uint16 bad_password_count;
-               uint16 logon_count;
-               samr_AcctFlags acct_flags;
-       } samr_UserInfo3;
-
-       typedef struct {
-               samr_LogonHours logon_hours;
-       } samr_UserInfo4;
-
-       typedef struct {
-               lsa_String account_name;
-               lsa_String full_name;
-               uint32 rid;
-               uint32 primary_gid;
-               lsa_String home_directory;
-               lsa_String home_drive;
-               lsa_String logon_script;
-               lsa_String profile_path;
-               lsa_String description;
-               lsa_String workstations;
-               NTTIME last_logon;
-               NTTIME last_logoff;
-               samr_LogonHours logon_hours;
-               uint16 bad_password_count;
-               uint16 logon_count;
-               NTTIME last_password_change;
-               NTTIME acct_expiry;
-               samr_AcctFlags acct_flags;
-       } samr_UserInfo5;
-
-       typedef struct {
-               lsa_String account_name;
-               lsa_String full_name;
-       } samr_UserInfo6;
-
-       typedef struct {
-               lsa_String account_name;
-       } samr_UserInfo7;
-
-       typedef struct {
-               lsa_String full_name;
-       } samr_UserInfo8;
-
-       typedef struct {
-               uint32 primary_gid;
-       } samr_UserInfo9;
-
-       typedef struct {
-               lsa_String home_directory;
-               lsa_String home_drive;
-       } samr_UserInfo10;
-
-       typedef struct {
-               lsa_String logon_script;
-       } samr_UserInfo11;
-
-       typedef struct {
-               lsa_String profile_path;
-       } samr_UserInfo12;
-
-       typedef struct {
-               lsa_String description;
-       } samr_UserInfo13;
-
-       typedef struct {
-               lsa_String workstations;
-       } samr_UserInfo14;
-
-       typedef struct {
-               samr_AcctFlags acct_flags;
-       } samr_UserInfo16;
-       
-       typedef struct {
-               NTTIME acct_expiry;
-       } samr_UserInfo17;
-
-       typedef [public, flag(NDR_PAHEX)] struct {
-               uint8 hash[16];
-       } samr_Password;
-
-       typedef struct {
-               samr_Password lm_pwd;
-               samr_Password nt_pwd;
-               boolean8 lm_pwd_active;
-               boolean8 nt_pwd_active;
-       } samr_UserInfo18;
-
-       typedef struct {
-               lsa_String parameters;
-       } samr_UserInfo20;
-
-       /* this defines the bits used for fields_present in info21 */
-       typedef [bitmap32bit] bitmap {
-               SAMR_FIELD_ACCOUNT_NAME     = 0x00000001,
-               SAMR_FIELD_FULL_NAME        = 0x00000002,
-               SAMR_FIELD_RID              = 0x00000004,
-               SAMR_FIELD_PRIMARY_GID      = 0x00000008,
-               SAMR_FIELD_DESCRIPTION      = 0x00000010,
-               SAMR_FIELD_COMMENT          = 0x00000020,
-               SAMR_FIELD_HOME_DIRECTORY   = 0x00000040,
-               SAMR_FIELD_HOME_DRIVE       = 0x00000080,
-               SAMR_FIELD_LOGON_SCRIPT     = 0x00000100,
-               SAMR_FIELD_PROFILE_PATH     = 0x00000200,
-               SAMR_FIELD_WORKSTATIONS     = 0x00000400,
-               SAMR_FIELD_LAST_LOGON       = 0x00000800,
-               SAMR_FIELD_LAST_LOGOFF      = 0x00001000,
-               SAMR_FIELD_LOGON_HOURS      = 0x00002000,
-               SAMR_FIELD_BAD_PWD_COUNT    = 0x00004000,
-               SAMR_FIELD_NUM_LOGONS       = 0x00008000,
-               SAMR_FIELD_ALLOW_PWD_CHANGE = 0x00010000,
-               SAMR_FIELD_FORCE_PWD_CHANGE = 0x00020000,
-               SAMR_FIELD_LAST_PWD_CHANGE  = 0x00040000,
-               SAMR_FIELD_ACCT_EXPIRY      = 0x00080000,
-               SAMR_FIELD_ACCT_FLAGS       = 0x00100000,
-               SAMR_FIELD_PARAMETERS       = 0x00200000,
-               SAMR_FIELD_COUNTRY_CODE     = 0x00400000,
-               SAMR_FIELD_CODE_PAGE        = 0x00800000,
-               SAMR_FIELD_PASSWORD         = 0x01000000, /* either of these */
-               SAMR_FIELD_PASSWORD2        = 0x02000000, /* two bits seems to work */
-               SAMR_FIELD_PRIVATE_DATA     = 0x04000000,
-               SAMR_FIELD_EXPIRED_FLAG     = 0x08000000,
-               SAMR_FIELD_SEC_DESC         = 0x10000000,
-               SAMR_FIELD_OWF_PWD          = 0x20000000
-       } samr_FieldsPresent;
-
-       /* used for 'password_expired' in samr_UserInfo21 */
-       const int PASS_MUST_CHANGE_AT_NEXT_LOGON = 0x01;
-       const int PASS_DONT_CHANGE_AT_NEXT_LOGON = 0x00;
-
-       typedef struct {
-               NTTIME last_logon;
-               NTTIME last_logoff;
-               NTTIME last_password_change;
-               NTTIME acct_expiry;
-               NTTIME allow_password_change;
-               NTTIME force_password_change;
-               lsa_String account_name;
-               lsa_String full_name;
-               lsa_String home_directory;
-               lsa_String home_drive;
-               lsa_String logon_script;
-               lsa_String profile_path;
-               lsa_String description;
-               lsa_String workstations;
-               lsa_String comment;
-               lsa_String parameters;
-               lsa_String unknown1;
-               lsa_String unknown2;
-               lsa_String unknown3;
-               uint32 buf_count;
-               [size_is(buf_count)] uint8 *buffer;
-               uint32 rid;
-               uint32 primary_gid;
-               samr_AcctFlags acct_flags;
-               samr_FieldsPresent fields_present;
-               samr_LogonHours logon_hours;
-               uint16 bad_password_count;
-               uint16 logon_count;
-               uint16 country_code;
-               uint16 code_page;
-               uint8  nt_password_set;
-               uint8  lm_password_set;
-               uint8  password_expired;
-               uint8  unknown4;
-       } samr_UserInfo21;
-
-       typedef [public, flag(NDR_PAHEX)] struct {
-               uint8 data[516];
-       } samr_CryptPassword;
-
-       typedef struct {
-               samr_UserInfo21 info;
-               samr_CryptPassword password;
-       } samr_UserInfo23;
-
-       typedef struct {
-               samr_CryptPassword password;
-               uint8 pw_len;
-       } samr_UserInfo24;
-
-       typedef [flag(NDR_PAHEX)] struct {
-               uint8 data[532];
-       } samr_CryptPasswordEx;
-
-       typedef struct {
-               samr_UserInfo21 info;
-               samr_CryptPasswordEx password;
-       } samr_UserInfo25;
-
-       typedef struct {
-               samr_CryptPasswordEx password;
-               uint8 pw_len;
-       } samr_UserInfo26;
-
-       typedef [switch_type(uint16)] union {
-               [case(1)] samr_UserInfo1 info1;
-               [case(2)] samr_UserInfo2 info2;
-               [case(3)] samr_UserInfo3 info3;
-               [case(4)] samr_UserInfo4 info4;
-               [case(5)] samr_UserInfo5 info5;
-               [case(6)] samr_UserInfo6 info6;
-               [case(7)] samr_UserInfo7 info7;
-               [case(8)] samr_UserInfo8 info8;
-               [case(9)] samr_UserInfo9 info9;
-               [case(10)] samr_UserInfo10 info10;
-               [case(11)] samr_UserInfo11 info11;
-               [case(12)] samr_UserInfo12 info12;
-               [case(13)] samr_UserInfo13 info13;
-               [case(14)] samr_UserInfo14 info14;
-               [case(16)] samr_UserInfo16 info16;
-               [case(17)] samr_UserInfo17 info17;
-               [case(18)] samr_UserInfo18 info18;
-               [case(20)] samr_UserInfo20 info20;
-               [case(21)] samr_UserInfo21 info21;
-               [case(23)] samr_UserInfo23 info23;
-               [case(24)] samr_UserInfo24 info24;
-               [case(25)] samr_UserInfo25 info25;
-               [case(26)] samr_UserInfo26 info26;
-       } samr_UserInfo;
-
-       [public] NTSTATUS samr_QueryUserInfo(
-               [in,ref]                  policy_handle *user_handle,
-               [in]                      uint16 level,
-               [out,unique,switch_is(level)] samr_UserInfo *info
-               );
-
-
-       /************************/
-       /* Function    0x25     */
-       [public] NTSTATUS samr_SetUserInfo(
-               [in,ref]                   policy_handle *user_handle,
-               [in]                       uint16 level,
-               [in,ref,switch_is(level)]  samr_UserInfo *info
-               );
-
-       /************************/
-       /* Function    0x26     */
-       /*
-         this is a password change interface that doesn't give
-         the server the plaintext password. Depricated.
-       */
-       NTSTATUS samr_ChangePasswordUser(
-               [in,ref]    policy_handle *user_handle,
-               [in]        boolean8 lm_present,
-               [in,unique] samr_Password *old_lm_crypted,
-               [in,unique] samr_Password *new_lm_crypted,
-               [in]        boolean8 nt_present,
-               [in,unique] samr_Password *old_nt_crypted,
-               [in,unique] samr_Password *new_nt_crypted,
-               [in]        boolean8 cross1_present,
-               [in,unique] samr_Password *nt_cross,
-               [in]        boolean8 cross2_present,
-               [in,unique] samr_Password *lm_cross
-               );
-
-       /************************/
-       /* Function    0x27     */
-
-       typedef [public] struct {
-               uint32 rid;
-               samr_GroupAttrs attributes;
-       } samr_RidWithAttribute;
-
-       typedef [public] struct {
-               uint32     count;
-               [size_is(count)] samr_RidWithAttribute *rids;
-       } samr_RidWithAttributeArray;
-
-       NTSTATUS samr_GetGroupsForUser(
-               [in,ref]   policy_handle *user_handle,
-               [out,unique] samr_RidWithAttributeArray  *rids
-               );
-
-       /************************/
-       /* Function    0x28     */
-
-       typedef struct {
-               uint32    idx;
-               uint32    rid;
-               samr_AcctFlags acct_flags;
-               lsa_String account_name;
-               lsa_String description;
-               lsa_String full_name;
-       } samr_DispEntryGeneral;
-
-       typedef struct {
-               uint32 count;
-               [size_is(count)] samr_DispEntryGeneral *entries;
-       } samr_DispInfoGeneral;
-
-       typedef struct {
-               uint32    idx;
-               uint32    rid;
-               samr_AcctFlags acct_flags;
-               lsa_String account_name;
-               lsa_String description;
-       } samr_DispEntryFull;
-
-       typedef struct {
-               uint32 count;
-               [size_is(count)] samr_DispEntryFull *entries;
-       } samr_DispInfoFull;
-
-       typedef struct {
-               uint32    idx;
-               uint32    rid;
-               samr_GroupAttrs acct_flags;
-               lsa_String account_name;
-               lsa_String description;
-       } samr_DispEntryFullGroup;
-
-       typedef struct {
-               uint32 count;
-               [size_is(count)] samr_DispEntryFullGroup *entries;
-       } samr_DispInfoFullGroups;
-
-       typedef struct {
-               uint32    idx;
-               lsa_AsciiStringLarge account_name;
-       } samr_DispEntryAscii;
-
-       typedef struct {
-               uint32 count;
-               [size_is(count)] samr_DispEntryAscii *entries;
-       } samr_DispInfoAscii;
-
-       typedef [switch_type(uint16)] union {
-               [case(1)] samr_DispInfoGeneral info1;/* users */
-               [case(2)] samr_DispInfoFull info2; /* trust accounts? */
-               [case(3)] samr_DispInfoFullGroups info3; /* groups */
-               [case(4)] samr_DispInfoAscii info4; /* users */
-               [case(5)] samr_DispInfoAscii info5; /* groups */
-       } samr_DispInfo;
-
-       NTSTATUS samr_QueryDisplayInfo(
-               [in,ref]    policy_handle *domain_handle,
-               [in]        uint16 level,
-               [in]        uint32 start_idx,
-               [in]        uint32 max_entries,
-               [in]        uint32 buf_size,
-               [out]       uint32 total_size,
-               [out]       uint32 returned_size,
-               [out,switch_is(level)] samr_DispInfo info
-               );
-
-
-       /************************/
-       /* Function    0x29     */
-
-       /*
-         this seems to be an alphabetic search function. The returned index
-         is the index for samr_QueryDisplayInfo needed to get names occurring
-         after the specified name. The supplied name does not need to exist
-         in the database (for example you can supply just a first letter for 
-         searching starting at that letter)
-
-         The level corresponds to the samr_QueryDisplayInfo level
-       */
-       NTSTATUS samr_GetDisplayEnumerationIndex(
-               [in,ref]    policy_handle *domain_handle,
-               [in]        uint16 level,
-               [in]        lsa_String name,
-               [out]       uint32 idx
-               );
-
-
-
-       /************************/
-       /* Function    0x2a     */
-
-       /*
-         w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
-       */
-       NTSTATUS samr_TestPrivateFunctionsDomain(
-               [in,ref]    policy_handle *domain_handle
-               );
-
-
-       /************************/
-       /* Function    0x2b     */
-
-       /*
-         w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
-       */
-       NTSTATUS samr_TestPrivateFunctionsUser(
-               [in,ref]    policy_handle *user_handle
-               );
-
-
-       /************************/
-       /* Function    0x2c     */
-
-       typedef struct {
-               uint16 min_password_length;
-               samr_PasswordProperties password_properties;
-       } samr_PwInfo;
-
-       [public] NTSTATUS samr_GetUserPwInfo(
-               [in,ref]    policy_handle *user_handle,
-               [out]       samr_PwInfo info
-               );
-
-       /************************/
-       /* Function    0x2d     */
-       NTSTATUS samr_RemoveMemberFromForeignDomain(
-               [in,ref]    policy_handle *domain_handle,
-               [in,ref]    dom_sid2 *sid
-               );
-
-       /************************/
-       /* Function    0x2e     */
-
-       /*
-         how is this different from QueryDomainInfo ??
-       */
-       NTSTATUS samr_QueryDomainInfo2(
-               [in,ref]      policy_handle *domain_handle,
-               [in]          uint16 level,
-               [out,unique,switch_is(level)] samr_DomainInfo *info
-               );
-
-       /************************/
-       /* Function    0x2f     */
-
-       /*
-         how is this different from QueryUserInfo ??
-       */
-       NTSTATUS samr_QueryUserInfo2(
-               [in,ref]                  policy_handle *user_handle,
-               [in]                      uint16 level,
-               [out,unique,switch_is(level)]    samr_UserInfo *info
-               );
-
-       /************************/
-       /* Function    0x30     */
-
-       /*
-         how is this different from QueryDisplayInfo??
-       */
-       NTSTATUS samr_QueryDisplayInfo2(
-               [in,ref]    policy_handle *domain_handle,
-               [in]        uint16 level,
-               [in]        uint32 start_idx,
-               [in]        uint32 max_entries,
-               [in]        uint32 buf_size,
-               [out]       uint32 total_size,
-               [out]       uint32 returned_size,
-               [out,switch_is(level)] samr_DispInfo info
-               );
-
-       /************************/
-       /* Function    0x31     */
-
-       /*
-         how is this different from GetDisplayEnumerationIndex ??
-       */
-       NTSTATUS samr_GetDisplayEnumerationIndex2(
-               [in,ref]    policy_handle *domain_handle,
-               [in]        uint16 level,
-               [in]        lsa_String name,
-               [out]       uint32 idx
-               );
-
-
-       /************************/
-       /* Function    0x32     */
-       NTSTATUS samr_CreateUser2(
-               [in,ref]      policy_handle *domain_handle,
-               [in,ref]      lsa_String *account_name,
-               [in]          samr_AcctFlags acct_flags,
-               [in]          samr_UserAccessMask access_mask,
-               [out,ref]     policy_handle *user_handle,
-               [out,ref]     uint32 *access_granted,
-               [out,ref]     uint32 *rid
-               );
-
-
-       /************************/
-       /* Function    0x33     */
-
-       /*
-         another duplicate. There must be a reason ....
-       */
-       NTSTATUS samr_QueryDisplayInfo3(
-               [in,ref]    policy_handle *domain_handle,
-               [in]        uint16 level,
-               [in]        uint32 start_idx,
-               [in]        uint32 max_entries,
-               [in]        uint32 buf_size,
-               [out]       uint32 total_size,
-               [out]       uint32 returned_size,
-               [out,switch_is(level)] samr_DispInfo info
-               );
-
-       /************************/
-       /* Function    0x34     */
-       NTSTATUS samr_AddMultipleMembersToAlias(
-               [in,ref]    policy_handle *alias_handle,
-               [in,ref]    lsa_SidArray *sids
-               );
-
-       /************************/
-       /* Function    0x35     */
-       NTSTATUS samr_RemoveMultipleMembersFromAlias(
-               [in,ref]    policy_handle *alias_handle,
-               [in,ref]    lsa_SidArray *sids
-               );
-
-       /************************/
-       /* Function    0x36     */
-
-       NTSTATUS samr_OemChangePasswordUser2(
-               [in,unique]       lsa_AsciiString *server,
-               [in,ref]          lsa_AsciiString *account,
-               [in,unique]       samr_CryptPassword *password,
-               [in,unique]       samr_Password *hash
-               );
-
-       /************************/
-       /* Function    0x37     */
-       NTSTATUS samr_ChangePasswordUser2(
-               [in,unique]       lsa_String *server,
-               [in,ref]          lsa_String *account,
-               [in,unique]       samr_CryptPassword *nt_password,
-               [in,unique]       samr_Password *nt_verifier,
-               [in]              boolean8 lm_change,
-               [in,unique]       samr_CryptPassword *lm_password,
-               [in,unique]       samr_Password *lm_verifier
-               );
-
-       /************************/
-       /* Function    0x38     */
-       NTSTATUS samr_GetDomPwInfo(
-               [in,unique] lsa_String *domain_name,
-               [out]       samr_PwInfo info
-               );
-
-       /************************/
-       /* Function    0x39     */
-       NTSTATUS samr_Connect2(
-               [in,unique,string,charset(UTF16)] uint16 *system_name,
-               [in] samr_ConnectAccessMask access_mask,
-               [out,ref]  policy_handle *connect_handle
-               );
-
-       /************************/
-       /* Function    0x3a     */
-       /*
-         seems to be an exact alias for samr_SetUserInfo() 
-       */
-       [public] NTSTATUS samr_SetUserInfo2(
-               [in,ref]                   policy_handle *user_handle,
-               [in]                       uint16 level,
-               [in,ref,switch_is(level)]  samr_UserInfo *info
-               );
-
-       /************************/
-       /* Function    0x3b     */
-       /*
-         this one is mysterious. I have a few guesses, but nothing working yet
-       */
-       NTSTATUS samr_SetBootKeyInformation(
-               [in,ref]   policy_handle *connect_handle,
-               [in]       uint32 unknown1,
-               [in]       uint32 unknown2,
-               [in]       uint32 unknown3
-               );
-
-       /************************/
-       /* Function    0x3c     */
-       NTSTATUS samr_GetBootKeyInformation(
-               [in,ref]   policy_handle *domain_handle,
-               [out]      uint32 unknown
-               );
-
-       /************************/
-       /* Function    0x3d     */
-       NTSTATUS samr_Connect3(
-               [in,unique,string,charset(UTF16)] uint16 *system_name,
-               /* this unknown value seems to be completely ignored by w2k3 */
-               [in] uint32 unknown,
-               [in] samr_ConnectAccessMask access_mask,
-               [out,ref]  policy_handle *connect_handle
-               );
-
-       /************************/
-       /* Function    0x3e     */
-
-       typedef enum {
-               SAMR_CONNECT_PRE_W2K    = 1,
-               SAMR_CONNECT_W2K        = 2,
-               SAMR_CONNECT_AFTER_W2K  = 3
-       } samr_ConnectVersion;
-
-       NTSTATUS samr_Connect4(
-               [in,unique,string,charset(UTF16)] uint16 *system_name,
-               [in] samr_ConnectVersion client_version,
-               [in] samr_ConnectAccessMask access_mask,
-               [out,ref]  policy_handle *connect_handle
-               );
-
-       /************************/
-       /* Function    0x3f     */
-
-       typedef enum samr_RejectReason samr_RejectReason;
-
-       typedef struct {
-               samr_RejectReason reason;
-               uint32 unknown1;
-               uint32 unknown2;
-       } samr_ChangeReject;
-
-       NTSTATUS samr_ChangePasswordUser3(
-               [in,unique]       lsa_String *server,
-               [in,ref]          lsa_String *account,
-               [in,unique]       samr_CryptPassword *nt_password,
-               [in,unique]       samr_Password *nt_verifier,
-               [in]              boolean8 lm_change,
-               [in,unique]       samr_CryptPassword *lm_password,
-               [in,unique]       samr_Password *lm_verifier,
-               [in,unique]       samr_CryptPassword *password3,
-               [out,unique]      samr_DomInfo1 *dominfo,
-               [out,unique]      samr_ChangeReject *reject
-               );
-
-       /************************/
-       /* Function    0x40      */
-
-       typedef struct {
-               samr_ConnectVersion client_version; /* w2k3 gives 3 */
-               uint32         unknown2; /* w2k3 gives 0 */
-       } samr_ConnectInfo1;
-
-       typedef union {
-               [case(1)]  samr_ConnectInfo1 info1;
-       } samr_ConnectInfo;
-
-       [public] NTSTATUS samr_Connect5(
-               [in,unique,string,charset(UTF16)] uint16 *system_name,
-               [in]       samr_ConnectAccessMask  access_mask,
-               [in,out]   uint32             level,
-               [in,out,switch_is(level),ref] samr_ConnectInfo *info,
-               [out,ref]  policy_handle      *connect_handle
-               );
-
-       /************************/
-       /* Function    0x41     */
-       NTSTATUS samr_RidToSid(
-               [in,ref]    policy_handle *domain_handle,
-               [in]        uint32        rid,
-               [out,unique] dom_sid2      *sid
-               );
-
-
-       /************************/
-       /* Function    0x42     */
-
-       /*
-         this should set the DSRM password for the server, which is used
-         when booting into Directory Services Recovery Mode on a DC. Win2003
-         gives me NT_STATUS_NOT_SUPPORTED
-       */
-
-       NTSTATUS samr_SetDsrmPassword(
-               [in,unique] lsa_String *name,
-               [in]       uint32 unknown,
-               [in,unique] samr_Password *hash
-               );
-
-
-       /************************/
-       /* Function    0x43     */
-       /************************/
-       typedef [bitmap32bit] bitmap {
-               SAMR_VALIDATE_FIELD_PASSWORD_LAST_SET           = 0x00000001,
-               SAMR_VALIDATE_FIELD_BAD_PASSWORD_TIME           = 0x00000002,
-               SAMR_VALIDATE_FIELD_LOCKOUT_TIME                = 0x00000004,
-               SAMR_VALIDATE_FIELD_BAD_PASSWORD_COUNT          = 0x00000008,
-               SAMR_VALIDATE_FIELD_PASSWORD_HISTORY_LENGTH     = 0x00000010,
-               SAMR_VALIDATE_FIELD_PASSWORD_HISTORY            = 0x00000020
-       } samr_ValidateFieldsPresent;
-
-       typedef enum {
-               NetValidateAuthentication = 1,
-               NetValidatePasswordChange= 2,
-               NetValidatePasswordReset = 3
-       } samr_ValidatePasswordLevel;
-
-       /* NetApi maps samr_ValidationStatus errors to WERRORs. Haven't
-        * identified the mapping of
-        * - NERR_PasswordFilterError
-        * - NERR_PasswordExpired and
-        * - NERR_PasswordCantChange
-        * yet - Guenther
-        */
-
-       typedef enum {
-               SAMR_VALIDATION_STATUS_SUCCESS = 0,
-               SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE = 1,
-               SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT = 2,
-               SAMR_VALIDATION_STATUS_BAD_PASSWORD = 4,
-               SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT = 5,
-               SAMR_VALIDATION_STATUS_PWD_TOO_SHORT = 6,
-               SAMR_VALIDATION_STATUS_PWD_TOO_LONG = 7,
-               SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH = 8,
-               SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9
-       } samr_ValidationStatus;
-
-       typedef struct {
-               uint32 length;
-               [size_is(length)] uint8 *data;
-        } samr_ValidationBlob;
-
-       typedef struct {
-               samr_ValidateFieldsPresent fields_present;
-               NTTIME_hyper last_password_change;
-               NTTIME_hyper bad_password_time;
-               NTTIME_hyper lockout_time;
-               uint32 bad_pwd_count;
-               uint32 pwd_history_len;
-               [size_is(pwd_history_len)] samr_ValidationBlob *pwd_history;
-       } samr_ValidatePasswordInfo;
-
-       typedef struct {
-               samr_ValidatePasswordInfo info;
-               samr_ValidationStatus status;
-       } samr_ValidatePasswordRepCtr;
-
-       typedef [switch_type(uint16)] union {
-               [case(1)] samr_ValidatePasswordRepCtr ctr1;
-               [case(2)] samr_ValidatePasswordRepCtr ctr2;
-               [case(3)] samr_ValidatePasswordRepCtr ctr3;
-       } samr_ValidatePasswordRep;
-
-       typedef struct {
-               samr_ValidatePasswordInfo info;
-               lsa_StringLarge password;
-               lsa_StringLarge account;
-               samr_ValidationBlob hash;
-               boolean8 pwd_must_change_at_next_logon;
-               boolean8 clear_lockout;
-       } samr_ValidatePasswordReq3;
-
-       typedef struct {
-               samr_ValidatePasswordInfo info;
-               lsa_StringLarge password;
-               lsa_StringLarge account;
-               samr_ValidationBlob hash;
-               boolean8 password_matched;
-       } samr_ValidatePasswordReq2;
-
-       typedef struct {
-               samr_ValidatePasswordInfo info;
-               boolean8 password_matched;
-       } samr_ValidatePasswordReq1;
-
-       typedef [switch_type(uint16)] union {
-               [case(1)] samr_ValidatePasswordReq1 req1;
-               [case(2)] samr_ValidatePasswordReq2 req2;
-               [case(3)] samr_ValidatePasswordReq3 req3;
-       } samr_ValidatePasswordReq;
-
-       NTSTATUS samr_ValidatePassword(
-               [in] samr_ValidatePasswordLevel level,
-               [in,switch_is(level)] samr_ValidatePasswordReq req,
-               [out,unique,switch_is(level)] samr_ValidatePasswordRep *rep
-               );
-}
index b3118d772dc184f965eccc7bb52d0d73986251ed..c093b536dab7da628054ba29f7fb7ac70373a97a 100644 (file)
 #include "../lib/util/util_ldb.h"
 #include "param/param.h"
 
-/* these query macros make samr_Query[User|Group]Info a bit easier to read */
+/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */
 
 #define QUERY_STRING(msg, field, attr) \
-       r->out.info->field.string = samdb_result_string(msg, attr, "");
+       info->field.string = samdb_result_string(msg, attr, "");
 #define QUERY_UINT(msg, field, attr) \
-       r->out.info->field = samdb_result_uint(msg, attr, 0);
+       info->field = samdb_result_uint(msg, attr, 0);
 #define QUERY_RID(msg, field, attr) \
-       r->out.info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
+       info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
 #define QUERY_UINT64(msg, field, attr) \
-       r->out.info->field = samdb_result_uint64(msg, attr, 0);
+       info->field = samdb_result_uint64(msg, attr, 0);
 #define QUERY_APASSC(msg, field, attr) \
-       r->out.info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
-                                                          a_state->domain_state->domain_dn, msg, attr);
+       info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
+                                                        a_state->domain_state->domain_dn, msg, attr);
 #define QUERY_FPASSC(msg, field, attr) \
-       r->out.info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
-                                                          a_state->domain_state->domain_dn, msg);
+       info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
+                                                        a_state->domain_state->domain_dn, msg);
 #define QUERY_LHOURS(msg, field, attr) \
-       r->out.info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
+       info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
 #define QUERY_AFLAGS(msg, field, attr) \
-       r->out.info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
+       info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
+#define QUERY_PARAMETERS(msg, field, attr) \
+       info->field = samdb_result_parameters(mem_ctx, msg, attr);
 
 
 /* these are used to make the Set[User|Group]Info code easier to follow */
        set_el->flags = LDB_FLAG_MOD_REPLACE;                           \
 } while (0)
 
+#define SET_PARAMETERS(msg, field, attr) do {                          \
+       struct ldb_message_element *set_el;                             \
+       if (samdb_msg_add_parameters(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \
+               return NT_STATUS_NO_MEMORY;                             \
+       }                                                               \
+       set_el = ldb_msg_find_element(msg, attr);                       \
+       set_el->flags = LDB_FLAG_MOD_REPLACE;                           \
+} while (0)
+
+
 
 /* 
   samr_Connect 
@@ -217,7 +229,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA
        struct dcesrv_handle *h;
        struct sec_desc_buf *sd;
 
-       r->out.sdbuf = NULL;
+       *r->out.sdbuf = NULL;
 
        DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
 
@@ -228,7 +240,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA
 
        sd->sd = samdb_default_security_descriptor(mem_ctx);
 
-       r->out.sdbuf = sd;
+       *r->out.sdbuf = sd;
 
        return NT_STATUS_OK;
 }
@@ -265,7 +277,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
        int ret;
        struct ldb_dn *partitions_basedn;
 
-       r->out.sid = NULL;
+       *r->out.sid = NULL;
 
        DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
 
@@ -307,7 +319,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
                return NT_STATUS_NO_SUCH_DOMAIN;
        }
 
-       r->out.sid = sid;
+       *r->out.sid = sid;
 
        return NT_STATUS_OK;
 }
@@ -332,8 +344,8 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
        struct ldb_dn *partitions_basedn;
 
        *r->out.resume_handle = 0;
-       r->out.sam = NULL;
-       r->out.num_entries = 0;
+       *r->out.sam = NULL;
+       *r->out.num_entries = 0;
 
        DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
 
@@ -389,9 +401,9 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
                }
        }
 
-       r->out.sam = array;
-       r->out.num_entries = i;
-       array->count = r->out.num_entries;
+       *r->out.sam = array;
+       *r->out.num_entries = i;
+       array->count = *r->out.num_entries;
 
        return NT_STATUS_OK;
 }
@@ -765,18 +777,19 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call,
 {
        struct dcesrv_handle *h;
        struct samr_domain_state *d_state;
+       union samr_DomainInfo *info;
 
        struct ldb_message **dom_msgs;
        const char * const *attrs = NULL;
        
-       r->out.info = NULL;
+       *r->out.info = NULL;
 
        DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
 
        d_state = h->data;
 
-       r->out.info = talloc(mem_ctx, union samr_DomainInfo);
-       if (!r->out.info) {
+       info = talloc(mem_ctx, union samr_DomainInfo);
+       if (!info) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -881,47 +894,49 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call,
                }
        }
 
-       ZERO_STRUCTP(r->out.info);
+       *r->out.info = info;
+
+       ZERO_STRUCTP(info);
 
        switch (r->in.level) {
        case 1:
                return dcesrv_samr_info_DomInfo1(d_state, mem_ctx, dom_msgs, 
-                                                &r->out.info->info1);
+                                                &info->info1);
        case 2:
                return dcesrv_samr_info_DomGeneralInformation(d_state, mem_ctx, dom_msgs, 
-                                                             &r->out.info->general);
+                                                             &info->general);
        case 3:
                return dcesrv_samr_info_DomInfo3(d_state, mem_ctx, dom_msgs, 
-                                                &r->out.info->info3);
+                                                &info->info3);
        case 4:
                return dcesrv_samr_info_DomOEMInformation(d_state, mem_ctx, dom_msgs, 
-                                                         &r->out.info->oem);
+                                                         &info->oem);
        case 5:
                return dcesrv_samr_info_DomInfo5(d_state, mem_ctx, dom_msgs, 
-                                                &r->out.info->info5);
+                                                &info->info5);
        case 6:
                return dcesrv_samr_info_DomInfo6(d_state, mem_ctx, dom_msgs, 
-                                                &r->out.info->info6);
+                                                &info->info6);
        case 7:
                return dcesrv_samr_info_DomInfo7(d_state, mem_ctx, dom_msgs, 
-                                                &r->out.info->info7);
+                                                &info->info7);
        case 8:
                return dcesrv_samr_info_DomInfo8(d_state, mem_ctx, dom_msgs, 
-                                                &r->out.info->info8);
+                                                &info->info8);
        case 9:
                return dcesrv_samr_info_DomInfo9(d_state, mem_ctx, dom_msgs, 
-                                                &r->out.info->info9);
+                                                &info->info9);
        case 11:
                return dcesrv_samr_info_DomGeneralInformation2(d_state, mem_ctx, dom_msgs, 
-                                                              &r->out.info->general2);
+                                                              &info->general2);
        case 12:
                return dcesrv_samr_info_DomInfo12(d_state, mem_ctx, dom_msgs, 
-                                                 &r->out.info->info12);
+                                                 &info->info12);
        case 13:
                return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs, 
-                                                 &r->out.info->info13);
+                                                 &info->info13);
        }
-       
+
        return NT_STATUS_INVALID_INFO_CLASS;
 }
 
@@ -1135,10 +1150,11 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
        int ldb_cnt, count, i, first;
        struct samr_SamEntry *entries;
        const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+       struct samr_SamArray *sam;
 
        *r->out.resume_handle = 0;
-       r->out.sam = NULL;
-       r->out.num_entries = 0;
+       *r->out.sam = NULL;
+       *r->out.num_entries = 0;
 
        DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
 
@@ -1189,20 +1205,22 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
 
        /* return the rest, limit by max_size. Note that we 
           use the w2k3 element size value of 54 */
-       r->out.num_entries = count - first;
-       r->out.num_entries = MIN(r->out.num_entries, 
+       *r->out.num_entries = count - first;
+       *r->out.num_entries = MIN(*r->out.num_entries,
                                 1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
 
-       r->out.sam = talloc(mem_ctx, struct samr_SamArray);
-       if (!r->out.sam) {
+       sam = talloc(mem_ctx, struct samr_SamArray);
+       if (!sam) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       r->out.sam->entries = entries+first;
-       r->out.sam->count = r->out.num_entries;
+       sam->entries = entries+first;
+       sam->count = *r->out.num_entries;
+
+       *r->out.sam = sam;
 
-       if (r->out.num_entries < count - first) {
-               *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+       if (*r->out.num_entries < count - first) {
+               *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
                return STATUS_MORE_ENTRIES;
        }
 
@@ -1492,10 +1510,11 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
        int ret, num_filtered_entries, i, first;
        struct samr_SamEntry *entries;
        const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
+       struct samr_SamArray *sam;
 
        *r->out.resume_handle = 0;
-       r->out.sam = NULL;
-       r->out.num_entries = 0;
+       *r->out.sam = NULL;
+       *r->out.num_entries = 0;
 
        DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
 
@@ -1539,24 +1558,26 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
 
        /* return the rest, limit by max_size. Note that we 
           use the w2k3 element size value of 54 */
-       r->out.num_entries = num_filtered_entries - first;
-       r->out.num_entries = MIN(r->out.num_entries, 
+       *r->out.num_entries = num_filtered_entries - first;
+       *r->out.num_entries = MIN(*r->out.num_entries,
                                 1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
 
-       r->out.sam = talloc(mem_ctx, struct samr_SamArray);
-       if (!r->out.sam) {
+       sam = talloc(mem_ctx, struct samr_SamArray);
+       if (!sam) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       r->out.sam->entries = entries+first;
-       r->out.sam->count = r->out.num_entries;
+       sam->entries = entries+first;
+       sam->count = *r->out.num_entries;
+
+       *r->out.sam = sam;
 
        if (first == num_filtered_entries) {
                return NT_STATUS_OK;
        }
 
-       if (r->out.num_entries < num_filtered_entries - first) {
-               *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+       if (*r->out.num_entries < num_filtered_entries - first) {
+               *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
                return STATUS_MORE_ENTRIES;
        }
 
@@ -1685,10 +1706,11 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call
        int ldb_cnt, count, i, first;
        struct samr_SamEntry *entries;
        const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+       struct samr_SamArray *sam;
 
        *r->out.resume_handle = 0;
-       r->out.sam = NULL;
-       r->out.num_entries = 0;
+       *r->out.sam = NULL;
+       *r->out.num_entries = 0;
 
        DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
 
@@ -1748,20 +1770,22 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call
                return NT_STATUS_OK;
        }
 
-       r->out.num_entries = count - first;
-       r->out.num_entries = MIN(r->out.num_entries, 1000);
+       *r->out.num_entries = count - first;
+       *r->out.num_entries = MIN(*r->out.num_entries, 1000);
 
-       r->out.sam = talloc(mem_ctx, struct samr_SamArray);
-       if (!r->out.sam) {
+       sam = talloc(mem_ctx, struct samr_SamArray);
+       if (!sam) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       r->out.sam->entries = entries+first;
-       r->out.sam->count = r->out.num_entries;
+       sam->entries = entries+first;
+       sam->count = *r->out.num_entries;
+
+       *r->out.sam = sam;
 
-       if (r->out.num_entries < count - first) {
+       if (*r->out.num_entries < count - first) {
                *r->out.resume_handle =
-                       entries[first+r->out.num_entries-1].idx;
+                       entries[first+*r->out.num_entries-1].idx;
                return STATUS_MORE_ENTRIES;
        }
 
@@ -1859,8 +1883,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
        const char * const attrs[] = { "sAMAccountType", "objectSid", NULL };
        int count;
 
-       ZERO_STRUCT(r->out.rids);
-       ZERO_STRUCT(r->out.types);
+       ZERO_STRUCTP(r->out.rids);
+       ZERO_STRUCTP(r->out.types);
 
        DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
 
@@ -1870,13 +1894,13 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
                return NT_STATUS_OK;
        }
 
-       r->out.rids.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
-       r->out.types.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
-       if (!r->out.rids.ids || !r->out.types.ids) {
+       r->out.rids->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+       r->out.types->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+       if (!r->out.rids->ids || !r->out.types->ids) {
                return NT_STATUS_NO_MEMORY;
        }
-       r->out.rids.count = r->in.num_names;
-       r->out.types.count = r->in.num_names;
+       r->out.rids->count = r->in.num_names;
+       r->out.types->count = r->in.num_names;
 
        num_mapped = 0;
 
@@ -1885,8 +1909,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
                struct dom_sid *sid;
                uint32_t atype, rtype;
 
-               r->out.rids.ids[i] = 0;
-               r->out.types.ids[i] = SID_NAME_UNKNOWN;
+               r->out.rids->ids[i] = 0;
+               r->out.types->ids[i] = SID_NAME_UNKNOWN;
 
                count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs, 
                                     "sAMAccountName=%s", 
@@ -1915,8 +1939,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
                        continue;
                }
 
-               r->out.rids.ids[i] = sid->sub_auths[sid->num_auths-1];
-               r->out.types.ids[i] = rtype;
+               r->out.rids->ids[i] = sid->sub_auths[sid->num_auths-1];
+               r->out.types->ids[i] = rtype;
                num_mapped++;
        }
        
@@ -1940,8 +1964,8 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
        struct lsa_String *names;
        uint32_t *ids;
 
-       ZERO_STRUCT(r->out.names);
-       ZERO_STRUCT(r->out.types);
+       ZERO_STRUCTP(r->out.names);
+       ZERO_STRUCTP(r->out.types);
 
        DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
 
@@ -2002,11 +2026,11 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
                }
        }
 
-       r->out.names.names = names;
-       r->out.names.count = r->in.num_rids;
+       r->out.names->names = names;
+       r->out.names->count = r->in.num_rids;
 
-       r->out.types.ids = ids;
-       r->out.types.count = r->in.num_rids;
+       r->out.types->ids = ids;
+       r->out.types->count = r->in.num_rids;
 
        return status;
 }
@@ -2103,8 +2127,9 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
        const char * const attrs[4] = { "sAMAccountName", "description",
                                        "numMembers", NULL };
        int ret;
+       union samr_GroupInfo *info;
 
-       r->out.info = NULL;
+       *r->out.info = NULL;
 
        DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
 
@@ -2127,17 +2152,16 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
        msg = res->msgs[0];
 
        /* allocate the info structure */
-       r->out.info = talloc(mem_ctx, union samr_GroupInfo);
-       if (r->out.info == NULL) {
+       info = talloc_zero(mem_ctx, union samr_GroupInfo);
+       if (info == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
-       ZERO_STRUCTP(r->out.info);
 
        /* Fill in the level */
        switch (r->in.level) {
        case GROUPINFOALL:
                QUERY_STRING(msg, all.name,        "sAMAccountName");
-               r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+               info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
                QUERY_UINT  (msg, all.num_members,      "numMembers")
                QUERY_STRING(msg, all.description, "description");
                break;
@@ -2145,22 +2169,24 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
                QUERY_STRING(msg, name,            "sAMAccountName");
                break;
        case GROUPINFOATTRIBUTES:
-               r->out.info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+               info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
                break;
        case GROUPINFODESCRIPTION:
                QUERY_STRING(msg, description, "description");
                break;
        case GROUPINFOALL2:
                QUERY_STRING(msg, all2.name,        "sAMAccountName");
-               r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+               info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
                QUERY_UINT  (msg, all2.num_members,      "numMembers")
                QUERY_STRING(msg, all2.description, "description");
                break;
        default:
-               r->out.info = NULL;
+               talloc_free(info);
                return NT_STATUS_INVALID_INFO_CLASS;
        }
-       
+
+       *r->out.info = info;
+
        return NT_STATUS_OK;
 }
 
@@ -2467,7 +2493,7 @@ static NTSTATUS dcesrv_samr_QueryGroupMember(struct dcesrv_call_state *dce_call,
                }
        }
 
-       r->out.rids = array;
+       *r->out.rids = array;
 
        return NT_STATUS_OK;
 }
@@ -2574,8 +2600,9 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
        const char * const attrs[4] = { "sAMAccountName", "description",
                                        "numMembers", NULL };
        int ret;
+       union samr_AliasInfo *info;
 
-       r->out.info = NULL;
+       *r->out.info = NULL;
 
        DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
 
@@ -2590,11 +2617,10 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
        msg = res[0];
 
        /* allocate the info structure */
-       r->out.info = talloc(mem_ctx, union samr_AliasInfo);
-       if (r->out.info == NULL) {
+       info = talloc_zero(mem_ctx, union samr_AliasInfo);
+       if (info == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
-       ZERO_STRUCTP(r->out.info);
 
        switch(r->in.level) {
        case ALIASINFOALL:
@@ -2609,10 +2635,12 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
                QUERY_STRING(msg, description, "description");
                break;
        default:
-               r->out.info = NULL;
+               talloc_free(info);
                return NT_STATUS_INVALID_INFO_CLASS;
        }
-       
+
+       *r->out.info = info;
+
        return NT_STATUS_OK;
 }
 
@@ -2989,8 +3017,9 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
        struct ldb_context *sam_ctx;
 
        const char * const *attrs = NULL;
+       union samr_UserInfo *info;
 
-       r->out.info = NULL;
+       *r->out.info = NULL;
 
        DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
 
@@ -3175,11 +3204,10 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
        msg = res[0];
 
        /* allocate the info structure */
-       r->out.info = talloc(mem_ctx, union samr_UserInfo);
-       if (r->out.info == NULL) {
+       info = talloc_zero(mem_ctx, union samr_UserInfo);
+       if (info == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
-       ZERO_STRUCTP(r->out.info);
 
        /* fill in the reply */
        switch (r->in.level) {
@@ -3290,7 +3318,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
                break;
 
        case 20:
-               QUERY_STRING(msg, info20.parameters,    "userParameters");
+               QUERY_PARAMETERS(msg, info20.parameters,    "userParameters");
                break;
 
        case 21:
@@ -3309,11 +3337,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
                QUERY_STRING(msg, info21.description,          "description");
                QUERY_STRING(msg, info21.workstations,         "userWorkstations");
                QUERY_STRING(msg, info21.comment,              "comment");
-               QUERY_STRING(msg, info21.parameters,           "userParameters");
+               QUERY_PARAMETERS(msg, info21.parameters,       "userParameters");
                QUERY_RID   (msg, info21.rid,                  "objectSid");
                QUERY_UINT  (msg, info21.primary_gid,          "primaryGroupID");
                QUERY_AFLAGS(msg, info21.acct_flags,           "userAccountControl");
-               r->out.info->info21.fields_present = 0x00FFFFFF;
+               info->info21.fields_present = 0x00FFFFFF;
                QUERY_LHOURS(msg, info21.logon_hours,          "logonHours");
                QUERY_UINT  (msg, info21.bad_password_count,   "badPwdCount");
                QUERY_UINT  (msg, info21.logon_count,          "logonCount");
@@ -3323,10 +3351,12 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
                
 
        default:
-               r->out.info = NULL;
+               talloc_free(info);
                return NT_STATUS_INVALID_INFO_CLASS;
        }
-       
+
+       *r->out.info = info;
+
        return NT_STATUS_OK;
 }
 
@@ -3416,7 +3446,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
                break;
 
        case 20:
-               SET_STRING(msg, info20.parameters,      "userParameters");
+               SET_PARAMETERS(msg, info20.parameters,      "userParameters");
                break;
 
        case 21:
@@ -3446,7 +3476,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
                IFSET(SAMR_FIELD_ACCT_FLAGS)
                        SET_AFLAGS(msg, info21.acct_flags,     "userAccountControl");
                IFSET(SAMR_FIELD_PARAMETERS)   
-                       SET_STRING(msg, info21.parameters,     "userParameters");
+                       SET_PARAMETERS(msg, info21.parameters, "userParameters");
                IFSET(SAMR_FIELD_COUNTRY_CODE)
                        SET_UINT  (msg, info21.country_code,   "countryCode");
                IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3477,7 +3507,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
                IFSET(SAMR_FIELD_ACCT_FLAGS)     
                        SET_AFLAGS(msg, info23.info.acct_flags,   "userAccountControl");
                IFSET(SAMR_FIELD_PARAMETERS)     
-                       SET_STRING(msg, info23.info.parameters,   "userParameters");
+                       SET_PARAMETERS(msg, info23.info.parameters, "userParameters");
                IFSET(SAMR_FIELD_COUNTRY_CODE) 
                        SET_UINT  (msg, info23.info.country_code, "countryCode");
                IFSET(SAMR_FIELD_CODE_PAGE)    
@@ -3533,7 +3563,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
                IFSET(SAMR_FIELD_ACCT_FLAGS)     
                        SET_AFLAGS(msg, info25.info.acct_flags,   "userAccountControl");
                IFSET(SAMR_FIELD_PARAMETERS)     
-                       SET_STRING(msg, info25.info.parameters,   "userParameters");
+                       SET_PARAMETERS(msg, info25.info.parameters, "userParameters");
                IFSET(SAMR_FIELD_COUNTRY_CODE) 
                        SET_UINT  (msg, info25.info.country_code, "countryCode");
                IFSET(SAMR_FIELD_CODE_PAGE)    
@@ -3650,7 +3680,7 @@ static NTSTATUS dcesrv_samr_GetGroupsForUser(struct dcesrv_call_state *dce_call,
                }
        }
 
-       r->out.rids = array;
+       *r->out.rids = array;
 
        return NT_STATUS_OK;
 }
@@ -3808,65 +3838,65 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call,
                count += 1;
        }
 
-       r->out.total_size = count;
+       *r->out.total_size = count;
 
        if (r->in.start_idx >= count) {
-               r->out.returned_size = 0;
+               *r->out.returned_size = 0;
                switch(r->in.level) {
                case 1:
-                       r->out.info.info1.count = r->out.returned_size;
-                       r->out.info.info1.entries = NULL;
+                       r->out.info->info1.count = *r->out.returned_size;
+                       r->out.info->info1.entries = NULL;
                        break;
                case 2:
-                       r->out.info.info2.count = r->out.returned_size;
-                       r->out.info.info2.entries = NULL;
+                       r->out.info->info2.count = *r->out.returned_size;
+                       r->out.info->info2.entries = NULL;
                        break;
                case 3:
-                       r->out.info.info3.count = r->out.returned_size;
-                       r->out.info.info3.entries = NULL;
+                       r->out.info->info3.count = *r->out.returned_size;
+                       r->out.info->info3.entries = NULL;
                        break;
                case 4:
-                       r->out.info.info4.count = r->out.returned_size;
-                       r->out.info.info4.entries = NULL;
+                       r->out.info->info4.count = *r->out.returned_size;
+                       r->out.info->info4.entries = NULL;
                        break;
                case 5:
-                       r->out.info.info5.count = r->out.returned_size;
-                       r->out.info.info5.entries = NULL;
+                       r->out.info->info5.count = *r->out.returned_size;
+                       r->out.info->info5.entries = NULL;
                        break;
                }
        } else {
-               r->out.returned_size = MIN(count - r->in.start_idx,
+               *r->out.returned_size = MIN(count - r->in.start_idx,
                                           r->in.max_entries);
                switch(r->in.level) {
                case 1:
-                       r->out.info.info1.count = r->out.returned_size;
-                       r->out.info.info1.entries =
+                       r->out.info->info1.count = *r->out.returned_size;
+                       r->out.info->info1.entries =
                                &(entriesGeneral[r->in.start_idx]);
                        break;
                case 2:
-                       r->out.info.info2.count = r->out.returned_size;
-                       r->out.info.info2.entries =
+                       r->out.info->info2.count = *r->out.returned_size;
+                       r->out.info->info2.entries =
                                &(entriesFull[r->in.start_idx]);
                        break;
                case 3:
-                       r->out.info.info3.count = r->out.returned_size;
-                       r->out.info.info3.entries =
+                       r->out.info->info3.count = *r->out.returned_size;
+                       r->out.info->info3.entries =
                                &(entriesFullGroup[r->in.start_idx]);
                        break;
                case 4:
-                       r->out.info.info4.count = r->out.returned_size;
-                       r->out.info.info4.entries =
+                       r->out.info->info4.count = *r->out.returned_size;
+                       r->out.info->info4.entries =
                                &(entriesAscii[r->in.start_idx]);
                        break;
                case 5:
-                       r->out.info.info5.count = r->out.returned_size;
-                       r->out.info.info5.entries =
+                       r->out.info->info5.count = *r->out.returned_size;
+                       r->out.info->info5.entries =
                                &(entriesAscii[r->in.start_idx]);
                        break;
                }
        }
 
-       return (r->out.returned_size < (count - r->in.start_idx)) ?
+       return (*r->out.returned_size < (count - r->in.start_idx)) ?
                STATUS_MORE_ENTRIES : NT_STATUS_OK;
 }
 
@@ -3910,18 +3940,18 @@ static NTSTATUS dcesrv_samr_GetUserPwInfo(struct dcesrv_call_state *dce_call, TA
        struct dcesrv_handle *h;
        struct samr_account_state *a_state;
 
-       ZERO_STRUCT(r->out.info);
+       ZERO_STRUCTP(r->out.info);
 
        DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
 
        a_state = h->data;
 
-       r->out.info.min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
-                                                           a_state->domain_state->domain_dn, "minPwdLength", 
-                                                           NULL);
-       r->out.info.password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
-                                                           a_state->account_dn, 
-                                                           "pwdProperties", NULL);
+       r->out.info->min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+                                                            a_state->domain_state->domain_dn, "minPwdLength",
+                                                            NULL);
+       r->out.info->password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+                                                            a_state->account_dn,
+                                                            "pwdProperties", NULL);
        return NT_STATUS_OK;
 }
 
@@ -4008,11 +4038,10 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo2(struct dcesrv_call_state *dce_call,
        ZERO_STRUCT(r1.out);
        r1.in.domain_handle = r->in.domain_handle;
        r1.in.level  = r->in.level;
-       
+       r1.out.info  = r->out.info;
+
        status = dcesrv_samr_QueryDomainInfo(dce_call, mem_ctx, &r1);
        
-       r->out.info = r1.out.info;
-
        return status;
 }
 
@@ -4028,13 +4057,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo2(struct dcesrv_call_state *dce_call, T
        struct samr_QueryUserInfo r1;
        NTSTATUS status;
 
-       ZERO_STRUCT(r1.out);
        r1.in.user_handle = r->in.user_handle;
        r1.in.level  = r->in.level;
+       r1.out.info  = r->out.info;
        
        status = dcesrv_samr_QueryUserInfo(dce_call, mem_ctx, &r1);
-       
-       r->out.info = r1.out.info;
 
        return status;
 }
@@ -4054,14 +4081,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call
        q.in.start_idx = r->in.start_idx;
        q.in.max_entries = r->in.max_entries;
        q.in.buf_size = r->in.buf_size;
-       ZERO_STRUCT(q.out);
+       q.out.total_size = r->out.total_size;
+       q.out.returned_size = r->out.returned_size;
+       q.out.info = r->out.info;
 
        result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
 
-       r->out.total_size = q.out.total_size;
-       r->out.returned_size = q.out.returned_size;
-       r->out.info = q.out.info;
-
        return result;
 }
 
@@ -4090,14 +4115,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo3(struct dcesrv_call_state *dce_call
        q.in.start_idx = r->in.start_idx;
        q.in.max_entries = r->in.max_entries;
        q.in.buf_size = r->in.buf_size;
-       ZERO_STRUCT(q.out);
+       q.out.total_size = r->out.total_size;
+       q.out.returned_size = r->out.returned_size;
+       q.out.info = r->out.info;
 
        result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
 
-       r->out.total_size = q.out.total_size;
-       r->out.returned_size = q.out.returned_size;
-       r->out.info = q.out.info;
-
        return result;
 }
 
@@ -4138,7 +4161,7 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
        const char * const attrs[] = {"minPwdLength", "pwdProperties", NULL };
        struct ldb_context *sam_ctx;
 
-       ZERO_STRUCT(r->out.info);
+       ZERO_STRUCTP(r->out.info);
 
        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); 
        if (sam_ctx == NULL) {
@@ -4156,8 +4179,8 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       r->out.info.min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
-       r->out.info.password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
+       r->out.info->min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
+       r->out.info->password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
 
        talloc_free(msgs);
 
@@ -4267,9 +4290,9 @@ static NTSTATUS dcesrv_samr_Connect5(struct dcesrv_call_state *dce_call, TALLOC_
 
        status = dcesrv_samr_Connect(dce_call, mem_ctx, &c);
 
-       r->out.info->info1.client_version = SAMR_CONNECT_AFTER_W2K;
-       r->out.info->info1.unknown2 = 0;
-       r->out.level = r->in.level;
+       r->out.info_out->info1.client_version = SAMR_CONNECT_AFTER_W2K;
+       r->out.info_out->info1.unknown2 = 0;
+       *r->out.level_out = r->in.level_in;
 
        return status;
 }
@@ -4289,8 +4312,8 @@ static NTSTATUS dcesrv_samr_RidToSid(struct dcesrv_call_state *dce_call, TALLOC_
        d_state = h->data;
 
        /* form the users SID */
-       r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
-       if (!r->out.sid) {
+       *r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
+       if (!*r->out.sid) {
                return NT_STATUS_NO_MEMORY;
        }
 
index 1eb6a4f37c38c8d6cfdced7f48541d86cde5a4f9..ff8215a6734e19b3ae14378814a8531c5ec477e5 100644 (file)
@@ -352,7 +352,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
        uint8_t new_nt_hash[16], new_lm_hash[16];
        struct samr_Password nt_verifier, lm_verifier;
 
-       ZERO_STRUCT(r->out);
+       *r->out.dominfo = NULL;
+       *r->out.reject = NULL;
 
        if (r->in.nt_password == NULL ||
            r->in.nt_verifier == NULL) {
@@ -495,8 +496,8 @@ failed:
        talloc_free(sam_ctx);
 
        reject = talloc(mem_ctx, struct samr_ChangeReject);
-       r->out.dominfo = dominfo;
-       r->out.reject = reject;
+       *r->out.dominfo = dominfo;
+       *r->out.reject = reject;
 
        if (reject == NULL) {
                return status;
@@ -518,6 +519,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL
                                  struct samr_ChangePasswordUser2 *r)
 {
        struct samr_ChangePasswordUser3 r2;
+       struct samr_DomInfo1 *dominfo = NULL;
+       struct samr_ChangeReject *reject = NULL;
 
        r2.in.server = r->in.server;
        r2.in.account = r->in.account;
@@ -527,6 +530,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL
        r2.in.lm_password = r->in.lm_password;
        r2.in.lm_verifier = r->in.lm_verifier;
        r2.in.password3 = NULL;
+       r2.out.dominfo = &dominfo;
+       r2.out.reject = &reject;
 
        return dcesrv_samr_ChangePasswordUser3(dce_call, mem_ctx, &r2);
 }
index 7d5be368c2cc9a3c0d339b9c65471b9473f7c12b..3c28d1a019480854897c84478f75832ee2545a0f 100644 (file)
 
 static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                 struct policy_handle *handle, struct lsa_String *domname,
-                                uint32_t *access_mask, struct dom_sid **sid)
+                                uint32_t *access_mask, struct dom_sid **sid_p)
 {
        NTSTATUS status;
        struct policy_handle h, domain_handle;
        struct samr_Connect r1;
        struct samr_LookupDomain r2;
+       struct dom_sid2 *sid = NULL;
        struct samr_OpenDomain r3;
        
        printf("connecting\n");
@@ -59,6 +60,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        
        r2.in.connect_handle = &h;
        r2.in.domain_name = domname;
+       r2.out.sid = &sid;
 
        printf("domain lookup on %s\n", domname->string);
 
@@ -70,7 +72,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        r3.in.connect_handle = &h;
        r3.in.access_mask = *access_mask;
-       r3.in.sid = *sid = r2.out.sid;
+       r3.in.sid = *sid_p = *r2.out.sid;
        r3.out.domain_handle = &domain_handle;
 
        printf("opening domain\n");
index 12b8167a865a222559334709f743c415cb272e3e..9c9ecfd525ab0302743fd3aa0879b050b6025280 100644 (file)
@@ -42,12 +42,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct lsa_String names[2];
        uint32_t rid;
        struct policy_handle group_handle;
+       struct samr_Ids rids, types;
 
        names[0].string = groupname;
 
        r1.in.domain_handle  = domain_handle;
        r1.in.num_names      = 1;
        r1.in.names          = names;
+       r1.out.rids          = &rids;
+       r1.out.types         = &types;
        
        printf("group account lookup '%s'\n", groupname);
 
@@ -57,7 +60,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                return false;
        }
 
-       rid = r1.out.rids.ids[0];
+       rid = r1.out.rids->ids[0];
        
        r2.in.domain_handle  = domain_handle;
        r2.in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -139,6 +142,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct policy_handle h, domain_handle;
        struct samr_Connect r1;
        struct samr_LookupDomain r2;
+       struct dom_sid2 *sid = NULL;
        struct samr_OpenDomain r3;
        
        printf("connecting\n");
@@ -155,6 +159,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        
        r2.in.connect_handle = &h;
        r2.in.domain_name = domname;
+       r2.out.sid = &sid;
 
        printf("domain lookup on %s\n", domname->string);
 
@@ -166,7 +171,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        r3.in.connect_handle = &h;
        r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       r3.in.sid = r2.out.sid;
+       r3.in.sid = *r2.out.sid;
        r3.out.domain_handle = &domain_handle;
 
        printf("opening domain\n");
index 6d3e682976f3cceb2c69be68acd6f315d5f1ce9a..18007dccadd0f2e6804e7c98bf2b47a994fa34a9 100644 (file)
@@ -40,12 +40,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct lsa_String names[2];
        uint32_t rid;
        struct policy_handle user_handle;
+       struct samr_Ids rids, types;
 
        names[0].string = username;
 
        r1.in.domain_handle  = domain_handle;
        r1.in.num_names      = 1;
        r1.in.names          = names;
+       r1.out.rids          = &rids;
+       r1.out.types         = &types;
        
        printf("user account lookup '%s'\n", username);
 
@@ -55,7 +58,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                return false;
        }
 
-       rid = r1.out.rids.ids[0];
+       rid = r1.out.rids->ids[0];
        
        r2.in.domain_handle  = domain_handle;
        r2.in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -92,6 +95,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct policy_handle h, domain_handle;
        struct samr_Connect r1;
        struct samr_LookupDomain r2;
+       struct dom_sid2 *sid = NULL;
        struct samr_OpenDomain r3;
        
        printf("connecting\n");
@@ -108,6 +112,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        
        r2.in.connect_handle = &h;
        r2.in.domain_name = domname;
+       r2.out.sid = &sid;
 
        printf("domain lookup on %s\n", domname->string);
 
@@ -119,7 +124,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        r3.in.connect_handle = &h;
        r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       r3.in.sid = r2.out.sid;
+       r3.in.sid = *r2.out.sid;
        r3.out.domain_handle = &domain_handle;
 
        printf("opening domain\n");
index 54c5f2c29c1bb0817b249cfd9a228ed94f4d0f3b..942540c80e0b8877da3e09c7b9095ccb9b786972 100644 (file)
 bool test_opendomain(struct torture_context *tctx, 
                     struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                     struct policy_handle *handle, struct lsa_String *domname,
-                    struct dom_sid2 *sid)
+                    struct dom_sid2 *sid_p)
 {
        NTSTATUS status;
        struct policy_handle h, domain_handle;
        struct samr_Connect r1;
        struct samr_LookupDomain r2;
+       struct dom_sid2 *sid = NULL;
        struct samr_OpenDomain r3;
        
        torture_comment(tctx, "connecting\n");
@@ -51,6 +52,7 @@ bool test_opendomain(struct torture_context *tctx,
        
        r2.in.connect_handle = &h;
        r2.in.domain_name = domname;
+       r2.out.sid = &sid;
 
        torture_comment(tctx, "domain lookup on %s\n", domname->string);
 
@@ -59,7 +61,7 @@ bool test_opendomain(struct torture_context *tctx,
 
        r3.in.connect_handle = &h;
        r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       r3.in.sid = r2.out.sid;
+       r3.in.sid = *r2.out.sid;
        r3.out.domain_handle = &domain_handle;
 
        torture_comment(tctx, "opening domain\n");
@@ -68,7 +70,7 @@ bool test_opendomain(struct torture_context *tctx,
        torture_assert_ntstatus_ok(tctx, status, "OpenDomain failed");
        *handle = domain_handle;
 
-       *sid = *r2.out.sid;
+       *sid_p = **r2.out.sid;
        return true;
 }
 
@@ -84,19 +86,22 @@ bool test_user_cleanup(struct torture_context *tctx, struct dcerpc_pipe *p,
        struct lsa_String names[2];
        uint32_t rid;
        struct policy_handle user_handle;
+       struct samr_Ids rids, types;
 
        names[0].string = name;
 
        r1.in.domain_handle  = domain_handle;
        r1.in.num_names      = 1;
        r1.in.names          = names;
+       r1.out.rids          = &rids;
+       r1.out.types         = &types;
        
        torture_comment(tctx, "user account lookup '%s'\n", name);
 
        status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
        torture_assert_ntstatus_ok(tctx, status, "LookupNames failed");
 
-       rid = r1.out.rids.ids[0];
+       rid = r1.out.rids->ids[0];
        
        r2.in.domain_handle  = domain_handle;
        r2.in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -174,12 +179,15 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct lsa_String names[2];
        uint32_t rid;
        struct policy_handle group_handle;
+       struct samr_Ids rids, types;
 
        names[0].string = name;
 
        r1.in.domain_handle  = domain_handle;
        r1.in.num_names      = 1;
        r1.in.names          = names;
+       r1.out.rids          = &rids;
+       r1.out.types         = &types;
        
        printf("group account lookup '%s'\n", name);
 
@@ -189,7 +197,7 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                return false;
        }
 
-       rid = r1.out.rids.ids[0];
+       rid = r1.out.rids->ids[0];
        
        r2.in.domain_handle  = domain_handle;
        r2.in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;
index c2b849127fa6574c75509422d26d3b7a93d09f79..1148262dfe3e94bee0adc040d16274ffb445ec50 100644 (file)
@@ -355,7 +355,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
                               char **domain,
                               struct dcerpc_pipe **result_pipe,
                               struct policy_handle **result_handle,
-                              struct dom_sid **sid)
+                              struct dom_sid **sid_p)
 {
        struct dcerpc_pipe *samr_pipe;
        NTSTATUS status;
@@ -365,7 +365,10 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
        struct samr_Connect2 conn;
        struct samr_EnumDomains enumdom;
        uint32_t resume_handle = 0;
+       uint32_t num_entries = 0;
+       struct samr_SamArray *sam = NULL;
        struct samr_LookupDomain l;
+       struct dom_sid2 *sid = NULL;
        int dom_idx;
        struct lsa_String domain_name;
        struct lsa_String user_name;
@@ -423,6 +426,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
        enumdom.in.resume_handle = &resume_handle;
        enumdom.in.buf_size = (uint32_t)-1;
        enumdom.out.resume_handle = &resume_handle;
+       enumdom.out.num_entries = &num_entries;
+       enumdom.out.sam = &sam;
 
        status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom);
        if (!NT_STATUS_IS_OK(status)) {
@@ -430,20 +435,21 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
                goto fail;
        }
 
-       if (enumdom.out.num_entries != 2) {
+       if (*enumdom.out.num_entries != 2) {
                d_printf("samr_EnumDomains returned %d entries, expected 2\n",
-                        enumdom.out.num_entries);
+                        *enumdom.out.num_entries);
                status = NT_STATUS_UNSUCCESSFUL;
                goto fail;
        }
 
-       dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
+       dom_idx = strequal(sam->entries[0].name.string,
                           "builtin") ? 1:0;
 
        l.in.connect_handle = &conn_handle;
-       domain_name.string = enumdom.out.sam->entries[dom_idx].name.string;
+       domain_name.string = sam->entries[dom_idx].name.string;
        *domain = talloc_strdup(mem_ctx, domain_name.string);
        l.in.domain_name = &domain_name;
+       l.out.sid = &sid;
 
        status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l);
        if (!NT_STATUS_IS_OK(status)) {
@@ -453,7 +459,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
 
        o.in.connect_handle = &conn_handle;
        o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       o.in.sid = l.out.sid;
+       o.in.sid = *l.out.sid;
        o.out.domain_handle = &domain_handle;
 
        status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o);
@@ -477,10 +483,13 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
        if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
                struct samr_LookupNames ln;
                struct samr_OpenUser ou;
+               struct samr_Ids rids, types;
 
                ln.in.domain_handle = &domain_handle;
                ln.in.num_names = 1;
                ln.in.names = &user_name;
+               ln.out.rids = &rids;
+               ln.out.types = &types;
 
                status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln);
                if (!NT_STATUS_IS_OK(status)) {
@@ -491,7 +500,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
 
                ou.in.domain_handle = &domain_handle;
                ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-               user_rid = ou.in.rid = ln.out.rids.ids[0];
+               user_rid = ou.in.rid = ln.out.rids->ids[0];
                ou.out.user_handle = user_handle;
 
                status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
@@ -509,8 +518,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
 
        *result_pipe = samr_pipe;
        *result_handle = user_handle;
-       if (sid != NULL) {
-               *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
+       if (sid_p != NULL) {
+               *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid);
        }
        return NT_STATUS_OK;
 
@@ -555,6 +564,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
                struct samr_SetUserInfo sui;
                struct samr_QueryUserInfo qui;
                union samr_UserInfo u_info;
+               union samr_UserInfo *info;
                DATA_BLOB session_key;
 
 
@@ -597,6 +607,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
 
                qui.in.user_handle = wks_handle;
                qui.in.level = 21;
+               qui.out.info = &info;
 
                status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
                if (!NT_STATUS_IS_OK(status)) {
@@ -604,14 +615,14 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
                        goto done;
                }
 
-               qui.out.info->info21.allow_password_change = 0;
-               qui.out.info->info21.force_password_change = 0;
-               qui.out.info->info21.account_name.string = NULL;
-               qui.out.info->info21.rid = 0;
-               qui.out.info->info21.acct_expiry = 0;
-               qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
+               info->info21.allow_password_change = 0;
+               info->info21.force_password_change = 0;
+               info->info21.account_name.string = NULL;
+               info->info21.rid = 0;
+               info->info21.acct_expiry = 0;
+               info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
 
-               u_info.info21 = qui.out.info->info21;
+               u_info.info21 = info->info21;
                sui.in.user_handle = wks_handle;
                sui.in.info = &u_info;
                sui.in.level = 21;
@@ -721,9 +732,11 @@ static bool join3(struct smbcli_state *cli,
 
        {
                struct samr_QueryUserInfo q;
+               union samr_UserInfo *info;
 
                q.in.user_handle = wks_handle;
                q.in.level = 21;
+               q.out.info = &info;
 
                status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
                if (!NT_STATUS_IS_OK(status)) {
@@ -732,7 +745,7 @@ static bool join3(struct smbcli_state *cli,
                        goto done;
                }
 
-               last_password_change = q.out.info->info21.last_password_change;
+               last_password_change = info->info21.last_password_change;
        }
 
        cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
@@ -830,9 +843,11 @@ static bool join3(struct smbcli_state *cli,
 
        {
                struct samr_QueryUserInfo q;
+               union samr_UserInfo *info;
 
                q.in.user_handle = wks_handle;
                q.in.level = 21;
+               q.out.info = &info;
 
                status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
                if (!NT_STATUS_IS_OK(status)) {
@@ -843,7 +858,7 @@ static bool join3(struct smbcli_state *cli,
 
                if (use_level25) {
                        if (last_password_change
-                           == q.out.info->info21.last_password_change) {
+                           == info->info21.last_password_change) {
                                d_printf("(%s) last_password_change unchanged "
                                         "during join, level25 must change "
                                         "it\n", __location__);
@@ -852,7 +867,7 @@ static bool join3(struct smbcli_state *cli,
                }
                else {
                        if (last_password_change
-                           != q.out.info->info21.last_password_change) {
+                           != info->info21.last_password_change) {
                                d_printf("(%s) last_password_change changed "
                                         "during join, level24 doesn't "
                                         "change it\n", __location__);
index 23c288bfcc00cf24cea1cae2a45aa200203ae400..87690178a73246bcc4dc45e59f77a71770274720 100644 (file)
@@ -59,6 +59,13 @@ static void init_lsa_String(struct lsa_String *string, const char *s)
        string->string = s;
 }
 
+static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
+{
+       string->length = length;
+       string->size = length;
+       string->array = (uint16_t *)discard_const(s);
+}
+
 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
                                   struct policy_handle *handle)
 {
@@ -131,18 +138,20 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p,
        NTSTATUS status;
        struct samr_QuerySecurity r;
        struct samr_SetSecurity s;
+       struct sec_desc_buf *sdbuf = NULL;
 
        r.in.handle = handle;
        r.in.sec_info = 7;
+       r.out.sdbuf = &sdbuf;
 
        status = dcerpc_samr_QuerySecurity(p, tctx, &r);
        torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
 
-       torture_assert(tctx, r.out.sdbuf != NULL, "sdbuf is NULL");
+       torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
 
        s.in.handle = handle;
        s.in.sec_info = 7;
-       s.in.sdbuf = r.out.sdbuf;
+       s.in.sdbuf = sdbuf;
 
        if (torture_setting_bool(tctx, "samba4", false)) {
                torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
@@ -168,6 +177,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
        struct samr_QueryUserInfo q;
        struct samr_QueryUserInfo q0;
        union samr_UserInfo u;
+       union samr_UserInfo *info;
        bool ret = true;
        const char *test_account_name;
 
@@ -184,7 +194,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
        s2.in.info = &u;
 
        q.in.user_handle = handle;
-       q.out.info = &u;
+       q.out.info = &info;
        q0 = q;
 
 #define TESTCALL(call, r) \
@@ -204,6 +214,14 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
                        break; \
                }
 
+#define MEM_EQUAL(s1, s2, length, field) \
+               if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
+                       torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
+                              #field, (const char *)s2, __location__); \
+                       ret = false; \
+                       break; \
+               }
+
 #define INT_EQUAL(i1, i2, field) \
                if (i1 != i2) { \
                        torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
@@ -218,7 +236,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
                TESTCALL(QueryUserInfo, q) \
                s.in.level = lvl1; \
                s2.in.level = lvl1; \
-               u = *q.out.info; \
+               u = *info; \
                if (lvl1 == 21) { \
                        ZERO_STRUCT(u.info21); \
                        u.info21.fields_present = fpval; \
@@ -228,21 +246,45 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
                TESTCALL(SetUserInfo2, s2) \
                init_lsa_String(&u.info ## lvl1.field1, ""); \
                TESTCALL(QueryUserInfo, q); \
-               u = *q.out.info; \
+               u = *info; \
                STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
                q.in.level = lvl2; \
                TESTCALL(QueryUserInfo, q) \
-               u = *q.out.info; \
+               u = *info; \
                STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
        } while (0)
 
+#define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
+               torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+               q.in.level = lvl1; \
+               TESTCALL(QueryUserInfo, q) \
+               s.in.level = lvl1; \
+               s2.in.level = lvl1; \
+               u = *info; \
+               if (lvl1 == 21) { \
+                       ZERO_STRUCT(u.info21); \
+                       u.info21.fields_present = fpval; \
+               } \
+               init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
+               TESTCALL(SetUserInfo, s) \
+               TESTCALL(SetUserInfo2, s2) \
+               init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
+               TESTCALL(QueryUserInfo, q); \
+               u = *info; \
+               MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
+               q.in.level = lvl2; \
+               TESTCALL(QueryUserInfo, q) \
+               u = *info; \
+               MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
+       } while (0)
+
 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
                torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
                q.in.level = lvl1; \
                TESTCALL(QueryUserInfo, q) \
                s.in.level = lvl1; \
                s2.in.level = lvl1; \
-               u = *q.out.info; \
+               u = *info; \
                if (lvl1 == 21) { \
                        uint8_t *bits = u.info21.logon_hours.bits; \
                        ZERO_STRUCT(u.info21); \
@@ -257,11 +299,11 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
                TESTCALL(SetUserInfo2, s2) \
                u.info ## lvl1.field1 = 0; \
                TESTCALL(QueryUserInfo, q); \
-               u = *q.out.info; \
+               u = *info; \
                INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
                q.in.level = lvl2; \
                TESTCALL(QueryUserInfo, q) \
-               u = *q.out.info; \
+               u = *info; \
                INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
        } while (0)
 
@@ -359,10 +401,10 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
        TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", 
                           SAMR_FIELD_WORKSTATIONS);
 
-       TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
-       TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters", 
+       TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
+       TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
                           SAMR_FIELD_PARAMETERS);
-       TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters", 
+       TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
                           SAMR_FIELD_PARAMETERS);
 
        TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
@@ -512,12 +554,14 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx
        DATA_BLOB session_key;
        char *newpass;
        struct samr_GetUserPwInfo pwp;
+       struct samr_PwInfo info;
        int policy_min_pw_len = 0;
        pwp.in.user_handle = handle;
+       pwp.out.info = &info;
 
        status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
        if (NT_STATUS_IS_OK(status)) {
-               policy_min_pw_len = pwp.out.info.min_password_length;
+               policy_min_pw_len = pwp.out.info->min_password_length;
        }
        newpass = samr_rand_pass(tctx, policy_min_pw_len);
 
@@ -564,12 +608,14 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t
        DATA_BLOB session_key;
        char *newpass;
        struct samr_GetUserPwInfo pwp;
+       struct samr_PwInfo info;
        int policy_min_pw_len = 0;
        pwp.in.user_handle = handle;
+       pwp.out.info = &info;
 
        status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
        if (NT_STATUS_IS_OK(status)) {
-               policy_min_pw_len = pwp.out.info.min_password_length;
+               policy_min_pw_len = pwp.out.info->min_password_length;
        }
        newpass = samr_rand_pass(tctx, policy_min_pw_len);
 
@@ -643,12 +689,14 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc
        char *newpass;
        struct MD5Context ctx;
        struct samr_GetUserPwInfo pwp;
+       struct samr_PwInfo info;
        int policy_min_pw_len = 0;
        pwp.in.user_handle = handle;
+       pwp.out.info = &info;
 
        status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
        if (NT_STATUS_IS_OK(status)) {
-               policy_min_pw_len = pwp.out.info.min_password_length;
+               policy_min_pw_len = pwp.out.info->min_password_length;
        }
        if (makeshort && policy_min_pw_len) {
                newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
@@ -725,12 +773,14 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t
        uint8_t confounder[16];
        char *newpass;
        struct samr_GetUserPwInfo pwp;
+       struct samr_PwInfo info;
        int policy_min_pw_len = 0;
        pwp.in.user_handle = handle;
+       pwp.out.info = &info;
 
        status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
        if (NT_STATUS_IS_OK(status)) {
-               policy_min_pw_len = pwp.out.info.min_password_length;
+               policy_min_pw_len = pwp.out.info->min_password_length;
        }
        newpass = samr_rand_pass(tctx, policy_min_pw_len);
 
@@ -796,6 +846,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct
        NTSTATUS status;
        struct samr_SetAliasInfo r;
        struct samr_QueryAliasInfo q;
+       union samr_AliasInfo *info;
        uint16_t levels[] = {2, 3};
        int i;
        bool ret = true;
@@ -826,6 +877,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct
 
                q.in.alias_handle = handle;
                q.in.level = levels[i];
+               q.out.info = &info;
 
                status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
                if (!NT_STATUS_IS_OK(status)) {
@@ -842,11 +894,13 @@ static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context
                                  struct policy_handle *user_handle)
 {
        struct samr_GetGroupsForUser r;
+       struct samr_RidWithAttributeArray *rids = NULL;
        NTSTATUS status;
 
        torture_comment(tctx, "testing GetGroupsForUser\n");
 
        r.in.user_handle = user_handle;
+       r.out.rids = &rids;
 
        status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
        torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
@@ -860,8 +914,11 @@ static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tct
 {
        NTSTATUS status;
        struct samr_GetDomPwInfo r;
+       struct samr_PwInfo info;
 
        r.in.domain_name = domain_name;
+       r.out.info = &info;
+
        torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
 
        status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
@@ -893,10 +950,12 @@ static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tc
 {
        NTSTATUS status;
        struct samr_GetUserPwInfo r;
+       struct samr_PwInfo info;
 
        torture_comment(tctx, "Testing GetUserPwInfo\n");
 
        r.in.user_handle = handle;
+       r.out.info = &info;
 
        status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
        torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
@@ -911,15 +970,18 @@ static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *t
        NTSTATUS status;
        struct samr_LookupNames n;
        struct lsa_String sname[2];
+       struct samr_Ids rids, types;
 
        init_lsa_String(&sname[0], name);
 
        n.in.domain_handle = domain_handle;
        n.in.num_names = 1;
        n.in.names = sname;
+       n.out.rids = &rids;
+       n.out.types = &types;
        status = dcerpc_samr_LookupNames(p, tctx, &n);
        if (NT_STATUS_IS_OK(status)) {
-               *rid = n.out.rids.ids[0];
+               *rid = n.out.rids->ids[0];
        } else {
                return status;
        }
@@ -1071,6 +1133,7 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex
 
        char *newpass;
        struct samr_GetUserPwInfo pwp;
+       struct samr_PwInfo info;
        int policy_min_pw_len = 0;
 
        status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
@@ -1078,10 +1141,11 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex
                return false;
        }
        pwp.in.user_handle = &user_handle;
+       pwp.out.info = &info;
 
        status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
        if (NT_STATUS_IS_OK(status)) {
-               policy_min_pw_len = pwp.out.info.min_password_length;
+               policy_min_pw_len = pwp.out.info->min_password_length;
        }
        newpass = samr_rand_pass(tctx, policy_min_pw_len);
 
@@ -1346,12 +1410,14 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co
        uint8_t old_lm_hash[16], new_lm_hash[16];
 
        struct samr_GetDomPwInfo dom_pw_info;
+       struct samr_PwInfo info;
        int policy_min_pw_len = 0;
 
        struct lsa_String domain_name;
 
        domain_name.string = "";
        dom_pw_info.in.domain_name = &domain_name;
+       dom_pw_info.out.info = &info;
 
        torture_comment(tctx, "Testing OemChangePasswordUser2\n");
 
@@ -1362,7 +1428,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co
 
        status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
        if (NT_STATUS_IS_OK(status)) {
-               policy_min_pw_len = dom_pw_info.out.info.min_password_length;
+               policy_min_pw_len = dom_pw_info.out.info->min_password_length;
        }
 
        newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1515,11 +1581,13 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte
        uint8_t old_lm_hash[16], new_lm_hash[16];
 
        struct samr_GetDomPwInfo dom_pw_info;
+       struct samr_PwInfo info;
 
        struct lsa_String domain_name;
 
        domain_name.string = "";
        dom_pw_info.in.domain_name = &domain_name;
+       dom_pw_info.out.info = &info;
 
        torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
 
@@ -1531,7 +1599,7 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte
                int policy_min_pw_len = 0;
                status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
                if (NT_STATUS_IS_OK(status)) {
-                       policy_min_pw_len = dom_pw_info.out.info.min_password_length;
+                       policy_min_pw_len = dom_pw_info.out.info->min_password_length;
                }
 
                newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1594,6 +1662,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
        uint8_t old_nt_hash[16], new_nt_hash[16];
        uint8_t old_lm_hash[16], new_lm_hash[16];
        NTTIME t;
+       struct samr_DomInfo1 *dominfo = NULL;
+       struct samr_ChangeReject *reject = NULL;
 
        torture_comment(tctx, "Testing ChangePasswordUser3\n");
 
@@ -1641,6 +1711,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
        r.in.lm_password = &lm_pass;
        r.in.lm_verifier = &lm_verifier;
        r.in.password3 = NULL;
+       r.out.dominfo = &dominfo;
+       r.out.reject = &reject;
 
        status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
@@ -1670,6 +1742,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
        r.in.lm_password = &lm_pass;
        r.in.lm_verifier = &lm_verifier;
        r.in.password3 = NULL;
+       r.out.dominfo = &dominfo;
+       r.out.reject = &reject;
 
        status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
@@ -1712,21 +1786,23 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
        r.in.lm_password = &lm_pass;
        r.in.lm_verifier = &lm_verifier;
        r.in.password3 = NULL;
+       r.out.dominfo = &dominfo;
+       r.out.reject = &reject;
 
        unix_to_nt_time(&t, time(NULL));
 
        status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
-           && r.out.dominfo
-           && r.out.reject
+           && dominfo
+           && reject
            && handle_reject_reason
-           && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
-               if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
+           && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
+               if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
 
-                       if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
+                       if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
                                printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
-                                       SAMR_REJECT_OTHER, r.out.reject->reason);
+                                       SAMR_REJECT_OTHER, reject->reason);
                                return false;
                        }
                }
@@ -1740,54 +1816,54 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
 
                Guenther */
 
-               if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) && 
-                          (last_password_change + r.out.dominfo->min_password_age > t)) {
+               if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
+                          (last_password_change + dominfo->min_password_age > t)) {
 
-                       if (r.out.reject->reason != SAMR_REJECT_OTHER) {
+                       if (reject->reason != SAMR_REJECT_OTHER) {
                                printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
-                                       SAMR_REJECT_OTHER, r.out.reject->reason);
+                                       SAMR_REJECT_OTHER, reject->reason);
                                return false;
                        }
 
-               } else if ((r.out.dominfo->min_password_length > 0) && 
-                          (strlen(newpass) < r.out.dominfo->min_password_length)) {
+               } else if ((dominfo->min_password_length > 0) &&
+                          (strlen(newpass) < dominfo->min_password_length)) {
 
-                       if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
+                       if (reject->reason != SAMR_REJECT_TOO_SHORT) {
                                printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
-                                       SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
+                                       SAMR_REJECT_TOO_SHORT, reject->reason);
                                return false;
                        }
 
-               } else if ((r.out.dominfo->password_history_length > 0) && 
+               } else if ((dominfo->password_history_length > 0) &&
                            strequal(oldpass, newpass)) {
 
-                       if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
+                       if (reject->reason != SAMR_REJECT_IN_HISTORY) {
                                printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
-                                       SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
+                                       SAMR_REJECT_IN_HISTORY, reject->reason);
                                return false;
                        }
-               } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
+               } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
 
-                       if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
+                       if (reject->reason != SAMR_REJECT_COMPLEXITY) {
                                printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
-                                       SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
+                                       SAMR_REJECT_COMPLEXITY, reject->reason);
                                return false;
                        }
 
                }
 
-               if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
+               if (reject->reason == SAMR_REJECT_TOO_SHORT) {
                        /* retry with adjusted size */
                        return test_ChangePasswordUser3(p, tctx, account_string, 
-                                                       r.out.dominfo->min_password_length, 
+                                                       dominfo->min_password_length,
                                                        password, NULL, 0, false); 
 
                }
 
        } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
-               if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+               if (reject && reject->reason != SAMR_REJECT_OTHER) {
                        printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
-                              SAMR_REJECT_OTHER, r.out.reject->reason);
+                              SAMR_REJECT_OTHER, reject->reason);
                        return false;
                }
                /* Perhaps the server has a 'min password age' set? */
@@ -1823,6 +1899,8 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
        char *oldpass;
        uint8_t old_nt_hash[16], new_nt_hash[16];
        NTTIME t;
+       struct samr_DomInfo1 *dominfo = NULL;
+       struct samr_ChangeReject *reject = NULL;
 
        new_random_pass = samr_very_rand_pass(tctx, 128);
 
@@ -1889,15 +1967,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
        r.in.lm_password = NULL;
        r.in.lm_verifier = NULL;
        r.in.password3 = NULL;
+       r.out.dominfo = &dominfo;
+       r.out.reject = &reject;
 
        unix_to_nt_time(&t, time(NULL));
 
        status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
-               if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+               if (reject && reject->reason != SAMR_REJECT_OTHER) {
                        printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
-                              SAMR_REJECT_OTHER, r.out.reject->reason);
+                              SAMR_REJECT_OTHER, reject->reason);
                        return false;
                }
                /* Perhaps the server has a 'min password age' set? */
@@ -1925,15 +2005,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
        r.in.lm_password = NULL;
        r.in.lm_verifier = NULL;
        r.in.password3 = NULL;
+       r.out.dominfo = &dominfo;
+       r.out.reject = &reject;
 
        unix_to_nt_time(&t, time(NULL));
 
        status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
-               if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+               if (reject && reject->reason != SAMR_REJECT_OTHER) {
                        printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
-                              SAMR_REJECT_OTHER, r.out.reject->reason);
+                              SAMR_REJECT_OTHER, reject->reason);
                        return false;
                }
                /* Perhaps the server has a 'min password age' set? */
@@ -2061,6 +2143,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
 {
        char *password = NULL;
        struct samr_QueryUserInfo q;
+       union samr_UserInfo *info;
        NTSTATUS status;
 
        bool ret = true;
@@ -2176,6 +2259,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
 
                q.in.user_handle = user_handle;
                q.in.level = 5;
+               q.out.info = &info;
                
                status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
                if (!NT_STATUS_IS_OK(status)) {
@@ -2184,15 +2268,15 @@ static bool test_user_ops(struct dcerpc_pipe *p,
                        ret = false;
                } else {
                        uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
-                       if ((q.out.info->info5.acct_flags) != expected_flags) {
+                       if ((info->info5.acct_flags) != expected_flags) {
                                printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
-                                      q.out.info->info5.acct_flags, 
+                                      info->info5.acct_flags,
                                       expected_flags);
                                ret = false;
                        }
-                       if (q.out.info->info5.rid != rid) {
+                       if (info->info5.rid != rid) {
                                printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
-                                      q.out.info->info5.rid, rid);
+                                      info->info5.rid, rid);
 
                        }
                }
@@ -2481,6 +2565,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        /* set samr_SetDomainInfo level 1 with min_length 5 */
        {
                struct samr_QueryDomainInfo r;
+               union samr_DomainInfo *info = NULL;
                struct samr_SetDomainInfo s;
                uint16_t len_old, len;
                uint32_t pwd_prop_old;
@@ -2491,6 +2576,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
                r.in.domain_handle = domain_handle;
                r.in.level = 1;
+               r.out.info = &info;
 
                printf("testing samr_QueryDomainInfo level 1\n");
                status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
@@ -2500,7 +2586,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
                s.in.domain_handle = domain_handle;
                s.in.level = 1;
-               s.in.info = r.out.info;
+               s.in.info = info;
 
                /* remember the old min length, so we can reset it */
                len_old = s.in.info->info1.min_password_length;
@@ -2540,13 +2626,17 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                NTSTATUS status;
                struct samr_OpenUser r;
                struct samr_QueryUserInfo q;
+               union samr_UserInfo *info;
                struct samr_LookupNames n;
                struct policy_handle user_handle;
+               struct samr_Ids rids, types;
 
                n.in.domain_handle = domain_handle;
                n.in.num_names = 1;
                n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
                n.in.names[0].string = acct_name; 
+               n.out.rids = &rids;
+               n.out.types = &types;
 
                status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
                if (!NT_STATUS_IS_OK(status)) {
@@ -2556,17 +2646,18 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
                r.in.domain_handle = domain_handle;
                r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-               r.in.rid = n.out.rids.ids[0];
+               r.in.rid = n.out.rids->ids[0];
                r.out.user_handle = &user_handle;
 
                status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
+                       printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
                        return false;
                }
 
                q.in.user_handle = &user_handle;
                q.in.level = 5;
+               q.out.info = &info;
 
                status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
                if (!NT_STATUS_IS_OK(status)) {
@@ -2577,7 +2668,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                printf("calling test_ChangePasswordUser3 with too early password change\n");
 
                if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 
-                                             q.out.info->info5.last_password_change, true)) {
+                                             info->info5.last_password_change, true)) {
                        ret = false;
                }
        }
@@ -2607,6 +2698,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
        NTSTATUS status;
        struct samr_CreateUser r;
        struct samr_QueryUserInfo q;
+       union samr_UserInfo *info;
        struct samr_DeleteUser d;
        uint32_t rid;
 
@@ -2654,6 +2746,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
        } else {
                q.in.user_handle = &user_handle;
                q.in.level = 16;
+               q.out.info = &info;
                
                status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
                if (!NT_STATUS_IS_OK(status)) {
@@ -2661,9 +2754,9 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
                               q.in.level, nt_errstr(status));
                        ret = false;
                } else {
-                       if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
+                       if ((info->info16.acct_flags & acct_flags) != acct_flags) {
                                printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
-                                      q.out.info->info16.acct_flags, 
+                                      info->info16.acct_flags,
                                       acct_flags);
                                ret = false;
                        }
@@ -2705,6 +2798,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
        NTSTATUS status;
        struct samr_CreateUser2 r;
        struct samr_QueryUserInfo q;
+       union samr_UserInfo *info;
        struct samr_DeleteUser d;
        struct policy_handle user_handle;
        uint32_t rid;
@@ -2783,6 +2877,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
                if (NT_STATUS_IS_OK(status)) {
                        q.in.user_handle = &user_handle;
                        q.in.level = 5;
+                       q.out.info = &info;
                        
                        status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
                        if (!NT_STATUS_IS_OK(status)) {
@@ -2794,31 +2889,31 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
                                if (acct_flags == ACB_NORMAL) {
                                        expected_flags |= ACB_PW_EXPIRED;
                                }
-                               if ((q.out.info->info5.acct_flags) != expected_flags) {
+                               if ((info->info5.acct_flags) != expected_flags) {
                                        printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
-                                              q.out.info->info5.acct_flags, 
+                                              info->info5.acct_flags,
                                               expected_flags);
                                        ret = false;
                                } 
                                switch (acct_flags) {
                                case ACB_SVRTRUST:
-                                       if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
+                                       if (info->info5.primary_gid != DOMAIN_RID_DCS) {
                                                printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", 
-                                                      DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
+                                                      DOMAIN_RID_DCS, info->info5.primary_gid);
                                                ret = false;
                                        }
                                        break;
                                case ACB_WSTRUST:
-                                       if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
+                                       if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
                                                printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", 
-                                                      DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
+                                                      DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
                                                ret = false;
                                        }
                                        break;
                                case ACB_NORMAL:
-                                       if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
+                                       if (info->info5.primary_gid != DOMAIN_RID_USERS) {
                                                printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", 
-                                                      DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
+                                                      DOMAIN_RID_USERS, info->info5.primary_gid);
                                                ret = false;
                                        }
                                        break;
@@ -2852,6 +2947,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 {
        NTSTATUS status;
        struct samr_QueryAliasInfo r;
+       union samr_AliasInfo *info;
        uint16_t levels[] = {1, 2, 3};
        int i;
        bool ret = true;
@@ -2861,6 +2957,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
                r.in.alias_handle = handle;
                r.in.level = levels[i];
+               r.out.info = &info;
 
                status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -2878,6 +2975,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 {
        NTSTATUS status;
        struct samr_QueryGroupInfo r;
+       union samr_GroupInfo *info;
        uint16_t levels[] = {1, 2, 3, 4, 5};
        int i;
        bool ret = true;
@@ -2887,6 +2985,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
                r.in.group_handle = handle;
                r.in.level = levels[i];
+               r.out.info = &info;
 
                status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -2904,11 +3003,13 @@ static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 {
        NTSTATUS status;
        struct samr_QueryGroupMember r;
+       struct samr_RidTypeArray *rids = NULL;
        bool ret = true;
 
        printf("Testing QueryGroupMember\n");
 
        r.in.group_handle = handle;
+       r.out.rids = &rids;
 
        status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
@@ -2925,6 +3026,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 {
        NTSTATUS status;
        struct samr_QueryGroupInfo r;
+       union samr_GroupInfo *info;
        struct samr_SetGroupInfo s;
        uint16_t levels[] = {1, 2, 3, 4};
        uint16_t set_ok[] = {0, 1, 1, 1};
@@ -2936,6 +3038,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
                r.in.group_handle = handle;
                r.in.level = levels[i];
+               r.out.info = &info;
 
                status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -2948,7 +3051,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
                s.in.group_handle = handle;
                s.in.level = levels[i];
-               s.in.info = r.out.info;
+               s.in.info = *r.out.info;
 
 #if 0
                /* disabled this, as it changes the name only from the point of view of samr, 
@@ -2990,6 +3093,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 {
        NTSTATUS status;
        struct samr_QueryUserInfo r;
+       union samr_UserInfo *info;
        uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                           11, 12, 13, 14, 16, 17, 20, 21};
        int i;
@@ -3000,6 +3104,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
                r.in.user_handle = handle;
                r.in.level = levels[i];
+               r.out.info = &info;
 
                status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -3017,6 +3122,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 {
        NTSTATUS status;
        struct samr_QueryUserInfo2 r;
+       union samr_UserInfo *info;
        uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                           11, 12, 13, 14, 16, 17, 20, 21};
        int i;
@@ -3027,6 +3133,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
                r.in.user_handle = handle;
                r.in.level = levels[i];
+               r.out.info = &info;
 
                status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -3174,6 +3281,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
        NTSTATUS status;
        struct samr_OpenUser r;
        struct samr_QueryUserInfo q;
+       union samr_UserInfo *info;
        struct policy_handle user_handle;
        bool ret = true;
 
@@ -3192,6 +3300,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
 
        q.in.user_handle = &user_handle;
        q.in.level = 16;
+       q.out.info = &info;
        
        status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
        if (!NT_STATUS_IS_OK(status)) {
@@ -3199,9 +3308,9 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
                       nt_errstr(status));
                ret = false;
        } else {
-               if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
+               if ((acct_flag_mask & info->info16.acct_flags) == 0) {
                        printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
-                              acct_flag_mask, q.out.info->info16.acct_flags, rid);
+                              acct_flag_mask, info->info16.acct_flags, rid);
                        ret = false;
                }
        }
@@ -3223,6 +3332,11 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
        bool ret = true;
        struct samr_LookupNames n;
        struct samr_LookupRids  lr ;
+       struct lsa_Strings names;
+       struct samr_Ids rids, types;
+       struct samr_SamArray *sam = NULL;
+       uint32_t num_entries = 0;
+
        uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, 
                            ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, 
                            ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, 
@@ -3236,6 +3350,8 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
                r.in.acct_flags = mask = masks[mask_idx];
                r.in.max_size = (uint32_t)-1;
                r.out.resume_handle = &resume_handle;
+               r.out.num_entries = &num_entries;
+               r.out.sam = &sam;
 
                status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
                if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&  
@@ -3244,18 +3360,18 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
                        return false;
                }
        
-               torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
+               torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
 
-               if (r.out.sam->count == 0) {
+               if (sam->count == 0) {
                        continue;
                }
 
-               for (i=0;i<r.out.sam->count;i++) {
+               for (i=0;i<sam->count;i++) {
                        if (mask) {
-                               if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
+                               if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
                                        ret = false;
                                }
-                       } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
+                       } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
                                ret = false;
                        }
                }
@@ -3263,10 +3379,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
 
        printf("Testing LookupNames\n");
        n.in.domain_handle = handle;
-       n.in.num_names = r.out.sam->count;
-       n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
-       for (i=0;i<r.out.sam->count;i++) {
-               n.in.names[i].string = r.out.sam->entries[i].name.string;
+       n.in.num_names = sam->count;
+       n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
+       n.out.rids = &rids;
+       n.out.types = &types;
+       for (i=0;i<sam->count;i++) {
+               n.in.names[i].string = sam->entries[i].name.string;
        }
        status = dcerpc_samr_LookupNames(p, tctx, &n);
        if (!NT_STATUS_IS_OK(status)) {
@@ -3277,10 +3395,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
 
        printf("Testing LookupRids\n");
        lr.in.domain_handle = handle;
-       lr.in.num_rids = r.out.sam->count;
-       lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
-       for (i=0;i<r.out.sam->count;i++) {
-               lr.in.rids[i] = r.out.sam->entries[i].idx;
+       lr.in.num_rids = sam->count;
+       lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
+       lr.out.names = &names;
+       lr.out.types = &types;
+       for (i=0;i<sam->count;i++) {
+               lr.in.rids[i] = sam->entries[i].idx;
        }
        status = dcerpc_samr_LookupRids(p, tctx, &lr);
        torture_assert_ntstatus_ok(tctx, status, "LookupRids");
@@ -3337,6 +3457,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        struct samr_EnumDomainGroups r;
        uint32_t resume_handle=0;
+       struct samr_SamArray *sam = NULL;
+       uint32_t num_entries = 0;
        int i;
        bool ret = true;
 
@@ -3346,6 +3468,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        r.in.resume_handle = &resume_handle;
        r.in.max_size = (uint32_t)-1;
        r.out.resume_handle = &resume_handle;
+       r.out.num_entries = &num_entries;
+       r.out.sam = &sam;
 
        status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
@@ -3353,12 +3477,12 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                return false;
        }
        
-       if (!r.out.sam) {
+       if (!sam) {
                return false;
        }
 
-       for (i=0;i<r.out.sam->count;i++) {
-               if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
+       for (i=0;i<sam->count;i++) {
+               if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
                        ret = false;
                }
        }
@@ -3372,6 +3496,8 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        struct samr_EnumDomainAliases r;
        uint32_t resume_handle=0;
+       struct samr_SamArray *sam = NULL;
+       uint32_t num_entries = 0;
        int i;
        bool ret = true;
 
@@ -3379,7 +3505,9 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        r.in.domain_handle = handle;
        r.in.resume_handle = &resume_handle;
-       r.in.acct_flags = (uint32_t)-1;
+       r.in.max_size = (uint32_t)-1;
+       r.out.sam = &sam;
+       r.out.num_entries = &num_entries;
        r.out.resume_handle = &resume_handle;
 
        status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
@@ -3388,12 +3516,12 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                return false;
        }
        
-       if (!r.out.sam) {
+       if (!sam) {
                return false;
        }
 
-       for (i=0;i<r.out.sam->count;i++) {
-               if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
+       for (i=0;i<sam->count;i++) {
+               if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
                        ret = false;
                }
        }
@@ -3409,14 +3537,19 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m
        bool ret = true;
        uint16_t levels[] = {1, 2, 3, 4, 5};
        uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
+       struct lsa_String name;
+       uint32_t idx = 0;
        int i;
 
        for (i=0;i<ARRAY_SIZE(levels);i++) {
                printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
 
+               init_lsa_String(&name, TEST_ACCOUNT_NAME);
+
                r.in.domain_handle = handle;
                r.in.level = levels[i];
-               init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
+               r.in.name = &name;
+               r.out.idx = &idx;
 
                status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
 
@@ -3428,7 +3561,7 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m
                        ret = false;
                }
 
-               init_lsa_String(&r.in.name, "zzzzzzzz");
+               init_lsa_String(&name, "zzzzzzzz");
 
                status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
                
@@ -3450,14 +3583,19 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *
        bool ret = true;
        uint16_t levels[] = {1, 2, 3, 4, 5};
        uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
+       struct lsa_String name;
+       uint32_t idx = 0;
        int i;
 
        for (i=0;i<ARRAY_SIZE(levels);i++) {
                printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
 
+               init_lsa_String(&name, TEST_ACCOUNT_NAME);
+
                r.in.domain_handle = handle;
                r.in.level = levels[i];
-               init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
+               r.in.name = &name;
+               r.out.idx = &idx;
 
                status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
                if (ok_lvl[i] && 
@@ -3468,7 +3606,7 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *
                        ret = false;
                }
 
-               init_lsa_String(&r.in.name, "zzzzzzzz");
+               init_lsa_String(&name, "zzzzzzzz");
 
                status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
                if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
@@ -3502,6 +3640,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
 {
        struct samr_OpenUser r;
        struct samr_QueryUserInfo q;
+       union samr_UserInfo *info;
        struct policy_handle user_handle;
        int i, ret = true;
        NTSTATUS status;
@@ -3510,16 +3649,16 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
        for (i = 0; ; i++) {
                switch (querydisplayinfo->in.level) {
                case 1:
-                       if (i >= querydisplayinfo->out.info.info1.count) {
+                       if (i >= querydisplayinfo->out.info->info1.count) {
                                return ret;
                        }
-                       r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
+                       r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
                        break;
                case 2:
-                       if (i >= querydisplayinfo->out.info.info2.count) {
+                       if (i >= querydisplayinfo->out.info->info2.count) {
                                return ret;
                        }
-                       r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
+                       r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
                        break;
                case 3:
                        /* Groups */
@@ -3543,6 +3682,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
                
                q.in.user_handle = &user_handle;
                q.in.level = 21;
+               q.out.info = &info;
                status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
                if (!NT_STATUS_IS_OK(status)) {
                        printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
@@ -3551,41 +3691,41 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
                
                switch (querydisplayinfo->in.level) {
                case 1:
-                       if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
+                       if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
                                *seen_testuser = true;
                        }
-                       STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name, 
-                                          q.out.info->info21.full_name, q.out.info->info21.account_name);
-                       STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name, 
-                                          q.out.info->info21.account_name, q.out.info->info21.account_name);
-                       STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description, 
-                                          q.out.info->info21.description, q.out.info->info21.account_name);
-                       INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid, 
-                                       q.out.info->info21.rid, q.out.info->info21.account_name);
-                       INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags, 
-                                       q.out.info->info21.acct_flags, q.out.info->info21.account_name);
+                       STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
+                                          info->info21.full_name, info->info21.account_name);
+                       STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
+                                          info->info21.account_name, info->info21.account_name);
+                       STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
+                                          info->info21.description, info->info21.account_name);
+                       INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
+                                       info->info21.rid, info->info21.account_name);
+                       INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
+                                       info->info21.acct_flags, info->info21.account_name);
                        
                        break;
                case 2:
-                       STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name, 
-                                          q.out.info->info21.account_name, q.out.info->info21.account_name);
-                       STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description, 
-                                          q.out.info->info21.description, q.out.info->info21.account_name);
-                       INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid, 
-                                       q.out.info->info21.rid, q.out.info->info21.account_name);
-                       INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL), 
-                                       q.out.info->info21.acct_flags, q.out.info->info21.account_name);
+                       STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
+                                          info->info21.account_name, info->info21.account_name);
+                       STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
+                                          info->info21.description, info->info21.account_name);
+                       INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
+                                       info->info21.rid, info->info21.account_name);
+                       INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
+                                       info->info21.acct_flags, info->info21.account_name);
                        
-                       if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
+                       if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
                                printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n", 
-                                      q.out.info->info21.account_name.string);
+                                      info->info21.account_name.string);
                        }
 
-                       if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
+                       if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
                                printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
-                                      q.out.info->info21.account_name.string,
-                                      querydisplayinfo->out.info.info2.entries[i].acct_flags,
-                                      q.out.info->info21.acct_flags);
+                                      info->info21.account_name.string,
+                                      querydisplayinfo->out.info->info2.entries[i].acct_flags,
+                                      info->info21.acct_flags);
                                return false;
                        }
                        
@@ -3605,10 +3745,15 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        struct samr_QueryDisplayInfo r;
        struct samr_QueryDomainInfo dom_info;
+       union samr_DomainInfo *info = NULL;
        bool ret = true;
        uint16_t levels[] = {1, 2, 3, 4, 5};
        int i;
        bool seen_testuser = false;
+       uint32_t total_size;
+       uint32_t returned_size;
+       union samr_DispInfo disp_info;
+
 
        for (i=0;i<ARRAY_SIZE(levels);i++) {
                printf("Testing QueryDisplayInfo level %u\n", levels[i]);
@@ -3620,6 +3765,9 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                        r.in.level = levels[i];
                        r.in.max_entries = 2;
                        r.in.buf_size = (uint32_t)-1;
+                       r.out.total_size = &total_size;
+                       r.out.returned_size = &returned_size;
+                       r.out.info = &disp_info;
                        
                        status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
                        if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
@@ -3632,27 +3780,29 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
                                        ret = false;
                                }
-                               r.in.start_idx += r.out.info.info1.count;
+                               r.in.start_idx += r.out.info->info1.count;
                                break;
                        case 2:
                                if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
                                        ret = false;
                                }
-                               r.in.start_idx += r.out.info.info2.count;
+                               r.in.start_idx += r.out.info->info2.count;
                                break;
                        case 3:
-                               r.in.start_idx += r.out.info.info3.count;
+                               r.in.start_idx += r.out.info->info3.count;
                                break;
                        case 4:
-                               r.in.start_idx += r.out.info.info4.count;
+                               r.in.start_idx += r.out.info->info4.count;
                                break;
                        case 5:
-                               r.in.start_idx += r.out.info.info5.count;
+                               r.in.start_idx += r.out.info->info5.count;
                                break;
                        }
                }
                dom_info.in.domain_handle = handle;
                dom_info.in.level = 2;
+               dom_info.out.info = &info;
+
                /* Check number of users returned is correct */
                status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
                if (!NT_STATUS_IS_OK(status)) {
@@ -3664,17 +3814,17 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                switch (r.in.level) {
                case 1:
                case 4:
-                       if (dom_info.out.info->general.num_users < r.in.start_idx) {
+                       if (info->general.num_users < r.in.start_idx) {
                                printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
-                                      r.in.start_idx, dom_info.out.info->general.num_groups,
-                                      dom_info.out.info->general.domain_name.string);
+                                      r.in.start_idx, info->general.num_groups,
+                                      info->general.domain_name.string);
                                ret = false;
                        }
                        if (!seen_testuser) {
                                struct policy_handle user_handle;
                                if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
                                        printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n", 
-                                              dom_info.out.info->general.domain_name.string);
+                                              info->general.domain_name.string);
                                        ret = false;
                                        test_samr_handle_Close(p, mem_ctx, &user_handle);
                                }
@@ -3682,10 +3832,10 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                        break;
                case 3:
                case 5:
-                       if (dom_info.out.info->general.num_groups != r.in.start_idx) {
+                       if (info->general.num_groups != r.in.start_idx) {
                                printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
-                                      r.in.start_idx, dom_info.out.info->general.num_groups,
-                                      dom_info.out.info->general.domain_name.string);
+                                      r.in.start_idx, info->general.num_groups,
+                                      info->general.domain_name.string);
                                ret = false;
                        }
                        
@@ -3705,6 +3855,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        bool ret = true;
        uint16_t levels[] = {1, 2, 3, 4, 5};
        int i;
+       uint32_t total_size;
+       uint32_t returned_size;
+       union samr_DispInfo info;
 
        for (i=0;i<ARRAY_SIZE(levels);i++) {
                printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
@@ -3714,6 +3867,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                r.in.start_idx = 0;
                r.in.max_entries = 1000;
                r.in.buf_size = (uint32_t)-1;
+               r.out.total_size = &total_size;
+               r.out.returned_size = &returned_size;
+               r.out.info = &info;
 
                status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -3734,6 +3890,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context
        bool ret = true;
        uint16_t levels[] = {1, 2, 3, 4, 5};
        int i;
+       uint32_t total_size;
+       uint32_t returned_size;
+       union samr_DispInfo info;
 
        for (i=0;i<ARRAY_SIZE(levels);i++) {
                torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
@@ -3743,6 +3902,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context
                r.in.start_idx = 0;
                r.in.max_entries = 1000;
                r.in.buf_size = (uint32_t)-1;
+               r.out.total_size = &total_size;
+               r.out.returned_size = &returned_size;
+               r.out.info = &info;
 
                status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -3762,6 +3924,9 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
        NTSTATUS status;
        struct samr_QueryDisplayInfo r;
        bool ret = true;
+       uint32_t total_size;
+       uint32_t returned_size;
+       union samr_DispInfo info;
 
        printf("Testing QueryDisplayInfo continuation\n");
 
@@ -3770,14 +3935,17 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
        r.in.start_idx = 0;
        r.in.max_entries = 1;
        r.in.buf_size = (uint32_t)-1;
+       r.out.total_size = &total_size;
+       r.out.returned_size = &returned_size;
+       r.out.info = &info;
 
        do {
                status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
-               if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
-                       if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
+               if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
+                       if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
                                printf("expected idx %d but got %d\n",
                                       r.in.start_idx + 1,
-                                      r.out.info.info1.entries[0].idx);
+                                      r.out.info->info1.entries[0].idx);
                                break;
                        }
                }
@@ -3791,7 +3959,7 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
                r.in.start_idx++;
        } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
                  NT_STATUS_IS_OK(status)) &&
-                r.out.returned_size != 0);
+                *r.out.returned_size != 0);
        
        return ret;     
 }
@@ -3801,6 +3969,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
 {
        NTSTATUS status;
        struct samr_QueryDomainInfo r;
+       union samr_DomainInfo *info = NULL;
        struct samr_SetDomainInfo s;
        uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
        uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
@@ -3827,6 +3996,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
 
                r.in.domain_handle = handle;
                r.in.level = levels[i];
+               r.out.info = &info;
 
                status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -3838,40 +4008,40 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
 
                switch (levels[i]) {
                case 2:
-                       if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
+                       if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
                                printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
-                                      levels[i], r.out.info->general.oem_information.string, domain_comment);
+                                      levels[i], info->general.oem_information.string, domain_comment);
                                ret = false;
                        }
-                       if (!r.out.info->general.primary.string) {
+                       if (!info->general.primary.string) {
                                printf("QueryDomainInfo level %u returned no PDC name\n",
                                       levels[i]);
                                ret = false;
-                       } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
-                               if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
+                       } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
+                               if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
                                        printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
-                                              levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
+                                              levels[i], info->general.primary.string, dcerpc_server_name(p));
                                }
                        }
                        break;
                case 4:
-                       if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
+                       if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
                                printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
-                                      levels[i], r.out.info->oem.oem_information.string, domain_comment);
+                                      levels[i], info->oem.oem_information.string, domain_comment);
                                ret = false;
                        }
                        break;
                case 6:
-                       if (!r.out.info->info6.primary.string) {
+                       if (!info->info6.primary.string) {
                                printf("QueryDomainInfo level %u returned no PDC name\n",
                                       levels[i]);
                                ret = false;
                        }
                        break;
                case 11:
-                       if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
+                       if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
                                printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
-                                      levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
+                                      levels[i], info->general2.general.oem_information.string, domain_comment);
                                ret = false;
                        }
                        break;
@@ -3881,7 +4051,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
 
                s.in.domain_handle = handle;
                s.in.level = levels[i];
-               s.in.info = r.out.info;
+               s.in.info = info;
 
                status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
                if (set_ok[i]) {
@@ -3918,6 +4088,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context
 {
        NTSTATUS status;
        struct samr_QueryDomainInfo2 r;
+       union samr_DomainInfo *info = NULL;
        uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
        int i;
        bool ret = true;
@@ -3927,6 +4098,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context
 
                r.in.domain_handle = handle;
                r.in.level = levels[i];
+               r.out.info = &info;
 
                status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -3949,8 +4121,13 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
        struct samr_QueryDisplayInfo q2;
        NTSTATUS status;
        uint32_t resume_handle=0;
+       struct samr_SamArray *sam = NULL;
+       uint32_t num_entries = 0;
        int i;
        bool ret = true;
+       uint32_t total_size;
+       uint32_t returned_size;
+       union samr_DispInfo info;
 
        int num_names = 0;
        const char **names = NULL;
@@ -3961,6 +4138,8 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
        q1.in.resume_handle = &resume_handle;
        q1.in.max_size = 5;
        q1.out.resume_handle = &resume_handle;
+       q1.out.num_entries = &num_entries;
+       q1.out.sam = &sam;
 
        status = STATUS_MORE_ENTRIES;
        while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
@@ -3970,22 +4149,25 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
                    !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
                        break;
 
-               for (i=0; i<q1.out.num_entries; i++) {
+               for (i=0; i<*q1.out.num_entries; i++) {
                        add_string_to_array(tctx,
-                                           q1.out.sam->entries[i].name.string,
+                                           sam->entries[i].name.string,
                                            &names, &num_names);
                }
        }
 
        torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
        
-       torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
+       torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
 
        q2.in.domain_handle = handle;
        q2.in.level = 5;
        q2.in.start_idx = 0;
        q2.in.max_entries = 5;
        q2.in.buf_size = (uint32_t)-1;
+       q2.out.total_size = &total_size;
+       q2.out.returned_size = &returned_size;
+       q2.out.info = &info;
 
        status = STATUS_MORE_ENTRIES;
        while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
@@ -3995,9 +4177,9 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
                    !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
                        break;
 
-               for (i=0; i<q2.out.info.info5.count; i++) {
+               for (i=0; i<q2.out.info->info5.count; i++) {
                        int j;
-                       const char *name = q2.out.info.info5.entries[i].account_name.string;
+                       const char *name = q2.out.info->info5.entries[i].account_name.string;
                        bool found = false;
                        for (j=0; j<num_names; j++) {
                                if (names[j] == NULL)
@@ -4015,7 +4197,7 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
                                ret = false;
                        }
                }
-               q2.in.start_idx += q2.out.info.info5.count;
+               q2.in.start_idx += q2.out.info->info5.count;
        }
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -4076,7 +4258,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
        struct samr_RidToSid r;
        NTSTATUS status;
        bool ret = true;
-       struct dom_sid *calc_sid;
+       struct dom_sid *calc_sid, *out_sid;
        int rids[] = { 0, 42, 512, 10200 };
        int i;
 
@@ -4086,6 +4268,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
                calc_sid = dom_sid_dup(tctx, domain_sid);
                r.in.domain_handle = domain_handle;
                r.in.rid = rids[i];
+               r.out.sid = &out_sid;
                
                status = dcerpc_samr_RidToSid(p, tctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
@@ -4094,9 +4277,9 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
                } else {
                        calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
 
-                       if (!dom_sid_equal(calc_sid, r.out.sid)) {
+                       if (!dom_sid_equal(calc_sid, out_sid)) {
                                printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
-                                      dom_sid_string(tctx, r.out.sid), 
+                                      dom_sid_string(tctx, out_sid),
                                       dom_sid_string(tctx, calc_sid));
                                ret = false;
                        }
@@ -4112,10 +4295,12 @@ static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_con
        struct samr_GetBootKeyInformation r;
        NTSTATUS status;
        bool ret = true;
+       uint32_t unknown = 0;
 
        torture_comment(tctx, "Testing GetBootKeyInformation\n");
 
        r.in.domain_handle = domain_handle;
+       r.out.unknown = &unknown;
 
        status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
@@ -4134,6 +4319,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
        struct samr_AddGroupMember r;
        struct samr_DeleteGroupMember d;
        struct samr_QueryGroupMember q;
+       struct samr_RidTypeArray *rids = NULL;
        struct samr_SetMemberAttributesOfGroup s;
        uint32_t rid;
 
@@ -4173,6 +4359,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
        }
 
        q.in.group_handle = group_handle;
+       q.out.rids = &rids;
 
        status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
        torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
@@ -4388,6 +4575,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
 {
        NTSTATUS status;
        struct samr_LookupDomain r;
+       struct dom_sid2 *sid = NULL;
        struct lsa_String n1;
        struct lsa_String n2;
        bool ret = true;
@@ -4397,6 +4585,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
        /* check for correct error codes */
        r.in.connect_handle = handle;
        r.in.domain_name = &n2;
+       r.out.sid = &sid;
        n2.string = NULL;
 
        status = dcerpc_samr_LookupDomain(p, tctx, &r);
@@ -4419,7 +4608,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
                ret = false;
        }
 
-       if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
+       if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
                ret = false;
        }
 
@@ -4433,6 +4622,8 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx
        NTSTATUS status;
        struct samr_EnumDomains r;
        uint32_t resume_handle = 0;
+       uint32_t num_entries = 0;
+       struct samr_SamArray *sam = NULL;
        int i;
        bool ret = true;
 
@@ -4440,17 +4631,19 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx
        r.in.resume_handle = &resume_handle;
        r.in.buf_size = (uint32_t)-1;
        r.out.resume_handle = &resume_handle;
+       r.out.num_entries = &num_entries;
+       r.out.sam = &sam;
 
        status = dcerpc_samr_EnumDomains(p, tctx, &r);
        torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
 
-       if (!r.out.sam) {
+       if (!*r.out.sam) {
                return false;
        }
 
-       for (i=0;i<r.out.sam->count;i++) {
+       for (i=0;i<sam->count;i++) {
                if (!test_LookupDomain(p, tctx, handle, 
-                                      r.out.sam->entries[i].name.string, which_ops)) {
+                                      sam->entries[i].name.string, which_ops)) {
                        ret = false;
                }
        }
@@ -4473,6 +4666,7 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
        struct samr_Connect5 r5;
        union samr_ConnectInfo info;
        struct policy_handle h;
+       uint32_t level_out = 0;
        bool ret = true, got_handle = false;
 
        torture_comment(tctx, "testing samr_Connect\n");
@@ -4553,9 +4747,10 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
 
        r5.in.system_name = "";
        r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       r5.in.level = 1;
-       r5.in.info = &info;
-       r5.out.info = &info;
+       r5.in.level_in = 1;
+       r5.out.level_out = &level_out;
+       r5.in.info_in = &info;
+       r5.out.info_out = &info;
        r5.out.connect_handle = &h;
 
        status = dcerpc_samr_Connect5(p, tctx, &r5);
index bfff8c9267f72402efb6d3b114d6d072e9816d96..9a8e44201940a8eb3c81f5d4553288329304a7b2 100644 (file)
@@ -52,13 +52,15 @@ static NTSTATUS torture_samr_Connect5(struct torture_context *tctx,
        NTSTATUS status;
        struct samr_Connect5 r5;
        union samr_ConnectInfo info;
+       uint32_t level_out = 0;
 
        info.info1.client_version = 0;
        info.info1.unknown2 = 0;
        r5.in.system_name = "";
-       r5.in.level = 1;
-       r5.in.info = &info;
-       r5.out.info = &info;
+       r5.in.level_in = 1;
+       r5.in.info_in = &info;
+       r5.out.info_out = &info;
+       r5.out.level_out = &level_out;
        r5.out.connect_handle = h;
        r5.in.access_mask = mask;
 
@@ -147,6 +149,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
        int i;
        uint32_t mask;
        uint32_t resume_handle = 0;
+       struct samr_SamArray *sam = NULL;
+       uint32_t num_entries = 0;
 
        printf("testing which bits in Connect5 accessmask allows us to EnumDomains\n");
        mask = 1;
@@ -170,6 +174,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
                        ed.in.resume_handle = &resume_handle;
                        ed.in.buf_size = (uint32_t)-1;
                        ed.out.resume_handle = &resume_handle;
+                       ed.out.num_entries = &num_entries;
+                       ed.out.sam = &sam;
 
                        status = dcerpc_samr_EnumDomains(p, tctx, &ed);
                        if (!NT_STATUS_IS_OK(status)) {
@@ -195,6 +201,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
                        ed.in.resume_handle = &resume_handle;
                        ed.in.buf_size = (uint32_t)-1;
                        ed.out.resume_handle = &resume_handle;
+                       ed.out.num_entries = &num_entries;
+                       ed.out.sam = &sam;
 
                        status = dcerpc_samr_EnumDomains(p, tctx, &ed);
                        if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
@@ -236,7 +244,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
        struct samr_SetSecurity ss;
        struct security_ace ace;
        struct security_descriptor *sd;
-       struct sec_desc_buf sdb;
+       struct sec_desc_buf sdb, *sdbuf = NULL;
        bool ret = true;
        int sd_size;
        struct dcerpc_pipe *test_p;
@@ -255,6 +263,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
        /* get the current ACL for the SAMR policy handle */
        qs.in.handle = &ch;
        qs.in.sec_info = SECINFO_DACL;
+       qs.out.sdbuf = &sdbuf;
        status = dcerpc_samr_QuerySecurity(p, tctx, &qs);
        if (!NT_STATUS_IS_OK(status)) {
                printf("QuerySecurity failed - %s\n", nt_errstr(status));
@@ -262,13 +271,13 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
        }
 
        /* how big is the security descriptor? */
-       sd_size = qs.out.sdbuf->sd_size;
+       sd_size = sdbuf->sd_size;
 
 
        /* add an ACE to the security descriptor to deny the user the
         * 'connect to server' right
         */
-       sd = qs.out.sdbuf->sd;
+       sd = sdbuf->sd;
        ace.type = SEC_ACE_TYPE_ACCESS_DENIED;
        ace.flags = 0;
        ace.access_mask = SAMR_ACCESS_CONNECT_TO_SERVER;
@@ -314,7 +323,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
                printf("QuerySecurity failed - %s\n", nt_errstr(status));
                ret = false;
        }
-       if (sd_size != qs.out.sdbuf->sd_size) {
+       if (sd_size != sdbuf->sd_size) {
                printf("security descriptor changed\n");
                ret = false;
        }
@@ -387,6 +396,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
 {
        NTSTATUS status;
        struct samr_LookupDomain ld;
+       struct dom_sid2 *sid = NULL;
        struct policy_handle ch;
        struct lsa_String dn;
        int i;
@@ -412,6 +422,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
 
                        ld.in.connect_handle = &ch;
                        ld.in.domain_name    = &dn;
+                       ld.out.sid           = &sid;
                        dn.string            = lp_workgroup(tctx->lp_ctx);
 
                        status = dcerpc_samr_LookupDomain(p, tctx, &ld);
@@ -471,6 +482,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
 {
        NTSTATUS status;
        struct samr_LookupDomain ld;
+       struct dom_sid2 *sid = NULL;
        struct samr_OpenDomain od;
        struct policy_handle ch;
        struct policy_handle dh;
@@ -488,6 +500,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
 
        ld.in.connect_handle = &ch;
        ld.in.domain_name    = &dn;
+       ld.out.sid           = &sid;
        dn.string            = lp_workgroup(tctx->lp_ctx);
        status = dcerpc_samr_LookupDomain(p, tctx, &ld);
        if (!NT_STATUS_IS_OK(status)) {
@@ -517,7 +530,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
 
                        od.in.connect_handle = &ch;
                        od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-                       od.in.sid = ld.out.sid;
+                       od.in.sid = *ld.out.sid;
                        od.out.domain_handle = &dh;
 
                        status = dcerpc_samr_OpenDomain(p, tctx, &od);
index 12ddc934c96a8e9a24dbb34dfc0bb07667c9d355..a3fc6f740f0569aecda1ec86daa2911f157ff669 100644 (file)
@@ -151,17 +151,19 @@ struct samsync_trusted_domain {
 static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx, 
                                                 struct samsync_state *samsync_state, 
                                                 const char *domain, 
-                                                struct dom_sid **sid)
+                                                struct dom_sid **sid_p)
 {
        struct lsa_String name;
        struct samr_OpenDomain o;
        struct samr_LookupDomain l;
+       struct dom_sid2 *sid = NULL;
        struct policy_handle *domain_handle = talloc(mem_ctx, struct policy_handle);
        NTSTATUS nt_status;
 
        name.string = domain;
        l.in.connect_handle = samsync_state->connect_handle;
        l.in.domain_name = &name;
+       l.out.sid = &sid;
 
        nt_status = dcerpc_samr_LookupDomain(samsync_state->p_samr, mem_ctx, &l);
        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -171,11 +173,11 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx,
 
        o.in.connect_handle = samsync_state->connect_handle;
        o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       o.in.sid = l.out.sid;
+       o.in.sid = *l.out.sid;
        o.out.domain_handle = domain_handle;
        
        if (sid) {
-               *sid = l.out.sid;
+               *sid_p = *l.out.sid;
        }
 
        nt_status = dcerpc_samr_OpenDomain(samsync_state->p_samr, mem_ctx, &o);
@@ -192,10 +194,12 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx,
                                                        struct policy_handle *handle) 
 {
        struct samr_QuerySecurity r;
+       struct sec_desc_buf *sdbuf = NULL;
        NTSTATUS status;
 
        r.in.handle = handle;
        r.in.sec_info = 0x7;
+       r.out.sdbuf = &sdbuf;
 
        status = dcerpc_samr_QuerySecurity(samsync_state->p_samr, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
@@ -203,7 +207,7 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
-       return r.out.sdbuf;
+       return sdbuf;
 }
 
 static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx, 
@@ -260,6 +264,15 @@ static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx,
        } \
 } while (0)
 
+#define TEST_BINARY_STRING_EQUAL(s1, s2) do {\
+       if (!((!s1.array || s1.array[0]=='\0') && (!s2.array || s2.array[0]=='\0')) \
+           && memcmp(s1.array, s2.array, s1.length * 2) != 0) {\
+             printf("%s: string mismatch: " #s1 ":%s != " #s2 ": %s\n", \
+                    __location__, (const char *)s1.array, (const char *)s2.array);\
+             ret = false;\
+       } \
+} while (0)
+
 #define TEST_SID_EQUAL(s1, s2) do {\
        if (!dom_sid_equal(s1, s2)) {\
              printf("%s: dom_sid mismatch: " #s1 ":%s != " #s2 ": %s\n", \
@@ -294,6 +307,7 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
        struct netr_DELTA_DOMAIN *domain = delta->delta_union.domain;
        struct dom_sid *dom_sid;
        struct samr_QueryDomainInfo q[14]; /* q[0] will be unused simple for clarity */
+       union samr_DomainInfo *info[14];
        uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
        NTSTATUS nt_status;
        int i;
@@ -341,8 +355,10 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
               (long long)samsync_state->seq_num[database_id]);
 
        for (i=0;i<ARRAY_SIZE(levels);i++) {
+
                q[levels[i]].in.domain_handle = samsync_state->domain_handle[database_id];
                q[levels[i]].in.level = levels[i];
+               q[levels[i]].out.info = &info[levels[i]];
 
                nt_status = dcerpc_samr_QueryDomainInfo(samsync_state->p_samr, mem_ctx, &q[levels[i]]);
 
@@ -353,23 +369,23 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
                }
        }
 
-       TEST_STRING_EQUAL(q[5].out.info->info5.domain_name, domain->domain_name);
+       TEST_STRING_EQUAL(info[5]->info5.domain_name, domain->domain_name);
        
-       TEST_STRING_EQUAL(q[2].out.info->general.oem_information, domain->oem_information);
-       TEST_STRING_EQUAL(q[4].out.info->oem.oem_information, domain->oem_information);
-       TEST_TIME_EQUAL(q[2].out.info->general.force_logoff_time, domain->force_logoff_time);
-       TEST_TIME_EQUAL(q[3].out.info->info3.force_logoff_time, domain->force_logoff_time);
+       TEST_STRING_EQUAL(info[2]->general.oem_information, domain->oem_information);
+       TEST_STRING_EQUAL(info[4]->oem.oem_information, domain->oem_information);
+       TEST_TIME_EQUAL(info[2]->general.force_logoff_time, domain->force_logoff_time);
+       TEST_TIME_EQUAL(info[3]->info3.force_logoff_time, domain->force_logoff_time);
 
-       TEST_TIME_EQUAL(q[1].out.info->info1.min_password_length, domain->min_password_length);
-       TEST_TIME_EQUAL(q[1].out.info->info1.password_history_length, domain->password_history_length);
-       TEST_TIME_EQUAL(q[1].out.info->info1.max_password_age, domain->max_password_age);
-       TEST_TIME_EQUAL(q[1].out.info->info1.min_password_age, domain->min_password_age);
+       TEST_TIME_EQUAL(info[1]->info1.min_password_length, domain->min_password_length);
+       TEST_TIME_EQUAL(info[1]->info1.password_history_length, domain->password_history_length);
+       TEST_TIME_EQUAL(info[1]->info1.max_password_age, domain->max_password_age);
+       TEST_TIME_EQUAL(info[1]->info1.min_password_age, domain->min_password_age);
 
-       TEST_UINT64_EQUAL(q[8].out.info->info8.sequence_num, 
+       TEST_UINT64_EQUAL(info[8]->info8.sequence_num,
                        domain->sequence_num);
-       TEST_TIME_EQUAL(q[8].out.info->info8.domain_create_time, 
+       TEST_TIME_EQUAL(info[8]->info8.domain_create_time,
                        domain->domain_create_time);
-       TEST_TIME_EQUAL(q[13].out.info->info13.domain_create_time, 
+       TEST_TIME_EQUAL(info[13]->info13.domain_create_time,
                        domain->domain_create_time);
 
        TEST_SEC_DESC_EQUAL(domain->sdbuf, samr, samsync_state->domain_handle[database_id]);
@@ -425,9 +441,12 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
 
        struct samr_OpenUser r;
        struct samr_QueryUserInfo q;
+       union samr_UserInfo *info;
        struct policy_handle user_handle;
 
  &