r4616: the first phase in the addition of proper support for
authorAndrew Tridgell <tridge@samba.org>
Sun, 9 Jan 2005 08:34:05 +0000 (08:34 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:08:34 +0000 (13:08 -0500)
dcerpc_alter_context and multiple context_ids in the dcerpc client
library.

This stage does the following:

 - split "struct dcerpc_pipe" into two parts, the main part being "struct dcerpc_connection", which
   contains all the parts not dependent on the context, and "struct dcerpc_pipe" which has
   the context dependent part. This is similar to the layering in libcli_*() for SMB

 - disable the current dcerpc_alter code. I've used a #warning until i
   get the 2nd phase finished. I don't know how portable #warning is, but
   it won't be long before I add full alter context support anyway, so it won't last long

 - cleanup the allocation of dcerpc_pipe structures. The previous code
   was quite awkward.
(This used to be commit 4004c69937be7e5dae56f9567ca607f982d395d3)

23 files changed:
source4/build/pidl/client.pm
source4/build/pidl/proxy.pm
source4/lib/dcom/common/main.c
source4/libcli/util/clilsa.c
source4/librpc/rpc/dcerpc.c
source4/librpc/rpc/dcerpc.h
source4/librpc/rpc/dcerpc_auth.c
source4/librpc/rpc/dcerpc_ntlm.c
source4/librpc/rpc/dcerpc_schannel.c
source4/librpc/rpc/dcerpc_smb.c
source4/librpc/rpc/dcerpc_sock.c
source4/librpc/rpc/dcerpc_spnego.c
source4/librpc/rpc/dcerpc_util.c
source4/rpc_server/remote/dcesrv_remote.c
source4/torture/rpc/mgmt.c
source4/torture/rpc/netlogon.c
source4/torture/rpc/samlogon.c
source4/torture/rpc/samsync.c
source4/torture/rpc/scanner.c
source4/torture/rpc/schannel.c
source4/torture/rpc/spoolss.c
source4/torture/rpc/xplogin.c
source4/utils/ndrdump.c

index c16662e3acd5e6cb4e74bd99c8ce2fc2fb71efdf..1be895208fea713de2d70bf7ecc0cd9a6f7950ed 100644 (file)
@@ -21,7 +21,7 @@ sub ParseFunction($$)
        $res .= "
 struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)
 {
-       if (p->flags & DCERPC_DEBUG_PRINT_IN) {
+       if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
                NDR_PRINT_IN_DEBUG($name, r);
        }
        
@@ -38,7 +38,7 @@ NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *
 
        status = dcerpc_ndr_request_recv(req);
 
-        if (NT_STATUS_IS_OK(status) && (p->flags & DCERPC_DEBUG_PRINT_OUT)) {
+        if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
                NDR_PRINT_OUT_DEBUG($name, r);          
        }
 ";
index 3dd569a814efa3b45f03c4438bcbf67a29a694e5..a09a8be5d4bc96f4e4cc4883e4cb3eed468ef7cf 100644 (file)
@@ -101,7 +101,7 @@ static struct rpc_request *dcom_proxy_$interface->{NAME}_$name\_send(struct dcom
        r->in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION;
        r->in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION;
 
-       if (p->flags & DCERPC_DEBUG_PRINT_IN) {
+       if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
                NDR_PRINT_IN_DEBUG($name, r);           
        }
 
@@ -123,7 +123,7 @@ static NTSTATUS dcom_proxy_$interface->{NAME}_$name(struct dcom_interface_p *d,
 
        status = dcerpc_ndr_request_recv(req);
 
-       if (NT_STATUS_IS_OK(status) && (p->flags & DCERPC_DEBUG_PRINT_OUT)) {
+       if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
                NDR_PRINT_OUT_DEBUG($name, r);          
        }
        ";
index 09c5fd280c6f15eace1b749b381a711ecd002027..02e1dea13980c38c7551a9ebcaf8d5c09b62dbfb 100644 (file)
@@ -354,6 +354,8 @@ NTSTATUS dcom_get_pipe (struct dcom_interface_p *iface, struct dcerpc_pipe **p)
        oxid = iface->ox->oxid;
        iid = iface->interface->iid;
 
+#warning "dcerpc_alter needed"
+#if 0
        if (iface->ox->pipe) {
                if (!GUID_equal(&iface->ox->pipe->syntax.uuid, &iid)) {
                        iface->ox->pipe->syntax.uuid = iid;
@@ -365,7 +367,7 @@ NTSTATUS dcom_get_pipe (struct dcom_interface_p *iface, struct dcerpc_pipe **p)
                *p = iface->ox->pipe;
                return NT_STATUS_OK;
        }
-
+#endif
        i = 0;
        do {
                status = dcerpc_binding_from_STRINGBINDING(iface->ctx, &binding, iface->ox->bindings.stringbindings[i]);
index 843d45607b8bb382d19478b26cbae365e88484f0..c032af0abc58fe13a08490e21f7c86de35d7cd9f 100644 (file)
@@ -76,8 +76,14 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli)
        }
        lsa->ipc_tree->tid = tcon.tconx.out.cnum;
 
+       lsa->pipe = dcerpc_pipe_init(lsa);
+       if (lsa->pipe == NULL) {
+               talloc_free(lsa);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        /* open the LSA pipe */
-       status = dcerpc_pipe_open_smb(&lsa->pipe, lsa->ipc_tree, DCERPC_LSARPC_NAME);
+       status = dcerpc_pipe_open_smb(lsa->pipe->conn, lsa->ipc_tree, DCERPC_LSARPC_NAME);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(lsa);
                return status;
index ee7250a4f9cefbe4802da8cf54feb0129be2a244..a29e7f7b6b9886b990139148d9e42ee82238cbbb 100644 (file)
@@ -3,7 +3,7 @@
    raw dcerpc operations
 
    Copyright (C) Tim Potter 2003
-   Copyright (C) Andrew Tridgell 2003
+   Copyright (C) Andrew Tridgell 2003-2005
    Copyright (C) Jelmer Vernooij 2004
    
    This program is free software; you can redistribute it and/or modify
 #include "dlinklist.h"
 #include "librpc/gen_ndr/ndr_epmapper.h"
 
-struct dcerpc_interface_list *dcerpc_pipes = NULL;
+static struct dcerpc_interface_list *dcerpc_pipes = NULL;
 
+/*
+  register a dcerpc client interface
+*/
 NTSTATUS librpc_register_interface(const struct dcerpc_interface_table *interface)
 {
        struct dcerpc_interface_list *l = talloc_p(talloc_autofree_context(),
@@ -43,52 +46,92 @@ NTSTATUS librpc_register_interface(const struct dcerpc_interface_table *interfac
        return NT_STATUS_OK;
 }
 
+/*
+  return the list of registered dcerpc_pipes
+*/
+const struct dcerpc_interface_list *librpc_dcerpc_pipes(void)
+{
+       return dcerpc_pipes;
+}
+
+/* destroy a dcerpc connection */
+static int dcerpc_connection_destructor(void *ptr)
+{
+       struct dcerpc_connection *c = ptr;
+       if (c->transport.shutdown_pipe) {
+               c->transport.shutdown_pipe(c);
+       }
+       return 0;
+}
+
+
+/* initialise a dcerpc connection. */
+struct dcerpc_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx)
+{
+       struct dcerpc_connection *c;
+
+       c = talloc_zero(mem_ctx, struct dcerpc_connection);
+       if (!c) {
+               return NULL;
+       }
+
+       c->call_id = 1;
+       c->security_state.auth_info = NULL;
+       c->security_state.session_key = dcerpc_generic_session_key;
+       c->security_state.generic_state = NULL;
+       c->binding_string = NULL;
+       c->flags = 0;
+       c->srv_max_xmit_frag = 0;
+       c->srv_max_recv_frag = 0;
+       c->pending = NULL;
+
+       talloc_set_destructor(c, dcerpc_connection_destructor);
+
+       return c;
+}
+
 /* initialise a dcerpc pipe. */
-struct dcerpc_pipe *dcerpc_pipe_init(void)
+struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx)
 {
        struct dcerpc_pipe *p;
 
-       p = talloc_p(NULL, struct dcerpc_pipe);
+       p = talloc_p(mem_ctx, struct dcerpc_pipe);
        if (!p) {
                return NULL;
        }
 
-       p->reference_count = 0;
-       p->call_id = 1;
-       p->security_state.auth_info = NULL;
-       p->security_state.session_key = dcerpc_generic_session_key;
-       p->security_state.generic_state = NULL;
-       p->binding_string = NULL;
-       p->flags = 0;
-       p->srv_max_xmit_frag = 0;
-       p->srv_max_recv_frag = 0;
+       p->conn = dcerpc_connection_init(p);
+       if (p->conn == NULL) {
+               talloc_free(p);
+               return NULL;
+       }
+
        p->last_fault_code = 0;
-       p->pending = NULL;
+       p->context_id = 0;
+
+       ZERO_STRUCT(p->syntax);
+       ZERO_STRUCT(p->transfer_syntax);
 
        return p;
 }
 
+
 /* 
    choose the next call id to use
 */
-static uint32_t next_call_id(struct dcerpc_pipe *p)
+static uint32_t next_call_id(struct dcerpc_connection *c)
 {
-       p->call_id++;
-       if (p->call_id == 0) {
-               p->call_id++;
+       c->call_id++;
+       if (c->call_id == 0) {
+               c->call_id++;
        }
-       return p->call_id;
+       return c->call_id;
 }
 
 /* close down a dcerpc over SMB pipe */
 void dcerpc_pipe_close(struct dcerpc_pipe *p)
 {
-       if (!p) return;
-       p->reference_count--;
-       if (p->reference_count <= 0) {
-               p->transport.shutdown_pipe(p);
-               talloc_free(p);
-       }
+       talloc_free(p);
 }
 
 /* we need to be able to get/set the fragment length without doing a full
@@ -124,17 +167,18 @@ void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v)
 /*
   setup for a ndr pull, also setting up any flags from the binding string
 */
-static struct ndr_pull *ndr_pull_init_flags(struct dcerpc_pipe *p, DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
+static struct ndr_pull *ndr_pull_init_flags(struct dcerpc_connection *c, 
+                                           DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
 {
        struct ndr_pull *ndr = ndr_pull_init_blob(blob, mem_ctx);
 
        if (ndr == NULL) return ndr;
 
-       if (p->flags & DCERPC_DEBUG_PAD_CHECK) {
+       if (c->flags & DCERPC_DEBUG_PAD_CHECK) {
                ndr->flags |= LIBNDR_FLAG_PAD_CHECK;
        }
 
-       if (p->flags & DCERPC_NDR_REF_ALLOC) {
+       if (c->flags & DCERPC_NDR_REF_ALLOC) {
                ndr->flags |= LIBNDR_FLAG_REF_ALLOC;
        }
 
@@ -145,12 +189,12 @@ static struct ndr_pull *ndr_pull_init_flags(struct dcerpc_pipe *p, DATA_BLOB *bl
    parse a data blob into a dcerpc_packet structure. This handles both
    input and output packets
 */
-static NTSTATUS dcerpc_pull(struct dcerpc_pipe *p, DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 
+static NTSTATUS dcerpc_pull(struct dcerpc_connection *c, DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 
                            struct dcerpc_packet *pkt)
 {
        struct ndr_pull *ndr;
 
-       ndr = ndr_pull_init_flags(p, blob, mem_ctx);
+       ndr = ndr_pull_init_flags(c, blob, mem_ctx);
        if (!ndr) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -177,7 +221,7 @@ static NTSTATUS dcerpc_connect_verifier(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
 }
 
 /*
-  generate a CONNECT level verifier
+  check a CONNECT level verifier
 */
 static NTSTATUS dcerpc_check_connect_verifier(DATA_BLOB *blob)
 {
@@ -191,7 +235,7 @@ static NTSTATUS dcerpc_check_connect_verifier(DATA_BLOB *blob)
 /* 
    parse a possibly signed blob into a dcerpc request packet structure
 */
-static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p
+static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_connection *c
                                         DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 
                                         struct dcerpc_packet *pkt)
 {
@@ -201,12 +245,12 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
        DATA_BLOB auth_blob;
 
        /* non-signed packets are simpler */
-       if (!p->security_state.auth_info || 
-           !p->security_state.generic_state) {
-               return dcerpc_pull(p, blob, mem_ctx, pkt);
+       if (!c->security_state.auth_info || 
+           !c->security_state.generic_state) {
+               return dcerpc_pull(c, blob, mem_ctx, pkt);
        }
 
-       ndr = ndr_pull_init_flags(p, blob, mem_ctx);
+       ndr = ndr_pull_init_flags(c, blob, mem_ctx);
        if (!ndr) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -226,7 +270,7 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
        }
 
        if (pkt->auth_length == 0 &&
-           p->security_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
+           c->security_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
                return NT_STATUS_OK;
        }
 
@@ -243,7 +287,7 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
        pkt->u.response.stub_and_verifier.length -= auth_blob.length;
 
        /* pull the auth structure */
-       ndr = ndr_pull_init_flags(p, &auth_blob, mem_ctx);
+       ndr = ndr_pull_init_flags(c, &auth_blob, mem_ctx);
        if (!ndr) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -259,9 +303,9 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
        
        
        /* check signature or unseal the packet */
-       switch (p->security_state.auth_info->auth_level) {
+       switch (c->security_state.auth_info->auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
-               status = gensec_unseal_packet(p->security_state.generic_state, 
+               status = gensec_unseal_packet(c->security_state.generic_state, 
                                              mem_ctx, 
                                              blob->data + DCERPC_REQUEST_LENGTH,
                                              pkt->u.response.stub_and_verifier.length, 
@@ -274,7 +318,7 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
                break;
                
        case DCERPC_AUTH_LEVEL_INTEGRITY:
-               status = gensec_check_packet(p->security_state.generic_state, 
+               status = gensec_check_packet(c->security_state.generic_state, 
                                             mem_ctx, 
                                             pkt->u.response.stub_and_verifier.data, 
                                             pkt->u.response.stub_and_verifier.length, 
@@ -308,7 +352,7 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
 /* 
    push a dcerpc request packet into a blob, possibly signing it.
 */
-static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p
+static NTSTATUS dcerpc_push_request_sign(struct dcerpc_connection *c
                                         DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 
                                         struct dcerpc_packet *pkt)
 {
@@ -317,9 +361,9 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
        DATA_BLOB creds2;
 
        /* non-signed packets are simpler */
-       if (!p->security_state.auth_info || 
-           !p->security_state.generic_state) {
-               return dcerpc_push_auth(blob, mem_ctx, pkt, p->security_state.auth_info);
+       if (!c->security_state.auth_info || 
+           !c->security_state.generic_state) {
+               return dcerpc_push_auth(blob, mem_ctx, pkt, c->security_state.auth_info);
        }
 
        ndr = ndr_push_init_ctx(mem_ctx);
@@ -327,7 +371,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+       if (c->flags & DCERPC_PUSH_BIGENDIAN) {
                ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
@@ -342,25 +386,25 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
 
        /* pad to 16 byte multiple in the payload portion of the
           packet. This matches what w2k3 does */
-       p->security_state.auth_info->auth_pad_length = 
+       c->security_state.auth_info->auth_pad_length = 
                (16 - (pkt->u.request.stub_and_verifier.length & 15)) & 15;
-       ndr_push_zero(ndr, p->security_state.auth_info->auth_pad_length);
+       ndr_push_zero(ndr, c->security_state.auth_info->auth_pad_length);
 
        /* sign or seal the packet */
-       switch (p->security_state.auth_info->auth_level) {
+       switch (c->security_state.auth_info->auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
        case DCERPC_AUTH_LEVEL_INTEGRITY:
-               p->security_state.auth_info->credentials
-                       = data_blob_talloc(mem_ctx, NULL, gensec_sig_size(p->security_state.generic_state));
-               data_blob_clear(&p->security_state.auth_info->credentials);
+               c->security_state.auth_info->credentials
+                       = data_blob_talloc(mem_ctx, NULL, gensec_sig_size(c->security_state.generic_state));
+               data_blob_clear(&c->security_state.auth_info->credentials);
                break;
 
        case DCERPC_AUTH_LEVEL_CONNECT:
-               status = dcerpc_connect_verifier(mem_ctx, &p->security_state.auth_info->credentials);
+               status = dcerpc_connect_verifier(mem_ctx, &c->security_state.auth_info->credentials);
                break;
                
        case DCERPC_AUTH_LEVEL_NONE:
-               p->security_state.auth_info->credentials = data_blob(NULL, 0);
+               c->security_state.auth_info->credentials = data_blob(NULL, 0);
                break;
                
        default:
@@ -373,7 +417,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
        }       
 
        /* add the auth verifier */
-       status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, p->security_state.auth_info);
+       status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, c->security_state.auth_info);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -385,18 +429,19 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
           in these earlier as we don't know the signature length (it
           could be variable length) */
        dcerpc_set_frag_length(blob, blob->length);
-       dcerpc_set_auth_length(blob, p->security_state.auth_info->credentials.length);
+       dcerpc_set_auth_length(blob, c->security_state.auth_info->credentials.length);
 
        /* sign or seal the packet */
-       switch (p->security_state.auth_info->auth_level) {
+       switch (c->security_state.auth_info->auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
-               status = gensec_seal_packet(p->security_state.generic_state, 
+               status = gensec_seal_packet(c->security_state.generic_state, 
                                            mem_ctx, 
                                            blob->data + DCERPC_REQUEST_LENGTH, 
-                                           pkt->u.request.stub_and_verifier.length+p->security_state.auth_info->auth_pad_length,
+                                           pkt->u.request.stub_and_verifier.length + 
+                                           c->security_state.auth_info->auth_pad_length,
                                            blob->data,
                                            blob->length - 
-                                           p->security_state.auth_info->credentials.length,
+                                           c->security_state.auth_info->credentials.length,
                                            &creds2);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
@@ -405,13 +450,14 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
                break;
 
        case DCERPC_AUTH_LEVEL_INTEGRITY:
-               status = gensec_sign_packet(p->security_state.generic_state, 
+               status = gensec_sign_packet(c->security_state.generic_state, 
                                            mem_ctx, 
                                            blob->data + DCERPC_REQUEST_LENGTH, 
-                                           pkt->u.request.stub_and_verifier.length+p->security_state.auth_info->auth_pad_length,
+                                           pkt->u.request.stub_and_verifier.length + 
+                                           c->security_state.auth_info->auth_pad_length,
                                            blob->data,
                                            blob->length - 
-                                           p->security_state.auth_info->credentials.length,
+                                           c->security_state.auth_info->credentials.length,
                                            &creds2);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
@@ -423,7 +469,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
                break;
 
        case DCERPC_AUTH_LEVEL_NONE:
-               p->security_state.auth_info->credentials = data_blob(NULL, 0);
+               c->security_state.auth_info->credentials = data_blob(NULL, 0);
                break;
 
        default:
@@ -431,7 +477,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
                break;
        }
 
-       data_blob_free(&p->security_state.auth_info->credentials);
+       data_blob_free(&c->security_state.auth_info->credentials);
 
        return NT_STATUS_OK;
 }
@@ -440,11 +486,11 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
 /* 
    fill in the fixed values in a dcerpc header 
 */
-static void init_dcerpc_hdr(struct dcerpc_pipe *p, struct dcerpc_packet *pkt)
+static void init_dcerpc_hdr(struct dcerpc_connection *c, struct dcerpc_packet *pkt)
 {
        pkt->rpc_vers = 5;
        pkt->rpc_vers_minor = 0;
-       if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+       if (c->flags & DCERPC_PUSH_BIGENDIAN) {
                pkt->drep[0] = 0;
        } else {
                pkt->drep[0] = DCERPC_DREP_LE;
@@ -465,10 +511,10 @@ struct full_request_state {
 /*
   receive a reply to a full request
  */
-static void full_request_recv(struct dcerpc_pipe *p, DATA_BLOB *blob, 
+static void full_request_recv(struct dcerpc_connection *c, DATA_BLOB *blob, 
                              NTSTATUS status)
 {
-       struct full_request_state *state = p->full_request_private;
+       struct full_request_state *state = c->full_request_private;
 
        if (!NT_STATUS_IS_OK(status)) {
                state->status = status;
@@ -482,7 +528,7 @@ static void full_request_recv(struct dcerpc_pipe *p, DATA_BLOB *blob,
   perform a single pdu synchronous request - used for the bind code
   this cannot be mixed with normal async requests
 */
-static NTSTATUS full_request(struct dcerpc_pipe *p
+static NTSTATUS full_request(struct dcerpc_connection *c
                             TALLOC_CTX *mem_ctx,
                             DATA_BLOB *request_blob,
                             DATA_BLOB *reply_blob)
@@ -497,16 +543,16 @@ static NTSTATUS full_request(struct dcerpc_pipe *p,
        state->reply_blob = reply_blob;
        state->status = NT_STATUS_OK;
 
-       p->transport.recv_data = full_request_recv;
-       p->full_request_private = state;
+       c->transport.recv_data = full_request_recv;
+       c->full_request_private = state;
 
-       status = p->transport.send_request(p, request_blob, True);
+       status = c->transport.send_request(c, request_blob, True);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
        while (NT_STATUS_IS_OK(state->status) && state->reply_blob) {
-               struct event_context *ctx = p->transport.event_context(p);
+               struct event_context *ctx = c->transport.event_context(c);
                if (event_loop_once(ctx) != 0) {
                        return NT_STATUS_CONNECTION_DISCONNECTED;
                }
@@ -534,41 +580,41 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
        p->syntax = *syntax;
        p->transfer_syntax = *transfer_syntax;
 
-       init_dcerpc_hdr(p, &pkt);
+       init_dcerpc_hdr(p->conn, &pkt);
 
        pkt.ptype = DCERPC_PKT_BIND;
        pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
-       pkt.call_id = p->call_id;
+       pkt.call_id = p->conn->call_id;
        pkt.auth_length = 0;
 
        pkt.u.bind.max_xmit_frag = 5840;
        pkt.u.bind.max_recv_frag = 5840;
        pkt.u.bind.assoc_group_id = 0;
        pkt.u.bind.num_contexts = 1;
-       pkt.u.bind.ctx_list = talloc_p(mem_ctx, struct dcerpc_ctx_list);
+       pkt.u.bind.ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
        if (!pkt.u.bind.ctx_list) {
                return NT_STATUS_NO_MEMORY;
        }
-       pkt.u.bind.ctx_list[0].context_id = 0;
+       pkt.u.bind.ctx_list[0].context_id = p->context_id;
        pkt.u.bind.ctx_list[0].num_transfer_syntaxes = 1;
        pkt.u.bind.ctx_list[0].abstract_syntax = p->syntax;
        pkt.u.bind.ctx_list[0].transfer_syntaxes = &p->transfer_syntax;
        pkt.u.bind.auth_info = data_blob(NULL, 0);
 
        /* construct the NDR form of the packet */
-       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->security_state.auth_info);
+       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, mem_ctx, &blob, &blob);
+       status = full_request(p->conn, mem_ctx, &blob, &blob);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
        /* unmarshall the NDR */
-       status = dcerpc_pull(p, &blob, mem_ctx, &pkt);
+       status = dcerpc_pull(p->conn, &blob, mem_ctx, &pkt);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -585,117 +631,49 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
        }
 
        if (pkt.ptype == DCERPC_PKT_BIND_ACK) {
-               p->srv_max_xmit_frag = pkt.u.bind_ack.max_xmit_frag;
-               p->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->security_state.auth_info && pkt.u.bind_ack.auth_info.length) {
+       if (p->conn->security_state.auth_info && pkt.u.bind_ack.auth_info.length) {
                status = ndr_pull_struct_blob(&pkt.u.bind_ack.auth_info,
                                              mem_ctx,
-                                             p->security_state.auth_info,
+                                             p->conn->security_state.auth_info,
                                              (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
        }
 
        return status;  
 }
 
-/* 
-   perform a alter context using the given syntax 
-
-   the auth_info structure is updated with the reply authentication info
-   on success
-*/
-NTSTATUS dcerpc_alter(struct dcerpc_pipe *p, 
-                    TALLOC_CTX *mem_ctx)
-{
-       struct dcerpc_packet pkt;
-       NTSTATUS status;
-       DATA_BLOB blob;
-
-       init_dcerpc_hdr(p, &pkt);
-
-       pkt.ptype = DCERPC_PKT_ALTER;
-       pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
-       pkt.call_id = p->call_id;
-       pkt.auth_length = 0;
-
-       pkt.u.alter.max_xmit_frag = 0x2000;
-       pkt.u.alter.max_recv_frag = 0x2000;
-       pkt.u.alter.assoc_group_id = 0;
-       pkt.u.alter.num_contexts = 1;
-       pkt.u.alter.ctx_list = talloc_p(mem_ctx, struct dcerpc_ctx_list);
-       if (!pkt.u.alter.ctx_list) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       pkt.u.alter.ctx_list[0].context_id = 0;
-       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->security_state.auth_info);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       /* send it on its way */
-       status = full_request(p, mem_ctx, &blob, &blob);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       /* unmarshall the NDR */
-       status = dcerpc_pull(p, &blob, mem_ctx, &pkt);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       if ((pkt.ptype != DCERPC_PKT_ALTER_ACK) ||
-           pkt.u.alter_ack.num_results == 0 ||
-           pkt.u.alter_ack.ctx_list[0].result != 0) {
-               status = NT_STATUS_UNSUCCESSFUL;
-       }
-
-       /* the bind_ack might contain a reply set of credentials */
-       if (p->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->security_state.auth_info,
-                                             (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
-       }
-
-       return status;  
-}
 
 /* 
    perform a continued bind (and auth3)
 */
-NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p
+NTSTATUS dcerpc_auth3(struct dcerpc_connection *c
                      TALLOC_CTX *mem_ctx)
 {
        struct dcerpc_packet pkt;
        NTSTATUS status;
        DATA_BLOB blob;
 
-       init_dcerpc_hdr(p, &pkt);
+       init_dcerpc_hdr(c, &pkt);
 
        pkt.ptype = DCERPC_PKT_AUTH3;
        pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
-       pkt.call_id = next_call_id(p);
+       pkt.call_id = next_call_id(c);
        pkt.auth_length = 0;
        pkt.u.auth3._pad = 0;
        pkt.u.auth3.auth_info = data_blob(NULL, 0);
 
        /* construct the NDR form of the packet */
-       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->security_state.auth_info);
+       status = dcerpc_push_auth(&blob, mem_ctx, &pkt, c->security_state.auth_info);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
        /* send it on its way */
-       status = p->transport.send_request(p, &blob, False);
+       status = c->transport.send_request(c, &blob, False);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -733,7 +711,7 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p,
   process a fragment received from the transport layer during a
   request
 */
-static void dcerpc_request_recv_data(struct dcerpc_pipe *p
+static void dcerpc_request_recv_data(struct dcerpc_connection *c
                                     DATA_BLOB *data,
                                     NTSTATUS status)
 {
@@ -743,11 +721,11 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
        
        if (!NT_STATUS_IS_OK(status)) {
                /* all pending requests get the error */
-               while (p->pending) {
-                       req = p->pending;
+               while (c->pending) {
+                       req = c->pending;
                        req->state = RPC_REQUEST_DONE;
                        req->status = status;
-                       DLIST_REMOVE(p->pending, req);
+                       DLIST_REMOVE(c->pending, req);
                        if (req->async.callback) {
                                req->async.callback(req);
                        }
@@ -757,12 +735,12 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
 
        pkt.call_id = 0;
 
-       status = dcerpc_pull_request_sign(p, data, (TALLOC_CTX *)data->data, &pkt);
+       status = dcerpc_pull_request_sign(c, data, (TALLOC_CTX *)data->data, &pkt);
 
        /* find the matching request. Notice we match before we check
           the status.  this is ok as a pending call_id can never be
           zero */
-       for (req=p->pending;req;req=req->next) {
+       for (req=c->pending;req;req=req->next) {
                if (pkt.call_id == req->call_id) break;
        }
 
@@ -774,7 +752,7 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
        if (!NT_STATUS_IS_OK(status)) {
                req->status = status;
                req->state = RPC_REQUEST_DONE;
-               DLIST_REMOVE(p->pending, req);
+               DLIST_REMOVE(c->pending, req);
                if (req->async.callback) {
                        req->async.callback(req);
                }
@@ -782,11 +760,11 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
        }
 
        if (pkt.ptype == DCERPC_PKT_FAULT) {
-               DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(p, pkt.u.fault.status)));
+               DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt.u.fault.status)));
                req->fault_code = pkt.u.fault.status;
                req->status = NT_STATUS_NET_WRITE_FAULT;
                req->state = RPC_REQUEST_DONE;
-               DLIST_REMOVE(p->pending, req);
+               DLIST_REMOVE(c->pending, req);
                if (req->async.callback) {
                        req->async.callback(req);
                }
@@ -799,7 +777,7 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
                req->fault_code = DCERPC_FAULT_OTHER;
                req->status = NT_STATUS_NET_WRITE_FAULT;
                req->state = RPC_REQUEST_DONE;
-               DLIST_REMOVE(p->pending, req);
+               DLIST_REMOVE(c->pending, req);
                if (req->async.callback) {
                        req->async.callback(req);
                }
@@ -816,7 +794,7 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
                if (!req->payload.data) {
                        req->status = NT_STATUS_NO_MEMORY;
                        req->state = RPC_REQUEST_DONE;
-                       DLIST_REMOVE(p->pending, req);
+                       DLIST_REMOVE(c->pending, req);
                        if (req->async.callback) {
                                req->async.callback(req);
                        }
@@ -828,13 +806,13 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
        }
 
        if (!(pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
-               p->transport.send_read(p);
+               c->transport.send_read(c);
                return;
        }
 
        /* we've got the full payload */
        req->state = RPC_REQUEST_DONE;
-       DLIST_REMOVE(p->pending, req);
+       DLIST_REMOVE(c->pending, req);
 
        if (!(pkt.drep[0] & DCERPC_DREP_LE)) {
                req->flags |= DCERPC_PULL_BIGENDIAN;
@@ -854,12 +832,12 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
 static int dcerpc_req_destructor(void *ptr)
 {
        struct rpc_request *req = ptr;
-       DLIST_REMOVE(req->p->pending, req);
+       DLIST_REMOVE(req->p->conn->pending, req);
        return 0;
 }
 
 /*
-  perform the send size of a async dcerpc request
+  perform the send side of a async dcerpc request
 */
 struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p, 
                                        const struct GUID *object,
@@ -873,7 +851,7 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
        uint32_t remaining, chunk_size;
        BOOL first_packet = True;
 
-       p->transport.recv_data = dcerpc_request_recv_data;
+       p->conn->transport.recv_data = dcerpc_request_recv_data;
 
        req = talloc_p(mem_ctx, struct rpc_request);
        if (req == NULL) {
@@ -881,7 +859,7 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
        }
 
        req->p = p;
-       req->call_id = next_call_id(p);
+       req->call_id = next_call_id(p->conn);
        req->status = NT_STATUS_OK;
        req->state = RPC_REQUEST_PENDING;
        req->payload = data_blob(NULL, 0);
@@ -889,20 +867,20 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
        req->fault_code = 0;
        req->async.callback = NULL;
 
-       init_dcerpc_hdr(p, &pkt);
+       init_dcerpc_hdr(p->conn, &pkt);
 
        remaining = stub_data->length;
 
        /* we can write a full max_recv_frag size, minus the dcerpc
           request header size */
-       chunk_size = p->srv_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH);
+       chunk_size = p->conn->srv_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH);
 
        pkt.ptype = DCERPC_PKT_REQUEST;
        pkt.call_id = req->call_id;
        pkt.auth_length = 0;
        pkt.pfc_flags = 0;
        pkt.u.request.alloc_hint = remaining;
-       pkt.u.request.context_id = 0;
+       pkt.u.request.context_id = p->context_id;
        pkt.u.request.opnum = opnum;
 
        if (object) {
@@ -911,7 +889,7 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
                chunk_size -= ndr_size_GUID(object,0);
        }
 
-       DLIST_ADD(p->pending, req);
+       DLIST_ADD(p->conn->pending, req);
 
        /* we send a series of pdus without waiting for a reply */
        while (remaining > 0 || first_packet) {
@@ -933,17 +911,17 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
                        (stub_data->length - remaining);
                pkt.u.request.stub_and_verifier.length = chunk;
 
-               req->status = dcerpc_push_request_sign(p, &blob, mem_ctx, &pkt);
+               req->status = dcerpc_push_request_sign(p->conn, &blob, mem_ctx, &pkt);
                if (!NT_STATUS_IS_OK(req->status)) {
                        req->state = RPC_REQUEST_DONE;
-                       DLIST_REMOVE(p->pending, req);
+                       DLIST_REMOVE(p->conn->pending, req);
                        return req;
                }
                
-               req->status = p->transport.send_request(p, &blob, last_frag);
+               req->status = p->conn->transport.send_request(p->conn, &blob, last_frag);
                if (!NT_STATUS_IS_OK(req->status)) {
                        req->state = RPC_REQUEST_DONE;
-                       DLIST_REMOVE(p->pending, req);
+                       DLIST_REMOVE(p->conn->pending, req);
                        return req;
                }               
 
@@ -961,7 +939,7 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
 */
 struct event_context *dcerpc_event_context(struct dcerpc_pipe *p)
 {
-       return p->transport.event_context(p);
+       return p->conn->transport.event_context(p->conn);
 }
 
 
@@ -1020,7 +998,7 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
   for that to the NDR we initially generated. If they don't match then we know
   we must have a bug in either the pull or push side of our code
 */
-static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_pipe *p
+static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c
                                       TALLOC_CTX *mem_ctx,
                                       DATA_BLOB blob,
                                       size_t struct_size,
@@ -1038,7 +1016,7 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_pipe *p,
                return NT_STATUS_NO_MEMORY;
        }
 
-       pull = ndr_pull_init_flags(p, &blob, mem_ctx);
+       pull = ndr_pull_init_flags(c, &blob, mem_ctx);
        if (!pull) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -1084,7 +1062,7 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_pipe *p,
   initially generated. If they don't match then we know we must have a
   bug in either the pull or push side of our code
 */
-static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_pipe *p,
+static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
                                        TALLOC_CTX *mem_ctx,
                                        void *struct_ptr,
                                        size_t struct_size,
@@ -1117,7 +1095,7 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_pipe *p,
 
        blob = ndr_push_blob(push);
 
-       pull = ndr_pull_init_flags(p, &blob, mem_ctx);
+       pull = ndr_pull_init_flags(c, &blob, mem_ctx);
        if (!pull) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -1182,7 +1160,7 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
                return NULL;
        }
 
-       if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+       if (p->conn->flags & DCERPC_PUSH_BIGENDIAN) {
                push->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
@@ -1198,8 +1176,8 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
        /* retrieve the blob */
        request = ndr_push_blob(push);
 
-       if (p->flags & DCERPC_DEBUG_VALIDATE_IN) {
-               status = dcerpc_ndr_validate_in(p, mem_ctx, request, call->struct_size, 
+       if (p->conn->flags & DCERPC_DEBUG_VALIDATE_IN) {
+               status = dcerpc_ndr_validate_in(p->conn, mem_ctx, request, call->struct_size, 
                                                call->ndr_push, call->ndr_pull);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(2,("Validation failed in dcerpc_ndr_request_send - %s\n",
@@ -1256,7 +1234,7 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
        talloc_free(req);
 
        /* prepare for ndr_pull_* */
-       pull = ndr_pull_init_flags(p, &response, mem_ctx);
+       pull = ndr_pull_init_flags(p->conn, &response, mem_ctx);
        if (!pull) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -1276,8 +1254,8 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
                return status;
        }
 
-       if (p->flags & DCERPC_DEBUG_VALIDATE_OUT) {
-               status = dcerpc_ndr_validate_out(p, mem_ctx, r, call->struct_size, 
+       if (p->conn->flags & DCERPC_DEBUG_VALIDATE_OUT) {
+               status = dcerpc_ndr_validate_out(p->conn, mem_ctx, r, call->struct_size, 
                                                 call->ndr_push, call->ndr_pull);
                if (!NT_STATUS_IS_OK(status)) {
                        dcerpc_log_packet(table, opnum, NDR_OUT, 
@@ -1329,25 +1307,25 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
 */
 const char *dcerpc_server_name(struct dcerpc_pipe *p)
 {
-       if (!p->transport.peer_name) {
+       if (!p->conn->transport.peer_name) {
                return "";
        }
-       return p->transport.peer_name(p);
+       return p->conn->transport.peer_name(p->conn);
 }
 
+
 /*
-  a useful function to get the auth_level 
+  get the dcerpc auth_level for a open connection
 */
-
-uint32 dcerpc_auth_level(struct dcerpc_pipe *p) 
+uint32 dcerpc_auth_level(struct dcerpc_connection *c) 
 {
        uint8_t auth_level;
 
-       if (p->flags & DCERPC_SEAL) {
+       if (c->flags & DCERPC_SEAL) {
                auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
-       } else if (p->flags & DCERPC_SIGN) {
+       } else if (c->flags & DCERPC_SIGN) {
                auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
-       } else if (p->flags & DCERPC_CONNECT) {
+       } else if (c->flags & DCERPC_CONNECT) {
                auth_level = DCERPC_AUTH_LEVEL_CONNECT;
        } else {
                auth_level = DCERPC_AUTH_LEVEL_NONE;
index 1b2feeadb29994e0989c72e5f2ada907eaf7c80f..00f1fb6488615fd5b80a14396f86bd3bcdf2e6f2 100644 (file)
@@ -1,9 +1,10 @@
 /* 
    Unix SMB/CIFS implementation.
-   DCERPC interface structures
+
+   DCERPC client side interface structures
 
    Copyright (C) Tim Potter 2003
-   Copyright (C) Andrew Tridgell 2003
+   Copyright (C) Andrew Tridgell 2003-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
@@ -28,17 +29,19 @@ enum dcerpc_transport_t {
 /*
   this defines a generic security context for signed/sealed dcerpc pipes.
 */
-struct dcerpc_pipe;
+struct dcerpc_connection;
 struct dcerpc_security {
        struct dcerpc_auth *auth_info;
        struct gensec_security *generic_state;
 
        /* get the session key */
-       NTSTATUS (*session_key)(struct dcerpc_pipe *, DATA_BLOB *);
+       NTSTATUS (*session_key)(struct dcerpc_connection *, DATA_BLOB *);
 };
 
-struct dcerpc_pipe {
-       int reference_count;
+/*
+  this holds the information that is not specific to a particular rpc context_id
+*/
+struct dcerpc_connection {
        uint32_t call_id;
        uint32_t srv_max_xmit_frag;
        uint32_t srv_max_recv_frag;
@@ -46,35 +49,28 @@ struct dcerpc_pipe {
        struct dcerpc_security security_state;
        const char *binding_string;
 
-       struct dcerpc_syntax_id syntax;
-       struct dcerpc_syntax_id transfer_syntax;
-
        struct dcerpc_transport {
                enum dcerpc_transport_t transport;
                void *private;
 
-               NTSTATUS (*shutdown_pipe)(struct dcerpc_pipe *);
+               NTSTATUS (*shutdown_pipe)(struct dcerpc_connection *);
 
-               const char *(*peer_name)(struct dcerpc_pipe *);
+               const char *(*peer_name)(struct dcerpc_connection *);
 
                /* send a request to the server */
-               NTSTATUS (*send_request)(struct dcerpc_pipe *, DATA_BLOB *, BOOL trigger_read);
+               NTSTATUS (*send_request)(struct dcerpc_connection *, DATA_BLOB *, BOOL trigger_read);
 
                /* send a read request to the server */
-               NTSTATUS (*send_read)(struct dcerpc_pipe *);
+               NTSTATUS (*send_read)(struct dcerpc_connection *);
 
                /* get an event context for the connection */
-               struct event_context *(*event_context)(struct dcerpc_pipe *);
+               struct event_context *(*event_context)(struct dcerpc_connection *);
 
                /* a callback to the dcerpc code when a full fragment
                   has been received */
-               void (*recv_data)(struct dcerpc_pipe *, DATA_BLOB *, NTSTATUS status);
-
+               void (*recv_data)(struct dcerpc_connection *, DATA_BLOB *, NTSTATUS status);
        } transport;
 
-       /* the last fault code from a DCERPC fault */
-       uint32_t last_fault_code;
-
        /* pending requests */
        struct rpc_request *pending;
 
@@ -82,6 +78,22 @@ struct dcerpc_pipe {
        void *full_request_private;
 };
 
+/*
+  this encapsulates a full dcerpc client side pipe 
+*/
+struct dcerpc_pipe {
+       uint32_t context_id;
+
+       struct dcerpc_syntax_id syntax;
+       struct dcerpc_syntax_id transfer_syntax;
+
+       struct dcerpc_connection *conn;
+
+       /* the last fault code from a DCERPC fault */
+       uint32_t last_fault_code;
+};
+
+
 /* dcerpc pipe flags */
 #define DCERPC_DEBUG_PRINT_IN          (1<<0)
 #define DCERPC_DEBUG_PRINT_OUT         (1<<1)
@@ -141,8 +153,7 @@ struct dcerpc_interface_table {
        const struct dcerpc_endpoint_list *endpoints;
 };
 
-struct dcerpc_interface_list
-{
+struct dcerpc_interface_list {
        struct dcerpc_interface_list *prev, *next;
        const struct dcerpc_interface_table *table;
 };
index 36e4ba6eea1a3f397649f6aba9f414e6f825e904..9d43218e4b24c746ae22c75fef66d2b03d0b4d85 100644 (file)
@@ -45,7 +45,7 @@ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
 }
 
 NTSTATUS dcerpc_bind_auth3(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t auth_level,
-                         const char *uuid, uint_t version)
+                          const char *uuid, uint_t version)
 {
        NTSTATUS status;
        TALLOC_CTX *mem_ctx;
@@ -57,33 +57,34 @@ NTSTATUS dcerpc_bind_auth3(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
                return NT_STATUS_NO_MEMORY;
        }
        
-       if (!p->security_state.generic_state) {
-               status = gensec_client_start(p, &p->security_state.generic_state);
+       if (!p->conn->security_state.generic_state) {
+               status = gensec_client_start(p, &p->conn->security_state.generic_state);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
 
-               status = gensec_start_mech_by_authtype(p->security_state.generic_state, auth_type, auth_level);
+               status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state, 
+                                                      auth_type, auth_level);
 
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
        }
 
-       p->security_state.auth_info = talloc_p(p, struct dcerpc_auth);
-       if (!p->security_state.auth_info) {
+       p->conn->security_state.auth_info = talloc(p, struct dcerpc_auth);
+       if (!p->conn->security_state.auth_info) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
-       p->security_state.auth_info->auth_type = auth_type;
-       p->security_state.auth_info->auth_level = auth_level;
-       p->security_state.auth_info->auth_pad_length = 0;
-       p->security_state.auth_info->auth_reserved = 0;
-       p->security_state.auth_info->auth_context_id = random();
-       p->security_state.auth_info->credentials = null_data_blob;
+       p->conn->security_state.auth_info->auth_type = auth_type;
+       p->conn->security_state.auth_info->auth_level = auth_level;
+       p->conn->security_state.auth_info->auth_pad_length = 0;
+       p->conn->security_state.auth_info->auth_reserved = 0;
+       p->conn->security_state.auth_info->auth_context_id = random();
+       p->conn->security_state.auth_info->credentials = null_data_blob;
 
-       status = gensec_update(p->security_state.generic_state, mem_ctx,
+       status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
                               null_data_blob,
                               &credentials);
        
@@ -91,38 +92,40 @@ NTSTATUS dcerpc_bind_auth3(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
                goto done;
        }
 
-       p->security_state.auth_info->credentials = credentials;
+       p->conn->security_state.auth_info->credentials = credentials;
 
        status = dcerpc_bind_byuuid(p, mem_ctx, uuid, version);
        if (!NT_STATUS_IS_OK(status)) {
                goto done;
        }
 
-       status = gensec_update(p->security_state.generic_state, mem_ctx,
-                              p->security_state.auth_info->credentials,
+       status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
+                              p->conn->security_state.auth_info->credentials,
                               &credentials);
 
        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                goto done;
        }
 
-       p->security_state.auth_info->credentials = credentials;
+       p->conn->security_state.auth_info->credentials = credentials;
        
-       status = dcerpc_auth3(p, mem_ctx);
+       status = dcerpc_auth3(p->conn, mem_ctx);
 done:
        talloc_destroy(mem_ctx);
 
        if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(p->security_state.generic_state);
-               ZERO_STRUCT(p->security_state);
+               talloc_free(p->conn->security_state.generic_state);
+               ZERO_STRUCT(p->conn->security_state);
        } else {
                /* Authenticated connections use the generic session key */
-               p->security_state.session_key = dcerpc_generic_session_key;
+               p->conn->security_state.session_key = dcerpc_generic_session_key;
        }
 
        return status;
 }
 
+#warning "bind_alter not implemented"
+#if 0
 NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t auth_level,
                          const char *uuid, uint_t version)
 {
@@ -136,13 +139,13 @@ NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
                return NT_STATUS_NO_MEMORY;
        }
        
-       if (!p->security_state.generic_state) {
-               status = gensec_client_start(p, &p->security_state.generic_state);
+       if (!p->conn->security_state.generic_state) {
+               status = gensec_client_start(p, &p->conn->security_state.generic_state);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
 
-               status = gensec_start_mech_by_authtype(p->security_state.generic_state, 
+               status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state, 
                                                       auth_type, auth_level);
 
                if (!NT_STATUS_IS_OK(status)) {
@@ -150,20 +153,20 @@ NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
                }
        }
 
-       p->security_state.auth_info = talloc_p(p, struct dcerpc_auth);
-       if (!p->security_state.auth_info) {
+       p->conn->security_state.auth_info = talloc_p(p, struct dcerpc_auth);
+       if (!p->conn->security_state.auth_info) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
-       p->security_state.auth_info->auth_type = auth_type;
-       p->security_state.auth_info->auth_level = auth_level;
-       p->security_state.auth_info->auth_pad_length = 0;
-       p->security_state.auth_info->auth_reserved = 0;
-       p->security_state.auth_info->auth_context_id = random();
-       p->security_state.auth_info->credentials = null_data_blob;
+       p->conn->security_state.auth_info->auth_type = auth_type;
+       p->conn->security_state.auth_info->auth_level = auth_level;
+       p->conn->security_state.auth_info->auth_pad_length = 0;
+       p->conn->security_state.auth_info->auth_reserved = 0;
+       p->conn->security_state.auth_info->auth_context_id = random();
+       p->conn->security_state.auth_info->credentials = null_data_blob;
 
-       status = gensec_update(p->security_state.generic_state, mem_ctx,
+       status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
                               null_data_blob,
                               &credentials);
        
@@ -171,7 +174,7 @@ NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
                goto done;
        }
 
-       p->security_state.auth_info->credentials = credentials;
+       p->conn->security_state.auth_info->credentials = credentials;
 
        status = dcerpc_bind_byuuid(p, mem_ctx, uuid, version);
        if (!NT_STATUS_IS_OK(status)) {
@@ -179,15 +182,15 @@ NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
        }
 
        while(1) {
-               status = gensec_update(p->security_state.generic_state, mem_ctx,
-                              p->security_state.auth_info->credentials,
+               status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
+                              p->conn->security_state.auth_info->credentials,
                               &credentials);
 
                if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                        goto done;
                }
 
-               p->security_state.auth_info->credentials = credentials;
+               p->conn->security_state.auth_info->credentials = credentials;
 
                status = dcerpc_alter(p, mem_ctx);
                if (!NT_STATUS_IS_OK(status)) {
@@ -199,12 +202,13 @@ done:
        talloc_destroy(mem_ctx);
 
        if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(p->security_state.generic_state);
-               ZERO_STRUCT(p->security_state);
+               talloc_free(p->conn->security_state.generic_state);
+               ZERO_STRUCT(p->conn->security_state);
        } else {
                /* Authenticated connections use the generic session key */
-               p->security_state.session_key = dcerpc_generic_session_key;
+               p->conn->security_state.session_key = dcerpc_generic_session_key;
        }
 
        return status;
 }
+#endif
index c236b6c5164937ac0f0aebf8a7f025160038e993..8a83cea144d47784de6496647053a39726fd0840 100644 (file)
@@ -33,38 +33,39 @@ NTSTATUS dcerpc_bind_auth_ntlm(struct dcerpc_pipe *p,
 {
        NTSTATUS status;
 
-       if (!(p->flags & (DCERPC_SIGN | DCERPC_SEAL))) {
-               p->flags |= DCERPC_CONNECT;
+       if (!(p->conn->flags & (DCERPC_SIGN | DCERPC_SEAL))) {
+               p->conn->flags |= DCERPC_CONNECT;
        }
 
-       status = gensec_client_start(p, &p->security_state.generic_state);
+       status = gensec_client_start(p, &p->conn->security_state.generic_state);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status)));
                return status;
        }
 
-       status = gensec_set_domain(p->security_state.generic_state, domain);
+       status = gensec_set_domain(p->conn->security_state.generic_state, domain);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", 
                          domain, nt_errstr(status)));
                return status;
        }
 
-       status = gensec_set_username(p->security_state.generic_state, username);
+       status = gensec_set_username(p->conn->security_state.generic_state, username);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", 
                          username, nt_errstr(status)));
                return status;
        }
 
-       status = gensec_set_password(p->security_state.generic_state, password);
+       status = gensec_set_password(p->conn->security_state.generic_state, password);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start set GENSEC client password: %s\n", 
                          nt_errstr(status)));
                return status;
        }
 
-       status = gensec_start_mech_by_authtype(p->security_state.generic_state, DCERPC_AUTH_TYPE_NTLMSSP, dcerpc_auth_level(p));
+       status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state, 
+                                              DCERPC_AUTH_TYPE_NTLMSSP, dcerpc_auth_level(p->conn));
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start set GENSEC client NTLMSSP mechanism: %s\n",
                          nt_errstr(status)));
@@ -72,7 +73,7 @@ NTSTATUS dcerpc_bind_auth_ntlm(struct dcerpc_pipe *p,
        }
        
        status = dcerpc_bind_auth3(p, DCERPC_AUTH_TYPE_NTLMSSP,
-                                  dcerpc_auth_level(p),
+                                  dcerpc_auth_level(p->conn),
                                   uuid, version);
 
        if (!NT_STATUS_IS_OK(status)) {
index 8632a3cf168f1c272274f4336be30adb316aa789..92e8d0ca38801e4b196ad6501f89767568285d74 100644 (file)
@@ -339,7 +339,7 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
        const char *workgroup, *workstation;
        uint32_t negotiate_flags;
 
-       if (p->flags & DCERPC_SCHANNEL_128) {
+       if (p->conn->flags & DCERPC_SCHANNEL_128) {
                negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
        } else {
                negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
@@ -424,46 +424,48 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p,
        NTSTATUS status;
        struct dcerpc_schannel_state *dce_schan_state;
 
-       status = gensec_client_start(p, &p->security_state.generic_state);
+       status = gensec_client_start(p, &p->conn->security_state.generic_state);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       status = gensec_set_username(p->security_state.generic_state, username);
+       status = gensec_set_username(p->conn->security_state.generic_state, username);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to set schannel username to %s: %s\n", username, nt_errstr(status)));
-               talloc_free(p->security_state.generic_state);
-               p->security_state.generic_state = NULL;
+               talloc_free(p->conn->security_state.generic_state);
+               p->conn->security_state.generic_state = NULL;
                return status;
        }
        
-       status = gensec_set_domain(p->security_state.generic_state, domain);
+       status = gensec_set_domain(p->conn->security_state.generic_state, domain);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to set schannel domain to %s: %s\n", domain, nt_errstr(status)));
-               talloc_free(p->security_state.generic_state);
-               p->security_state.generic_state = NULL;
+               talloc_free(p->conn->security_state.generic_state);
+               p->conn->security_state.generic_state = NULL;
                return status;
        }
        
-       status = gensec_start_mech_by_authtype(p->security_state.generic_state, DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p));
+       status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state, 
+                                              DCERPC_AUTH_TYPE_SCHANNEL, 
+                                              dcerpc_auth_level(p->conn));
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start SCHANNEL GENSEC backend: %s\n", nt_errstr(status)));
-               talloc_free(p->security_state.generic_state);
-               p->security_state.generic_state = NULL;
+               talloc_free(p->conn->security_state.generic_state);
+               p->conn->security_state.generic_state = NULL;
                return status;
        }
 
-       dce_schan_state = p->security_state.generic_state->private_data;
+       dce_schan_state = p->conn->security_state.generic_state->private_data;
        dce_schan_state->creds = talloc_reference(dce_schan_state, creds);
 
-       status = dcerpc_bind_auth3(p, DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p),
-                                 uuid, version);
+       status = dcerpc_bind_auth3(p, DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p->conn),
+                                  uuid, version);
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to bind to pipe with SCHANNEL: %s\n", nt_errstr(status)));
-               talloc_free(p->security_state.generic_state);
-               p->security_state.generic_state = NULL;
+               talloc_free(p->conn->security_state.generic_state);
+               p->conn->security_state.generic_state = NULL;
                return status;
        }
 
@@ -484,11 +486,11 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (p->flags & DCERPC_SCHANNEL_BDC) {
+       if (p->conn->flags & DCERPC_SCHANNEL_BDC) {
                chan_type = SEC_CHAN_BDC;
-       } else if (p->flags & DCERPC_SCHANNEL_WORKSTATION) {
+       } else if (p->conn->flags & DCERPC_SCHANNEL_WORKSTATION) {
                chan_type = SEC_CHAN_WKSTA;
-       } else if (p->flags & DCERPC_SCHANNEL_DOMAIN) {
+       } else if (p->conn->flags & DCERPC_SCHANNEL_DOMAIN) {
                chan_type = SEC_CHAN_DOMAIN;
        }
 
index ab8a60b06039f05a354000aaf83b7f1fd337c074..837561981fcc0f115c6aeb432eb068db2e7e31c5 100644 (file)
@@ -35,9 +35,9 @@ struct smb_private {
 /*
   tell the dcerpc layer that the transport is dead
 */
-static void pipe_dead(struct dcerpc_pipe *p, NTSTATUS status)
+static void pipe_dead(struct dcerpc_connection *c, NTSTATUS status)
 {
-       p->transport.recv_data(p, NULL, status);
+       c->transport.recv_data(c, NULL, status);
 }
 
 
@@ -45,7 +45,7 @@ static void pipe_dead(struct dcerpc_pipe *p, NTSTATUS status)
    this holds the state of an in-flight call
 */
 struct smb_read_state {
-       struct dcerpc_pipe *p;
+       struct dcerpc_connection *c;
        struct smbcli_request *req;
        size_t received;
        DATA_BLOB data;
@@ -64,12 +64,12 @@ static void smb_read_callback(struct smbcli_request *req)
        NTSTATUS status;
 
        state = req->async.private;
-       smb = state->p->transport.private;
+       smb = state->c->transport.private;
        io = state->io;
 
        status = smb_raw_read_recv(state->req, io);
        if (NT_STATUS_IS_ERR(status)) {
-               pipe_dead(state->p, status);
+               pipe_dead(state->c, status);
                talloc_free(state);
                return;
        }
@@ -79,7 +79,7 @@ static void smb_read_callback(struct smbcli_request *req)
        if (state->received < 16) {
                DEBUG(0,("dcerpc_smb: short packet (length %d) in read callback!\n",
                         state->received));
-               pipe_dead(state->p, NT_STATUS_INFO_LENGTH_MISMATCH);
+               pipe_dead(state->c, NT_STATUS_INFO_LENGTH_MISMATCH);
                talloc_free(state);
                return;
        }
@@ -88,7 +88,7 @@ static void smb_read_callback(struct smbcli_request *req)
 
        if (frag_length <= state->received) {
                state->data.length = state->received;
-               state->p->transport.recv_data(state->p, &state->data, NT_STATUS_OK);
+               state->c->transport.recv_data(state->c, &state->data, NT_STATUS_OK);
                talloc_free(state);
                return;
        }
@@ -96,14 +96,14 @@ static void smb_read_callback(struct smbcli_request *req)
        /* initiate another read request, as we only got part of a fragment */
        state->data.data = talloc_realloc(state, state->data.data, uint8_t, frag_length);
 
-       io->readx.in.mincnt = MIN(state->p->srv_max_xmit_frag, 
+       io->readx.in.mincnt = MIN(state->c->srv_max_xmit_frag, 
                                  frag_length - state->received);
        io->readx.in.maxcnt = io->readx.in.mincnt;
        io->readx.out.data = state->data.data + state->received;
 
        state->req = smb_raw_read_send(smb->tree, io);
        if (state->req == NULL) {
-               pipe_dead(state->p, NT_STATUS_NO_MEMORY);
+               pipe_dead(state->c, NT_STATUS_NO_MEMORY);
                talloc_free(state);
                return;
        }
@@ -116,9 +116,9 @@ static void smb_read_callback(struct smbcli_request *req)
   trigger a read request from the server, possibly with some initial
   data in the read buffer
 */
-static NTSTATUS send_read_request_continue(struct dcerpc_pipe *p, DATA_BLOB *blob)
+static NTSTATUS send_read_request_continue(struct dcerpc_connection *c, DATA_BLOB *blob)
 {
-       struct smb_private *smb = p->transport.private;
+       struct smb_private *smb = c->transport.private;
        union smb_read *io;
        struct smb_read_state *state;
        struct smbcli_request *req;
@@ -128,7 +128,7 @@ static NTSTATUS send_read_request_continue(struct dcerpc_pipe *p, DATA_BLOB *blo
                return NT_STATUS_NO_MEMORY;
        }
 
-       state->p = p;
+       state->c = c;
        if (blob == NULL) {
                state->received = 0;
                state->data = data_blob_talloc(state, NULL, 0x2000);
@@ -171,16 +171,16 @@ static NTSTATUS send_read_request_continue(struct dcerpc_pipe *p, DATA_BLOB *blo
 /*
   trigger a read request from the server
 */
-static NTSTATUS send_read_request(struct dcerpc_pipe *p)
+static NTSTATUS send_read_request(struct dcerpc_connection *c)
 {
-       return send_read_request_continue(p, NULL);
+       return send_read_request_continue(c, NULL);
 }
 
 /* 
    this holds the state of an in-flight trans call
 */
 struct smb_trans_state {
-       struct dcerpc_pipe *p;
+       struct dcerpc_connection *c;
        struct smbcli_request *req;
        struct smb_trans2 *trans;
 };
@@ -191,33 +191,33 @@ struct smb_trans_state {
 static void smb_trans_callback(struct smbcli_request *req)
 {
        struct smb_trans_state *state = req->async.private;
-       struct dcerpc_pipe *p = state->p;
+       struct dcerpc_connection *c = state->c;
        NTSTATUS status;
 
        status = smb_raw_trans_recv(req, state, state->trans);
 
        if (NT_STATUS_IS_ERR(status)) {
-               pipe_dead(p, status);
+               pipe_dead(c, status);
                return;
        }
 
        if (!NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
-               p->transport.recv_data(p, &state->trans->out.data, NT_STATUS_OK);
+               c->transport.recv_data(c, &state->trans->out.data, NT_STATUS_OK);
                talloc_free(state);
                return;
        }
 
        /* there is more to receive - setup a readx */
-       send_read_request_continue(p, &state->trans->out.data);
+       send_read_request_continue(c, &state->trans->out.data);
        talloc_free(state);
 }
 
 /*
   send a SMBtrans style request
 */
-static NTSTATUS smb_send_trans_request(struct dcerpc_pipe *p, DATA_BLOB *blob)
+static NTSTATUS smb_send_trans_request(struct dcerpc_connection *c, DATA_BLOB *blob)
 {
-        struct smb_private *smb = p->transport.private;
+        struct smb_private *smb = c->transport.private;
         struct smb_trans2 *trans;
         uint16 setup[2];
        struct smb_trans_state *state;
@@ -227,7 +227,7 @@ static NTSTATUS smb_send_trans_request(struct dcerpc_pipe *p, DATA_BLOB *blob)
                return NT_STATUS_NO_MEMORY;
        }
 
-       state->p = p;
+       state->c = c;
        state->trans = talloc_p(state, struct smb_trans2);
        trans = state->trans;
 
@@ -263,11 +263,11 @@ static NTSTATUS smb_send_trans_request(struct dcerpc_pipe *p, DATA_BLOB *blob)
 */
 static void smb_write_callback(struct smbcli_request *req)
 {
-       struct dcerpc_pipe *p = req->async.private;
+       struct dcerpc_connection *c = req->async.private;
 
        if (!NT_STATUS_IS_OK(req->status)) {
                DEBUG(0,("dcerpc_smb: write callback error\n"));
-               pipe_dead(p, req->status);
+               pipe_dead(c, req->status);
        }
 
        smbcli_request_destroy(req);
@@ -276,14 +276,14 @@ static void smb_write_callback(struct smbcli_request *req)
 /* 
    send a packet to the server
 */
-static NTSTATUS smb_send_request(struct dcerpc_pipe *p, DATA_BLOB *blob, BOOL trigger_read)
+static NTSTATUS smb_send_request(struct dcerpc_connection *c, DATA_BLOB *blob, BOOL trigger_read)
 {
-       struct smb_private *smb = p->transport.private;
+       struct smb_private *smb = c->transport.private;
        union smb_write io;
        struct smbcli_request *req;
 
        if (trigger_read) {
-               return smb_send_trans_request(p, blob);
+               return smb_send_trans_request(c, blob);
        }
 
        io.generic.level = RAW_WRITE_WRITEX;
@@ -300,10 +300,10 @@ static NTSTATUS smb_send_request(struct dcerpc_pipe *p, DATA_BLOB *blob, BOOL tr
        }
 
        req->async.fn = smb_write_callback;
-       req->async.private = p;
+       req->async.private = c;
 
        if (trigger_read) {
-               send_read_request(p);
+               send_read_request(c);
        }
 
        return NT_STATUS_OK;
@@ -313,9 +313,9 @@ static NTSTATUS smb_send_request(struct dcerpc_pipe *p, DATA_BLOB *blob, BOOL tr
    return the event context for the pipe, so the caller can wait
    for events asynchronously
 */
-static struct event_context *smb_event_context(struct dcerpc_pipe *p)
+static struct event_context *smb_event_context(struct dcerpc_connection *c)
 {
-       struct smb_private *smb = p->transport.private;
+       struct smb_private *smb = c->transport.private;
 
        return smb->tree->session->transport->event.ctx;
 }
@@ -324,18 +324,18 @@ static struct event_context *smb_event_context(struct dcerpc_pipe *p)
 /* 
    shutdown SMB pipe connection
 */
-static NTSTATUS smb_shutdown_pipe(struct dcerpc_pipe *p)
+static NTSTATUS smb_shutdown_pipe(struct dcerpc_connection *c)
 {
-       struct smb_private *smb = p->transport.private;
-       union smb_close c;
+       struct smb_private *smb = c->transport.private;
+       union smb_close io;
 
        /* maybe we're still starting up */
        if (!smb) return NT_STATUS_OK;
 
-       c.close.level = RAW_CLOSE_CLOSE;
-       c.close.in.fnum = smb->fnum;
-       c.close.in.write_time = 0;
-       smb_raw_close(smb->tree, &c);
+       io.close.level = RAW_CLOSE_CLOSE;
+       io.close.in.fnum = smb->fnum;
+       io.close.in.write_time = 0;
+       smb_raw_close(smb->tree, &io);
 
        talloc_free(smb);
 
@@ -345,18 +345,18 @@ static NTSTATUS smb_shutdown_pipe(struct dcerpc_pipe *p)
 /*
   return SMB server name
 */
-static const char *smb_peer_name(struct dcerpc_pipe *p)
+static const char *smb_peer_name(struct dcerpc_connection *c)
 {
-       struct smb_private *smb = p->transport.private;
+       struct smb_private *smb = c->transport.private;
        return smb->tree->session->transport->called.name;
 }
 
 /*
   fetch the user session key 
 */
-static NTSTATUS smb_session_key(struct dcerpc_pipe *p, DATA_BLOB *session_key)
+static NTSTATUS smb_session_key(struct dcerpc_connection *c, DATA_BLOB *session_key)
 {
-       struct smb_private *smb = p->transport.private;
+       struct smb_private *smb = c->transport.private;
 
        if (smb->tree->session->user_session_key.data) {
                *session_key = smb->tree->session->user_session_key;
@@ -368,7 +368,7 @@ static NTSTATUS smb_session_key(struct dcerpc_pipe *p, DATA_BLOB *session_key)
 /* 
    open a rpc connection to a named pipe 
 */
-NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p
+NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_connection *c
                              struct smbcli_tree *tree,
                              const char *pipe_name)
 {
@@ -402,36 +402,31 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
                 return status;
         }
 
-        if (!(*p = dcerpc_pipe_init())) {
-                return NT_STATUS_NO_MEMORY;
-       }
        /*
          fill in the transport methods
        */
-       (*p)->transport.transport = NCACN_NP;
-       (*p)->transport.private = NULL;
-       (*p)->transport.shutdown_pipe = smb_shutdown_pipe;
-       (*p)->transport.peer_name = smb_peer_name;
-
-       (*p)->transport.send_request = smb_send_request;
-       (*p)->transport.send_read = send_read_request;
-       (*p)->transport.event_context = smb_event_context;
-       (*p)->transport.recv_data = NULL;
+       c->transport.transport = NCACN_NP;
+       c->transport.private = NULL;
+       c->transport.shutdown_pipe = smb_shutdown_pipe;
+       c->transport.peer_name = smb_peer_name;
+
+       c->transport.send_request = smb_send_request;
+       c->transport.send_read = send_read_request;
+       c->transport.event_context = smb_event_context;
+       c->transport.recv_data = NULL;
        
        /* Over-ride the default session key with the SMB session key */
-       (*p)->security_state.session_key = smb_session_key;
+       c->security_state.session_key = smb_session_key;
 
-       smb = talloc_p((*p), struct smb_private);
-       if (!smb) {
-               dcerpc_pipe_close(*p);
+       smb = talloc_p(c, struct smb_private);
+       if (smb == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
        smb->fnum = io.ntcreatex.out.fnum;
        smb->tree = tree;
 
-       (*p)->transport.private = smb;
+       c->transport.private = smb;
 
         return NT_STATUS_OK;
 }
@@ -439,11 +434,11 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
 /*
   return the SMB tree used for a dcerpc over SMB pipe
 */
-struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_pipe *p)
+struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_connection *c)
 {
-       struct smb_private *smb = p->transport.private;
+       struct smb_private *smb = c->transport.private;
 
-       if (p->transport.transport != NCACN_NP) {
+       if (c->transport.transport != NCACN_NP) {
                return NULL;
        }
 
index 762a22ad3e174cd1fa46805d796dd1b336ae6ed9..b48fedb0d816ef251702c7b845a223f9322fdaea 100644 (file)
@@ -54,7 +54,7 @@ struct sock_private {
 /*
   mark the socket dead
 */
-static void sock_dead(struct dcerpc_pipe *p, NTSTATUS status)
+static void sock_dead(struct dcerpc_connection *p, NTSTATUS status)
 {
        struct sock_private *sock = p->transport.private;
 
@@ -80,7 +80,7 @@ static void sock_dead(struct dcerpc_pipe *p, NTSTATUS status)
 /*
   process send requests
 */
-static void sock_process_send(struct dcerpc_pipe *p)
+static void sock_process_send(struct dcerpc_connection *p)
 {
        struct sock_private *sock = p->transport.private;
 
@@ -117,7 +117,7 @@ static void sock_process_send(struct dcerpc_pipe *p)
 /*
   process recv requests
 */
-static void sock_process_recv(struct dcerpc_pipe *p)
+static void sock_process_recv(struct dcerpc_connection *p)
 {
        struct sock_private *sock = p->transport.private;
        NTSTATUS status;
@@ -194,7 +194,7 @@ static void sock_process_recv(struct dcerpc_pipe *p)
 static void sock_io_handler(struct event_context *ev, struct fd_event *fde, 
                            struct timeval t, uint16_t flags)
 {
-       struct dcerpc_pipe *p = fde->private;
+       struct dcerpc_connection *p = fde->private;
        struct sock_private *sock = p->transport.private;
 
        if (flags & EVENT_FD_WRITE) {
@@ -213,7 +213,7 @@ static void sock_io_handler(struct event_context *ev, struct fd_event *fde,
 /* 
    initiate a read request 
 */
-static NTSTATUS sock_send_read(struct dcerpc_pipe *p)
+static NTSTATUS sock_send_read(struct dcerpc_connection *p)
 {
        struct sock_private *sock = p->transport.private;
 
@@ -227,7 +227,7 @@ static NTSTATUS sock_send_read(struct dcerpc_pipe *p)
 /* 
    send an initial pdu in a multi-pdu sequence
 */
-static NTSTATUS sock_send_request(struct dcerpc_pipe *p, DATA_BLOB *data, BOOL trigger_read)
+static NTSTATUS sock_send_request(struct dcerpc_connection *p, DATA_BLOB *data, BOOL trigger_read)
 {
        struct sock_private *sock = p->transport.private;
        struct sock_blob *blob;
@@ -261,7 +261,7 @@ static NTSTATUS sock_send_request(struct dcerpc_pipe *p, DATA_BLOB *data, BOOL t
 /* 
    return the event context so the caller can process asynchronously
 */
-static struct event_context *sock_event_context(struct dcerpc_pipe *p)
+static struct event_context *sock_event_context(struct dcerpc_connection *p)
 {
        struct sock_private *sock = p->transport.private;
 
@@ -271,7 +271,7 @@ static struct event_context *sock_event_context(struct dcerpc_pipe *p)
 /* 
    shutdown sock pipe connection
 */
-static NTSTATUS sock_shutdown_pipe(struct dcerpc_pipe *p)
+static NTSTATUS sock_shutdown_pipe(struct dcerpc_connection *p)
 {
        sock_dead(p, NT_STATUS_OK);
 
@@ -281,7 +281,7 @@ static NTSTATUS sock_shutdown_pipe(struct dcerpc_pipe *p)
 /*
   return sock server name
 */
-static const char *sock_peer_name(struct dcerpc_pipe *p)
+static const char *sock_peer_name(struct dcerpc_connection *p)
 {
        struct sock_private *sock = p->transport.private;
        return sock->server_name;
@@ -290,7 +290,7 @@ static const char *sock_peer_name(struct dcerpc_pipe *p)
 /* 
    open a rpc connection using the generic socket library
 */
-static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_pipe **p
+static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_connection *c
                                        const char *server,
                                        uint32_t port, 
                                        const char *type,
@@ -301,45 +301,40 @@ static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_pipe **p,
        struct fd_event fde;
        NTSTATUS status;
 
-       if (!(*p = dcerpc_pipe_init())) {
-                return NT_STATUS_NO_MEMORY;
-       }
-       sock = talloc_p((*p), struct sock_private);
+       sock = talloc_p(c, struct sock_private);
        if (!sock) {
-               talloc_free(*p);
                return NT_STATUS_NO_MEMORY;
        }
 
        status = socket_create(type, SOCKET_TYPE_STREAM, &socket_ctx, 0);
        if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(*p);
+               talloc_free(sock);
                return status;
        }
        talloc_steal(sock, socket_ctx);
 
        status = socket_connect(socket_ctx, NULL, 0, server, port, 0);
        if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(*p);
+               talloc_free(sock);
                return status;
        }
 
        /*
          fill in the transport methods
        */
-       (*p)->transport.transport = transport;
-       (*p)->transport.private = NULL;
+       c->transport.transport = transport;
+       c->transport.private = NULL;
 
-       (*p)->transport.send_request = sock_send_request;
-       (*p)->transport.send_read = sock_send_read;
-       (*p)->transport.event_context = sock_event_context;
-       (*p)->transport.recv_data = NULL;
+       c->transport.send_request = sock_send_request;
+       c->transport.send_read = sock_send_read;
+       c->transport.event_context = sock_event_context;
+       c->transport.recv_data = NULL;
 
-       (*p)->transport.shutdown_pipe = sock_shutdown_pipe;
-       (*p)->transport.peer_name = sock_peer_name;
+       c->transport.shutdown_pipe = sock_shutdown_pipe;
+       c->transport.peer_name = sock_peer_name;
        
        sock->sock = socket_ctx;
-       sock->server_name = talloc_strdup((*p), server);
+       sock->server_name = talloc_strdup(sock, server);
        sock->event_ctx = event_context_init(sock);
        sock->pending_send = NULL;
        sock->recv.received = 0;
@@ -349,11 +344,11 @@ static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_pipe **p,
        fde.fd = socket_get_fd(sock->sock);
        fde.flags = 0;
        fde.handler = sock_io_handler;
-       fde.private = *p;
+       fde.private = c;
 
        sock->fde = event_add_fd(sock->event_ctx, &fde);
 
-       (*p)->transport.private = sock;
+       c->transport.private = sock;
 
        /* ensure we don't get SIGPIPE */
        BlockSignals(True,SIGPIPE);
@@ -364,31 +359,31 @@ static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_pipe **p,
 /* 
    open a rpc connection using tcp
 */
-NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p, const char *server, uint32_t port)
+NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_connection *c, const char *server, uint32_t port)
 {
        NTSTATUS status;
        
        /* Try IPv6 first */
-       status = dcerpc_pipe_open_socket(p, server, port, "ipv6", NCACN_IP_TCP);
+       status = dcerpc_pipe_open_socket(c, server, port, "ipv6", NCACN_IP_TCP);
        if (NT_STATUS_IS_OK(status)) {
                return status;
        }
        
-       return dcerpc_pipe_open_socket(p, server, port, "ipv4", NCACN_IP_TCP);
+       return dcerpc_pipe_open_socket(c, server, port, "ipv4", NCACN_IP_TCP);
 }
 
 /* 
    open a rpc connection to a unix socket 
 */
-NTSTATUS dcerpc_pipe_open_unix_stream(struct dcerpc_pipe **p, const char *path)
+NTSTATUS dcerpc_pipe_open_unix_stream(struct dcerpc_connection *c, const char *path)
 {
-       return dcerpc_pipe_open_socket(p, path, 0, "unix", NCACN_UNIX_STREAM);
+       return dcerpc_pipe_open_socket(c, path, 0, "unix", NCACN_UNIX_STREAM);
 }
 
 /* 
    open a rpc connection to a named pipe 
 */
-NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_pipe **p, const char *identifier)
+NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_connection *c, const char *identifier)
 {
        NTSTATUS status;
        char *canon, *full_path;
@@ -398,7 +393,7 @@ NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_pipe **p, const char *identifier)
        string_replace(canon, '/', '\\');
        full_path = talloc_asprintf(canon, "%s/%s", lp_ncalrpc_dir(), canon);
 
-       status = dcerpc_pipe_open_socket(p, full_path, 0, "unix", NCALRPC);
+       status = dcerpc_pipe_open_socket(c, full_path, 0, "unix", NCALRPC);
        talloc_free(canon);
 
        return status;
index d15224b9812442bd5c152da47f124790f2f0797a..cab8865d6b818f74fa04056a165b2fb6c046a2f7 100644 (file)
@@ -3,7 +3,9 @@
 
    dcerpc authentication operations
 
-   Copyright (C) Andrew Tridgell 2003
+   Copyright (C) Stefan Metzmacher 2004
+   Copyright (C) Andrew Tridgell 2003-2005
+   Copyright (C) Andrew Bartlett 2004
    
    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
@@ -22,6 +24,8 @@
 
 #include "includes.h"
 
+#warning "this needs dcerpc_alter"
+#if 0
 /*
   do spnego style authentication on a gensec pipe
 */
@@ -33,49 +37,53 @@ NTSTATUS dcerpc_bind_auth_spnego(struct dcerpc_pipe *p,
 {
        NTSTATUS status;
 
-       status = gensec_client_start(p, &p->security_state.generic_state);
+       status = gensec_client_start(p, &p->conn->security_state.generic_state);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status)));
                return status;
        }
 
-       status = gensec_set_domain(p->security_state.generic_state, domain);
+       status = gensec_set_domain(p->conn->security_state.generic_state, domain);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", 
                          domain, nt_errstr(status)));
                return status;
        }
 
-       status = gensec_set_username(p->security_state.generic_state, username);
+       status = gensec_set_username(p->conn->security_state.generic_state, username);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", 
                          username, nt_errstr(status)));
                return status;
        }
 
-       status = gensec_set_password(p->security_state.generic_state, password);
+       status = gensec_set_password(p->conn->security_state.generic_state, password);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start set GENSEC client password: %s\n", 
                          nt_errstr(status)));
                return status;
        }
 
-       status = gensec_set_target_hostname(p->security_state.generic_state, p->transport.peer_name(p));
+       status = gensec_set_target_hostname(p->conn->security_state.generic_state, 
+                                           p->conn->transport.peer_name(p->conn));
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", 
                          nt_errstr(status)));
                return status;
        }
 
-       status = gensec_start_mech_by_authtype(p->security_state.generic_state, DCERPC_AUTH_TYPE_SPNEGO, dcerpc_auth_level(p));
+       status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state, 
+                                              DCERPC_AUTH_TYPE_SPNEGO, 
+                                              dcerpc_auth_level(p->conn));
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n",
                          nt_errstr(status)));
                return status;
        }
        
-       status = dcerpc_bind_alter(p, DCERPC_AUTH_TYPE_SPNEGO, dcerpc_auth_level(p),
-                                 uuid, version);
+       status = dcerpc_bind_alter(p, DCERPC_AUTH_TYPE_SPNEGO, 
+                                  dcerpc_auth_level(p->conn),
+                                  uuid, version);
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(2, ("Failed to bind to pipe with SPNEGO: %s\n", nt_errstr(status)));
@@ -84,3 +92,4 @@ NTSTATUS dcerpc_bind_auth_spnego(struct dcerpc_pipe *p,
 
        return status;
 }
+#endif
index 4adeee7a374b7bfe6317395309722a1b075899af..67b0c530bf9ae87f8806b7da962243d598237b4a 100644 (file)
@@ -30,8 +30,8 @@
 */
 const char *idl_pipe_name(const char *uuid, uint32_t if_version)
 {
-       struct dcerpc_interface_list *l;
-       for (l=dcerpc_pipes;l;l=l->next) {
+       const struct dcerpc_interface_list *l;
+       for (l=librpc_dcerpc_pipes();l;l=l->next) {
                if (strcasecmp(l->table->uuid, uuid) == 0 &&
                    l->table->if_version == if_version) {
                        return l->table->name;
@@ -45,8 +45,8 @@ const char *idl_pipe_name(const char *uuid, uint32_t if_version)
 */
 int idl_num_calls(const char *uuid, uint32_t if_version)
 {
-       struct dcerpc_interface_list *l;
-       for (l=dcerpc_pipes;l;l=l->next){
+       const struct dcerpc_interface_list *l;
+       for (l=librpc_dcerpc_pipes();l;l=l->next){
                if (strcasecmp(l->table->uuid, uuid) == 0 &&
                    l->table->if_version == if_version) {
                        return l->table->num_calls;
@@ -61,8 +61,8 @@ int idl_num_calls(const char *uuid, uint32_t if_version)
 */
 const struct dcerpc_interface_table *idl_iface_by_name(const char *name)
 {
-       struct dcerpc_interface_list *l;
-       for (l=dcerpc_pipes;l;l=l->next) {
+       const struct dcerpc_interface_list *l;
+       for (l=librpc_dcerpc_pipes();l;l=l->next) {
                if (strcasecmp(l->table->name, name) == 0) {
                        return l->table;
                }
@@ -75,8 +75,8 @@ const struct dcerpc_interface_table *idl_iface_by_name(const char *name)
 */
 const struct dcerpc_interface_table *idl_iface_by_uuid(const char *uuid)
 {
-       struct dcerpc_interface_list *l;
-       for (l=dcerpc_pipes;l;l=l->next) {
+       const struct dcerpc_interface_list *l;
+       for (l=librpc_dcerpc_pipes();l;l=l->next) {
                if (strcasecmp(l->table->uuid, uuid) == 0) {
                        return l->table;
                }
@@ -774,7 +774,7 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind
 
 /* open a rpc connection to a rpc pipe on SMB using the binding
    structure to determine the endpoint and options */
-static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p, 
+static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp
                                             struct dcerpc_binding *binding,
                                             const char *pipe_uuid, 
                                             uint32_t pipe_version,
@@ -782,19 +782,28 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
                                             const char *username,
                                             const char *password)
 {
+       struct dcerpc_pipe *p;
        NTSTATUS status;
        BOOL retry;
        struct smbcli_state *cli;
        const char *pipe_name = NULL;
-       TALLOC_CTX *mem_ctx = talloc_init("dcerpc_pipe_connect_ncacn_np");
+       TALLOC_CTX *tmp_ctx;
+
+       *pp = NULL;
+
+       p = dcerpc_pipe_init(NULL);
+       if (p == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       tmp_ctx = talloc_new(p);
        
        /* Look up identifier using the epmapper */
        if (!binding->endpoint) {
-               status = dcerpc_epm_map_binding(mem_ctx, binding, pipe_uuid, pipe_version);
+               status = dcerpc_epm_map_binding(tmp_ctx, binding, pipe_uuid, pipe_version);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0,("Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s\n", 
                                 pipe_uuid, nt_errstr(status)));
-                       talloc_destroy(mem_ctx);
+                       talloc_free(p);
                        return status;
                }
                DEBUG(1,("Mapped to DCERPC/NP pipe %s\n", binding->endpoint));
@@ -803,188 +812,199 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
        pipe_name = binding->endpoint;
 
        if (!strncasecmp(pipe_name, "/pipe/", 6) || 
-               !strncasecmp(pipe_name, "\\pipe\\", 6)) {
-               pipe_name+=6;
+           !strncasecmp(pipe_name, "\\pipe\\", 6)) {
+               pipe_name += 6;
        }
 
        if (pipe_name[0] != '\\') {
-               pipe_name = talloc_asprintf(mem_ctx, "\\%s", pipe_name);
+               pipe_name = talloc_asprintf(tmp_ctx, "\\%s", pipe_name);
        }
        
        if (!username || !username[0] || 
            (binding->flags & DCERPC_SCHANNEL_ANY)) {
-               status = smbcli_full_connection(NULL, &cli, lp_netbios_name(),
-                                            binding->host, NULL, 
-                                            "ipc$", "?????", 
-                                            "", "", NULL, 0, &retry);
+               status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(),
+                                               binding->host, NULL, 
+                                               "ipc$", "?????", 
+                                               "", "", NULL, 0, &retry);
        } else {
-               status = smbcli_full_connection(NULL, &cli, lp_netbios_name(),
-                                            binding->host, NULL, 
-                                            "ipc$", "?????", 
-                                            username, domain,
-                                            password, 0, &retry);
+               status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(),
+                                               binding->host, NULL, 
+                                               "ipc$", "?????", 
+                                               username, domain,
+                                               password, 0, &retry);
        }
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to connect to %s - %s\n", binding->host, nt_errstr(status)));
-               talloc_destroy(mem_ctx);
+               talloc_free(p);
                return status;
        }
 
-       status = dcerpc_pipe_open_smb(p, cli->tree, pipe_name);
+       status = dcerpc_pipe_open_smb(p->conn, cli->tree, pipe_name);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to open pipe %s - %s\n", pipe_name, nt_errstr(status)));
-               smbcli_tdis(cli);
-               smbcli_shutdown(cli);
-               talloc_destroy(mem_ctx);
+               talloc_free(p);
                return status;
        }
        
-       /* this ensures that the reference count is decremented so
-          a pipe close will really close the link */
-       talloc_steal(*p, cli);
-
-       (*p)->flags = binding->flags;
+       p->conn->flags = binding->flags;
 
        /* remember the binding string for possible secondary connections */
-       (*p)->binding_string = dcerpc_binding_string((*p), binding);
-
-       talloc_destroy(mem_ctx);
+       p->conn->binding_string = dcerpc_binding_string(p, binding);
 
        if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
-               status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version, 
+               status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version, 
                                                   domain, username, password);
        } else if (username && username[0] &&
                   (binding->flags & (DCERPC_CONNECT|DCERPC_SIGN|DCERPC_SEAL))) {
-               status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
+               status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
        } else {    
-               status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+               status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
 
        }
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
-               dcerpc_pipe_close(*p);
-               *p = NULL;
+               talloc_free(p);
                return status;
        }
 
+       (*pp) = p;
+       talloc_free(tmp_ctx);
+
        return NT_STATUS_OK;
 }
 
 /* open a rpc connection to a rpc pipe on SMP using the binding
    structure to determine the endpoint and options */
-static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **p, 
-                                                struct dcerpc_binding *binding,
-                                                const char *pipe_uuid, 
-                                                uint32_t pipe_version,
-                                                const char *domain,
-                                                const char *username,
-                                                const char *password)
+static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp
+                                           struct dcerpc_binding *binding,
+                                           const char *pipe_uuid, 
+                                           uint32_t pipe_version,
+                                           const char *domain,
+                                           const char *username,
+                                           const char *password)
 {
        NTSTATUS status;
-       TALLOC_CTX *mem_ctx = talloc_init("dcerpc_pipe_connect_ncalrpc");
+       struct dcerpc_pipe *p;
+       TALLOC_CTX *tmp_ctx;
+
+       (*pp) = NULL;
+
+       p = dcerpc_pipe_init(NULL);
+       if (p == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       tmp_ctx = talloc_new(p);
 
        /* Look up identifier using the epmapper */
        if (!binding->endpoint) {
-               status = dcerpc_epm_map_binding(mem_ctx, binding, pipe_uuid, pipe_version);
+               status = dcerpc_epm_map_binding(tmp_ctx, binding, pipe_uuid, pipe_version);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0,("Failed to map DCERPC/TCP NCALRPC identifier for '%s' - %s\n", 
                                 pipe_uuid, nt_errstr(status)));
-                       talloc_destroy(mem_ctx);
+                       talloc_free(p);
                        return status;
                }
                DEBUG(1,("Mapped to DCERPC/LRPC identifier %s\n", binding->endpoint));
        }
 
-       status = dcerpc_pipe_open_pipe(p, binding->endpoint);
-
+       status = dcerpc_pipe_open_pipe(p->conn, binding->endpoint);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("Failed to open ncalrpc pipe '%s' - %s\n", binding->endpoint, nt_errstr(status)));
-               talloc_destroy(mem_ctx);
+               DEBUG(0,("Failed to open ncalrpc pipe '%s' - %s\n", 
+                        binding->endpoint, nt_errstr(status)));
+               talloc_free(p);
                return status;
-    }
+       }
 
-       (*p)->flags = binding->flags;
+       p->conn->flags = binding->flags;
 
        /* remember the binding string for possible secondary connections */
-       (*p)->binding_string = dcerpc_binding_string((*p), binding);
+       p->conn->binding_string = dcerpc_binding_string(p, binding);
 
        if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
-               status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version, 
+               status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version, 
                                                   domain, username, password);
        } else if (username && username[0]) {
-               status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
+               status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
        } else {    
-               status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+               status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
        }
 
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("Failed to bind to uuid %s - %s\n", 
-                        pipe_uuid, nt_errstr(status)));
-               dcerpc_pipe_close(*p);
-               *p = NULL;
-               talloc_destroy(mem_ctx);
+               DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
+               talloc_free(p);
                return status;
        }
-       talloc_destroy(mem_ctx);
-    return status;
+
+       (*pp) = p;
+       talloc_free(tmp_ctx);
+
+       return status;
 }
 
 
 
 /* open a rpc connection to a rpc pipe on SMP using the binding
    structure to determine the endpoint and options */
-static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **p, 
-                                                struct dcerpc_binding *binding,
-                                                const char *pipe_uuid, 
-                                                uint32_t pipe_version,
-                                                const char *domain,
-                                                const char *username,
-                                                const char *password)
+static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp
+                                                     struct dcerpc_binding *binding,
+                                                     const char *pipe_uuid, 
+                                                     uint32_t pipe_version,
+                                                     const char *domain,
+                                                     const char *username,
+                                                     const char *password)
 {
        NTSTATUS status;
+       struct dcerpc_pipe *p;
+
+       (*pp) = NULL;
 
        if (!binding->endpoint) {
                DEBUG(0, ("Path to unix socket not specified\n"));
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       status = dcerpc_pipe_open_unix_stream(p, binding->endpoint);
+       p = dcerpc_pipe_init(NULL);
+       if (p == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = dcerpc_pipe_open_unix_stream(p->conn, binding->endpoint);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to open unix socket %s - %s\n", 
                         binding->endpoint, nt_errstr(status)));
+               talloc_free(p);
                 return status;
        }
 
-       (*p)->flags = binding->flags;
+       p->conn->flags = binding->flags;
 
        /* remember the binding string for possible secondary connections */
-       (*p)->binding_string = dcerpc_binding_string((*p), binding);
+       p->conn->binding_string = dcerpc_binding_string(p, binding);
 
        if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
-               status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version, 
+               status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version, 
                                                   domain, username, password);
        } else if (username && username[0]) {
-               status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
+               status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
        } else {    
-               status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+               status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
        }
 
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("Failed to bind to uuid %s - %s\n", 
-                        pipe_uuid, nt_errstr(status)));
-               dcerpc_pipe_close(*p);
-               *p = NULL;
+               DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
+               talloc_free(p);
                return status;
        }
+
+       (*pp) = p;
  
-    return status;
+       return status;
 }
 
 /* open a rpc connection to a rpc pipe on SMP using the binding
    structure to determine the endpoint and options */
-static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p, 
+static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **pp
                                                 struct dcerpc_binding *binding,
                                                 const char *pipe_uuid, 
                                                 uint32_t pipe_version,
@@ -994,14 +1014,24 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
 {
        NTSTATUS status;
        uint32_t port = 0;
-       TALLOC_CTX *mem_ctx = talloc_init("connect_ncacn_ip_tcp");
+       struct dcerpc_pipe *p;
+       TALLOC_CTX *tmp_ctx;
+
+       (*pp) = NULL;
+
+       p = dcerpc_pipe_init(NULL);
+       if (p == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       tmp_ctx = talloc_new(p);
 
        if (!binding->endpoint) {
-               status = dcerpc_epm_map_binding(mem_ctx, binding, 
-                                                pipe_uuid, pipe_version);
+               status = dcerpc_epm_map_binding(tmp_ctx, binding, 
+                                               pipe_uuid, pipe_version);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0,("Failed to map DCERPC/TCP port for '%s' - %s\n", 
                                 pipe_uuid, nt_errstr(status)));
+                       talloc_free(p);
                        return status;
                }
                DEBUG(1,("Mapped to DCERPC/TCP port %s\n", binding->endpoint));
@@ -1009,34 +1039,37 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
 
        port = atoi(binding->endpoint);
 
-       status = dcerpc_pipe_open_tcp(p, binding->host, port);
+       status = dcerpc_pipe_open_tcp(p->conn, binding->host, port);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to connect to %s:%d - %s\n", 
                         binding->host, port, nt_errstr(status)));
+               talloc_free(p);
                 return status;
         }
 
-       (*p)->flags = binding->flags;
+       p->conn->flags = binding->flags;
 
        /* remember the binding string for possible secondary connections */
-       (*p)->binding_string = dcerpc_binding_string((*p), binding);
+       p->conn->binding_string = dcerpc_binding_string(p, binding);
 
        if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
-               status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version, 
+               status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version, 
                                                   domain, username, password);
        } else if (username && username[0]) {
-               status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
+               status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
        } else {    
-               status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+               status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
        }
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to bind to uuid %s - %s\n", 
                         pipe_uuid, nt_errstr(status)));
-               dcerpc_pipe_close(*p);
-               *p = NULL;
+               talloc_free(p);
                return status;
        }
+
+       (*pp) = p;
+       talloc_free(tmp_ctx);
  
         return status;
 }
@@ -1044,7 +1077,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
 
 /* open a rpc connection to a rpc pipe, using the specified 
    binding structure to determine the endpoint and options */
-NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **p, 
+NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **pp
                               struct dcerpc_binding *binding,
                               const char *pipe_uuid, 
                               uint32_t pipe_version,
@@ -1056,18 +1089,20 @@ NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **p,
 
        switch (binding->transport) {
        case NCACN_NP:
-               status = dcerpc_pipe_connect_ncacn_np(p, binding, pipe_uuid, pipe_version,
+               status = dcerpc_pipe_connect_ncacn_np(pp, binding, pipe_uuid, pipe_version,
                                                      domain, username, password);
                break;
        case NCACN_IP_TCP:
-               status = dcerpc_pipe_connect_ncacn_ip_tcp(p, binding, pipe_uuid, pipe_version,
+               status = dcerpc_pipe_connect_ncacn_ip_tcp(pp, binding, pipe_uuid, pipe_version,
                                                          domain, username, password);
                break;
        case NCACN_UNIX_STREAM:
-               status = dcerpc_pipe_connect_ncacn_unix_stream(p, binding, pipe_uuid, pipe_version, domain, username, password);
+               status = dcerpc_pipe_connect_ncacn_unix_stream(pp, binding, pipe_uuid, pipe_version, 
+                                                              domain, username, password);
                break;
        case NCALRPC:
-               status = dcerpc_pipe_connect_ncalrpc(p, binding, pipe_uuid, pipe_version, domain, username, password);
+               status = dcerpc_pipe_connect_ncalrpc(pp, binding, pipe_uuid, pipe_version, 
+                                                    domain, username, password);
                break;
        default:
                return NT_STATUS_NOT_SUPPORTED;
@@ -1079,7 +1114,7 @@ NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **p,
 
 /* open a rpc connection to a rpc pipe, using the specified string
    binding to determine the endpoint and options */
-NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **p, 
+NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp
                             const char *binding,
                             const char *pipe_uuid, 
                             uint32_t pipe_version,
@@ -1089,23 +1124,23 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **p,
 {
        struct dcerpc_binding b;
        NTSTATUS status;
-       TALLOC_CTX *mem_ctx;
+       TALLOC_CTX *tmp_ctx;
 
-       mem_ctx = talloc_init("dcerpc_pipe_connect");
-       if (!mem_ctx) return NT_STATUS_NO_MEMORY;
+       tmp_ctx = talloc_new(NULL);
 
-       status = dcerpc_parse_binding(mem_ctx, binding, &b);
+       status = dcerpc_parse_binding(tmp_ctx, binding, &b);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
-               talloc_destroy(mem_ctx);
+               talloc_free(tmp_ctx);
                return status;
        }
 
-       DEBUG(3,("Using binding %s\n", dcerpc_binding_string(mem_ctx, &b)));
+       DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b)));
 
-       status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version, domain, username, password);
+       status = dcerpc_pipe_connect_b(pp, &b, pipe_uuid, pipe_version, domain, username, password);
+
+       talloc_free(tmp_ctx);
 
-       talloc_destroy(mem_ctx);
        return status;
 }
 
@@ -1125,32 +1160,37 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe *
        NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
        struct dcerpc_binding b;
 
-       switch (p->transport.transport) {
+       (*p2) = dcerpc_pipe_init(p);
+       if (*p2 == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       
+       switch (p->conn->transport.transport) {
        case NCACN_NP:
-               tree = dcerpc_smb_tree(p);
+               tree = dcerpc_smb_tree(p->conn);
                if (!tree) {
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
-               status = dcerpc_pipe_open_smb(p2, tree, pipe_name);
+               status = dcerpc_pipe_open_smb((*p2)->conn, tree, pipe_name);
                break;
 
        case NCACN_IP_TCP:
-               status = dcerpc_parse_binding(p, p->binding_string, &b);
+               status = dcerpc_parse_binding(p, p->conn->binding_string, &b);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
                b.flags &= ~DCERPC_AUTH_OPTIONS;
-               status = dcerpc_pipe_open_tcp(p2, b.host, atoi(b.endpoint));
+               status = dcerpc_pipe_open_tcp((*p2)->conn, b.host, atoi(b.endpoint));
                break;
 
        case NCALRPC:
-               status = dcerpc_parse_binding(p, p->binding_string, &b);
+               status = dcerpc_parse_binding(p, p->conn->binding_string, &b);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
                b.flags &= ~DCERPC_AUTH_OPTIONS;
-               status = dcerpc_pipe_open_pipe(p2, b.endpoint);
+               status = dcerpc_pipe_open_pipe((*p2)->conn, b.endpoint);
                break;
 
        default:
@@ -1158,22 +1198,22 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe *
        }
 
        if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(*p2);
                return status;
        }
 
-       talloc_steal(p, *p2);
-
-       (*p2)->flags = p->flags;
+       (*p2)->conn->flags = p->conn->flags;
 
        status = dcerpc_bind_auth_none(*p2, pipe_uuid, pipe_version);
        if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(*p2);
                 return status;
         }
 
        return NT_STATUS_OK;
 }
 
-NTSTATUS dcerpc_generic_session_key(struct dcerpc_pipe *p,
+NTSTATUS dcerpc_generic_session_key(struct dcerpc_connection *c,
                                    DATA_BLOB *session_key)
 {
        /* this took quite a few CPU cycles to find ... */
@@ -1188,7 +1228,7 @@ NTSTATUS dcerpc_generic_session_key(struct dcerpc_pipe *p,
 NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p,
                                  DATA_BLOB *session_key)
 {
-       return p->security_state.session_key(p, session_key);
+       return p->conn->security_state.session_key(p->conn, session_key);
 }
 
 
index 8feb54a500c8697df9be3b525f7ee4ef76bd126f..83c550974d9a9d5b865759b93f12f66c95782568 100644 (file)
@@ -105,7 +105,7 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT
        name = table->calls[opnum].name;
        call = &table->calls[opnum];
 
-       if (private->c_pipe->flags & DCERPC_DEBUG_PRINT_IN) {
+       if (private->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_IN) {
                ndr_print_function_debug(call->ndr_print, name, NDR_IN | NDR_SET_VALUES, r);            
        }
 
@@ -118,7 +118,8 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT
                return NT_STATUS_NET_WRITE_FAULT;
        }
 
-       if ((dce_call->fault_code == 0) && (private->c_pipe->flags & DCERPC_DEBUG_PRINT_OUT)) {
+       if ((dce_call->fault_code == 0) && 
+           (private->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
                ndr_print_function_debug(call->ndr_print, name, NDR_OUT, r);            
        }
 
@@ -212,9 +213,9 @@ static BOOL remote_fill_interface(struct dcesrv_interface *iface, const struct d
 
 static BOOL remote_op_interface_by_uuid(struct dcesrv_interface *iface, const char *uuid, uint32_t if_version)
 {
-       struct dcerpc_interface_list *l;
+       const struct dcerpc_interface_list *l;
 
-       for (l=dcerpc_pipes;l;l=l->next) {
+       for (l=librpc_dcerpc_pipes();l;l=l->next) {
                if (l->table->if_version == if_version &&
                        strcmp(l->table->uuid, uuid)==0) {
                        return remote_fill_interface(iface, l->table);
@@ -226,9 +227,9 @@ static BOOL remote_op_interface_by_uuid(struct dcesrv_interface *iface, const ch
 
 static BOOL remote_op_interface_by_name(struct dcesrv_interface *iface, const char *name)
 {
-       struct dcerpc_interface_list *l;
+       const struct dcerpc_interface_list *l;
 
-       for (l=dcerpc_pipes;l;l=l->next) {
+       for (l=librpc_dcerpc_pipes();l;l=l->next) {
                if (strcmp(l->table->name, name)==0) {
                        return remote_fill_interface(iface, l->table);
                }
index 0353dd6189860a015099cda3cad7f34f26bb174f..1dea24517dc22e0ebb3cc743397bd23ccffa043a 100644 (file)
@@ -180,7 +180,7 @@ BOOL torture_rpc_mgmt(void)
        TALLOC_CTX *mem_ctx;
        BOOL ret = True;
        const char *binding = lp_parm_string(-1, "torture", "binding");
-       struct dcerpc_interface_list *l;
+       const struct dcerpc_interface_list *l;
        struct dcerpc_binding b;
 
        mem_ctx = talloc_init("torture_rpc_mgmt");
@@ -196,7 +196,7 @@ BOOL torture_rpc_mgmt(void)
                return False;
        }
 
-       for (l=dcerpc_pipes;l;l=l->next) {              
+       for (l=librpc_dcerpc_pipes();l;l=l->next) {             
                /* some interfaces are not mappable */
                if (l->table->num_calls == 0 ||
                    strcmp(l->table->name, "mgmt") == 0) {
index 774abbdf82de03f412f6f4b69510eab3f926832e..67e0bc9393e5336983306c6e617f9bb3b78ede58 100644 (file)
@@ -1110,7 +1110,7 @@ static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
        int i;
        BOOL ret = True;
 
-       if (p->transport.transport != NCACN_NP) {
+       if (p->conn->transport.transport != NCACN_NP) {
                return True;
        }
 
index 56631a4a160892055518ffb07799b86fed1e9695..3e12054e039c4e0d8c72f92981d6ebd1d64776fc 100644 (file)
@@ -1261,7 +1261,7 @@ BOOL torture_rpc_samlogon(void)
                goto failed;
        }
 
-       status = dcerpc_schannel_creds(p->security_state.generic_state, mem_ctx, &creds);
+       status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds);
        if (!NT_STATUS_IS_OK(status)) {
                ret = False;
                goto failed;
index 4c47870015dabaa03e4a707eaaa6790791813a3c..4a71e909579b591df9d4a14b141a6d1f143a08a5 100644 (file)
@@ -1313,7 +1313,7 @@ BOOL torture_rpc_samsync(void)
                goto failed;
        }
 
-       status = dcerpc_schannel_creds(samsync_state->p->security_state.generic_state, mem_ctx, &samsync_state->creds);
+       status = dcerpc_schannel_creds(samsync_state->p->conn->security_state.generic_state, mem_ctx, &samsync_state->creds);
        if (!NT_STATUS_IS_OK(status)) {
                ret = False;
        }
@@ -1342,7 +1342,8 @@ BOOL torture_rpc_samsync(void)
                goto failed;
        }
 
-       status = dcerpc_schannel_creds(samsync_state->p_netlogon_wksta->security_state.generic_state, mem_ctx, &samsync_state->creds_netlogon_wksta);
+       status = dcerpc_schannel_creds(samsync_state->p_netlogon_wksta->conn->security_state.generic_state, 
+                                      mem_ctx, &samsync_state->creds_netlogon_wksta);
        if (!NT_STATUS_IS_OK(status)) {
                ret = False;
        }
index f9a4d337afa1ad257b4026399747fce6e144a9e6..a0ebf9d6425dade1e76f84ead5953503478213b6 100644 (file)
@@ -134,7 +134,7 @@ BOOL torture_rpc_scanner(void)
         struct dcerpc_pipe *p;
        TALLOC_CTX *mem_ctx;
        BOOL ret = True;
-       struct dcerpc_interface_list *l;
+       const struct dcerpc_interface_list *l;
        const char *binding = lp_parm_string(-1, "torture", "binding");
        struct dcerpc_binding b;
 
@@ -151,7 +151,7 @@ BOOL torture_rpc_scanner(void)
                return False;
        }
 
-       for (l=dcerpc_pipes;l;l=l->next) {              
+       for (l=librpc_dcerpc_pipes();l;l=l->next) {             
                /* some interfaces are not mappable */
                if (l->table->num_calls == 0 ||
                    strcmp(l->table->name, "mgmt") == 0) {
index b220b9ff65a3ed7006abacf554a90b80a9fcd04d..f791492e6d1bdc32237db148e1aa913651ce7d67 100644 (file)
@@ -184,7 +184,7 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx,
                goto failed;
        }
 
-       status = dcerpc_schannel_creds(p_netlogon->security_state.generic_state, mem_ctx, &creds);
+       status = dcerpc_schannel_creds(p_netlogon->conn->security_state.generic_state, mem_ctx, &creds);
        if (!NT_STATUS_IS_OK(status)) {
                goto failed;
        }
index bfd03810c2577c1c4748e442a481e5855812ec72..6f2edf9f47580c778b61e82ff6deda0d8691924d 100644 (file)
@@ -649,7 +649,7 @@ static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
        BOOL ret = True;
 
        /* only makes sense on SMB */
-       if (p->transport.transport != NCACN_NP) {
+       if (p->conn->transport.transport != NCACN_NP) {
                return True;
        }
 
index c50a489e422bf61f4113f71660a1bebe9e6c78ec..a60a73c19550d979fcea435945489c650638cf4a 100644 (file)
@@ -180,14 +180,8 @@ static NTSTATUS anon_ipc(struct smbcli_transport *transport,
        return NT_STATUS_OK;
 }
 
-static int close_pipe(void *ptr)
-{
-       struct dcerpc_pipe *p = ptr;
-       dcerpc_pipe_close(p);
-       return 0;
-}
-
-static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
+static NTSTATUS connect_to_pipe(struct dcerpc_pipe **pp,
+                               TALLOC_CTX *mem_ctx,
                                struct smbcli_transport *transport,
                                const char *pipe_name,
                                const char *pipe_uuid,
@@ -196,26 +190,30 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
        const char *binding = lp_parm_string(-1, "torture", "binding");
        struct dcerpc_binding b;
        NTSTATUS status;
-       TALLOC_CTX *mem_ctx;
+       struct dcerpc_pipe *p;
+       TALLOC_CTX *tmp_ctx;
        struct smbcli_tree *tree;
-
+       
        if (!NT_STATUS_IS_OK(status = anon_ipc(transport, &tree)))
                return status;
 
        if (binding == NULL)
                return NT_STATUS_INVALID_PARAMETER;
 
-       mem_ctx = talloc_init("dcerpc_pipe_connect");
-       if (!mem_ctx) return NT_STATUS_NO_MEMORY;
+       p = dcerpc_pipe_init(mem_ctx);
+       if (p == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       tmp_ctx = talloc_new(p);
 
-       status = dcerpc_parse_binding(mem_ctx, binding, &b);
+       status = dcerpc_parse_binding(tmp_ctx, binding, &b);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
-               talloc_destroy(mem_ctx);
+               talloc_free(p);
                return status;
        }
 
-       DEBUG(3,("Using binding %s\n", dcerpc_binding_string(mem_ctx, &b)));
+       DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b)));
 
        if (b.endpoint == NULL) {
                const struct dcerpc_interface_table *table =
@@ -226,14 +224,14 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
                if (!table) {
                        DEBUG(0,("Unknown interface endpoint '%s'\n",
                                 pipe_uuid));
-                       talloc_destroy(mem_ctx);
+                       talloc_free(tmp_ctx);
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
                /* Find one of the default pipes for this interface */
                for (i = 0; i < table->endpoints->count; i++) {
                        const char * const *names = table->endpoints->names;
-                       status = dcerpc_parse_binding(mem_ctx, names[i],
+                       status = dcerpc_parse_binding(tmp_ctx, names[i],
                                                      &default_binding);
 
                        if (NT_STATUS_IS_OK(status) &&
@@ -248,23 +246,23 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
 
        if (!strncasecmp(pipe_name, "/pipe/", 6) || 
                !strncasecmp(pipe_name, "\\pipe\\", 6)) {
-               pipe_name+=6;
+               pipe_name += 6;
        }
 
        if (pipe_name[0] != '\\') {
                pipe_name = talloc_asprintf(mem_ctx, "\\%s", pipe_name);
        }
        
-       status = dcerpc_pipe_open_smb(p, tree, pipe_name);
+       status = dcerpc_pipe_open_smb(p->conn, tree, pipe_name);
 
-       if (!NT_STATUS_IS_OK(status))
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(p);
                return status;
+       }
 
-       talloc_destroy(mem_ctx);
+       talloc_free(tmp_ctx);
+       (*pp) = p;
        
-       talloc_set_destructor(*p, close_pipe);
-       talloc_steal(*p, tree);
-
        return NT_STATUS_OK;
 }
 
@@ -284,7 +282,7 @@ static NTSTATUS test_enumtrusts(struct smbcli_transport *transport)
        if (mem_ctx == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       status = connect_to_pipe(&p, transport, DCERPC_LSARPC_NAME,
+       status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
                                 DCERPC_LSARPC_UUID, 
                                 DCERPC_LSARPC_VERSION);
 
@@ -355,7 +353,7 @@ static NTSTATUS test_lookupnames(struct smbcli_transport *transport,
        if (mem_ctx == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       status = connect_to_pipe(&p, transport, DCERPC_LSARPC_NAME,
+       status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
                                 DCERPC_LSARPC_UUID, 
                                 DCERPC_LSARPC_VERSION);
 
@@ -462,7 +460,7 @@ static NTSTATUS setup_netlogon_creds(struct smbcli_transport *transport,
        if (mem_ctx == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       status = connect_to_pipe(p, transport, DCERPC_NETLOGON_NAME,
+       status = connect_to_pipe(p, mem_ctx, transport, DCERPC_NETLOGON_NAME,
                                 DCERPC_NETLOGON_UUID,
                                 DCERPC_NETLOGON_VERSION);
 
@@ -621,7 +619,7 @@ static NTSTATUS test_getgroups(struct smbcli_transport *transport,
        if (mem_ctx == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       status = connect_to_pipe(&p, transport, DCERPC_SAMR_NAME,
+       status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
                                 DCERPC_SAMR_UUID, 
                                 DCERPC_SAMR_VERSION);
 
@@ -785,7 +783,7 @@ static NTSTATUS test_getallsids(struct smbcli_transport *transport,
        if (mem_ctx == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       status = connect_to_pipe(&p, transport, DCERPC_SAMR_NAME,
+       status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
                                 DCERPC_SAMR_UUID, 
                                 DCERPC_SAMR_VERSION);
 
@@ -984,7 +982,7 @@ static NTSTATUS test_remoteTOD(struct smbcli_transport *transport)
        if (mem_ctx == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       status = connect_to_pipe(&p, transport, DCERPC_SRVSVC_NAME,
+       status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SRVSVC_NAME,
                                 DCERPC_SRVSVC_UUID,
                                 DCERPC_SRVSVC_VERSION);
 
@@ -1054,14 +1052,14 @@ static BOOL xp_login(const char *dcname, const char *wksname,
                return False;
 
        status = connect_to_pipe(&netlogon_schannel_pipe,
-                                transport, DCERPC_NETLOGON_NAME,
+                                mem_ctx, transport, DCERPC_NETLOGON_NAME,
                                 DCERPC_NETLOGON_UUID,
                                 DCERPC_NETLOGON_VERSION);
 
        if (!NT_STATUS_IS_OK(status))
                return False;
 
-       netlogon_schannel_pipe->flags |= DCERPC_SEAL;
+       netlogon_schannel_pipe->conn->flags |= DCERPC_SEAL;
 
        status = dcerpc_bind_auth_schannel_withkey(netlogon_schannel_pipe,
                                                   DCERPC_NETLOGON_UUID,
index 1b80ea1825233a0fa622a6da30cf60446e1a780b..99bf1bfe8124c3b2c03cfe9dcf7bb2e5f7f9d5a7 100644 (file)
@@ -46,14 +46,14 @@ static const struct dcerpc_interface_call *find_function(
 
 static void show_pipes(void)
 {
-       struct dcerpc_interface_list *p;
+       const struct dcerpc_interface_list *l;
        printf("\nYou must specify a pipe\n");
        printf("known pipes are:\n");
-       for (p=dcerpc_pipes;p;p=p->next) {
-               if(p->table->helpstring) {
-                       printf("\t%s - %s\n", p->table->name, p->table->helpstring);
+       for (l=librpc_dcerpc_pipes();l;l=l->next) {
+               if(l->table->helpstring) {
+                       printf("\t%s - %s\n", l->table->name, l->table->helpstring);
                } else {
-                       printf("\t%s\n", p->table->name);
+                       printf("\t%s\n", l->table->name);
                }
        }
        exit(1);