r4617: basic alter_context requests now work in our client library. The test
authorAndrew Tridgell <tridge@samba.org>
Sun, 9 Jan 2005 09:38:16 +0000 (09:38 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:08:34 +0000 (13:08 -0500)
just does a simple LSA/DSSETUP combo, which is what w2k does in the
ACL editor rpc calls that triggered this work
(This used to be commit 0129ec947aa1fa5a7104dc3a666af3cb9bd104f1)

source4/librpc/idl/dcerpc.idl
source4/librpc/rpc/dcerpc.c
source4/librpc/rpc/dcerpc_util.c
source4/torture/config.mk
source4/torture/rpc/alter_context.c [new file with mode: 0644]
source4/torture/rpc/dssetup.c
source4/torture/rpc/lsa.c
source4/torture/torture.c

index 64769119049172769e0074f32c4f5b02103dd101..d9ed119abdd3fb6e25074a991238465c77ac620d 100644 (file)
@@ -144,7 +144,7 @@ interface dcerpc
                [flag(NDR_REMAINING)] DATA_BLOB auth_info;
        } dcerpc_auth3;
 
-       typedef enum {
+       typedef [enum8bit] enum {
                DCERPC_PKT_REQUEST     =  0,
                DCERPC_PKT_PING        =  1,
                DCERPC_PKT_RESPONSE    =  2,
@@ -195,14 +195,14 @@ interface dcerpc
        const uint8 DCERPC_DREP_LE  = 0x10;
 
        typedef [public] struct {
-               uint8 rpc_vers;         /* RPC version */
-               uint8 rpc_vers_minor;   /* Minor version */
-               uint8 ptype;            /* Packet type */
-               uint8 pfc_flags;        /* Fragmentation flags */
-               uint8 drep[4];          /* NDR data representation */
-               uint16 frag_length;     /* Total length of fragment */
-               uint16 auth_length;     /* authenticator length */
-               uint32 call_id;         /* Call identifier */
+               uint8 rpc_vers;         /* RPC version */
+               uint8 rpc_vers_minor;   /* Minor version */
+               dcerpc_pkt_type ptype;  /* Packet type */
+               uint8 pfc_flags;        /* Fragmentation flags */
+               uint8 drep[4];          /* NDR data representation */
+               uint16 frag_length;     /* Total length of fragment */
+               uint16 auth_length;     /* authenticator length */
+               uint32 call_id;         /* Call identifier */
                [switch_is(ptype)] dcerpc_payload u;
        } dcerpc_packet;
 }
index a29e7f7b6b9886b990139148d9e42ee82238cbbb..d75f6db935782e208e5d3eca3a3da982aed48710 100644 (file)
@@ -24,6 +24,7 @@
 #include "includes.h"
 #include "dlinklist.h"
 #include "librpc/gen_ndr/ndr_epmapper.h"
+#include "librpc/gen_ndr/ndr_dcerpc.h"
 
 static struct dcerpc_interface_list *dcerpc_pipes = NULL;
 
@@ -630,10 +631,8 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       if (pkt.ptype == DCERPC_PKT_BIND_ACK) {
-               p->conn->srv_max_xmit_frag = pkt.u.bind_ack.max_xmit_frag;
-               p->conn->srv_max_recv_frag = pkt.u.bind_ack.max_recv_frag;
-       }
+       p->conn->srv_max_xmit_frag = pkt.u.bind_ack.max_xmit_frag;
+       p->conn->srv_max_recv_frag = pkt.u.bind_ack.max_recv_frag;
 
        /* the bind_ack might contain a reply set of credentials */
        if (p->conn->security_state.auth_info && pkt.u.bind_ack.auth_info.length) {
@@ -1332,3 +1331,80 @@ uint32 dcerpc_auth_level(struct dcerpc_connection *c)
        }
        return auth_level;
 }
