The branch, master has been updated
       via  5e892fb s4-dns: dlz_bind9: improve log message consistency
       via  f15d10d s4-dns: dlz_bind9: Fix ipv6 updates
       via  13b36be s4:librpc/rpc: allow a shortcut in 
dcerpc_pipe_connect_ncacn_np_smb[2]_send()
       via  a13eeba s4:librpc/rpc: split out continue_smb_open()
       via  35192e8 s4:librpc/rpc: remove pipe_np_smb2_state and use 
pipe_np_smb_state
       via  7ea0475 s4:librpc/rpc: remember some smbXcli_* pointers within 
struct dcerpc_pipe_connect
       via  ae406ac s4:librpc/rpc: use DCERPC_REQUEST_TIMEOUT for smb opens
       via  d1b5016 s4:librpc/rpc: remove some unused functions and structures 
from dcerpc_sock.c
       via  e4f7b90 s4:librpc/rpc: avoid using dcerpc_socket_peer_addr()
       via  3aebaf4 s4:librpc/rpc: set "localaddress" and reset "host" for 
ncacn_ip_tcp
       via  374c5c4 s4:librpc/rpc: return the local/remote ip from 
dcerpc_pipe_open_tcp_recv()
       via  4c11fa6 s4:librpc/rpc: optionally return the local address from 
dcerpc_pipe_open_socket_recv()
       via  dfee057 s4:librpc/rpc: avoid using dcerpc_unix_socket_path()
      from  a448699 torture3: Add a little gencache_parse load test

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 5e892fb674c13e5a3b35b310557d1e2a43bd5bb5
Author: Arvid Requate <requ...@univention.de>
Date:   Sun May 18 19:16:06 2014 +0200

    s4-dns: dlz_bind9: improve log message consistency
    
    Change-Id: I0a12c048fd4e667b9aa0777f99c8f8306fc090ea
    Signed-off-by: Arvid Requate <requ...@univention.de>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Kai Blin <k...@samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abart...@samba.org>
    Autobuild-Date(master): Mon May 26 05:55:46 CEST 2014 on sn-devel-104

commit f15d10df29285024eae75eb83e03ff14d22524e6
Author: Arvid Requate <requ...@univention.de>
Date:   Sat May 17 18:25:01 2014 +0200

    s4-dns: dlz_bind9: Fix ipv6 updates
    
    b9_record_match needs to consider all allowed representations of IPv6
    addresses (RFC 2373), otherwise DNS subtractrdataset operations fail
    due to differences in zero padding between bind9 frontend and ndr_pull
    of a dnsp_DnssrvRpcRecord structure.
    
    Change-Id: Ic0a1b16008458993dc644646d7f4ae3d3a3c5fed
    Signed-off-by: Arvid Requate <requ...@univention.de>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Kai Blin <k...@samba.org>
    Reviewed-by: Guenter Kukkukk <ku...@samba.org>

commit 13b36be68fb54d8e993aefe7b8b5e53f7316a126
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Jan 15 13:06:20 2014 +0100

    s4:librpc/rpc: allow a shortcut in 
dcerpc_pipe_connect_ncacn_np_smb[2]_send()
    
    If the caller provided smbXcli * pointers of an existing connection,
    we can use it.
    
    This will be used later in order to allow multiple dcerpc connections
    over the same smb connection.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit a13eebac7dbc4c496e3784d2b31be89670dddb6d
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Jan 15 13:03:27 2014 +0100

    s4:librpc/rpc: split out continue_smb_open()
    
    The smb and smb2 code pathes are the same.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 35192e8316291daf70576ceeb483c0204ec9d455
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Jan 15 12:58:52 2014 +0100

    s4:librpc/rpc: remove pipe_np_smb2_state and use pipe_np_smb_state
    
    There's no need for two almost identical structures.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 7ea04759d7f94a5d4fa57a63612afd9e752ba5e9
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Jan 15 12:56:36 2014 +0100

    s4:librpc/rpc: remember some smbXcli_* pointers within struct 
dcerpc_pipe_connect
    
    This will simplify further improvements.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit ae406ac6687a5c093e196741ac0187cf27a83b3d
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Jan 15 13:17:42 2014 +0100

    s4:librpc/rpc: use DCERPC_REQUEST_TIMEOUT for smb opens
    
    There's no need to make the connect timeout dynamic.
    We implicitly used SMB_REQUEST_TIMEOUT which is also 60 seconds before.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit d1b5016572a3d1fe45a50015bcaf7ecb51ed6a4d
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Feb 14 01:15:23 2014 +0100

    s4:librpc/rpc: remove some unused functions and structures from 
