#include "lib/util/dlinklist.h"
#include "lib/events/events.h"
#include "librpc/rpc/dcerpc.h"
+#include "librpc/rpc/dcerpc_proto.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "librpc/gen_ndr/ndr_dcerpc.h"
#include "libcli/composite/composite.h"
#include "auth/gensec/gensec.h"
+#include "param/param.h"
-NTSTATUS dcerpc_init(void)
+_PUBLIC_ NTSTATUS dcerpc_init(void)
{
- gensec_init();
+ gensec_init(global_loadparm);
return NT_STATUS_OK;
}
static int dcerpc_connection_destructor(struct dcerpc_connection *conn)
{
if (conn->dead) {
- conn->free_skipped = True;
+ conn->free_skipped = true;
return -1;
}
dcerpc_connection_dead(conn, NT_STATUS_LOCAL_DISCONNECT);
the event context is optional
*/
static struct dcerpc_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx,
- struct event_context *ev)
+ struct event_context *ev,
+ struct smb_iconv_convenience *ic)
{
struct dcerpc_connection *c;
return NULL;
}
- if (ev == NULL) {
- ev = event_context_init(c);
- if (ev == NULL) {
- talloc_free(c);
- return NULL;
- }
- }
+ c->iconv_convenience = talloc_reference(c, ic);
- c->event_ctx = ev;
-
- if (!talloc_reference(c, ev)) {
+ c->event_ctx = talloc_reference(c, ev);
+
+ if (c->event_ctx == NULL) {
talloc_free(c);
return NULL;
}
+
c->call_id = 1;
c->security_state.auth_info = NULL;
c->security_state.session_key = dcerpc_generic_session_key;
}
/* initialise a dcerpc pipe. */
-struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct event_context *ev)
+_PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct smb_iconv_convenience *ic)
{
struct dcerpc_pipe *p;
return NULL;
}
- p->conn = dcerpc_connection_init(p, ev);
+ p->conn = dcerpc_connection_init(p, ev, ic);
if (p->conn == NULL) {
talloc_free(p);
return NULL;
}
-/*
+/**
setup for a ndr pull, also setting up any flags from the binding string
*/
static struct ndr_pull *ndr_pull_init_flags(struct dcerpc_connection *c,
DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
{
- struct ndr_pull *ndr = ndr_pull_init_blob(blob, mem_ctx);
+ struct ndr_pull *ndr = ndr_pull_init_blob(blob, mem_ctx, c->iconv_convenience);
if (ndr == NULL) return ndr;
struct ncacn_packet *pkt)
{
struct ndr_pull *ndr;
+ enum ndr_err_code ndr_err;
ndr = ndr_pull_init_flags(c, blob, mem_ctx);
if (!ndr) {
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
- return ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+ ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+
+ return NT_STATUS_OK;
}
/*
NTSTATUS status;
struct dcerpc_auth auth;
DATA_BLOB auth_blob;
+ enum ndr_err_code ndr_err;
if (pkt->auth_length == 0 &&
c->security_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
- status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
}
-
+ status = NT_STATUS_OK;
+
/* check signature or unseal the packet */
switch (c->security_state.auth_info->auth_level) {
case DCERPC_AUTH_LEVEL_PRIVACY:
*/
static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ size_t sig_size,
struct ncacn_packet *pkt)
{
NTSTATUS status;
struct ndr_push *ndr;
DATA_BLOB creds2;
size_t payload_length;
+ enum ndr_err_code ndr_err;
/* non-signed packets are simpler */
if (!c->security_state.auth_info ||
!c->security_state.generic_state) {
- return ncacn_push_auth(blob, mem_ctx, pkt, c->security_state.auth_info);
+ return ncacn_push_auth(blob, mem_ctx, c->iconv_convenience, pkt, c->security_state.auth_info);
}
- ndr = ndr_push_init_ctx(mem_ctx);
+ ndr = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
if (!ndr) {
return NT_STATUS_NO_MEMORY;
}
ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
}
- status = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
}
+ status = NT_STATUS_OK;
/* pad to 16 byte multiple in the payload portion of the
packet. This matches what w2k3 does */
* GENSEC mech does AEAD signing of the packet
* headers */
c->security_state.auth_info->credentials
- = data_blob_talloc(mem_ctx, NULL, gensec_sig_size(c->security_state.generic_state,
- payload_length));
+ = data_blob_talloc(mem_ctx, NULL, sig_size);
data_blob_clear(&c->security_state.auth_info->credentials);
break;
}
/* add the auth verifier */
- status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, c->security_state.auth_info);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, c->security_state.auth_info);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
}
+ status = NT_STATUS_OK;
/* extract the whole packet as a blob */
*blob = ndr_push_blob(ndr);
return status;
}
blob->length -= c->security_state.auth_info->credentials.length;
- status = data_blob_append(mem_ctx, blob,
- creds2.data, creds2.length);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (!data_blob_append(mem_ctx, blob,
+ creds2.data, creds2.length)) {
+ return NT_STATUS_NO_MEMORY;
}
dcerpc_set_auth_length(blob, creds2.length);
if (c->security_state.auth_info->credentials.length == 0) {
return status;
}
blob->length -= c->security_state.auth_info->credentials.length;
- status = data_blob_append(mem_ctx, blob,
- creds2.data, creds2.length);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (!data_blob_append(mem_ctx, blob,
+ creds2.data, creds2.length)) {
+ return NT_STATUS_NO_MEMORY;
}
dcerpc_set_auth_length(blob, creds2.length);
if (c->security_state.auth_info->credentials.length == 0) {
conn->srv_max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
conn->srv_max_recv_frag = pkt->u.bind_ack.max_recv_frag;
+ if ((req->p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) &&
+ (pkt->pfc_flags & DCERPC_PFC_FLAG_CONC_MPX)) {
+ conn->flags |= DCERPC_CONCURRENT_MULTIPLEX;
+ }
+
+ if ((req->p->binding->flags & DCERPC_HEADER_SIGNING) &&
+ (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)) {
+ conn->flags |= DCERPC_HEADER_SIGNING;
+ }
+
/* the bind_ack might contain a reply set of credentials */
if (conn->security_state.auth_info &&
pkt->u.bind_ack.auth_info.length) {
- c->status = ndr_pull_struct_blob(
+ enum ndr_err_code ndr_err;
+ ndr_err = ndr_pull_struct_blob(
&pkt->u.bind_ack.auth_info, conn,
+ NULL,
conn->security_state.auth_info,
(ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
- if (!composite_is_ok(c)) return;
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ c->status = ndr_map_error2ntstatus(ndr_err);
+ if (!composite_is_ok(c)) return;
+ }
}
req->p->assoc_group_id = pkt->u.bind_ack.assoc_group_id;
pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX;
}
+ if (p->binding->flags & DCERPC_HEADER_SIGNING) {
+ pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
+ }
+
pkt.u.bind.max_xmit_frag = 5840;
pkt.u.bind.max_recv_frag = 5840;
pkt.u.bind.assoc_group_id = p->binding->assoc_group_id;
pkt.u.bind.auth_info = data_blob(NULL, 0);
/* construct the NDR form of the packet */
- c->status = ncacn_push_auth(&blob, c, &pkt,
+ c->status = ncacn_push_auth(&blob, c, p->conn->iconv_convenience, &pkt,
p->conn->security_state.auth_info);
if (!composite_is_ok(c)) return c;
talloc_set_destructor(req, dcerpc_req_dequeue);
c->status = p->conn->transport.send_request(p->conn, &blob,
- True);
+ true);
if (!composite_is_ok(c)) return c;
event_add_timed(c->event_ctx, req,
/*
perform a continued bind (and auth3)
*/
-NTSTATUS dcerpc_auth3(struct dcerpc_connection *c,
+NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
TALLOC_CTX *mem_ctx)
{
struct ncacn_packet pkt;
NTSTATUS status;
DATA_BLOB blob;
- init_ncacn_hdr(c, &pkt);
+ init_ncacn_hdr(p->conn, &pkt);
pkt.ptype = DCERPC_PKT_AUTH3;
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
- pkt.call_id = next_call_id(c);
+ pkt.call_id = next_call_id(p->conn);
pkt.auth_length = 0;
pkt.u.auth3._pad = 0;
pkt.u.auth3.auth_info = data_blob(NULL, 0);
+ if (p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) {
+ pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX;
+ }
+
+ if (p->binding->flags & DCERPC_HEADER_SIGNING) {
+ pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
+ }
+
/* construct the NDR form of the packet */
- status = ncacn_push_auth(&blob, mem_ctx, &pkt, c->security_state.auth_info);
+ status = ncacn_push_auth(&blob, mem_ctx,
+ p->conn->iconv_convenience,
+ &pkt,
+ p->conn->security_state.auth_info);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* send it on its way */
- status = c->transport.send_request(c, &blob, False);
+ status = p->conn->transport.send_request(p->conn, &blob, false);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- return status;
+ return NT_STATUS_OK;
}
static struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
const struct GUID *object,
uint16_t opnum,
- BOOL async,
+ bool async,
DATA_BLOB *stub_data)
{
struct rpc_request *req;
req->flags = 0;
req->fault_code = 0;
req->async_call = async;
- req->ignore_timeout = False;
+ req->ignore_timeout = false;
req->async.callback = NULL;
req->async.private_data = NULL;
req->recv_handler = NULL;
if (object != NULL) {
- req->object = talloc_memdup(req, object, sizeof(*object));
+ req->object = (struct GUID *)talloc_memdup(req, (const void *)object, sizeof(*object));
if (req->object == NULL) {
talloc_free(req);
return NULL;
struct ncacn_packet pkt;
DATA_BLOB blob;
uint32_t remaining, chunk_size;
- BOOL first_packet = True;
+ bool first_packet = true;
+ size_t sig_size = 0;
req = c->request_queue;
if (req == NULL) {
/* we can write a full max_recv_frag size, minus the dcerpc
request header size */
- chunk_size = p->conn->srv_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH);
+ chunk_size = p->conn->srv_max_recv_frag;
+ chunk_size -= DCERPC_REQUEST_LENGTH;
+ if (c->security_state.generic_state) {
+ chunk_size -= DCERPC_AUTH_TRAILER_LENGTH;
+ sig_size = gensec_sig_size(c->security_state.generic_state,
+ p->conn->srv_max_recv_frag);
+ chunk_size -= sig_size;
+ chunk_size -= (chunk_size % 16);
+ }
pkt.ptype = DCERPC_PKT_REQUEST;
pkt.call_id = req->call_id;
/* we send a series of pdus without waiting for a reply */
while (remaining > 0 || first_packet) {
uint32_t chunk = MIN(chunk_size, remaining);
- BOOL last_frag = False;
+ bool last_frag = false;
- first_packet = False;
+ first_packet = false;
pkt.pfc_flags &= ~(DCERPC_PFC_FLAG_FIRST |DCERPC_PFC_FLAG_LAST);
if (remaining == stub_data->length) {
}
if (chunk == remaining) {
pkt.pfc_flags |= DCERPC_PFC_FLAG_LAST;
- last_frag = True;
+ last_frag = true;
}
pkt.u.request.stub_and_verifier.data = stub_data->data +
(stub_data->length - remaining);
pkt.u.request.stub_and_verifier.length = chunk;
- req->status = ncacn_push_request_sign(p->conn, &blob, req, &pkt);
+ req->status = ncacn_push_request_sign(p->conn, &blob, req, sig_size, &pkt);
if (!NT_STATUS_IS_OK(req->status)) {
req->state = RPC_REQUEST_DONE;
DLIST_REMOVE(p->conn->pending, req);
return the event context for a dcerpc pipe
used by callers who wish to operate asynchronously
*/
-struct event_context *dcerpc_event_context(struct dcerpc_pipe *p)
+_PUBLIC_ struct event_context *dcerpc_event_context(struct dcerpc_pipe *p)
{
return p->conn->event_ctx;
}
NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
struct GUID *object,
uint16_t opnum,
- BOOL async,
+ bool async,
TALLOC_CTX *mem_ctx,
DATA_BLOB *stub_data_in,
DATA_BLOB *stub_data_out)
void *st;
struct ndr_pull *pull;
struct ndr_push *push;
- NTSTATUS status;
DATA_BLOB blob2;
+ enum ndr_err_code ndr_err;
st = talloc_size(mem_ctx, struct_size);
if (!st) {
}
pull->flags |= LIBNDR_FLAG_REF_ALLOC;
- status = ndr_pull(pull, NDR_IN, st);
- if (!NT_STATUS_IS_OK(status)) {
- return ndr_pull_error(pull, NDR_ERR_VALIDATE,
- "failed input validation pull - %s",
- nt_errstr(status));
+ ndr_err = ndr_pull(pull, NDR_IN, st);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
+ "failed input validation pull - %s",
+ nt_errstr(status));
+ return ndr_map_error2ntstatus(ndr_err);
}
- push = ndr_push_init_ctx(mem_ctx);
+ push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
if (!push) {
return NT_STATUS_NO_MEMORY;
}
- status = ndr_push(push, NDR_IN, st);
- if (!NT_STATUS_IS_OK(status)) {
- return ndr_push_error(push, NDR_ERR_VALIDATE,
- "failed input validation push - %s",
- nt_errstr(status));
+ ndr_err = ndr_push(push, NDR_IN, st);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
+ "failed input validation push - %s",
+ nt_errstr(status));
+ return ndr_map_error2ntstatus(ndr_err);
}
blob2 = ndr_push_blob(push);
dump_data(3, blob.data, blob.length);
DEBUG(3,("secondary:\n"));
dump_data(3, blob2.data, blob2.length);
- return ndr_push_error(push, NDR_ERR_VALIDATE,
- "failed input validation data - %s",
- nt_errstr(status));
+ ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
+ "failed input validation blobs doesn't match");
+ return ndr_map_error2ntstatus(ndr_err);
}
return NT_STATUS_OK;
void *st;
struct ndr_pull *pull;
struct ndr_push *push;
- NTSTATUS status;
DATA_BLOB blob, blob2;
TALLOC_CTX *mem_ctx = pull_in;
char *s1, *s2;
+ enum ndr_err_code ndr_err;
st = talloc_size(mem_ctx, struct_size);
if (!st) {
}
memcpy(st, struct_ptr, struct_size);
- push = ndr_push_init_ctx(mem_ctx);
+ push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
if (!push) {
return NT_STATUS_NO_MEMORY;
}
- status = ndr_push(push, NDR_OUT, struct_ptr);
- if (!NT_STATUS_IS_OK(status)) {
- return ndr_push_error(push, NDR_ERR_VALIDATE,
- "failed output validation push - %s",
- nt_errstr(status));
+ ndr_err = ndr_push(push, NDR_OUT, struct_ptr);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
+ "failed output validation push - %s",
+ nt_errstr(status));
+ return ndr_map_error2ntstatus(ndr_err);
}
blob = ndr_push_blob(push);
}
pull->flags |= LIBNDR_FLAG_REF_ALLOC;
- status = ndr_pull(pull, NDR_OUT, st);
- if (!NT_STATUS_IS_OK(status)) {
- return ndr_pull_error(pull, NDR_ERR_VALIDATE,
- "failed output validation pull - %s",
- nt_errstr(status));
+ ndr_err = ndr_pull(pull, NDR_OUT, st);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
+ "failed output validation pull - %s",
+ nt_errstr(status));
+ return ndr_map_error2ntstatus(ndr_err);
}
- push = ndr_push_init_ctx(mem_ctx);
+ push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
if (!push) {
return NT_STATUS_NO_MEMORY;
}
- status = ndr_push(push, NDR_OUT, st);
- if (!NT_STATUS_IS_OK(status)) {
- return ndr_push_error(push, NDR_ERR_VALIDATE,
- "failed output validation push2 - %s",
- nt_errstr(status));
+ ndr_err = ndr_push(push, NDR_OUT, st);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
+ "failed output validation push2 - %s",
+ nt_errstr(status));
+ return ndr_map_error2ntstatus(ndr_err);
}
blob2 = ndr_push_blob(push);
dump_data(3, blob.data, blob.length);
DEBUG(3,("secondary:\n"));
dump_data(3, blob2.data, blob2.length);
- return ndr_push_error(push, NDR_ERR_VALIDATE,
- "failed output validation data - %s",
- nt_errstr(status));
+ ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
+ "failed output validation blobs doesn't match");
+ return ndr_map_error2ntstatus(ndr_err);
}
/* this checks the printed forms of the two structures, which effectively
NDR_OUT, st);
if (strcmp(s1, s2) != 0) {
#if 1
- printf("VALIDATE ERROR:\nWIRE:\n%s\n GEN:\n%s\n", s1, s2);
+ DEBUG(3,("VALIDATE ERROR:\nWIRE:\n%s\n GEN:\n%s\n", s1, s2));
#else
/* this is sometimes useful */
printf("VALIDATE ERROR\n");
file_save("gen.dat", s2, strlen(s2));
system("diff -u wire.dat gen.dat");
#endif
+ ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
+ "failed output validation strings doesn't match");
+ return ndr_map_error2ntstatus(ndr_err);
}
return NT_STATUS_OK;
}
-/*
+/**
send a rpc request given a dcerpc_call structure
*/
struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
NTSTATUS status;
DATA_BLOB request;
struct rpc_request *req;
+ enum ndr_err_code ndr_err;
call = &table->calls[opnum];
/* setup for a ndr_push_* call */
- push = ndr_push_init_ctx(mem_ctx);
+ push = ndr_push_init_ctx(mem_ctx, p->conn->iconv_convenience);
if (!push) {
return NULL;
}
}
/* push the structure into a blob */
- status = call->ndr_push(push, NDR_IN, r);
- if (!NT_STATUS_IS_OK(status)) {
+ ndr_err = call->ndr_push(push, NDR_IN, r);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = ndr_map_error2ntstatus(ndr_err);
DEBUG(2,("Unable to ndr_push structure in dcerpc_ndr_request_send - %s\n",
nt_errstr(status)));
talloc_free(push);
uint32_t opnum = req->ndr.opnum;
const struct ndr_interface_table *table = req->ndr.table;
const struct ndr_interface_call *call = &table->calls[opnum];
+ enum ndr_err_code ndr_err;
/* make sure the recv code doesn't free the request, as we
need to grab the flags element before it is freed */
dump_data(10, pull->data, pull->data_size);
/* pull the structure from the blob */
- status = call->ndr_pull(pull, NDR_OUT, r);
- if (!NT_STATUS_IS_OK(status)) {
+ ndr_err = call->ndr_pull(pull, NDR_OUT, r);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = ndr_map_error2ntstatus(ndr_err);
dcerpc_log_packet(table, opnum, NDR_OUT,
&response);
return status;
this can be used when you have ndr push/pull functions in the
standard format
*/
-NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
+_PUBLIC_ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
const struct GUID *object,
const struct ndr_interface_table *table,
uint32_t opnum,
/*
a useful function for retrieving the server name we connected to
*/
-const char *dcerpc_server_name(struct dcerpc_pipe *p)
+_PUBLIC_ const char *dcerpc_server_name(struct dcerpc_pipe *p)
{
- if (!p->conn->transport.peer_name) {
- return "";
+ if (!p->conn->transport.target_hostname) {
+ if (!p->conn->transport.peer_name) {
+ return "";
+ }
+ return p->conn->transport.peer_name(p->conn);
}
- return p->conn->transport.peer_name(p->conn);
+ return p->conn->transport.target_hostname(p->conn);
}
/* the alter_resp might contain a reply set of credentials */
if (recv_pipe->conn->security_state.auth_info &&
pkt->u.alter_resp.auth_info.length) {
- c->status = ndr_pull_struct_blob(
+ enum ndr_err_code ndr_err;
+ ndr_err = ndr_pull_struct_blob(
&pkt->u.alter_resp.auth_info, recv_pipe,
+ NULL,
recv_pipe->conn->security_state.auth_info,
(ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
- if (!composite_is_ok(c)) return;
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ c->status = ndr_map_error2ntstatus(ndr_err);
+ if (!composite_is_ok(c)) return;
+ }
}
composite_done(c);
pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX;
}
+ if (p->binding->flags & DCERPC_HEADER_SIGNING) {
+ pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
+ }
+
pkt.u.alter.max_xmit_frag = 5840;
pkt.u.alter.max_recv_frag = 5840;
pkt.u.alter.assoc_group_id = p->binding->assoc_group_id;
pkt.u.alter.auth_info = data_blob(NULL, 0);
/* construct the NDR form of the packet */
- c->status = ncacn_push_auth(&blob, mem_ctx, &pkt,
+ c->status = ncacn_push_auth(&blob, mem_ctx, p->conn->iconv_convenience, &pkt,
p->conn->security_state.auth_info);
if (!composite_is_ok(c)) return c;
DLIST_ADD_END(p->conn->pending, req, struct rpc_request *);
talloc_set_destructor(req, dcerpc_req_dequeue);
- c->status = p->conn->transport.send_request(p->conn, &blob, True);
+ c->status = p->conn->transport.send_request(p->conn, &blob, true);
if (!composite_is_ok(c)) return c;
event_add_timed(c->event_ctx, req,
/*
send a dcerpc alter_context request
*/
-NTSTATUS dcerpc_alter_context(struct dcerpc_pipe *p,
+_PUBLIC_ NTSTATUS dcerpc_alter_context(struct dcerpc_pipe *p,
TALLOC_CTX *mem_ctx,
const struct ndr_syntax_id *syntax,
const struct ndr_syntax_id *transfer_syntax)