added code to the RPC-SPOOLSS test that demonstrates that policy
authorAndrew Tridgell <tridge@samba.org>
Tue, 20 Jan 2004 06:07:09 +0000 (06:07 +0000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 20 Jan 2004 06:07:09 +0000 (06:07 +0000)
handles are not shared between open dcerpc connections, even when
those connections are on the same SMB socket. I have tested this with
w2k3, w2k and NT4. It seems that policy handles have a strict scope of
the dcerpc connection on which they were opened.

I realise that this goes against existing folk-law in the team, but it
seems that the previous testing (I'm not sure who did this?) was
wrong. Perhaps clients do send us policy handles from other
connections, but if they do then the correct thing to do is to fail
the operation with a dcerpc fault. I suspect that failing it with
exactly the right dcerpc fault code is important.
(This used to be commit 2ed24d29bafd9055d5782acdd595cd0f378a651a)

source4/librpc/rpc/dcerpc.h
source4/librpc/rpc/dcerpc_smb.c
source4/librpc/rpc/dcerpc_tcp.c
source4/librpc/rpc/dcerpc_util.c
source4/torture/rpc/spoolss.c

index 5d258820418f2a7417f90e8ccc31ddf50ab61922..fdd17fcbb39a0fe1cc6b5d27a2160bef7829c250 100644 (file)
@@ -29,6 +29,9 @@
   marshalling/unmarshalling routines in decrpc.c
 */
 
+enum dcerpc_transport_t {NCACN_NP, NCACN_IP_TCP};
+
+
 struct dcerpc_pipe {
        TALLOC_CTX *mem_ctx;
        int reference_count;
@@ -38,8 +41,10 @@ struct dcerpc_pipe {
        unsigned flags;
        struct ntlmssp_state *ntlmssp_state;
        struct dcerpc_auth *auth_info;
-
+       const char *binding_string;
+       
        struct dcerpc_transport {
+               enum dcerpc_transport_t transport;
                void *private;
                NTSTATUS (*full_request)(struct dcerpc_pipe *, 
                                         TALLOC_CTX *, DATA_BLOB *, DATA_BLOB *);
@@ -94,8 +99,6 @@ struct dcerpc_interface_table {
 };
 
 
-enum dcerpc_transport_t {NCACN_NP, NCACN_IP_TCP};
-
 /* this describes a binding to a particular transport/pipe */
 struct dcerpc_binding {
        enum dcerpc_transport_t transport;
index fc71a47cf4012758fb0aa6cabafc75add3c7610d..da43a8a92b1f8c572c396d87b35a51add0af0877 100644 (file)
@@ -354,6 +354,7 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
        /*
          fill in the transport methods
        */
+       (*p)->transport.transport = NCACN_NP;
        (*p)->transport.private = NULL;
        (*p)->transport.full_request = smb_full_request;
        (*p)->transport.secondary_request = smb_secondary_request;
@@ -375,3 +376,17 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
 
         return NT_STATUS_OK;
 }
+
+/*
+  return the SMB tree used for a dcerpc over SMB pipe
+*/
+struct cli_tree *dcerpc_smb_tree(struct dcerpc_pipe *p)
+{
+       struct smb_private *smb = p->transport.private;
+
+       if (p->transport.transport != NCACN_NP) {
+               return NULL;
+       }
+
+       return smb->tree;
+}
index b577260033ca719e4c3c54ef219315725913bef1..afdf2430718966c5c1c929c9ea3dfccfc78d880c 100644 (file)
@@ -183,6 +183,7 @@ NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p,
        /*
          fill in the transport methods
        */
+       (*p)->transport.transport = NCACN_IP_TCP;
        (*p)->transport.private = NULL;
        (*p)->transport.full_request = tcp_full_request;
        (*p)->transport.secondary_request = tcp_secondary_request;
index 8efcefc8a79ec61cf593dfdb869db8190a70d182..1ef776125f3cded0f331c3a0b9ec890fbce54f9f 100644 (file)
@@ -578,6 +578,11 @@ NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **p,
                break;
        }
 
+       /* remember the binding string for possible secondary connections */
+       if (NT_STATUS_IS_OK(status)) {
+               (*p)->binding_string = dcerpc_binding_string((*p)->mem_ctx, binding);
+       }
+
        return status;
 }
 
@@ -613,3 +618,37 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **p,
        talloc_destroy(mem_ctx);
        return status;
 }
+
+
+/*
+  create a secondary dcerpc connection on SMB
+  the secondary connection will be on the same SMB connection, but
+  use a new fnum
+*/
+NTSTATUS dcerpc_secondary_smb(struct dcerpc_pipe *p, struct dcerpc_pipe **p2,
+                             const char *pipe_name,
+                             const char *pipe_uuid,
+                             uint32 pipe_version)
+{
+       NTSTATUS status;
+       struct cli_tree *tree;
+
+       tree = dcerpc_smb_tree(p);
+       if (!tree) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       status = dcerpc_pipe_open_smb(p2, tree, pipe_name);
+       if (!NT_STATUS_IS_OK(status)) {
+                return status;
+        }
+       
+       (*p2)->flags = p->flags;
+
+       status = dcerpc_bind_auth_none(*p2, pipe_uuid, pipe_version);
+       if (!NT_STATUS_IS_OK(status)) {
+                return status;
+        }
+
+       return NT_STATUS_OK;
+}
index 14cfbd0d290a6ac71bc1ced9f01a14f17f5b4863..5b118bec7b12d2150399c8255924c786497b5fb4 100644 (file)
@@ -573,6 +573,39 @@ static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        return True;
 }
 
+static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+                                      struct policy_handle *handle)
+{
+       NTSTATUS status;
+       struct dcerpc_pipe *p2;
+
+       /* only makes sense on SMB */
+       if (p->transport.transport != NCACN_NP) {
+               return True;
+       }
+
+       printf("testing close on secondary pipe\n");
+
+       status = dcerpc_secondary_smb(p, &p2, 
+                                     DCERPC_SPOOLSS_NAME, 
+                                     DCERPC_SPOOLSS_UUID, 
+                                     DCERPC_SPOOLSS_VERSION);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Failed to create secondary connection\n");
+               return False;
+       }
+
+       if (test_ClosePrinter(p2, mem_ctx, handle)) {
+               printf("ERROR: Allowed close on secondary connection!\n");
+               dcerpc_pipe_close(p2);
+               return False;
+       }
+
+       dcerpc_pipe_close(p2);
+
+       return True;
+}
+
 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                             const char *name)
 {
@@ -605,6 +638,10 @@ static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                ret = False;
        }
 
+       if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
+               ret = False;
+       }
+
        if (!test_ClosePrinter(p, mem_ctx, &handle)) {
                ret = False;
        }
@@ -693,6 +730,10 @@ static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                ret = False;
        }
 
+       if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
+               ret = False;
+       }
+
        if (!test_ClosePrinter(p, mem_ctx, &handle)) {
                ret = False;
        }