dcerpc_sock.c
    
    Now we just dcerpc_sock.c doesn't need to maintain 'struct sock_private'
    in p->transport.private_data anymore, we're just using a raw tstream_context
    as p->transport.stream.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit e4f7b90295c461da8acdf1c4f23ae02c00211ed1
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Feb 14 01:08:31 2014 +0100

    s4:librpc/rpc: avoid using dcerpc_socket_peer_addr()
    
    We use information stored in the dcerpc_binding in order
    to open a secondary connection.
    
    The goals are:
    - dcerpc_secondary_connection_* should just use the dcerpc_binding
      information for the first connection and just call dcerpc_pipe_connect_*
    - Get rid of dcerpc_pipe->transport.* and just use a tstream_context.
      All other details should be maintained only by the higher levels.
    - Hide dcerpc_pipe and dcecli_connection behind dcerpc_binding_handle.
    - Have just one entry point to create a new connection. For source4/librpc
      this will be dcerpc_pipe_connect_*. For source3/rpc_client we need
      a similar function.
    - We'll have a new dcerpc_connection layer, with also just one
      entry point to create a new connection.
    - Replace dcerpc_pipe and dcecli_connection with the new dcerpc_connection 
layer.
    - Replace rpc_pipe_client with the new dcerpc_connection layer.
    - When the client side is unified we can change the server
      as it needs to act as a client in order to register the endpoint mappings.
    - Then the core of the server will be changed to use the new 
dcerpc_connection
      layer.
    
    As dcerpc_socket_peer_addr() uses p->transport.private_data
    as 'struct sock_private', we should avoid it.
    We can then remove dcerpc_unix_socket_path() and 'struct sock_private'.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 3aebaf4c1340292baec0db8448e60af2079600c1
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Feb 13 16:28:54 2014 +0100

    s4:librpc/rpc: set "localaddress" and reset "host" for ncacn_ip_tcp
    
    We should remember local and remote ip address in dcerpc_pipe->binding.
    
    Note: that we still have the "target_hostname" unmodified, if present.
    
    This way dcerpc_pipe->binding can be used to create a secondary connection
    that is a additional connection for the existing association group.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 374c5c4109facbcf3e9a20d1b116d369f14164c0
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Feb 13 16:27:22 2014 +0100

    s4:librpc/rpc: return the local/remote ip from dcerpc_pipe_open_tcp_recv()
    
    It's important that the caller can remember the ips,
    so that a secondary connection can use the same addresses
    in order to get association group binding to work.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit 4c11fa68d48caa06d6f9c9db462a2d2e6a0bc3d3
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Feb 13 16:22:59 2014 +0100

    s4:librpc/rpc: optionally return the local address from 
dcerpc_pipe_open_socket_recv()
    
    The caller should be able to remember the local address that was used
    for the connection.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

commit dfee05744797459d1303a54edb5955dec1e4cb1a
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Feb 13 09:53:49 2014 +0100

    s4:librpc/rpc: avoid using dcerpc_unix_socket_path()
    
    We use information stored in the dcerpc_binding in order
    to open a secondary connection.
    
    The goals are:
    - dcerpc_secondary_connection_* should just use the dcerpc_binding
      information for the first connection and just call dcerpc_pipe_connect_*
    - Get rid of dcerpc_pipe->transport.* and just use a tstream_context.
      All other details should be maintained only by the higher levels.
    - Hide dcerpc_pipe and dcecli_connection behind dcerpc_binding_handle.
    - Have just one entry point to create a new connection. For source4/librpc
      this will be dcerpc_pipe_connect_*. For source3/rpc_client we need
      a similar function.
    - We'll have a new dcerpc_connection layer, with also just one
      entry point to create a new connection.
    - Replace dcerpc_pipe and dcecli_connection with the new dcerpc_connection 
layer.
    - Replace rpc_pipe_client with the new dcerpc_connection layer.
    - When the client side is unified we can change the server
      as it needs to act as a client in order to register the endpoint mappings.
    - Then the core of the server will be changed to use the new 
