Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/librpc/rpc/dcerpc.c

    r414 r745  
    3131#include "auth/gensec/gensec.h"
    3232#include "param/param.h"
     33#include "lib/util/tevent_ntstatus.h"
     34#include "librpc/rpc/rpc_common.h"
     35
     36enum rpc_request_state {
     37        RPC_REQUEST_QUEUED,
     38        RPC_REQUEST_PENDING,
     39        RPC_REQUEST_DONE
     40};
     41
     42/*
     43  handle for an async dcerpc request
     44*/
     45struct rpc_request {
     46        struct rpc_request *next, *prev;
     47        struct dcerpc_pipe *p;
     48        NTSTATUS status;
     49        uint32_t call_id;
     50        enum rpc_request_state state;
     51        DATA_BLOB payload;
     52        uint32_t flags;
     53        uint32_t fault_code;
     54
     55        /* this is used to distinguish bind and alter_context requests
     56           from normal requests */
     57        void (*recv_handler)(struct rpc_request *conn,
     58                             DATA_BLOB *blob, struct ncacn_packet *pkt);
     59
     60        const struct GUID *object;
     61        uint16_t opnum;
     62        DATA_BLOB request_data;
     63        bool ignore_timeout;
     64
     65        /* use by the ndr level async recv call */
     66        struct {
     67                const struct ndr_interface_table *table;
     68                uint32_t opnum;
     69                void *struct_ptr;
     70                TALLOC_CTX *mem_ctx;
     71        } ndr;
     72
     73        struct {
     74                void (*callback)(struct rpc_request *);
     75                void *private_data;
     76        } async;
     77};
    3378
    3479_PUBLIC_ NTSTATUS dcerpc_init(struct loadparm_context *lp_ctx)
     
    3782}
    3883
    39 static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status);
    40 static void dcerpc_ship_next_request(struct dcerpc_connection *c);
     84static void dcerpc_connection_dead(struct dcecli_connection *conn, NTSTATUS status);
     85static void dcerpc_ship_next_request(struct dcecli_connection *c);
     86
     87static struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
     88                                               const struct GUID *object,
     89                                               uint16_t opnum,
     90                                               DATA_BLOB *stub_data);
     91static NTSTATUS dcerpc_request_recv(struct rpc_request *req,
     92                                    TALLOC_CTX *mem_ctx,
     93                                    DATA_BLOB *stub_data);
     94static NTSTATUS dcerpc_ndr_validate_in(struct dcecli_connection *c,
     95                                       TALLOC_CTX *mem_ctx,
     96                                       DATA_BLOB blob,
     97                                       size_t struct_size,
     98                                       ndr_push_flags_fn_t ndr_push,
     99                                       ndr_pull_flags_fn_t ndr_pull);
     100static NTSTATUS dcerpc_ndr_validate_out(struct dcecli_connection *c,
     101                                        struct ndr_pull *pull_in,
     102                                        void *struct_ptr,
     103                                        size_t struct_size,
     104                                        ndr_push_flags_fn_t ndr_push,
     105                                        ndr_pull_flags_fn_t ndr_pull,
     106                                        ndr_print_function_t ndr_print);
    41107
    42108/* destroy a dcerpc connection */
    43 static int dcerpc_connection_destructor(struct dcerpc_connection *conn)
     109static int dcerpc_connection_destructor(struct dcecli_connection *conn)
    44110{
    45111        if (conn->dead) {
     
    55121   the event context is optional
    56122*/
    57 static struct dcerpc_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx,
    58                                                  struct tevent_context *ev,
    59                                                  struct smb_iconv_convenience *ic)
    60 {
    61         struct dcerpc_connection *c;
    62 
    63         c = talloc_zero(mem_ctx, struct dcerpc_connection);
     123static struct dcecli_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx,
     124                                                 struct tevent_context *ev)
     125{
     126        struct dcecli_connection *c;
     127
     128        c = talloc_zero(mem_ctx, struct dcecli_connection);
    64129        if (!c) {
    65130                return NULL;
    66131        }
    67 
    68         c->iconv_convenience = talloc_reference(c, ic);
    69132
    70133        c->event_ctx = ev;
     
    90153}
    91154
     155struct dcerpc_bh_state {
     156        struct dcerpc_pipe *p;
     157};
     158
     159static bool dcerpc_bh_is_connected(struct dcerpc_binding_handle *h)
     160{
     161        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     162                                     struct dcerpc_bh_state);
     163
     164        if (!hs->p) {
     165                return false;
     166        }
     167
     168        return true;
     169}
     170
     171static uint32_t dcerpc_bh_set_timeout(struct dcerpc_binding_handle *h,
     172                                      uint32_t timeout)
     173{
     174        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     175                                     struct dcerpc_bh_state);
     176        uint32_t old;
     177
     178        if (!hs->p) {
     179                return DCERPC_REQUEST_TIMEOUT;
     180        }
     181
     182        old = hs->p->request_timeout;
     183        hs->p->request_timeout = timeout;
     184
     185        return old;
     186}
     187
     188struct dcerpc_bh_raw_call_state {
     189        struct dcerpc_binding_handle *h;
     190        DATA_BLOB in_data;
     191        DATA_BLOB out_data;
     192        uint32_t out_flags;
     193};
     194
     195static void dcerpc_bh_raw_call_done(struct rpc_request *subreq);
     196
     197static struct tevent_req *dcerpc_bh_raw_call_send(TALLOC_CTX *mem_ctx,
     198                                                  struct tevent_context *ev,
     199                                                  struct dcerpc_binding_handle *h,
     200                                                  const struct GUID *object,
     201                                                  uint32_t opnum,
     202                                                  uint32_t in_flags,
     203                                                  const uint8_t *in_data,
     204                                                  size_t in_length)
     205{
     206        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     207                                     struct dcerpc_bh_state);
     208        struct tevent_req *req;
     209        struct dcerpc_bh_raw_call_state *state;
     210        bool ok;
     211        struct rpc_request *subreq;
     212
     213        req = tevent_req_create(mem_ctx, &state,
     214                                struct dcerpc_bh_raw_call_state);
     215        if (req == NULL) {
     216                return NULL;
     217        }
     218        state->h = h;
     219        state->in_data.data = discard_const_p(uint8_t, in_data);
     220        state->in_data.length = in_length;
     221
     222        ok = dcerpc_bh_is_connected(h);
     223        if (!ok) {
     224                tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     225                return tevent_req_post(req, ev);
     226        }
     227
     228        subreq = dcerpc_request_send(hs->p,
     229                                     object,
     230                                     opnum,
     231                                     &state->in_data);
     232        if (tevent_req_nomem(subreq, req)) {
     233                return tevent_req_post(req, ev);
     234        }
     235        subreq->async.callback = dcerpc_bh_raw_call_done;
     236        subreq->async.private_data = req;
     237
     238        return req;
     239}
     240
     241static void dcerpc_bh_raw_call_done(struct rpc_request *subreq)
     242{
     243        struct tevent_req *req =
     244                talloc_get_type_abort(subreq->async.private_data,
     245                struct tevent_req);
     246        struct dcerpc_bh_raw_call_state *state =
     247                tevent_req_data(req,
     248                struct dcerpc_bh_raw_call_state);
     249        NTSTATUS status;
     250        uint32_t fault_code;
     251
     252        state->out_flags = 0;
     253        if (subreq->flags & DCERPC_PULL_BIGENDIAN) {
     254                state->out_flags |= LIBNDR_FLAG_BIGENDIAN;
     255        }
     256
     257        fault_code = subreq->fault_code;
     258
     259        status = dcerpc_request_recv(subreq, state, &state->out_data);
     260        if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
     261                status = dcerpc_fault_to_nt_status(fault_code);
     262        }
     263        if (!NT_STATUS_IS_OK(status)) {
     264                tevent_req_nterror(req, status);
     265                return;
     266        }
     267
     268        tevent_req_done(req);
     269}
     270
     271static NTSTATUS dcerpc_bh_raw_call_recv(struct tevent_req *req,
     272                                        TALLOC_CTX *mem_ctx,
     273                                        uint8_t **out_data,
     274                                        size_t *out_length,
     275                                        uint32_t *out_flags)
     276{
     277        struct dcerpc_bh_raw_call_state *state =
     278                tevent_req_data(req,
     279                struct dcerpc_bh_raw_call_state);
     280        NTSTATUS status;
     281
     282        if (tevent_req_is_nterror(req, &status)) {
     283                tevent_req_received(req);
     284                return status;
     285        }
     286
     287        *out_data = talloc_move(mem_ctx, &state->out_data.data);
     288        *out_length = state->out_data.length;
     289        *out_flags = state->out_flags;
     290        tevent_req_received(req);
     291        return NT_STATUS_OK;
     292}
     293
     294struct dcerpc_bh_disconnect_state {
     295        uint8_t _dummy;
     296};
     297
     298static struct tevent_req *dcerpc_bh_disconnect_send(TALLOC_CTX *mem_ctx,
     299                                                struct tevent_context *ev,
     300                                                struct dcerpc_binding_handle *h)
     301{
     302        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     303                                     struct dcerpc_bh_state);
     304        struct tevent_req *req;
     305        struct dcerpc_bh_disconnect_state *state;
     306        bool ok;
     307
     308        req = tevent_req_create(mem_ctx, &state,
     309                                struct dcerpc_bh_disconnect_state);
     310        if (req == NULL) {
     311                return NULL;
     312        }
     313
     314        ok = dcerpc_bh_is_connected(h);
     315        if (!ok) {
     316                tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     317                return tevent_req_post(req, ev);
     318        }
     319
     320        /* TODO: do a real disconnect ... */
     321        hs->p = NULL;
     322
     323        tevent_req_done(req);
     324        return tevent_req_post(req, ev);
     325}
     326
     327static NTSTATUS dcerpc_bh_disconnect_recv(struct tevent_req *req)
     328{
     329        NTSTATUS status;
     330
     331        if (tevent_req_is_nterror(req, &status)) {
     332                tevent_req_received(req);
     333                return status;
     334        }
     335
     336        tevent_req_received(req);
     337        return NT_STATUS_OK;
     338}
     339
     340static bool dcerpc_bh_push_bigendian(struct dcerpc_binding_handle *h)
     341{
     342        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     343                                     struct dcerpc_bh_state);
     344
     345        if (hs->p->conn->flags & DCERPC_PUSH_BIGENDIAN) {
     346                return true;
     347        }
     348
     349        return false;
     350}
     351
     352static bool dcerpc_bh_ref_alloc(struct dcerpc_binding_handle *h)
     353{
     354        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     355                                     struct dcerpc_bh_state);
     356
     357        if (hs->p->conn->flags & DCERPC_NDR_REF_ALLOC) {
     358                return true;
     359        }
     360
     361        return false;
     362}
     363
     364static bool dcerpc_bh_use_ndr64(struct dcerpc_binding_handle *h)
     365{
     366        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     367                                     struct dcerpc_bh_state);
     368
     369        if (hs->p->conn->flags & DCERPC_NDR64) {
     370                return true;
     371        }
     372
     373        return false;
     374}
     375
     376static void dcerpc_bh_do_ndr_print(struct dcerpc_binding_handle *h,
     377                                   int ndr_flags,
     378                                   const void *_struct_ptr,
     379                                   const struct ndr_interface_call *call)
     380{
     381        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     382                                     struct dcerpc_bh_state);
     383        void *struct_ptr = discard_const(_struct_ptr);
     384
     385        if (ndr_flags & NDR_IN) {
     386                if (hs->p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
     387                        ndr_print_function_debug(call->ndr_print,
     388                                                 call->name,
     389                                                 ndr_flags,
     390                                                 struct_ptr);
     391                }
     392        }
     393        if (ndr_flags & NDR_OUT) {
     394                if (hs->p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
     395                        ndr_print_function_debug(call->ndr_print,
     396                                                 call->name,
     397                                                 ndr_flags,
     398                                                 struct_ptr);
     399                }
     400        }
     401}
     402
     403static void dcerpc_bh_ndr_push_failed(struct dcerpc_binding_handle *h,
     404                                      NTSTATUS error,
     405                                      const void *struct_ptr,
     406                                      const struct ndr_interface_call *call)
     407{
     408        DEBUG(2,("Unable to ndr_push structure for %s - %s\n",
     409                 call->name, nt_errstr(error)));
     410}
     411
     412static void dcerpc_bh_ndr_pull_failed(struct dcerpc_binding_handle *h,
     413                                      NTSTATUS error,
     414                                      const DATA_BLOB *blob,
     415                                      const struct ndr_interface_call *call)
     416{
     417        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     418                                     struct dcerpc_bh_state);
     419        const uint32_t num_examples = 20;
     420        uint32_t i;
     421
     422        DEBUG(2,("Unable to ndr_pull structure for %s - %s\n",
     423                 call->name, nt_errstr(error)));
     424
     425        if (hs->p->conn->packet_log_dir == NULL) return;
     426
     427        for (i=0;i<num_examples;i++) {
     428                char *name=NULL;
     429                asprintf(&name, "%s/rpclog/%s-out.%d",
     430                         hs->p->conn->packet_log_dir,
     431                         call->name, i);
     432                if (name == NULL) {
     433                        return;
     434                }
     435                if (!file_exist(name)) {
     436                        if (file_save(name, blob->data, blob->length)) {
     437                                DEBUG(10,("Logged rpc packet to %s\n", name));
     438                        }
     439                        free(name);
     440                        break;
     441                }
     442                free(name);
     443        }
     444}
     445
     446static NTSTATUS dcerpc_bh_ndr_validate_in(struct dcerpc_binding_handle *h,
     447                                          TALLOC_CTX *mem_ctx,
     448                                          const DATA_BLOB *blob,
     449                                          const struct ndr_interface_call *call)
     450{
     451        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     452                                     struct dcerpc_bh_state);
     453
     454        if (hs->p->conn->flags & DCERPC_DEBUG_VALIDATE_IN) {
     455                NTSTATUS status;
     456
     457                status = dcerpc_ndr_validate_in(hs->p->conn,
     458                                                mem_ctx,
     459                                                *blob,
     460                                                call->struct_size,
     461                                                call->ndr_push,
     462                                                call->ndr_pull);
     463                if (!NT_STATUS_IS_OK(status)) {
     464                        DEBUG(0,("Validation [in] failed for %s - %s\n",
     465                                 call->name, nt_errstr(status)));
     466                        return status;
     467                }
     468        }
     469
     470        DEBUG(10,("rpc request data:\n"));
     471        dump_data(10, blob->data, blob->length);
     472
     473        return NT_STATUS_OK;
     474}
     475
     476static NTSTATUS dcerpc_bh_ndr_validate_out(struct dcerpc_binding_handle *h,
     477                                           struct ndr_pull *pull_in,
     478                                           const void *_struct_ptr,
     479                                           const struct ndr_interface_call *call)
     480{
     481        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     482                                     struct dcerpc_bh_state);
     483        void *struct_ptr = discard_const(_struct_ptr);
     484
     485        DEBUG(10,("rpc reply data:\n"));
     486        dump_data(10, pull_in->data, pull_in->data_size);
     487
     488        if (pull_in->offset != pull_in->data_size) {
     489                DEBUG(0,("Warning! ignoring %u unread bytes at ofs:%u (0x%08X) for %s!\n",
     490                         pull_in->data_size - pull_in->offset,
     491                         pull_in->offset, pull_in->offset,
     492                         call->name));
     493                /* we used to return NT_STATUS_INFO_LENGTH_MISMATCH here,
     494                   but it turns out that early versions of NT
     495                   (specifically NT3.1) add junk onto the end of rpc
     496                   packets, so if we want to interoperate at all with
     497                   those versions then we need to ignore this error */
     498        }
     499
     500        if (hs->p->conn->flags & DCERPC_DEBUG_VALIDATE_OUT) {
     501                NTSTATUS status;
     502
     503                status = dcerpc_ndr_validate_out(hs->p->conn,
     504                                                 pull_in,
     505                                                 struct_ptr,
     506                                                 call->struct_size,
     507                                                 call->ndr_push,
     508                                                 call->ndr_pull,
     509                                                 call->ndr_print);
     510                if (!NT_STATUS_IS_OK(status)) {
     511                        DEBUG(2,("Validation [out] failed for %s - %s\n",
     512                                 call->name, nt_errstr(status)));
     513                        return status;
     514                }
     515        }
     516
     517        return NT_STATUS_OK;
     518}
     519
     520static const struct dcerpc_binding_handle_ops dcerpc_bh_ops = {
     521        .name                   = "dcerpc",
     522        .is_connected           = dcerpc_bh_is_connected,
     523        .set_timeout            = dcerpc_bh_set_timeout,
     524        .raw_call_send          = dcerpc_bh_raw_call_send,
     525        .raw_call_recv          = dcerpc_bh_raw_call_recv,
     526        .disconnect_send        = dcerpc_bh_disconnect_send,
     527        .disconnect_recv        = dcerpc_bh_disconnect_recv,
     528
     529        .push_bigendian         = dcerpc_bh_push_bigendian,
     530        .ref_alloc              = dcerpc_bh_ref_alloc,
     531        .use_ndr64              = dcerpc_bh_use_ndr64,
     532        .do_ndr_print           = dcerpc_bh_do_ndr_print,
     533        .ndr_push_failed        = dcerpc_bh_ndr_push_failed,
     534        .ndr_pull_failed        = dcerpc_bh_ndr_pull_failed,
     535        .ndr_validate_in        = dcerpc_bh_ndr_validate_in,
     536        .ndr_validate_out       = dcerpc_bh_ndr_validate_out,
     537};
     538
    92539/* initialise a dcerpc pipe. */
    93 _PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
    94                                      struct smb_iconv_convenience *ic)
     540struct dcerpc_binding_handle *dcerpc_pipe_binding_handle(struct dcerpc_pipe *p)
     541{
     542        struct dcerpc_binding_handle *h;
     543        struct dcerpc_bh_state *hs;
     544
     545        h = dcerpc_binding_handle_create(p,
     546                                         &dcerpc_bh_ops,
     547                                         NULL,
     548                                         NULL, /* TODO */
     549                                         &hs,
     550                                         struct dcerpc_bh_state,
     551                                         __location__);
     552        if (h == NULL) {
     553                return NULL;
     554        }
     555        hs->p = p;
     556
     557        dcerpc_binding_handle_set_sync_ev(h, p->conn->event_ctx);
     558
     559        return h;
     560}
     561
     562/* initialise a dcerpc pipe. */
     563_PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev)
    95564{
    96565        struct dcerpc_pipe *p;
    97566
    98         p = talloc(mem_ctx, struct dcerpc_pipe);
     567        p = talloc_zero(mem_ctx, struct dcerpc_pipe);
    99568        if (!p) {
    100569                return NULL;
    101570        }
    102571
    103         p->conn = dcerpc_connection_init(p, ev, ic);
     572        p->conn = dcerpc_connection_init(p, ev);
    104573        if (p->conn == NULL) {
    105574                talloc_free(p);
     
    119588        }
    120589
     590        p->binding_handle = dcerpc_pipe_binding_handle(p);
     591        if (p->binding_handle == NULL) {
     592                talloc_free(p);
     593                return NULL;
     594        }
     595
    121596        return p;
    122597}
     
    126601   choose the next call id to use
    127602*/
    128 static uint32_t next_call_id(struct dcerpc_connection *c)
     603static uint32_t next_call_id(struct dcecli_connection *c)
    129604{
    130605        c->call_id++;
     
    135610}
    136611
    137 /* we need to be able to get/set the fragment length without doing a full
    138    decode */
    139 void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v)
    140 {
    141         if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
    142                 SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
    143         } else {
    144                 RSSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
    145         }
    146 }
    147 
    148 uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob)
    149 {
    150         if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
    151                 return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
    152         } else {
    153                 return RSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
    154         }
    155 }
    156 
    157 void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v)
    158 {
    159         if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
    160                 SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
    161         } else {
    162                 RSSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
    163         }
    164 }
    165 
    166 
    167612/**
    168613  setup for a ndr pull, also setting up any flags from the binding string
    169614*/
    170 static struct ndr_pull *ndr_pull_init_flags(struct dcerpc_connection *c,
     615static struct ndr_pull *ndr_pull_init_flags(struct dcecli_connection *c,
    171616                                            DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
    172617{
    173         struct ndr_pull *ndr = ndr_pull_init_blob(blob, mem_ctx, c->iconv_convenience);
     618        struct ndr_pull *ndr = ndr_pull_init_blob(blob, mem_ctx);
    174619
    175620        if (ndr == NULL) return ndr;
     
    194639   input and output packets
    195640*/
    196 static NTSTATUS ncacn_pull(struct dcerpc_connection *c, DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
     641static NTSTATUS ncacn_pull(struct dcecli_connection *c, DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
    197642                            struct ncacn_packet *pkt)
    198643{
     
    220665   parse the authentication information on a dcerpc response packet
    221666*/
    222 static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX *mem_ctx,
     667static NTSTATUS ncacn_pull_request_auth(struct dcecli_connection *c, TALLOC_CTX *mem_ctx,
    223668                                        DATA_BLOB *raw_packet,
    224669                                        struct ncacn_packet *pkt)
    225670{
    226         struct ndr_pull *ndr;
    227671        NTSTATUS status;
    228672        struct dcerpc_auth auth;
    229         DATA_BLOB auth_blob;
    230         enum ndr_err_code ndr_err;
     673        uint32_t auth_length;
    231674
    232675        if (!c->security_state.auth_info ||
     
    255698        }
    256699
    257         auth_blob.length = 8 + pkt->auth_length;
    258 
    259         /* check for a valid length */
    260         if (pkt->u.response.stub_and_verifier.length < auth_blob.length) {
    261                 return NT_STATUS_INFO_LENGTH_MISMATCH;
    262         }
    263 
    264         auth_blob.data =
    265                 pkt->u.response.stub_and_verifier.data +
    266                 pkt->u.response.stub_and_verifier.length - auth_blob.length;
    267         pkt->u.response.stub_and_verifier.length -= auth_blob.length;
    268 
    269         /* pull the auth structure */
    270         ndr = ndr_pull_init_flags(c, &auth_blob, mem_ctx);
    271         if (!ndr) {
    272                 return NT_STATUS_NO_MEMORY;
    273         }
    274 
    275         if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
    276                 ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
    277         }
    278 
    279         ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
    280         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    281                 return ndr_map_error2ntstatus(ndr_err);
    282         }
    283         status = NT_STATUS_OK;
     700        status = dcerpc_pull_auth_trailer(pkt, mem_ctx,
     701                                          &pkt->u.response.stub_and_verifier,
     702                                          &auth, &auth_length, false);
     703        NT_STATUS_NOT_OK_RETURN(status);
     704
     705        pkt->u.response.stub_and_verifier.length -= auth_length;
    284706
    285707        /* check signature or unseal the packet */
     
    318740        }
    319741       
    320         /* remove the indicated amount of paddiing */
     742        /* remove the indicated amount of padding */
    321743        if (pkt->u.response.stub_and_verifier.length < auth.auth_pad_length) {
    322744                return NT_STATUS_INFO_LENGTH_MISMATCH;
     
    331753   push a dcerpc request packet into a blob, possibly signing it.
    332754*/
    333 static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
     755static NTSTATUS ncacn_push_request_sign(struct dcecli_connection *c,
    334756                                         DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
    335757                                         size_t sig_size,
     
    345767        /* non-signed packets are simpler */
    346768        if (sig_size == 0) {
    347                 return ncacn_push_auth(blob, mem_ctx, c->iconv_convenience, pkt, NULL);
     769                return ncacn_push_auth(blob, mem_ctx, pkt, NULL);
    348770        }
    349771
     
    355777        case DCERPC_AUTH_LEVEL_CONNECT:
    356778                /* TODO: let the gensec mech decide if it wants to generate a signature */
    357                 return ncacn_push_auth(blob, mem_ctx, c->iconv_convenience, pkt, NULL);
     779                return ncacn_push_auth(blob, mem_ctx, pkt, NULL);
    358780
    359781        case DCERPC_AUTH_LEVEL_NONE:
    360                 return ncacn_push_auth(blob, mem_ctx, c->iconv_convenience, pkt, NULL);
     782                return ncacn_push_auth(blob, mem_ctx, pkt, NULL);
    361783
    362784        default:
     
    364786        }
    365787
    366         ndr = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
     788        ndr = ndr_push_init_ctx(mem_ctx);
    367789        if (!ndr) {
    368790                return NT_STATUS_NO_MEMORY;
     
    386808                return ndr_map_error2ntstatus(ndr_err);
    387809        }
    388         status = NT_STATUS_OK;
    389810
    390811        /* pad to 16 byte multiple in the payload portion of the
    391            packet. This matches what w2k3 does */
    392         c->security_state.auth_info->auth_pad_length =
     812           packet. This matches what w2k3 does. Note that we can't use
     813           ndr_push_align() as that is relative to the start of the
     814           whole packet, whereas w2k8 wants it relative to the start
     815           of the stub */
     816        c->security_state.auth_info->auth_pad_length =
    393817                (16 - (pkt->u.request.stub_and_verifier.length & 15)) & 15;
    394818        ndr_err = ndr_push_zero(ndr, c->security_state.auth_info->auth_pad_length);
     
    396820                return ndr_map_error2ntstatus(ndr_err);
    397821        }
    398         status = NT_STATUS_OK;
    399822
    400823        payload_length = pkt->u.request.stub_and_verifier.length +
     
    409832                return ndr_map_error2ntstatus(ndr_err);
    410833        }
    411         status = NT_STATUS_OK;
    412834
    413835        /* extract the whole packet as a blob */
     
    457879
    458880        if (creds2.length != sig_size) {
    459                 DEBUG(0,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n",
    460                         creds2.length, (uint32_t)sig_size,
    461                         c->security_state.auth_info->auth_pad_length,
    462                         pkt->u.request.stub_and_verifier.length));
    463                 return NT_STATUS_INTERNAL_ERROR;
     881                /* this means the sig_size estimate for the signature
     882                   was incorrect. We have to correct the packet
     883                   sizes. That means we could go over the max fragment
     884                   length */
     885                DEBUG(3,("ncacn_push_request_sign: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n",
     886                        (unsigned) creds2.length,
     887                        (unsigned) sig_size,
     888                        (unsigned) c->security_state.auth_info->auth_pad_length,
     889                        (unsigned) pkt->u.request.stub_and_verifier.length));
     890                dcerpc_set_frag_length(blob, blob->length + creds2.length);
     891                dcerpc_set_auth_length(blob, creds2.length);
    464892        }
    465893
     
    475903   fill in the fixed values in a dcerpc header
    476904*/
    477 static void init_ncacn_hdr(struct dcerpc_connection *c, struct ncacn_packet *pkt)
     905static void init_ncacn_hdr(struct dcecli_connection *c, struct ncacn_packet *pkt)
    478906{
    479907        pkt->rpc_vers = 5;
     
    535963  mark the dcerpc connection dead. All outstanding requests get an error
    536964*/
    537 static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status)
     965static void dcerpc_connection_dead(struct dcecli_connection *conn, NTSTATUS status)
    538966{
    539967        if (conn->dead) return;
     
    566994  packets we need to handle
    567995*/
    568 static void dcerpc_request_recv_data(struct dcerpc_connection *c,
     996static void dcerpc_request_recv_data(struct dcecli_connection *c,
    569997                                     DATA_BLOB *raw_packet, struct ncacn_packet *pkt);
    570998
     
    5741002  dispatch to the appropriate handler
    5751003*/
    576 static void dcerpc_recv_data(struct dcerpc_connection *conn, DATA_BLOB *blob, NTSTATUS status)
     1004static void dcerpc_recv_data(struct dcecli_connection *conn, DATA_BLOB *blob, NTSTATUS status)
    5771005{
    5781006        struct ncacn_packet pkt;
     
    6001028}
    6011029
    602 
    6031030/*
    6041031  Receive a bind reply from the transport
     
    6081035{
    6091036        struct composite_context *c;
    610         struct dcerpc_connection *conn;
     1037        struct dcecli_connection *conn;
    6111038
    6121039        c = talloc_get_type(req->async.private_data, struct composite_context);
     
    6231050            (pkt->u.bind_ack.num_results == 0) ||
    6241051            (pkt->u.bind_ack.ctx_list[0].result != 0)) {
     1052                req->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
    6251053                composite_error(c, NT_STATUS_NET_WRITE_FAULT);
    6261054                return;
     
    6431071
    6441072        /* the bind_ack might contain a reply set of credentials */
    645         if (conn->security_state.auth_info &&
    646             pkt->u.bind_ack.auth_info.length) {
    647                 enum ndr_err_code ndr_err;
    648                 ndr_err = ndr_pull_struct_blob(
    649                         &pkt->u.bind_ack.auth_info, conn,
    650                         NULL,
    651                         conn->security_state.auth_info,
    652                         (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
    653                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    654                         c->status = ndr_map_error2ntstatus(ndr_err);
    655                         if (!composite_is_ok(c)) return;
     1073        if (conn->security_state.auth_info && pkt->u.bind_ack.auth_info.length) {
     1074                NTSTATUS status;
     1075                uint32_t auth_length;
     1076                status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.bind_ack.auth_info,
     1077                                                  conn->security_state.auth_info, &auth_length, true);
     1078                if (!NT_STATUS_IS_OK(status)) {
     1079                        composite_error(c, status);
     1080                        return;
    6561081                }
    6571082        }
     
    7321157
    7331158        /* construct the NDR form of the packet */
    734         c->status = ncacn_push_auth(&blob, c, p->conn->iconv_convenience, &pkt,
     1159        c->status = ncacn_push_auth(&blob, c, &pkt,
    7351160                                    p->conn->security_state.auth_info);
    7361161        if (!composite_is_ok(c)) return c;
     
    7911216        pkt.call_id = next_call_id(p->conn);
    7921217        pkt.auth_length = 0;
    793         pkt.u.auth3._pad = 0;
    7941218        pkt.u.auth3.auth_info = data_blob(NULL, 0);
    7951219
     
    8041228        /* construct the NDR form of the packet */
    8051229        status = ncacn_push_auth(&blob, mem_ctx,
    806                                  p->conn->iconv_convenience,
    8071230                                 &pkt,
    8081231                                 p->conn->security_state.auth_info);
     
    8271250  This function frees the data
    8281251*/
    829 static void dcerpc_request_recv_data(struct dcerpc_connection *c,
     1252static void dcerpc_request_recv_data(struct dcecli_connection *c,
    8301253                                     DATA_BLOB *raw_packet, struct ncacn_packet *pkt)
    8311254{
    8321255        struct rpc_request *req;
    833         uint_t length;
     1256        unsigned int length;
    8341257        NTSTATUS status = NT_STATUS_OK;
    8351258
     
    9471370                                               const struct GUID *object,
    9481371                                               uint16_t opnum,
    949                                                bool async,
    9501372                                               DATA_BLOB *stub_data)
    9511373{
     
    9661388        req->flags = 0;
    9671389        req->fault_code = 0;
    968         req->async_call = async;
    9691390        req->ignore_timeout = false;
    9701391        req->async.callback = NULL;
     
    10071428*/
    10081429
    1009 static void dcerpc_ship_next_request(struct dcerpc_connection *c)
     1430static void dcerpc_ship_next_request(struct dcecli_connection *c)
    10101431{
    10111432        struct rpc_request *req;
     
    10171438        bool first_packet = true;
    10181439        size_t sig_size = 0;
     1440        bool need_async = false;
    10191441
    10201442        req = c->request_queue;
     
    10261448        stub_data = &req->request_data;
    10271449
    1028         if (!req->async_call && (c->pending != NULL)) {
    1029                 return;
     1450        if (c->pending) {
     1451                need_async = true;
    10301452        }
    10311453
     
    10641486                pkt.u.request.object.object = *req->object;
    10651487                pkt.pfc_flags |= DCERPC_PFC_FLAG_OBJECT_UUID;
    1066                 chunk_size -= ndr_size_GUID(req->object,NULL,0);
     1488                chunk_size -= ndr_size_GUID(req->object,0);
    10671489        }
    10681490
     
    10951517                }
    10961518
    1097                 if (last_frag && !req->async_call) {
     1519                if (last_frag && !need_async) {
    10981520                        do_trans = true;
    10991521                }
     
    11331555  perform the receive side of a async dcerpc request
    11341556*/
    1135 NTSTATUS dcerpc_request_recv(struct rpc_request *req,
    1136                              TALLOC_CTX *mem_ctx,
    1137                              DATA_BLOB *stub_data)
     1557static NTSTATUS dcerpc_request_recv(struct rpc_request *req,
     1558                                    TALLOC_CTX *mem_ctx,
     1559                                    DATA_BLOB *stub_data)
    11381560{
    11391561        NTSTATUS status;
     
    11581580
    11591581/*
    1160   perform a full request/response pair on a dcerpc pipe
    1161 */
    1162 NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
    1163                         struct GUID *object,
    1164                         uint16_t opnum,
    1165                         TALLOC_CTX *mem_ctx,
    1166                         DATA_BLOB *stub_data_in,
    1167                         DATA_BLOB *stub_data_out)
    1168 {
    1169         struct rpc_request *req;
    1170 
    1171         req = dcerpc_request_send(p, object, opnum, false, stub_data_in);
    1172         if (req == NULL) {
    1173                 return NT_STATUS_NO_MEMORY;
    1174         }
    1175 
    1176         return dcerpc_request_recv(req, mem_ctx, stub_data_out);
    1177 }
    1178 
    1179 
    1180 /*
    11811582  this is a paranoid NDR validator. For every packet we push onto the wire
    11821583  we pull it back again, then push it again. Then we compare the raw NDR data
     
    11841585  we must have a bug in either the pull or push side of our code
    11851586*/
    1186 static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c,
     1587static NTSTATUS dcerpc_ndr_validate_in(struct dcecli_connection *c,
    11871588                                       TALLOC_CTX *mem_ctx,
    11881589                                       DATA_BLOB blob,
     
    12071608        }
    12081609        pull->flags |= LIBNDR_FLAG_REF_ALLOC;
     1610
     1611        if (c->flags & DCERPC_PUSH_BIGENDIAN) {
     1612                pull->flags |= LIBNDR_FLAG_BIGENDIAN;
     1613        }
     1614
     1615        if (c->flags & DCERPC_NDR64) {
     1616                pull->flags |= LIBNDR_FLAG_NDR64;
     1617        }
    12091618
    12101619        ndr_err = ndr_pull(pull, NDR_IN, st);
     
    12171626        }
    12181627
    1219         push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
     1628        push = ndr_push_init_ctx(mem_ctx);
    12201629        if (!push) {
    12211630                return NT_STATUS_NO_MEMORY;
    12221631        }       
     1632
     1633        if (c->flags & DCERPC_PUSH_BIGENDIAN) {
     1634                push->flags |= LIBNDR_FLAG_BIGENDIAN;
     1635        }
     1636
     1637        if (c->flags & DCERPC_NDR64) {
     1638                push->flags |= LIBNDR_FLAG_NDR64;
     1639        }
    12231640
    12241641        ndr_err = ndr_push(push, NDR_IN, st);
     
    12531670  bug in either the pull or push side of our code
    12541671*/
    1255 static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
     1672static NTSTATUS dcerpc_ndr_validate_out(struct dcecli_connection *c,
    12561673                                        struct ndr_pull *pull_in,
    12571674                                        void *struct_ptr,
     
    12751692        memcpy(st, struct_ptr, struct_size);
    12761693
    1277         push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
     1694        push = ndr_push_init_ctx(mem_ctx);
    12781695        if (!push) {
    12791696                return NT_STATUS_NO_MEMORY;
     
    13061723        }
    13071724
    1308         push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
     1725        push = ndr_push_init_ctx(mem_ctx);
    13091726        if (!push) {
    13101727                return NT_STATUS_NO_MEMORY;
     
    13561773}
    13571774
    1358 
    1359 /**
    1360  send a rpc request given a dcerpc_call structure
    1361  */
    1362 struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
    1363                                             const struct GUID *object,
    1364                                             const struct ndr_interface_table *table,
    1365                                             uint32_t opnum,
    1366                                             bool async,
    1367                                             TALLOC_CTX *mem_ctx,
    1368                                             void *r)
    1369 {
    1370         const struct ndr_interface_call *call;
    1371         struct ndr_push *push;
    1372         NTSTATUS status;
    1373         DATA_BLOB request;
    1374         struct rpc_request *req;
    1375         enum ndr_err_code ndr_err;
    1376 
    1377         call = &table->calls[opnum];
    1378 
    1379         /* setup for a ndr_push_* call */
    1380         push = ndr_push_init_ctx(mem_ctx, p->conn->iconv_convenience);
    1381         if (!push) {
    1382                 return NULL;
    1383         }
    1384 
    1385         if (p->conn->flags & DCERPC_PUSH_BIGENDIAN) {
    1386                 push->flags |= LIBNDR_FLAG_BIGENDIAN;
    1387         }
    1388 
    1389         if (p->conn->flags & DCERPC_NDR64) {
    1390                 push->flags |= LIBNDR_FLAG_NDR64;
    1391         }
    1392 
    1393         /* push the structure into a blob */
    1394         ndr_err = call->ndr_push(push, NDR_IN, r);
    1395         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1396                 status = ndr_map_error2ntstatus(ndr_err);
    1397                 DEBUG(2,("Unable to ndr_push structure in dcerpc_ndr_request_send - %s\n",
    1398                          nt_errstr(status)));
    1399                 talloc_free(push);
    1400                 return NULL;
    1401         }
    1402 
    1403         /* retrieve the blob */
    1404         request = ndr_push_blob(push);
    1405 
    1406         if (p->conn->flags & DCERPC_DEBUG_VALIDATE_IN) {
    1407                 status = dcerpc_ndr_validate_in(p->conn, push, request, call->struct_size,
    1408                                                 call->ndr_push, call->ndr_pull);
    1409                 if (!NT_STATUS_IS_OK(status)) {
    1410                         DEBUG(2,("Validation failed in dcerpc_ndr_request_send - %s\n",
    1411                                  nt_errstr(status)));
    1412                         talloc_free(push);
    1413                         return NULL;
    1414                 }
    1415         }
    1416 
    1417         DEBUG(10,("rpc request data:\n"));
    1418         dump_data(10, request.data, request.length);
    1419 
    1420         /* make the actual dcerpc request */
    1421         req = dcerpc_request_send(p, object, opnum, async, &request);
    1422 
    1423         if (req != NULL) {
    1424                 req->ndr.table = table;
    1425                 req->ndr.opnum = opnum;
    1426                 req->ndr.struct_ptr = r;
    1427                 req->ndr.mem_ctx = mem_ctx;
    1428         }
    1429 
    1430         talloc_free(push);
    1431 
    1432         return req;
    1433 }
    1434 
    1435 /*
    1436   receive the answer from a dcerpc_ndr_request_send()
    1437 */
    1438 _PUBLIC_ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
    1439 {
    1440         struct dcerpc_pipe *p = req->p;
    1441         NTSTATUS status;
    1442         DATA_BLOB response;
    1443         struct ndr_pull *pull;
    1444         uint_t flags;
    1445         TALLOC_CTX *mem_ctx = req->ndr.mem_ctx;
    1446         void *r = req->ndr.struct_ptr;
    1447         uint32_t opnum = req->ndr.opnum;
    1448         const struct ndr_interface_table *table = req->ndr.table;
    1449         const struct ndr_interface_call *call = &table->calls[opnum];
    1450         enum ndr_err_code ndr_err;
    1451 
    1452         /* make sure the recv code doesn't free the request, as we
    1453            need to grab the flags element before it is freed */
    1454         if (talloc_reference(p, req) == NULL) {
    1455                 return NT_STATUS_NO_MEMORY;
    1456         }
    1457 
    1458         status = dcerpc_request_recv(req, mem_ctx, &response);
    1459         if (!NT_STATUS_IS_OK(status)) {
    1460                 talloc_unlink(p, req);
    1461                 return status;
    1462         }
    1463 
    1464         flags = req->flags;
    1465 
    1466         /* prepare for ndr_pull_* */
    1467         pull = ndr_pull_init_flags(p->conn, &response, mem_ctx);
    1468         if (!pull) {
    1469                 talloc_unlink(p, req);
    1470                 return NT_STATUS_NO_MEMORY;
    1471         }
    1472 
    1473         if (pull->data) {
    1474                 pull->data = talloc_steal(pull, pull->data);
    1475         }
    1476         talloc_unlink(p, req);
    1477 
    1478         if (flags & DCERPC_PULL_BIGENDIAN) {
    1479                 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
    1480         }
    1481 
    1482         DEBUG(10,("rpc reply data:\n"));
    1483         dump_data(10, pull->data, pull->data_size);
    1484 
    1485         /* pull the structure from the blob */
    1486         ndr_err = call->ndr_pull(pull, NDR_OUT, r);
    1487         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1488                 status = ndr_map_error2ntstatus(ndr_err);
    1489                 dcerpc_log_packet(p->conn->packet_log_dir,
    1490                                                   table, opnum, NDR_OUT,
    1491                                                   &response);
    1492                 return status;
    1493         }
    1494 
    1495         if (p->conn->flags & DCERPC_DEBUG_VALIDATE_OUT) {
    1496                 status = dcerpc_ndr_validate_out(p->conn, pull, r, call->struct_size,
    1497                                                  call->ndr_push, call->ndr_pull,
    1498                                                  call->ndr_print);
    1499                 if (!NT_STATUS_IS_OK(status)) {
    1500                         dcerpc_log_packet(p->conn->packet_log_dir,
    1501                                                           table, opnum, NDR_OUT,
    1502                                   &response);
    1503                         return status;
    1504                 }
    1505         }
    1506 
    1507         if (pull->offset != pull->data_size) {
    1508                 DEBUG(0,("Warning! ignoring %d unread bytes in rpc packet!\n",
    1509                          pull->data_size - pull->offset));
    1510                 /* we used to return NT_STATUS_INFO_LENGTH_MISMATCH here,
    1511                    but it turns out that early versions of NT
    1512                    (specifically NT3.1) add junk onto the end of rpc
    1513                    packets, so if we want to interoperate at all with
    1514                    those versions then we need to ignore this error */
    1515         }
    1516 
    1517         /* TODO: make pull context independent from the output mem_ctx and free the pull context */
    1518 
    1519         return NT_STATUS_OK;
    1520 }
    1521 
    1522 
    1523 /*
    1524   a useful helper function for synchronous rpc requests
    1525 
    1526   this can be used when you have ndr push/pull functions in the
    1527   standard format
    1528 */
    1529 _PUBLIC_ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
    1530                             const struct GUID *object,
    1531                             const struct ndr_interface_table *table,
    1532                             uint32_t opnum,
    1533                             TALLOC_CTX *mem_ctx,
    1534                             void *r)
    1535 {
    1536         struct rpc_request *req;
    1537 
    1538         req = dcerpc_ndr_request_send(p, object, table, opnum, false, mem_ctx, r);
    1539         if (req == NULL) {
    1540                 return NT_STATUS_NO_MEMORY;
    1541         }
    1542 
    1543         return dcerpc_ndr_request_recv(req);
    1544 }
    1545 
    1546 
    15471775/*
    15481776  a useful function for retrieving the server name we connected to
     
    15631791  get the dcerpc auth_level for a open connection
    15641792*/
    1565 uint32_t dcerpc_auth_level(struct dcerpc_connection *c)
     1793uint32_t dcerpc_auth_level(struct dcecli_connection *c)
    15661794{
    15671795        uint8_t auth_level;
     
    16001828        }
    16011829
     1830        if (pkt->ptype == DCERPC_PKT_FAULT) {
     1831                DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt->u.fault.status)));
     1832                recv_pipe->last_fault_code = pkt->u.fault.status;
     1833                composite_error(c, NT_STATUS_NET_WRITE_FAULT);
     1834                return;
     1835        }
     1836
    16021837        if (pkt->ptype != DCERPC_PKT_ALTER_RESP ||
    16031838            pkt->u.alter_resp.num_results == 0 ||
    16041839            pkt->u.alter_resp.ctx_list[0].result != 0) {
     1840                recv_pipe->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
    16051841                composite_error(c, NT_STATUS_NET_WRITE_FAULT);
    16061842                return;
     
    16101846        if (recv_pipe->conn->security_state.auth_info &&
    16111847            pkt->u.alter_resp.auth_info.length) {
    1612                 enum ndr_err_code ndr_err;
    1613                 ndr_err = ndr_pull_struct_blob(
    1614                         &pkt->u.alter_resp.auth_info, recv_pipe,
    1615                         NULL,
    1616                         recv_pipe->conn->security_state.auth_info,
    1617                         (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
    1618                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1619                         c->status = ndr_map_error2ntstatus(ndr_err);
    1620                         if (!composite_is_ok(c)) return;
     1848                struct dcecli_connection *conn = recv_pipe->conn;
     1849                NTSTATUS status;
     1850                uint32_t auth_length;
     1851                status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.alter_resp.auth_info,
     1852                                                  conn->security_state.auth_info, &auth_length, true);
     1853                if (!NT_STATUS_IS_OK(status)) {
     1854                        composite_error(c, status);
     1855                        return;
    16211856                }
    16221857        }
     
    16741909
    16751910        /* construct the NDR form of the packet */
    1676         c->status = ncacn_push_auth(&blob, mem_ctx, p->conn->iconv_convenience, &pkt,
     1911        c->status = ncacn_push_auth(&blob, mem_ctx, &pkt,
    16771912                                    p->conn->security_state.auth_info);
    16781913        if (!composite_is_ok(c)) return c;
     
    17251960        return dcerpc_alter_context_recv(creq);
    17261961}
     1962
Note: See TracChangeset for help on using the changeset viewer.