r25398: Parse loadparm context to all lp_*() functions.
[ira/wip.git] / source4 / librpc / rpc / dcerpc_util.c
index d3eed5c4bb7a8f3f0b2c8a91dedd44d317cfec83..408860c9edb5436c5e400f8d775788bf078df61f 100644 (file)
@@ -10,7 +10,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -19,8 +19,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "librpc/gen_ndr/ndr_dcerpc.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "auth/credentials/credentials.h"
+#include "param/param.h"
 
 /*
   find a dcerpc call on an interface by name
 */
-const struct dcerpc_interface_call *dcerpc_iface_find_call(const struct dcerpc_interface_table *iface,
-                                                          const char *name)
+const struct ndr_interface_call *dcerpc_iface_find_call(const struct ndr_interface_table *iface,
+                                                       const char *name)
 {
        int i;
        for (i=0;i<iface->num_calls;i++) {
@@ -65,7 +65,7 @@ NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
                ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
-       if (pkt->pfc_flags & DCERPC_PFC_FLAG_ORPC) {
+       if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
                ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
        }
 
@@ -152,7 +152,7 @@ static const struct {
 
 const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
 {
-       struct dcerpc_syntax_id syntax;
+       struct ndr_syntax_id syntax;
        NTSTATUS status;
 
        switch(epm_floor->lhs.protocol) {
@@ -232,19 +232,21 @@ const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
 /*
   form a binding string from a binding structure
 */
-const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b)
+char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b)
 {
        char *s = talloc_strdup(mem_ctx, "");
        int i;
-       const char *t_name=NULL;
+       const char *t_name = NULL;
 
-       for (i=0;i<ARRAY_SIZE(transports);i++) {
-               if (transports[i].transport == b->transport) {
-                       t_name = transports[i].name;
+       if (b->transport != NCA_UNKNOWN) {
+               for (i=0;i<ARRAY_SIZE(transports);i++) {
+                       if (transports[i].transport == b->transport) {
+                               t_name = transports[i].name;
+                       }
+               }
+               if (!t_name) {
+                       return NULL;
                }
-       }
-       if (!t_name) {
-               return NULL;
        }
 
        if (!GUID_all_zero(&b->object.uuid)) { 
@@ -252,39 +254,43 @@ const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bindi
                                    GUID_string(mem_ctx, &b->object.uuid));
        }
 
-       s = talloc_asprintf_append(s, "%s:", t_name);
-       if (!s) return NULL;
+       if (t_name != NULL) {
+               s = talloc_asprintf_append_buffer(s, "%s:", t_name);
+               if (s == NULL) {
+                       return NULL;
+               }
+       }
 
        if (b->host) {
-               s = talloc_asprintf_append(s, "%s", b->host);
+               s = talloc_asprintf_append_buffer(s, "%s", b->host);
        }
 
        if (!b->endpoint && !b->options && !b->flags) {
                return s;
        }
 
-       s = talloc_asprintf_append(s, "[");
+       s = talloc_asprintf_append_buffer(s, "[");
 
        if (b->endpoint) {
-               s = talloc_asprintf_append(s, "%s", b->endpoint);
+               s = talloc_asprintf_append_buffer(s, "%s", b->endpoint);
        }
 
        /* this is a *really* inefficent way of dealing with strings,
           but this is rarely called and the strings are always short,
           so I don't care */
        for (i=0;b->options && b->options[i];i++) {
-               s = talloc_asprintf_append(s, ",%s", b->options[i]);
+               s = talloc_asprintf_append_buffer(s, ",%s", b->options[i]);
                if (!s) return NULL;
        }
 
        for (i=0;i<ARRAY_SIZE(ncacn_options);i++) {
                if (b->flags & ncacn_options[i].flag) {
-                       s = talloc_asprintf_append(s, ",%s", ncacn_options[i].name);
+                       s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name);
                        if (!s) return NULL;
                }
        }
 
-       s = talloc_asprintf_append(s, "]");
+       s = talloc_asprintf_append_buffer(s, "]");
 
        return s;
 }
@@ -295,7 +301,7 @@ const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bindi
 NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out)
 {
        struct dcerpc_binding *b;
-       char *options, *type;
+       char *options;
        char *p;
        int i, j, comma_count;
 
@@ -324,27 +330,31 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
        b->object.if_version = 0;
 
        p = strchr(s, ':');
-       if (!p) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
 
-       type = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s));
-       if (!type) {
-               return NT_STATUS_NO_MEMORY;
-       }
+       if (p == NULL) {
+               b->transport = NCA_UNKNOWN;
+       } else {
+               char *type = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s));
+               if (!type) {
+                       return NT_STATUS_NO_MEMORY;
+               }
 