dcerpc_connection
      layer.
    
    As dcerpc_unix_socket_path() uses p->transport.private_data
    as 'struct sock_private', we should avoid it.
    We can then remove dcerpc_unix_socket_path() and 'struct sock_private'.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Andrew Bartlett <abart...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source4/dns_server/dlz_bind9.c        |   14 ++-
 source4/librpc/rpc/dcerpc_connect.c   |  137 +++++++++++++++-----------------
 source4/librpc/rpc/dcerpc_secondary.c |  123 +++++++++++++++++++++++++-----
 source4/librpc/rpc/dcerpc_smb.c       |   12 +--
 source4/librpc/rpc/dcerpc_sock.c      |  100 ++++++++++++------------
 5 files changed, 231 insertions(+), 155 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c
index 677578a..3ffb06b 100644
--- a/source4/dns_server/dlz_bind9.c
+++ b/source4/dns_server/dlz_bind9.c
@@ -210,7 +210,7 @@ static bool b9_format(struct dlz_bind9_data *state,
        }
 
        default:
-               state->log(ISC_LOG_ERROR, "samba b9_putrr: unhandled record 
type %u",
+               state->log(ISC_LOG_ERROR, "samba_dlz b9_format: unhandled 
record type %u",
                           rec->wType);
                return false;
        }