+
+
+/* 
+   send a dcerpc alter_context request
+*/
+NTSTATUS dcerpc_alter_context(struct dcerpc_pipe *p, 
+                             TALLOC_CTX *mem_ctx,
+                             const struct dcerpc_syntax_id *syntax,
+                             const struct dcerpc_syntax_id *transfer_syntax)
+{
+       struct dcerpc_packet pkt;
+       NTSTATUS status;
+       DATA_BLOB blob;
+
+       p->syntax = *syntax;
+       p->transfer_syntax = *transfer_syntax;
+
+       init_dcerpc_hdr(p->conn, &pkt);
+
+       pkt.ptype = DCERPC_PKT_ALTER;
+       pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
+       pkt.call_id = p->conn->call_id;
+       pkt.auth_length = 0;
+
+       pkt.u.alter.max_xmit_frag = 5840;
+       pkt.u.alter.max_recv_frag = 5840;
+       pkt.u.alter.assoc_group_id = 0;
+       pkt.u.alter.num_contexts = 1;
+       pkt.u.alter.ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
+       if (!pkt.u.alter.ctx_list) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       pkt.u.alter.ctx_list[0].context_id = p->context_id;
+       pkt.u.alter.ctx_list[0].num_transfer_syntaxes = 1;
+       pkt.u.alter.ctx_list[0].abstract_syntax = p->syntax;
+       pkt.u.alter.ctx_list[0].transfer_syntaxes = &p->transfer_syntax;
+       pkt.u.alter.auth_info = data_blob(NULL, 0);
+
+       /* construct the NDR form of the packet */
+       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->conn->security_state.auth_info);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       /* send it on its way */
+       status = full_request(p->conn, mem_ctx, &blob, &blob);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       /* unmarshall the NDR */
+       status = dcerpc_pull(p->conn, &blob, mem_ctx, &pkt);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (pkt.ptype == DCERPC_PKT_BIND_NAK) {
+               DEBUG(2,("dcerpc: alter_nak reason %d\n", pkt.u.bind_nak.reject_reason));
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       if ((pkt.ptype != DCERPC_PKT_ALTER_ACK) ||
+           pkt.u.alter_ack.num_results == 0 ||
+           pkt.u.alter_ack.ctx_list[0].result != 0) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       /* the alter_ack might contain a reply set of credentials */
+       if (p->conn->security_state.auth_info && pkt.u.alter_ack.auth_info.length) {
+               status = ndr_pull_struct_blob(&pkt.u.alter_ack.auth_info,
+                                             mem_ctx,
+                                             p->conn->security_state.auth_info,
+                                             (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
+       }
+
+       return status;  
+}
index 67b0c530bf9ae87f8806b7da962243d598237b4a..702a1f6ecfc1d976071fbff1c1179b7846188df4 100644 (file)
@@ -1265,3 +1265,50 @@ void dcerpc_log_packet(const struct dcerpc_interface_table *ndr,
        }
 }
 
+
+
+/*
+  create a secondary context from a primary connection
+
+  this uses dcerpc_alter_context() to create a new dcerpc context_id
+*/
+NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p, struct dcerpc_pipe **pp2,
+                                 uint32_t context_id,
+                                 const char *pipe_uuid,
+                                 uint32_t pipe_version)
+{
+       NTSTATUS status;
+       struct dcerpc_pipe *p2;
+       
+       p2 = talloc_zero(p, struct dcerpc_pipe);
+       if (p2 == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       p2->conn = talloc_reference(p2, p->conn);
+
+       p2->context_id = context_id;
+
+       status = GUID_from_string(pipe_uuid, &p2->syntax.uuid);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(p2);
+               return status;
+       }
+       p2->syntax.if_version = pipe_version;
+
+       status = GUID_from_string(NDR_GUID, &p2->transfer_syntax.uuid);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(p2);
+               return status;
+       }
+       p2->transfer_syntax.if_version = NDR_GUID_VERSION;
+
+       status = dcerpc_alter_context(p2, p2, &p2->syntax, &p2->transfer_syntax);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(p2);
+               return status;
+       }
+
+       *pp2 = p2;
+
+       return status;
+}
index 658d1f1ba6be365f545eb0e031686f2fd2433295..172d8c02f143ab4b26f1e3e22bb952136d95c5f4 100644 (file)
@@ -98,7 +98,8 @@ ADD_OBJ_FILES = \
                torture/rpc/samsync.o \
                torture/rpc/rot.o \
                torture/rpc/bind.o \
-               torture/rpc/dssetup.o
+               torture/rpc/dssetup.o \
+               torture/rpc/alter_context.o
 REQUIRED_SUBSYSTEMS = \
                NDR_ALL RPC_NDR_SAMR RPC_NDR_WINREG RPC_NDR_OXIDRESOLVER \
                RPC_NDR_EVENTLOG RPC_NDR_ECHO RPC_NDR_SVCCTL \
