summaryrefslogtreecommitdiff
path: root/source4/librpc
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2003-12-16 09:02:58 +0000
committerAndrew Tridgell <tridge@samba.org>2003-12-16 09:02:58 +0000
commit24c22aef90d8534ee2d016b37b2b302f1367d106 (patch)
treececb9192f1a83f7232041cda58e83e1d94ac57b5 /source4/librpc
parent1413faae582949e7d12174df7102723eea914464 (diff)
downloadsamba-24c22aef90d8534ee2d016b37b2b302f1367d106.tar.gz
samba-24c22aef90d8534ee2d016b37b2b302f1367d106.tar.bz2
samba-24c22aef90d8534ee2d016b37b2b302f1367d106.zip
a fairly large commit!
This adds support for bigendian rpc in the client. I have installed SUN pcnetlink locally and am using it to test the samba4 rpc code. This allows us to easily find places where we have stuffed up the types (such as 2 uint16 versus a uint32), as testing both big-endian and little-endian easily shows which is correct. I have now used this to fix several bugs like that in the samba4 IDL. In order to make this work I also had to redefine a GUID as a true structure, not a blob. From the pcnetlink wire it is clear that it is indeed defined as a structure (the byte order changes). This required changing lots of Samba code to use a GUID as a structure. I also had to fix the if_version code in dcerpc syntax IDs, as it turns out they are a single uint32 not two uint16s. The big-endian support is a bit ugly at the moment, and breaks the layering in some places. More work is needed, especially on the server side. (This used to be commit bb1af644a5a7b188290ce36232f255da0e5d66d2)
Diffstat (limited to 'source4/librpc')
-rw-r--r--source4/librpc/idl/dcerpc.idl6
-rw-r--r--source4/librpc/idl/misc.idl8
-rw-r--r--source4/librpc/ndr/ndr_basic.c77
-rw-r--r--source4/librpc/rpc/dcerpc.c89
-rw-r--r--source4/librpc/rpc/dcerpc.h3
-rw-r--r--source4/librpc/rpc/dcerpc_smb.c4
-rw-r--r--source4/librpc/rpc/dcerpc_tcp.c2
-rw-r--r--source4/librpc/rpc/dcerpc_util.c14
8 files changed, 132 insertions, 71 deletions
diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl
index cf195b6aea..ad82679576 100644
--- a/source4/librpc/idl/dcerpc.idl
+++ b/source4/librpc/idl/dcerpc.idl
@@ -13,8 +13,7 @@ interface dcerpc
{
typedef [public] struct {
GUID uuid;
- uint16 major_version;
- uint16 minor_version;
+ uint32 if_version;
} dcerpc_syntax_id;
typedef struct {
@@ -28,7 +27,7 @@ interface dcerpc
uint16 max_xmit_frag;
uint16 max_recv_frag;
uint32 assoc_group_id;
- uint8 num_contexts;
+ uint8 num_contexts;
dcerpc_ctx_list ctx_list[num_contexts];
[flag(NDR_ALIGN8)] DATA_BLOB _pad;
[flag(NDR_REMAINING)] DATA_BLOB auth_info;
@@ -167,6 +166,7 @@ interface dcerpc
const uint8 DCERPC_PFC_FLAG_NOCALL = 0x20;
/* these offsets are needed by the signing code */
+ const uint8 DCERPC_DREP_OFFSET = 4;
const uint8 DCERPC_FRAG_LEN_OFFSET = 8;
const uint8 DCERPC_AUTH_LEN_OFFSET = 10;
diff --git a/source4/librpc/idl/misc.idl b/source4/librpc/idl/misc.idl
index eb2288bc35..a1f8549eaa 100644
--- a/source4/librpc/idl/misc.idl
+++ b/source4/librpc/idl/misc.idl
@@ -8,6 +8,14 @@
interface misc
{
+ typedef [public,noprint] struct {
+ uint32 time_low;
+ uint16 time_mid;
+ uint16 time_hi_and_version;
+ uint8 clock_seq[2];
+ uint8 node[6];
+ } GUID;
+
/* a domain SID. Note that unlike Samba3 this contains a pointer,
so you can't copy them using assignment */
typedef [public,noprint] struct {
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
index 3b5aea60ca..ed75b8c27c 100644
--- a/source4/librpc/ndr/ndr_basic.c
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -22,6 +22,12 @@
#include "includes.h"
+#define NDR_BE(ndr) ((ndr)->flags & LIBNDR_FLAG_BIGENDIAN)
+#define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
+#define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
+#define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
+#define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
+
/*
parse a uint8
*/
@@ -41,7 +47,7 @@ NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, uint16 *v)
{
NDR_PULL_ALIGN(ndr, 2);
NDR_PULL_NEED_BYTES(ndr, 2);
- *v = SVAL(ndr->data, ndr->offset);
+ *v = NDR_SVAL(ndr, ndr->offset);
ndr->offset += 2;
return NT_STATUS_OK;
}
@@ -54,7 +60,7 @@ NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, uint32 *v)
{
NDR_PULL_ALIGN(ndr, 4);
NDR_PULL_NEED_BYTES(ndr, 4);
- *v = IVAL(ndr->data, ndr->offset);
+ *v = NDR_IVAL(ndr, ndr->offset);
ndr->offset += 4;
return NT_STATUS_OK;
}
@@ -66,8 +72,8 @@ NTSTATUS ndr_pull_HYPER_T(struct ndr_pull *ndr, HYPER_T *v)
{
NDR_PULL_ALIGN(ndr, 8);
NDR_PULL_NEED_BYTES(ndr, 8);
- v->low = IVAL(ndr->data, ndr->offset);
- v->high = IVAL(ndr->data, ndr->offset+4);
+ v->low = NDR_IVAL(ndr, ndr->offset);
+ v->high = NDR_IVAL(ndr, ndr->offset+4);
ndr->offset += 8;
return NT_STATUS_OK;
}
@@ -174,18 +180,6 @@ NTSTATUS ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, uint32 *data
}
/*
- parse a GUID
-*/
-NTSTATUS ndr_pull_GUID(struct ndr_pull *ndr, int ndr_flags, GUID *guid)
-{
- if (ndr_flags & NDR_SCALARS) {
- return ndr_pull_bytes(ndr, guid->info, GUID_SIZE);
- }
- return NT_STATUS_OK;
-}
-
-
-/*
push a uint8
*/
NTSTATUS ndr_push_uint8(struct ndr_push *ndr, uint8 v)
@@ -203,7 +197,7 @@ NTSTATUS ndr_push_uint16(struct ndr_push *ndr, uint16 v)
{
NDR_PUSH_ALIGN(ndr, 2);
NDR_PUSH_NEED_BYTES(ndr, 2);
- SSVAL(ndr->data, ndr->offset, v);
+ NDR_SSVAL(ndr, ndr->offset, v);
ndr->offset += 2;
return NT_STATUS_OK;
}
@@ -215,7 +209,7 @@ NTSTATUS ndr_push_uint32(struct ndr_push *ndr, uint32 v)
{
NDR_PUSH_ALIGN(ndr, 4);
NDR_PUSH_NEED_BYTES(ndr, 4);
- SIVAL(ndr->data, ndr->offset, v);
+ NDR_SIVAL(ndr, ndr->offset, v);
ndr->offset += 4;
return NT_STATUS_OK;
}
@@ -227,8 +221,8 @@ NTSTATUS ndr_push_HYPER_T(struct ndr_push *ndr, HYPER_T v)
{
NDR_PUSH_ALIGN(ndr, 8);
NDR_PUSH_NEED_BYTES(ndr, 8);
- SIVAL(ndr->data, ndr->offset, v.low);
- SIVAL(ndr->data, ndr->offset+4, v.high);
+ NDR_SIVAL(ndr, ndr->offset, v.low);
+ NDR_SIVAL(ndr, ndr->offset+4, v.high);
ndr->offset += 8;
return NT_STATUS_OK;
}
@@ -582,17 +576,6 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
}
/*
- push a GUID
-*/
-NTSTATUS ndr_push_GUID(struct ndr_push *ndr, int ndr_flags, GUID *guid)
-{
- if (ndr_flags & NDR_SCALARS) {
- return ndr_push_bytes(ndr, guid->info, GUID_SIZE);
- }
- return NT_STATUS_OK;
-}
-
-/*
push a NTTIME
*/
NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)
@@ -770,26 +753,25 @@ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
{
uint32 time_low;
uint32 time_mid, time_hi_and_version;
- uint32 clock_seq_hi_and_reserved;
- uint32 clock_seq_low;
+ uint32 clock_seq[2];
uint32 node[6];
int i;
if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
&time_low, &time_mid, &time_hi_and_version,
- &clock_seq_hi_and_reserved, &clock_seq_low,
+ &clock_seq[0], &clock_seq[1],
&node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
return NT_STATUS_INVALID_PARAMETER;
}
- SIVAL(guid->info, 0, time_low);
- SSVAL(guid->info, 4, time_mid);
- SSVAL(guid->info, 6, time_hi_and_version);
- SCVAL(guid->info, 8, clock_seq_hi_and_reserved);
- SCVAL(guid->info, 9, clock_seq_low);
+ guid->time_low = time_low;
+ guid->time_mid = time_mid;
+ guid->time_hi_and_version = time_hi_and_version;
+ guid->clock_seq[0] = clock_seq[0];
+ guid->clock_seq[1] = clock_seq[1];
for (i=0;i<6;i++) {
- SCVAL(guid->info, 10 + i, node[i]);
- }
+ guid->node[i] = node[i];
+ }
return NT_STATUS_OK;
}
@@ -801,12 +783,13 @@ const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
{
return talloc_asprintf(mem_ctx,
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- IVAL(guid->info, 0), SVAL(guid->info, 4),
- SVAL(guid->info, 6),
- guid->info[8], guid->info[9],
- guid->info[10], guid->info[11],
- guid->info[12], guid->info[13],
- guid->info[14], guid->info[15]);
+ guid->time_low, guid->time_mid,
+ guid->time_hi_and_version,
+ guid->clock_seq[0],
+ guid->clock_seq[1],
+ guid->node[0], guid->node[1],
+ guid->node[2], guid->node[3],
+ guid->node[4], guid->node[5]);
}
void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index 3dcaca83ec..c82d8d67ab 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -64,6 +64,35 @@ void dcerpc_pipe_close(struct dcerpc_pipe *p)
}
}
+/* we need to be able to get/set the fragment length without doing a full
+ decode */
+void dcerpc_set_frag_length(DATA_BLOB *blob, uint16 v)
+{
+ if (CVAL(blob->data,DCERPC_DREP_OFFSET) & 0x10) {
+ SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
+ } else {
+ RSSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
+ }
+}
+
+uint16 dcerpc_get_frag_length(DATA_BLOB *blob)
+{
+ if (CVAL(blob->data,DCERPC_DREP_OFFSET) & 0x10) {
+ return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
+ } else {
+ return RSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
+ }
+}
+
+void dcerpc_set_auth_length(DATA_BLOB *blob, uint16 v)
+{
+ if (CVAL(blob->data,DCERPC_DREP_OFFSET) & 0x10) {
+ SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
+ } else {
+ RSSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
+ }
+}
+
/*
parse a data blob into a dcerpc_packet structure. This handles both
@@ -79,6 +108,10 @@ static NTSTATUS dcerpc_pull(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
+ if (! (CVAL(blob, DCERPC_DREP_OFFSET) & 0x10)) {
+ ndr->flags |= DCERPC_PULL_BIGENDIAN;
+ }
+
return ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
}
@@ -104,6 +137,10 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
return NT_STATUS_NO_MEMORY;
}
+ if (! (CVAL(blob, DCERPC_DREP_OFFSET) & 0x10)) {
+ ndr->flags |= DCERPC_PULL_BIGENDIAN;
+ }
+
/* pull the basic packet */
status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
if (!NT_STATUS_IS_OK(status)) {
@@ -132,6 +169,10 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
return NT_STATUS_NO_MEMORY;
}
+ if (! (CVAL(blob, DCERPC_DREP_OFFSET) & 0x10)) {
+ ndr->flags |= DCERPC_PULL_BIGENDIAN;
+ }
+
status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
if (!NT_STATUS_IS_OK(status)) {
return status;
@@ -184,7 +225,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
/* non-signed packets are simpler */
if (!p->auth_info || !p->ntlmssp_state) {
- return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info);
+ return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info, p->flags);
}
ndr = ndr_push_init_ctx(mem_ctx);
@@ -192,6 +233,10 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
return NT_STATUS_NO_MEMORY;
}
+ if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
status = ndr_push_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
if (!NT_STATUS_IS_OK(status)) {
return status;
@@ -242,8 +287,8 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
/* fill in the fragment length and auth_length, we can't fill
in these earlier as we don't know the signature length (it
could be variable length) */
- SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, blob->length);
- SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, p->auth_info->credentials.length);
+ dcerpc_set_frag_length(blob, blob->length);
+ dcerpc_set_auth_length(blob, p->auth_info->credentials.length);
data_blob_free(&p->auth_info->credentials);
@@ -254,11 +299,15 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
/*
fill in the fixed values in a dcerpc header
*/
-static void init_dcerpc_hdr(struct dcerpc_packet *pkt)
+static void init_dcerpc_hdr(struct dcerpc_pipe *p, struct dcerpc_packet *pkt)
{
pkt->rpc_vers = 5;
pkt->rpc_vers_minor = 0;
- pkt->drep[0] = 0x10; /* Little endian */
+ if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ pkt->drep[0] = 0;
+ } else {
+ pkt->drep[0] = 0x10;
+ }
pkt->drep[1] = 0;
pkt->drep[2] = 0;
pkt->drep[3] = 0;
@@ -281,7 +330,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
DATA_BLOB blob;
struct dcerpc_syntax_id tsyntax;
- init_dcerpc_hdr(&pkt);
+ init_dcerpc_hdr(p, &pkt);
pkt.ptype = DCERPC_PKT_BIND;
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
@@ -304,7 +353,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
pkt.u.bind.auth_info = data_blob(NULL, 0);
/* construct the NDR form of the packet */
- status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
+ status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info, p->flags);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -353,7 +402,7 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
NTSTATUS status;
DATA_BLOB blob;
- init_dcerpc_hdr(&pkt);
+ init_dcerpc_hdr(p, &pkt);
pkt.ptype = DCERPC_PKT_AUTH3;
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
@@ -363,7 +412,7 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
pkt.u.auth.auth_info = data_blob(NULL, 0);
/* construct the NDR form of the packet */
- status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
+ status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info, p->flags);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -392,15 +441,13 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p,
DEBUG(2,("Invalid uuid string in dcerpc_bind_byuuid\n"));
return status;
}
- syntax.major_version = version;
- syntax.minor_version = 0;
+ syntax.if_version = version;
status = GUID_from_string(NDR_GUID, &transfer_syntax.uuid);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- transfer_syntax.major_version = NDR_GUID_VERSION;
- transfer_syntax.minor_version = 0;
+ transfer_syntax.if_version = NDR_GUID_VERSION;
return dcerpc_bind(p, mem_ctx, &syntax, &transfer_syntax);
}
@@ -420,7 +467,7 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
DATA_BLOB blob, payload;
uint32 remaining, chunk_size;
- init_dcerpc_hdr(&pkt);
+ init_dcerpc_hdr(p, &pkt);
remaining = stub_data_in->length;
@@ -552,6 +599,12 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
*stub_data_out = payload;
}
+ if (!(pkt.drep[0] & 0x10)) {
+ p->flags |= DCERPC_PULL_BIGENDIAN;
+ } else {
+ p->flags &= ~DCERPC_PULL_BIGENDIAN;
+ }
+
return status;
}
@@ -723,6 +776,10 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
return NT_STATUS_NO_MEMORY;
}
+ if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ push->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
/* push the structure into a blob */
status = ndr_push(push, NDR_IN, struct_ptr);
if (!NT_STATUS_IS_OK(status)) {
@@ -755,6 +812,10 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
goto failed;
}
+ if (p->flags & DCERPC_PULL_BIGENDIAN) {
+ pull->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
DEBUG(10,("rpc reply data:\n"));
dump_data(10, pull->data, pull->data_size);
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index fa2ced2537..5d25882041 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -65,6 +65,9 @@ struct dcerpc_pipe {
#define DCERPC_SIGN 16
#define DCERPC_SEAL 32
+#define DCERPC_PUSH_BIGENDIAN 64
+#define DCERPC_PULL_BIGENDIAN 128
+
/*
this is used to find pointers to calls
*/
diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c
index 9acae00249..fc71a47cf4 100644
--- a/source4/librpc/rpc/dcerpc_smb.c
+++ b/source4/librpc/rpc/dcerpc_smb.c
@@ -91,7 +91,7 @@ static NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p,
/* we might have recieved a partial fragment, in which case we
need to pull the rest of it */
- frag_length = SVAL(payload.data, 8);
+ frag_length = dcerpc_get_frag_length(&payload);
if (frag_length <= payload.length) {
goto done;
}
@@ -197,7 +197,7 @@ NTSTATUS smb_secondary_request(struct dcerpc_pipe *p,
return status;
}
- frag_length = SVAL(blob->data, 8);
+ frag_length = dcerpc_get_frag_length(blob);
if (frag_length <= blob->length) {
return status;
}
diff --git a/source4/librpc/rpc/dcerpc_tcp.c b/source4/librpc/rpc/dcerpc_tcp.c
index 468cd9465b..b577260033 100644
--- a/source4/librpc/rpc/dcerpc_tcp.c
+++ b/source4/librpc/rpc/dcerpc_tcp.c
@@ -60,7 +60,7 @@ static NTSTATUS tcp_raw_recv(struct dcerpc_pipe *p,
/* we might have recieved a partial fragment, in which case we
need to pull the rest of it */
- frag_length = SVAL(blob1.data, 8);
+ frag_length = dcerpc_get_frag_length(&blob1);
if (frag_length == blob1.length) {
*blob = blob1;
return NT_STATUS_OK;
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index 02e224a26f..fbc97f316d 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -59,7 +59,7 @@ NTSTATUS dcerpc_epm_map_tcp_port(const char *server,
NTSTATUS status;
struct epm_Map r;
struct policy_handle handle;
- GUID guid;
+ struct GUID guid;
struct epm_twr_t twr, *twr_r;
if (strcasecmp(uuid, DCERPC_EPMAPPER_UUID) == 0 ||
@@ -223,7 +223,8 @@ const struct dcerpc_interface_table *idl_iface_by_uuid(const char *uuid)
*/
NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
struct dcerpc_packet *pkt,
- struct dcerpc_auth *auth_info)
+ struct dcerpc_auth *auth_info,
+ unsigned flags)
{
NTSTATUS status;
struct ndr_push *ndr;
@@ -233,6 +234,10 @@ NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
+ if (flags & DCERPC_PUSH_BIGENDIAN) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
if (auth_info) {
pkt->auth_length = auth_info->credentials.length;
} else {
@@ -251,7 +256,7 @@ NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
*blob = ndr_push_blob(ndr);
/* fill in the frag length */
- SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, blob->length);
+ dcerpc_set_frag_length(blob, blob->length);
return NT_STATUS_OK;
}
@@ -278,7 +283,8 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
} options[] = {
{"sign", DCERPC_SIGN},
{"seal", DCERPC_SEAL},
- {"validate", DCERPC_DEBUG_VALIDATE_BOTH}
+ {"validate", DCERPC_DEBUG_VALIDATE_BOTH},
+ {"bigendian", DCERPC_PUSH_BIGENDIAN}
};
p = strchr(s, ':');