@@ -379,14 +379,14 @@ static bool b9_parse(struct dlz_bind9_data *state,
                break;
 
        default:
-               state->log(ISC_LOG_ERROR, "samba b9_parse: unhandled record 
type %u",
+               state->log(ISC_LOG_ERROR, "samba_dlz b9_parse: unhandled record 
type %u",
                           rec->wType);
                return false;
        }
 
        /* we should be at the end of the buffer now */
        if (strtok_r(NULL, "\t ", &saveptr) != NULL) {
-               state->log(ISC_LOG_ERROR, "samba b9_parse: unexpected data at 
end of string for '%s'",
+               state->log(ISC_LOG_ERROR, "samba_dlz b9_parse: unexpected data 
at end of string for '%s'",
                           rdatastr);
                return false;
        }
@@ -1440,6 +1440,8 @@ static bool b9_record_match(struct dlz_bind9_data *state,
 {
        bool status;
        int i;
+       struct in6_addr rec1_in_addr6;
+       struct in6_addr rec2_in_addr6;
 
        if (rec1->wType != rec2->wType) {
                return false;
@@ -1454,7 +1456,9 @@ static bool b9_record_match(struct dlz_bind9_data *state,
        case DNS_TYPE_A:
                return strcmp(rec1->data.ipv4, rec2->data.ipv4) == 0;
        case DNS_TYPE_AAAA:
-               return strcmp(rec1->data.ipv6, rec2->data.ipv6) == 0;
+               inet_pton(AF_INET6, rec1->data.ipv6, &rec1_in_addr6);
+               inet_pton(AF_INET6, rec2->data.ipv6, &rec2_in_addr6);
+               return memcmp(&rec1_in_addr6, &rec2_in_addr6, 
sizeof(rec1_in_addr6)) == 0;
        case DNS_TYPE_CNAME:
                return dns_name_equal(rec1->data.cname, rec2->data.cname);
        case DNS_TYPE_TXT:
@@ -1492,7 +1496,7 @@ static bool b9_record_match(struct dlz_bind9_data *state,
                        rec1->data.soa.expire == rec2->data.soa.expire &&
                        rec1->data.soa.minimum == rec2->data.soa.minimum;
        default:
-               state->log(ISC_LOG_ERROR, "samba b9_putrr: unhandled record 
type %u",
+               state->log(ISC_LOG_ERROR, "samba_dlz b9_record_match: unhandled 
record type %u",
                           rec1->wType);
                break;
        }
diff --git a/source4/librpc/rpc/dcerpc_connect.c 
b/source4/librpc/rpc/dcerpc_connect.c
index da452e6..ecb5315 100644
--- a/source4/librpc/rpc/dcerpc_connect.c
+++ b/source4/librpc/rpc/dcerpc_connect.c
@@ -38,14 +38,19 @@
 
 struct dcerpc_pipe_connect {
        struct dcecli_connection *conn;
-       const struct dcerpc_binding *binding;
-       const char *pipe_name;
+       struct dcerpc_binding *binding;
        const struct ndr_interface_table *interface;
        struct cli_credentials *creds;
        struct resolve_context *resolve_ctx;
        struct {
                const char *dir;
        } ncalrpc;
+       struct {
+               struct smbXcli_conn *conn;
+               struct smbXcli_session *session;
+               struct smbXcli_tcon *tcon;
+               const char *pipe_name;
+       } smb;
 };
 
 struct pipe_np_smb_state {
@@ -69,46 +74,49 @@ static void continue_pipe_open_smb(struct composite_context 
*ctx)
        composite_done(c);
 }
 
+static void continue_smb_open(struct composite_context *c);
 
 /*
   Stage 2 of ncacn_np_smb: Open a named pipe after successful smb connection
 */
 static void continue_smb_connect(struct composite_context *ctx)
 {
-       struct composite_context *open_ctx;
        struct composite_context *c = talloc_get_type(ctx->async.private_data,
                                                      struct composite_context);
        struct pipe_np_smb_state *s = talloc_get_type(c->private_data,
                                                      struct pipe_np_smb_state);
        struct smbcli_tree *t;
-       struct smbXcli_conn *conn;
-       struct smbXcli_session *session;
-       struct smbXcli_tcon *tcon;
-       uint32_t timeout_msec;
 
        /* receive result of smb connect request */
        c->status = smb_composite_connect_recv(ctx, s->io.conn);
        if (!composite_is_ok(c)) return;
 
+       t = s->conn.out.tree;
+
        /* prepare named pipe open parameters */
-       s->io.pipe_name = dcerpc_binding_get_string_option(s->io.binding, 
"endpoint");
-       if (s->io.pipe_name == NULL) {
-               composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
-               return;
-       }
+       s->io.smb.conn = t->session->transport->conn;
+       s->io.smb.session = t->session->smbXcli;
+       s->io.smb.tcon = t->smbXcli;
+       smb1cli_tcon_set_id(s->io.smb.tcon, t->tid);
+       s->io.smb.pipe_name = dcerpc_binding_get_string_option(s->io.binding,
+                                                              "endpoint");
+
+       continue_smb_open(c);
+}
 
-       t = s->conn.out.tree;
-       conn = t->session->transport->conn;
-       session = t->session->smbXcli;
-       tcon = t->smbXcli;
-       smb1cli_tcon_set_id(tcon, t->tid);
-       timeout_msec = t->session->transport->options.request_timeout * 1000;
+static void continue_smb_open(struct composite_context *c)
+{
+       struct pipe_np_smb_state *s = talloc_get_type(c->private_data,
+                                                     struct pipe_np_smb_state);
+       struct composite_context *open_ctx;
 
        /* send named pipe open request */
        open_ctx = dcerpc_pipe_open_smb_send(s->io.conn,
-                                            conn, session,
-                                            tcon, timeout_msec,
-                                            s->io.pipe_name);
+                                            s->io.smb.conn,
+                                            s->io.smb.session,
+                                            s->io.smb.tcon,
+                                            DCERPC_REQUEST_TIMEOUT * 1000,
+                                            s->io.smb.pipe_name);
        if (composite_nomem(open_ctx, c)) return;
 
        composite_continue(c, open_ctx, continue_pipe_open_smb, c);
@@ -138,6 +146,11 @@ static struct composite_context 
*dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT
        s->io  = *io;
        conn   = &s->conn;
 
+       if (smbXcli_conn_is_connected(s->io.smb.conn)) {
+               continue_smb_open(c);
+               return c;
+       }
+
        /* prepare smb connection parameters: we're connecting to IPC$ share on
           remote rpc server */
        conn->in.dest_host = dcerpc_binding_get_string_option(s->io.binding, 
"host");
@@ -192,70 +205,30 @@ static NTSTATUS 
dcerpc_pipe_connect_ncacn_np_smb_recv(struct composite_context *
        return status;
 }
 
-
-struct pipe_np_smb2_state {
-       struct dcerpc_pipe_connect io;
-};
-
-
-/*
-  Stage 3 of ncacn_np_smb: Named pipe opened (or not)
-*/
-static void continue_pipe_open_smb2(struct composite_context *ctx)
-{
-       struct composite_context *c = talloc_get_type(ctx->async.private_data,
-                                                     struct composite_context);
-
-       /* receive result of named pipe open request on smb2 */
-       c->status = dcerpc_pipe_open_smb_recv(ctx);
-       if (!composite_is_ok(c)) return;
-
-       composite_done(c);
-}
-
-
 /*
   Stage 2 of ncacn_np_smb2: Open a named pipe after successful smb2 connection
 */
 static void continue_smb2_connect(struct tevent_req *subreq)
 {
-       struct composite_context *open_req;
        struct composite_context *c =
                tevent_req_callback_data(subreq,
                struct composite_context);
-       struct pipe_np_smb2_state *s = talloc_get_type(c->private_data,
-                                                      struct 
pipe_np_smb2_state);
+       struct pipe_np_smb_state *s = talloc_get_type(c->private_data,
+                                                     struct pipe_np_smb_state);
        struct smb2_tree *t;
-       struct smbXcli_conn *conn;
-       struct smbXcli_session *session;
-       struct smbXcli_tcon *tcon;
-       uint32_t timeout_msec;
 
        /* receive result of smb2 connect request */
        c->status = smb2_connect_recv(subreq, s->io.conn, &t);
        TALLOC_FREE(subreq);
        if (!composite_is_ok(c)) return;
 
-       /* prepare named pipe open parameters */
-       s->io.pipe_name = dcerpc_binding_get_string_option(s->io.binding, 
"endpoint");
-       if (s->io.pipe_name == NULL) {
-               composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
-               return;
-       }
-
-       conn = t->session->transport->conn;
-       session = t->session->smbXcli;
-       tcon = t->smbXcli;
-       timeout_msec = t->session->transport->options.request_timeout * 1000;
-
-       /* send named pipe open request */
-       open_req = dcerpc_pipe_open_smb_send(s->io.conn,
-                                            conn, session,
-                                            tcon, timeout_msec,
-                                            s->io.pipe_name);
-       if (composite_nomem(open_req, c)) return;
+       s->io.smb.conn = t->session->transport->conn;
+       s->io.smb.session = t->session->smbXcli;
+       s->io.smb.tcon = t->smbXcli;
+       s->io.smb.pipe_name = dcerpc_binding_get_string_option(s->io.binding,
+                                                              "endpoint");
 
-       composite_continue(c, open_req, continue_pipe_open_smb2, c);
+       continue_smb_open(c);
 }
 
 
@@ -269,7 +242,7 @@ static struct composite_context 
*dcerpc_pipe_connect_ncacn_np_smb2_send(
                                        struct loadparm_context *lp_ctx)
 {
        struct composite_context *c;
-       struct pipe_np_smb2_state *s;
+       struct pipe_np_smb_state *s;
        struct tevent_req *subreq;
        struct smbcli_options options;
        const char *host;
@@ -279,12 +252,17 @@ static struct composite_context 
*dcerpc_pipe_connect_ncacn_np_smb2_send(
        c = composite_create(mem_ctx, io->conn->event_ctx);
        if (c == NULL) return NULL;
 
-       s = talloc_zero(c, struct pipe_np_smb2_state);
+       s = talloc_zero(c, struct pipe_np_smb_state);
        if (composite_nomem(s, c)) return c;
        c->private_data = s;
 
        s->io = *io;
 
+       if (smbXcli_conn_is_connected(s->io.smb.conn)) {
+               continue_smb_open(c);
+               return c;
+       }
+
        host = dcerpc_binding_get_string_option(s->io.binding, "host");
        flags = dcerpc_binding_get_flags(s->io.binding);
 
@@ -344,9 +322,23 @@ static void continue_pipe_open_ncacn_ip_tcp(struct 
composite_context *ctx)
 {
        struct composite_context *c = talloc_get_type(ctx->async.private_data,
                                                      struct composite_context);
+       struct pipe_ip_tcp_state *s = talloc_get_type(c->private_data,
+                                                     struct pipe_ip_tcp_state);
+       char *localaddr = NULL;
+       char *remoteaddr = NULL;
 
        /* receive result of named pipe open request on tcp/ip */
-       c->status = dcerpc_pipe_open_tcp_recv(ctx);
+       c->status = dcerpc_pipe_open_tcp_recv(ctx, s, &localaddr, &remoteaddr);
+       if (!composite_is_ok(c)) return;
+
+       c->status = dcerpc_binding_set_string_option(s->io.binding,
+                                                    "localaddress",
+                                                    localaddr);
+       if (!composite_is_ok(c)) return;
+
+       c->status = dcerpc_binding_set_string_option(s->io.binding,
+                                                    "host",
+                                                    remoteaddr);
        if (!composite_is_ok(c)) return;
 
        composite_done(c);
@@ -614,7 +606,6 @@ static void continue_connect(struct composite_context *c, 
struct pipe_connect_st
        ZERO_STRUCT(pc);
        pc.conn         = s->pipe->conn;
        pc.binding      = s->binding;
-       pc.pipe_name    = NULL;
        pc.interface    = s->table;
        pc.creds        = s->credentials;
        pc.resolve_ctx  = lpcfg_resolve_context(s->lp_ctx);
diff --git a/source4/librpc/rpc/dcerpc_secondary.c 
b/source4/librpc/rpc/dcerpc_secondary.c
index be886a2..9f52345 100644
--- a/source4/librpc/rpc/dcerpc_secondary.c
+++ b/source4/librpc/rpc/dcerpc_secondary.c
@@ -31,20 +31,19 @@
 #include "auth/credentials/credentials.h"
 #include "param/param.h"
 #include "libcli/resolve/resolve.h"
-#include "lib/socket/socket.h"
+#include "lib/util/util_net.h"
 
 struct sec_conn_state {
        struct dcerpc_pipe *pipe;
        struct dcerpc_pipe *pipe2;
-       const struct dcerpc_binding *binding;
-       struct socket_address *peer_addr;
-       const char *localaddress;
+       struct dcerpc_binding *binding;
 };
 
 
 static void continue_open_smb(struct composite_context *ctx);
 static void continue_open_tcp(struct composite_context *ctx);
-static void continue_open_pipe(struct composite_context *ctx);
+static void continue_open_ncalrpc(struct composite_context *ctx);
+static void continue_open_ncacn_unix(struct composite_context *ctx);
 static void continue_pipe_open(struct composite_context *c);
 
 
@@ -59,7 +58,11 @@ _PUBLIC_ struct composite_context* 
dcerpc_secondary_connection_send(struct dcerp
        struct sec_conn_state *s;
        struct composite_context *pipe_smb_req;
        struct composite_context *pipe_tcp_req;
+       const char *localaddress = NULL;
        struct composite_context *pipe_ncalrpc_req;
+       const char *ncalrpc_dir = NULL;
+       struct composite_context *pipe_unix_req;
+       const char *host;
        const char *target_hostname;
        const char *endpoint;
 
@@ -72,7 +75,8 @@ _PUBLIC_ struct composite_context* 
dcerpc_secondary_connection_send(struct dcerp
        c->private_data = s;
 
        s->pipe     = p;
-       s->binding  = b;
+       s->binding  = dcerpc_binding_dup(s, b);
+       if (composite_nomem(s->binding, c)) return c;
 
        /* initialise second dcerpc pipe based on primary pipe's event context 
*/
        s->pipe2 = dcerpc_pipe_init(c, s->pipe->conn->event_ctx);
@@ -81,7 +85,22 @@ _PUBLIC_ struct composite_context* 
dcerpc_secondary_connection_send(struct dcerp
        if (DEBUGLEVEL >= 10)
                s->pipe2->conn->packet_log_dir = s->pipe->conn->packet_log_dir;
 
+       host = dcerpc_binding_get_string_option(s->binding, "host");
+       if (host == NULL) {
+               /*
+                * We may fallback to the host of the given connection
+                */
+               host = dcerpc_binding_get_string_option(s->pipe->binding,
+                                                       "host");
+       }
        target_hostname = dcerpc_binding_get_string_option(s->binding, 
"target_hostname");
+       if (target_hostname == NULL) {
+               /*
+                * We may fallback to the target_hostname of the given 
connection
+                */
+               target_hostname = 
dcerpc_binding_get_string_option(s->pipe->binding,
+                                                                  
"target_hostname");
+       }
        endpoint = dcerpc_binding_get_string_option(s->binding, "endpoint");
        if (endpoint == NULL) {
                /*
@@ -104,18 +123,40 @@ _PUBLIC_ struct composite_context* 
dcerpc_secondary_connection_send(struct dcerp
                return c;
 
        case NCACN_IP_TCP:
-               s->peer_addr = dcerpc_socket_peer_addr(s->pipe->conn, s);
-               if (!s->peer_addr) {
-                       composite_error(c, NT_STATUS_INVALID_PARAMETER);
+               if (host == NULL) {
+                       composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
                        return c;
                }
 
-               s->localaddress = dcerpc_binding_get_string_option(s->binding,
+               if (!is_ipaddress(host)) {
+                       /*
+                        * We may fallback to the host of the given connection
+                        */
+                       host = 
dcerpc_binding_get_string_option(s->pipe->binding,
+                                                               "host");
+                       if (host == NULL) {
+                               composite_error(c, 
NT_STATUS_INVALID_PARAMETER_MIX);
+                               return c;
+                       }
+                       if (!is_ipaddress(host)) {
+                               composite_error(c, 
NT_STATUS_INVALID_PARAMETER_MIX);
+                               return c;
+                       }
+               }
+
+               localaddress = dcerpc_binding_get_string_option(s->binding,
                                                                "localaddress");
+               if (localaddress == NULL) {
+                       /*
+                        * We may fallback to the localaddress of the given 
connection
+                        */
+                       localaddress = 
dcerpc_binding_get_string_option(s->pipe->binding,
+                                                                       
"localaddress");
+               }
 
                pipe_tcp_req = dcerpc_pipe_open_tcp_send(s->pipe2->conn,
-                                                        s->localaddress,
-                                                        s->peer_addr->addr,
+                                                        localaddress,
+                                                        host,
                                                         target_hostname,
                                                         atoi(endpoint),
                                                         
resolve_context_init(s));
@@ -123,10 +164,27 @@ _PUBLIC_ struct composite_context* 
dcerpc_secondary_connection_send(struct dcerp
                return c;
 
        case NCALRPC:
+               ncalrpc_dir = dcerpc_binding_get_string_option(s->binding,
+                                                              "ncalrpc_dir");
+               if (ncalrpc_dir == NULL) {
+                       ncalrpc_dir = 
dcerpc_binding_get_string_option(s->pipe->binding,
+                                                               "ncalrpc_dir");
+               }
+               if (ncalrpc_dir == NULL) {
+                       composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
+                       return c;
+               }
+
+               pipe_ncalrpc_req = dcerpc_pipe_open_pipe_send(s->pipe2->conn,
+                                                             ncalrpc_dir,
+                                                             endpoint);
+               composite_continue(c, pipe_ncalrpc_req, continue_open_ncalrpc, 
c);
+               return c;
+
        case NCACN_UNIX_STREAM:
-               pipe_ncalrpc_req = 
dcerpc_pipe_open_unix_stream_send(s->pipe2->conn, 
-                                                             
dcerpc_unix_socket_path(s->pipe->conn));
-               composite_continue(c, pipe_ncalrpc_req, continue_open_pipe, c);
+               pipe_unix_req = 
dcerpc_pipe_open_unix_stream_send(s->pipe2->conn,
+                                                                 endpoint);
+               composite_continue(c, pipe_unix_req, continue_open_ncacn_unix, 
c);
                return c;
 
        default:
@@ -160,18 +218,45 @@ static void continue_open_tcp(struct composite_context 
*ctx)
 {
        struct composite_context *c = talloc_get_type(ctx->async.private_data,
                                                      struct composite_context);
-       
-       c->status = dcerpc_pipe_open_tcp_recv(ctx);
+       struct sec_conn_state *s = talloc_get_type_abort(c->private_data,
+                                                        struct sec_conn_state);
+       char *localaddr = NULL;
+       char *remoteaddr = NULL;
+
+       c->status = dcerpc_pipe_open_tcp_recv(ctx, s, &localaddr, &remoteaddr);
+       if (!composite_is_ok(c)) return;
+
+       c->status = dcerpc_binding_set_string_option(s->binding,
+                                                    "localaddress",
+                                                    localaddr);
+       if (!composite_is_ok(c)) return;
+
+       c->status = dcerpc_binding_set_string_option(s->binding,
+                                                    "host",
+                                                    remoteaddr);
        if (!composite_is_ok(c)) return;
 
        continue_pipe_open(c);
 }
 
-
 /*
   Stage 2 of secondary_connection: Receive result of pipe open request on 
ncalrpc
 */
-static void continue_open_pipe(struct composite_context *ctx)
+static void continue_open_ncalrpc(struct composite_context *ctx)
+{
+       struct composite_context *c = talloc_get_type(ctx->async.private_data,
+                                                     struct composite_context);
+
+       c->status = dcerpc_pipe_open_pipe_recv(ctx);
+       if (!composite_is_ok(c)) return;
+
+       continue_pipe_open(c);
+}


-- 
Samba Shared Repository

Reply via email to