diff --git a/source4/torture/rpc/alter_context.c b/source4/torture/rpc/alter_context.c
new file mode 100644 (file)
index 0000000..d10604f
--- /dev/null
@@ -0,0 +1,70 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   test suite for dcerpc alter_context operations
+
+   Copyright (C) Andrew Tridgell 2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_lsa.h"
+#include "librpc/gen_ndr/ndr_dssetup.h"
+
+
+BOOL torture_rpc_alter_context(void)
+{
+        NTSTATUS status;
+        struct dcerpc_pipe *p, *p2;
+       TALLOC_CTX *mem_ctx;
+       BOOL ret = True;
+       struct policy_handle handle;
+
+       mem_ctx = talloc_init("torture_rpc_alter_context");
+
+       printf("opening LSA connection\n");
+       status = torture_rpc_connection(&p, 
+                                       DCERPC_LSARPC_NAME, 
+                                       DCERPC_LSARPC_UUID, 
+                                       DCERPC_LSARPC_VERSION);
+       if (!NT_STATUS_IS_OK(status)) {
+               return False;
+       }
+
+       if (!test_lsa_OpenPolicy2(p, mem_ctx, &handle)) {
+               ret = False;
+       }
+
+       printf("Opening secondary DSSETUP context\n");
+       status = dcerpc_secondary_context(p, &p2, 1, DCERPC_DSSETUP_UUID, DCERPC_DSSETUP_VERSION);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("dcerpc_alter_context failed - %s\n", nt_errstr(status));
+               return False;
+       }
+
+       printf("testing DSSETUP pipe operations\n");
+       ret &= test_DsRoleGetPrimaryDomainInformation(p2, mem_ctx);
+
+       if (!test_lsa_Close(p, mem_ctx, &handle)) {
+               ret = False;
+       }
+
+       talloc_destroy(mem_ctx);
+
+        torture_rpc_close(p);
+
+       return ret;
+}
index eb9dc83df673c484bd9f0d2bec4c1d8eb2b0086c..bafe562cdbde13f55798aad43ca438e9ebf30db1 100644 (file)
@@ -24,7 +24,7 @@
 #include "librpc/gen_ndr/ndr_dssetup.h"
 
 
-static BOOL test_DsRoleGetPrimaryDomainInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+BOOL test_DsRoleGetPrimaryDomainInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
 {
        struct dssetup_DsRoleGetPrimaryDomainInformation r;
        NTSTATUS status;
index 3784294797c164ff87ca2b6543d02513deef43e2..7f1411ea845288fc7cf19f1452a52a30038341ea 100644 (file)
@@ -65,8 +65,8 @@ static BOOL test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
 }
 
 
-static BOOL test_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                            struct policy_handle *handle)
+BOOL test_lsa_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+                         struct policy_handle *handle)
 {
        struct lsa_ObjectAttribute attr;
        struct lsa_QosInfo qos;
@@ -1298,9 +1298,9 @@ static BOOL test_GetUserName(struct dcerpc_pipe *p,
        return ret;
 }
 
-static BOOL test_Close(struct dcerpc_pipe *p, 
-                      TALLOC_CTX *mem_ctx, 
-                      struct policy_handle *handle)
+BOOL test_lsa_Close(struct dcerpc_pipe *p, 
+                   TALLOC_CTX *mem_ctx, 
+                   struct policy_handle *handle)
 {
        NTSTATUS status;
        struct lsa_Close r;
@@ -1351,7 +1351,7 @@ BOOL torture_rpc_lsa(void)
                ret = False;
        }
 
-       if (!test_OpenPolicy2(p, mem_ctx, &handle)) {
+       if (!test_lsa_OpenPolicy2(p, mem_ctx, &handle)) {
                ret = False;
        }
 
@@ -1401,7 +1401,7 @@ BOOL torture_rpc_lsa(void)
        }
 #endif
        
-       if (!test_Close(p, mem_ctx, &handle)) {
+       if (!test_lsa_Close(p, mem_ctx, &handle)) {
                ret = False;
        }
 
index ed3dbb401bff5cbb30e822b61c6d7ba67183a600..bc4feef3e9bfc68f540aa7bd3aa9d12f3532e9b2 100644 (file)
@@ -2450,6 +2450,7 @@ static struct {
        {"RPC-LOGIN", torture_rpc_login, 0},
        {"RPC-ROT", torture_rpc_rot, 0},
        {"RPC-DSSETUP", torture_rpc_dssetup, 0},
+        {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
 
        /* Distributed COM testers */
        {"DCOM-SIMPLE", torture_dcom_simple, 0},