-       for (i=0;i<ARRAY_SIZE(transports);i++) {
-               if (strcasecmp(type, transports[i].name) == 0) {
-                       b->transport = transports[i].transport;
-                       break;
+               for (i=0;i<ARRAY_SIZE(transports);i++) {
+                       if (strcasecmp(type, transports[i].name) == 0) {
+                               b->transport = transports[i].transport;
+                               break;
+                       }
                }
-       }
-       if (i==ARRAY_SIZE(transports)) {
-               DEBUG(0,("Unknown dcerpc transport '%s'\n", type));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
+
+               if (i==ARRAY_SIZE(transports)) {
+                       DEBUG(0,("Unknown dcerpc transport '%s'\n", type));
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               talloc_free(type);
        
-       s = p+1;
+               s = p+1;
+       }
 
        p = strchr(s, '[');
        if (p) {
@@ -358,13 +368,15 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
                b->host = talloc_strdup(b, s);
                options = NULL;
        }
-
        if (!b->host) {
                return NT_STATUS_NO_MEMORY;
        }
 
+       b->target_hostname = b->host;
+
        b->options = NULL;
        b->flags = 0;
+       b->assoc_group_id = 0;
        b->endpoint = NULL;
 
        if (!options) {
@@ -421,7 +433,7 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
        return NT_STATUS_OK;
 }
 
-NTSTATUS dcerpc_floor_get_lhs_data(struct epm_floor *epm_floor, struct dcerpc_syntax_id *syntax)
+NTSTATUS dcerpc_floor_get_lhs_data(struct epm_floor *epm_floor, struct ndr_syntax_id *syntax)
 {
        TALLOC_CTX *mem_ctx = talloc_init("floor_get_lhs_data");
        struct ndr_pull *ndr = ndr_pull_init_blob(&epm_floor->lhs.lhs_data, mem_ctx);
@@ -444,7 +456,7 @@ NTSTATUS dcerpc_floor_get_lhs_data(struct epm_floor *epm_floor, struct dcerpc_sy
        return status;
 }
 
-static DATA_BLOB dcerpc_floor_pack_lhs_data(TALLOC_CTX *mem_ctx, const struct dcerpc_syntax_id *syntax)
+static DATA_BLOB dcerpc_floor_pack_lhs_data(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax)
 {
        struct ndr_push *ndr = ndr_push_init_ctx(mem_ctx);
 
@@ -519,7 +531,9 @@ const char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm
        return NULL;
 }
 
-static NTSTATUS dcerpc_floor_set_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor,  const char *data)
+static NTSTATUS dcerpc_floor_set_rhs_data(TALLOC_CTX *mem_ctx, 
+                                         struct epm_floor *epm_floor,  
+                                         const char *data)
 {
        switch (epm_floor->lhs.protocol) {
        case EPM_PROTOCOL_TCP:
@@ -636,7 +650,9 @@ enum dcerpc_transport_t dcerpc_transport_by_tower(struct epm_tower *tower)
        return (unsigned int)-1;
 }
 
-NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, struct dcerpc_binding **b_out)
+NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, 
+                                  struct epm_tower *tower, 
+                                  struct dcerpc_binding **b_out)
 {
        NTSTATUS status;
        struct dcerpc_binding *binding;
@@ -647,7 +663,9 @@ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower,
        ZERO_STRUCT(binding->object);
        binding->options = NULL;
        binding->host = NULL;
+       binding->target_hostname = NULL;
        binding->flags = 0;
+       binding->assoc_group_id = 0;
 
        binding->transport = dcerpc_transport_by_tower(tower);
 
@@ -681,6 +699,8 @@ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower,
        /* Set network address */
        if (tower->num_floors >= 5) {
                binding->host = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[4]);
+               NT_STATUS_HAVE_NO_MEMORY(binding->host);
+               binding->target_hostname = binding->host;
        }
        *b_out = binding;
        return NT_STATUS_OK;
@@ -765,7 +785,7 @@ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *
 
 struct epm_map_binding_state {
        struct dcerpc_binding *binding;
-       const struct dcerpc_interface_table *table;
+       const struct ndr_interface_table *table;
        struct dcerpc_pipe *pipe;
        struct policy_handle handle;
        struct GUID guid;
@@ -796,6 +816,8 @@ static void continue_epm_recv_binding(struct composite_context *ctx)
        c->status = dcerpc_pipe_connect_b_recv(ctx, c, &s->pipe);
        if (!composite_is_ok(c)) return;
 
+       s->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;
+
        /* prepare requested binding parameters */
        s->binding->object         = s->table->syntax_id;
 
@@ -822,7 +844,7 @@ static void continue_epm_recv_binding(struct composite_context *ctx)
 */
 static void continue_epm_map(struct rpc_request *req)
 {
-       struct composite_context *c = talloc_get_type(req->async.private,
+       struct composite_context *c = talloc_get_type(req->async.private_data,
                                                      struct composite_context);
        struct epm_map_binding_state *s = talloc_get_type(c->private_data,
                                                          struct epm_map_binding_state);
@@ -832,7 +854,7 @@ static void continue_epm_map(struct rpc_request *req)
        if (!composite_is_ok(c)) return;
 
        /* check the details */
-       if (s->r.out.result != 0 || s->r.out.num_towers != 1) {
+       if (s->r.out.result != 0 || *s->r.out.num_towers != 1) {
                composite_error(c, NT_STATUS_PORT_UNREACHABLE);
                return;
        }
@@ -852,6 +874,8 @@ static void continue_epm_map(struct rpc_request *req)
        /* get received endpoint */
        s->binding->endpoint = talloc_reference(s->binding,
                                                dcerpc_floor_get_rhs_data(c, &s->twr_r->tower.floors[3]));
+       if (composite_nomem(s->binding->endpoint, c)) return;
+
        composite_done(c);
 }
 
@@ -862,49 +886,57 @@ static void continue_epm_map(struct rpc_request *req)
 */
 struct composite_context *dcerpc_epm_map_binding_send(TALLOC_CTX *mem_ctx,
                                                      struct dcerpc_binding *binding,
-                                                     const struct dcerpc_interface_table *table,
+                                                     const struct ndr_interface_table *table,
                                                      struct event_context *ev)
 {
        struct composite_context *c;
        struct epm_map_binding_state *s;
        struct composite_context *pipe_connect_req;
        struct cli_credentials *anon_creds;
+       struct event_context *new_ev = NULL;
 
        NTSTATUS status;
        struct dcerpc_binding *epmapper_binding;
        int i;
 
+       /* Try to find event context in memory context in case passed
+        * event_context (argument) was NULL. If there's none, just
+        * create a new one.
+        */
+       if (ev == NULL) {
+               ev = event_context_find(mem_ctx);
+               if (ev == NULL) {
+                       new_ev = event_context_init(mem_ctx);
+                       if (new_ev == NULL) return NULL;
+                       ev = new_ev;
+               }
+       }
+
        /* composite context allocation and setup */
-       c = talloc_zero(mem_ctx, struct composite_context);
-       if (c == NULL) return NULL;
+       c = composite_create(mem_ctx, ev);
+       if (c == NULL) {
+               talloc_free(new_ev);
+               return NULL;
+       }
+       talloc_steal(c, new_ev);
 
        s = talloc_zero(c, struct epm_map_binding_state);
        if (composite_nomem(s, c)) return c;
-
-       c->state = COMPOSITE_STATE_IN_PROGRESS;
        c->private_data = s;
-       c->event_ctx = ev;
 
-       /* Try to find event context in memory context in case passed
-        * event_context (argument) was NULL. If there's none, just
-        * create a new one.
-        */
-       if (c->event_ctx == NULL) {
-               c->event_ctx = event_context_find(mem_ctx);
-       }
-       
        s->binding = binding;
        s->table   = table;
 
        /* anonymous credentials for rpc connection used to get endpoint mapping */
        anon_creds = cli_credentials_init(mem_ctx);
-       cli_credentials_set_conf(anon_creds);
+       cli_credentials_set_event_context(anon_creds, ev);
+       cli_credentials_set_conf(anon_creds, global_loadparm);
        cli_credentials_set_anonymous(anon_creds);
 
        /*
          First, check if there is a default endpoint specified in the IDL
        */
-       if (table) {
+       if (table != NULL) {
                struct dcerpc_binding *default_binding;
 
                /* Find one of the default pipes for this interface */
@@ -912,7 +944,10 @@ struct composite_context *dcerpc_epm_map_binding_send(TALLOC_CTX *mem_ctx,
                        status = dcerpc_parse_binding(mem_ctx, table->endpoints->names[i], &default_binding);
 
                        if (NT_STATUS_IS_OK(status)) {
-                               if (default_binding->transport == binding->transport && default_binding->endpoint) {
+                               if (binding->transport == NCA_UNKNOWN) 
+                                       binding->transport = default_binding->transport;
+                               if (default_binding->transport == binding->transport && 
+                                       default_binding->endpoint) {
                                        binding->endpoint = talloc_reference(binding, default_binding->endpoint);
                                        talloc_free(default_binding);
 
@@ -930,14 +965,17 @@ struct composite_context *dcerpc_epm_map_binding_send(TALLOC_CTX *mem_ctx,
        if (composite_nomem(epmapper_binding, c)) return c;
 
        /* basic endpoint mapping data */
-       epmapper_binding->transport  = binding->transport;
-       epmapper_binding->host       = talloc_reference(epmapper_binding, binding->host);
-       epmapper_binding->options    = NULL;
-       epmapper_binding->flags      = 0;
-       epmapper_binding->endpoint   = NULL;
+       epmapper_binding->transport             = binding->transport;
+       epmapper_binding->host                  = talloc_reference(epmapper_binding, binding->host);
+       epmapper_binding->target_hostname       = epmapper_binding->host;
+       epmapper_binding->options               = NULL;
+       epmapper_binding->flags                 = 0;
+       epmapper_binding->assoc_group_id        = 0;
+       epmapper_binding->endpoint              = NULL;
 
        /* initiate rpc pipe connection */
-       pipe_connect_req = dcerpc_pipe_connect_b_send(c, epmapper_binding, &dcerpc_table_epmapper,
+       pipe_connect_req = dcerpc_pipe_connect_b_send(c, epmapper_binding, 
+                                                     &ndr_table_epmapper,
                                                      anon_creds, c->event_ctx);
        if (composite_nomem(pipe_connect_req, c)) return c;
        
@@ -962,7 +1000,7 @@ NTSTATUS dcerpc_epm_map_binding_recv(struct composite_context *c)
   Get endpoint mapping for rpc connection
 */
 NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding,
-                               const struct dcerpc_interface_table *table, struct event_context *ev)
+                               const struct ndr_interface_table *table, struct event_context *ev)
 {
        struct composite_context *c;
 
@@ -974,7 +1012,7 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind
 struct pipe_auth_state {
        struct dcerpc_pipe *pipe;
        struct dcerpc_binding *binding;
-       const struct dcerpc_interface_table *table;
+       const struct ndr_interface_table *table;
        struct cli_credentials *credentials;
 };
 
@@ -1049,7 +1087,7 @@ static void continue_auth_auto(struct composite_context *ctx)
        }
 
        if (!composite_is_ok(c)) return;
-       
+
        composite_done(c);
 }
 
@@ -1070,19 +1108,17 @@ static void continue_ntlmssp_connection(struct composite_context *ctx)
 
        /* receive secondary rpc connection */
        c->status = dcerpc_secondary_connection_recv(ctx, &p2);
+       if (!composite_is_ok(c)) return;
+
        talloc_steal(s, p2);
        talloc_steal(p2, s->pipe);
        s->pipe = p2;
 
-       if (!composite_is_ok(c)) return;
-
        /* initiate a authenticated bind */
        auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
                                         s->credentials, DCERPC_AUTH_TYPE_NTLMSSP,
                                         dcerpc_auth_level(s->pipe->conn),
                                         s->table->authservices->names[0]);
-       if (composite_nomem(auth_req, c)) return;
-               
        composite_continue(c, auth_req, continue_auth, c);
 }
 
@@ -1103,19 +1139,17 @@ static void continue_spnego_after_wrong_pass(struct composite_context *ctx)
 
        /* receive secondary rpc connection */
        c->status = dcerpc_secondary_connection_recv(ctx, &p2);
+       if (!composite_is_ok(c)) return;
+
        talloc_steal(s, p2);
        talloc_steal(p2, s->pipe);
        s->pipe = p2;
 
-       if (!composite_is_ok(c)) return;
-
        /* initiate a authenticated bind */
        auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
                                         s->credentials, DCERPC_AUTH_TYPE_SPNEGO,
                                         dcerpc_auth_level(s->pipe->conn),
                                         s->table->authservices->names[0]);
-       if (composite_nomem(auth_req, c)) return;
-               
        composite_continue(c, auth_req, continue_auth, c);
 }
 
@@ -1141,7 +1175,7 @@ static void continue_auth_none(struct composite_context *ctx)
 */
 struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p, 
                                                struct dcerpc_binding *binding,
-                                               const struct dcerpc_interface_table *table,
+                                               const struct ndr_interface_table *table,
                                                struct cli_credentials *credentials)
 {
        struct composite_context *c;
@@ -1150,17 +1184,15 @@ struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p,
        struct composite_context *auth_req;
        struct composite_context *auth_none_req;
        struct dcerpc_connection *conn;
+       uint8_t auth_type;
 
        /* composite context allocation and setup */
-       c = talloc_zero(NULL, struct composite_context);
+       c = composite_create(p, p->conn->event_ctx);
        if (c == NULL) return NULL;
 
        s = talloc_zero(c, struct pipe_auth_state);
        if (composite_nomem(s, c)) return c;
-
-       c->state = COMPOSITE_STATE_IN_PROGRESS;
        c->private_data = s;
-       c->event_ctx = p->conn->event_ctx;
 
        /* store parameters in state structure */
        s->binding      = binding;
@@ -1174,81 +1206,76 @@ struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p,
        /* remember the binding string for possible secondary connections */
        conn->binding_string = dcerpc_binding_string(p, binding);
 
-       if (!cli_credentials_is_anonymous(s->credentials) &&
-           (binding->flags & DCERPC_SCHANNEL) &&
-           !cli_credentials_get_netlogon_creds(s->credentials)) {
+       if (cli_credentials_is_anonymous(s->credentials)) {
+               auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe, s->table);
+               composite_continue(c, auth_none_req, continue_auth_none, c);
+               return c;
+       }
 
+       if ((binding->flags & DCERPC_SCHANNEL) &&
+           !cli_credentials_get_netlogon_creds(s->credentials)) {
                /* If we don't already have netlogon credentials for
                 * the schannel bind, then we have to get these
                 * first */
                auth_schannel_req = dcerpc_bind_auth_schannel_send(c, s->pipe, s->table,
                                                                   s->credentials,
                                                                   dcerpc_auth_level(conn));
-               if (composite_nomem(auth_schannel_req, c)) return c;
-
                composite_continue(c, auth_schannel_req, continue_auth_schannel, c);
+               return c;
+       }
+
+       /*
+        * we rely on the already authenticated CIFS connection
+        * if not doing sign or seal
+        */
+       if (conn->transport.transport == NCACN_NP &&
+           !(s->binding->flags & (DCERPC_SIGN|DCERPC_SEAL))) {
+               auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe, s->table);
+               composite_continue(c, auth_none_req, continue_auth_none, c);
+               return c;
+       }
 
-       } else if (!cli_credentials_is_anonymous(s->credentials) &&
-                  !(conn->transport.transport == NCACN_NP &&
-                    !(s->binding->flags & DCERPC_SIGN) &&
-                    !(s->binding->flags & DCERPC_SEAL))) {
 
-               /* Perform an authenticated DCE-RPC bind, except where
-                * we ask for a connection on NCACN_NP, and that
-                * connection is not signed or sealed.  For that case
-                * we rely on the already authenticated CIFS connection
-                */
-               
-               uint8_t auth_type;
+       /* Perform an authenticated DCE-RPC bind
+        */
+       if (!(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) {
+               /*
+                 we are doing an authenticated connection,
+                 but not using sign or seal. We must force
+                 the CONNECT dcerpc auth type as a NONE auth
+                 type doesn't allow authentication
+                 information to be passed.
+               */
+               conn->flags |= DCERPC_CONNECT;
+       }
 
-               if ((conn->flags & (DCERPC_SIGN|DCERPC_SEAL)) == 0) {
-                       /*
-                         we are doing an authenticated connection,
-                         but not using sign or seal. We must force
-                         the CONNECT dcerpc auth type as a NONE auth
-                         type doesn't allow authentication
-                         information to be passed.
-                       */
-                       conn->flags |= DCERPC_CONNECT;
-               }
+       if (s->binding->flags & DCERPC_AUTH_SPNEGO) {
+               auth_type = DCERPC_AUTH_TYPE_SPNEGO;
 
-               if (s->binding->flags & DCERPC_AUTH_SPNEGO) {
-                       auth_type = DCERPC_AUTH_TYPE_SPNEGO;
+       } else if (s->binding->flags & DCERPC_AUTH_KRB5) {
+               auth_type = DCERPC_AUTH_TYPE_KRB5;
 
-               } else if (s->binding->flags & DCERPC_AUTH_KRB5) {
-                       auth_type = DCERPC_AUTH_TYPE_KRB5;
+       } else if (s->binding->flags & DCERPC_SCHANNEL) {
+               auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
 
-               } else if (s->binding->flags & DCERPC_SCHANNEL) {
-                       auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
+       } else if (s->binding->flags & DCERPC_AUTH_NTLM) {
+               auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
 
-               } else if (s->binding->flags & DCERPC_AUTH_NTLM) {
-                       auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
-               } else {
-                       auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
-                                                        s->credentials, DCERPC_AUTH_TYPE_SPNEGO,
-                                                        dcerpc_auth_level(conn),
-                                                        s->table->authservices->names[0]);
-                       if (composite_nomem(auth_req, c)) return c;
-                       
-                       composite_continue(c, auth_req, continue_auth_auto, c);
-                       return c;
-               }
-               
+       } else {
+               /* try SPNEGO with fallback to NTLMSSP */
                auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
-                                                s->credentials, auth_type,
+                                                s->credentials, DCERPC_AUTH_TYPE_SPNEGO,
                                                 dcerpc_auth_level(conn),
                                                 s->table->authservices->names[0]);
-               if (composite_nomem(auth_req, c)) return c;
-               
-               composite_continue(c, auth_req, continue_auth, c);
-
-       } else {
-               auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe, s->table);
-               if (composite_nomem(auth_none_req, c)) return c;
-
-               composite_continue(c, auth_none_req, continue_auth_none, c);
+               composite_continue(c, auth_req, continue_auth_auto, c);
+               return c;
        }
 
+       auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
+                                        s->credentials, auth_type,
+                                        dcerpc_auth_level(conn),
+                                        s->table->authservices->names[0]);
+       composite_continue(c, auth_req, continue_auth, c);
        return c;
 }
 
@@ -1290,7 +1317,7 @@ NTSTATUS dcerpc_pipe_auth_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
 NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx,
                          struct dcerpc_pipe **p, 
                          struct dcerpc_binding *binding,
-                         const struct dcerpc_interface_table *table,
+                         const struct ndr_interface_table *table,
                          struct cli_credentials *credentials)
 {
        struct composite_context *c;
@@ -1325,7 +1352,7 @@ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p,
 
   this triggers on a debug level of >= 10
 */
-void dcerpc_log_packet(const struct dcerpc_interface_table *ndr,
+void dcerpc_log_packet(const struct ndr_interface_table *ndr,
                       uint32_t opnum, uint32_t flags, DATA_BLOB *pkt)
 {
        const int num_examples = 20;
@@ -1336,7 +1363,7 @@ void dcerpc_log_packet(const struct dcerpc_interface_table *ndr,
        for (i=0;i<num_examples;i++) {
                char *name=NULL;
                asprintf(&name, "%s/rpclog/%s-%u.%d.%s", 
-                        lp_lockdir(), ndr->name, opnum, i,
+                        lp_lockdir(global_loadparm), ndr->name, opnum, i,
                         (flags&NDR_IN)?"in":"out");
                if (name == NULL) {
                        return;
@@ -1361,7 +1388,7 @@ void dcerpc_log_packet(const struct dcerpc_interface_table *ndr,
 */
 NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p, 
                                  struct dcerpc_pipe **pp2,
-                                 const struct dcerpc_interface_table *table)
+                                 const struct ndr_interface_table *table)
 {
        NTSTATUS status;
        struct dcerpc_pipe *p2;
@@ -1379,6 +1406,8 @@ NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p,
 
        p2->transfer_syntax = ndr_transfer_syntax;
 
+       p2->binding = talloc_reference(p2, p->binding);
+
        status = dcerpc_alter_context(p2, p2, &p2->syntax, &p2->transfer_syntax);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(p2);