}
}
-uint16 dcerpc_get_frag_length(DATA_BLOB *blob)
+uint16 dcerpc_get_frag_length(const DATA_BLOB *blob)
{
if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
return NT_STATUS_NO_MEMORY;
}
- if (! (CVAL(blob, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
- ndr->flags |= DCERPC_PULL_BIGENDIAN;
+ if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
return ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
return NT_STATUS_NO_MEMORY;
}
- if (! (CVAL(blob, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
- ndr->flags |= DCERPC_PULL_BIGENDIAN;
+ if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
/* pull the basic packet */
return NT_STATUS_NO_MEMORY;
}
- if (! (CVAL(blob, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
- ndr->flags |= DCERPC_PULL_BIGENDIAN;
+ if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
/* non-signed packets are simpler */
if (!p->auth_info || !p->ntlmssp_state) {
- return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info, p->flags);
+ return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info);
}
ndr = ndr_push_init_ctx(mem_ctx);
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, p->flags);
+ status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
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, p->flags);
+ status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
*/
NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
struct dcerpc_packet *pkt,
- struct dcerpc_auth *auth_info,
- unsigned flags)
+ struct dcerpc_auth *auth_info)
{
NTSTATUS status;
struct ndr_push *ndr;
return NT_STATUS_NO_MEMORY;
}
- if (flags & DCERPC_PUSH_BIGENDIAN) {
+ if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
BOOL bUnixExtensions;
BOOL bDisableNetbios;
BOOL bKernelChangeNotify;
+ BOOL bRpcBigEndian;
int restrict_anonymous;
int name_cache_timeout;
BOOL client_signing;
{"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
{"client signing", P_BOOL, P_GLOBAL, &Globals.client_signing, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_DEVELOPER},
+ {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
{"Tuning Options", P_SEP, P_SEPARATOR},
FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
+FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
talloc_destroy(p->mem_ctx);
}
+static void dcesrv_init_hdr(struct dcerpc_packet *pkt)
+{
+ pkt->rpc_vers = 5;
+ pkt->rpc_vers_minor = 0;
+ if (lp_rpc_big_endian()) {
+ pkt->drep[0] = 0;
+ } else {
+ pkt->drep[0] = DCERPC_DREP_LE;
+ }
+ pkt->drep[1] = 0;
+ pkt->drep[2] = 0;
+ pkt->drep[3] = 0;
+}
+
/*
return a dcerpc fault
*/
NTSTATUS status;
/* setup a bind_ack */
- pkt.rpc_vers = 5;
- pkt.rpc_vers_minor = 0;
- pkt.drep[0] = 0x10; /* Little endian */
- pkt.drep[1] = 0;
- pkt.drep[2] = 0;
- pkt.drep[3] = 0;
+ dcesrv_init_hdr(&pkt);
pkt.auth_length = 0;
pkt.call_id = call->pkt.call_id;
pkt.ptype = DCERPC_PKT_FAULT;
return NT_STATUS_NO_MEMORY;
}
- status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0);
+ status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length);
+ dcerpc_set_frag_length(&rep->data, rep->data.length);
DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *);
NTSTATUS status;
/* setup a bind_ack */
- pkt.rpc_vers = 5;
- pkt.rpc_vers_minor = 0;
- pkt.drep[0] = 0x10; /* Little endian */
- pkt.drep[1] = 0;
- pkt.drep[2] = 0;
- pkt.drep[3] = 0;
+ dcesrv_init_hdr(&pkt);
pkt.auth_length = 0;
pkt.call_id = call->pkt.call_id;
pkt.ptype = DCERPC_PKT_BIND_NAK;
return NT_STATUS_NO_MEMORY;
}
- status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0);
+ status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length);
+ dcerpc_set_frag_length(&rep->data, rep->data.length);
DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *);
}
/* setup a bind_ack */
- pkt.rpc_vers = 5;
- pkt.rpc_vers_minor = 0;
- pkt.drep[0] = 0x10; /* Little endian */
- pkt.drep[1] = 0;
- pkt.drep[2] = 0;
- pkt.drep[3] = 0;
+ dcesrv_init_hdr(&pkt);
pkt.auth_length = 0;
pkt.call_id = call->pkt.call_id;
pkt.ptype = DCERPC_PKT_BIND_ACK;
}
status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt,
- call->dce->auth_state.auth_info, 0);
+ call->dce->auth_state.auth_info);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length);
+ dcerpc_set_frag_length(&rep->data, rep->data.length);
DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *);
DLIST_ADD_END(call->dce->call_list, call, struct dcesrv_call_state *);
return NT_STATUS_NO_MEMORY;
}
+ if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
+ pull->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
/* unravel the NDR for the packet */
status = call->dce->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r);
if (!NT_STATUS_IS_OK(status)) {
return NT_STATUS_NO_MEMORY;
}
+ if (lp_rpc_big_endian()) {
+ push->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
status = call->dce->ndr->calls[opnum].ndr_push(push, NDR_OUT, r);
if (!NT_STATUS_IS_OK(status)) {
return dcesrv_fault(call, DCERPC_FAULT_NDR);
}
/* form the dcerpc response packet */
- pkt.rpc_vers = 5;
- pkt.rpc_vers_minor = 0;
- pkt.drep[0] = 0x10; /* Little endian */
- pkt.drep[1] = 0;
- pkt.drep[2] = 0;
- pkt.drep[3] = 0;
+ dcesrv_init_hdr(&pkt);
pkt.auth_length = 0;
pkt.call_id = call->pkt.call_id;
pkt.ptype = DCERPC_PKT_RESPONSE;
return dcesrv_fault(call, DCERPC_FAULT_OTHER);
}
- SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length);
+ dcerpc_set_frag_length(&rep->data, rep->data.length);
DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *);
if (data->length < DCERPC_FRAG_LEN_OFFSET+2) {
return False;
}
- if (SVAL(data->data, DCERPC_FRAG_LEN_OFFSET) > data->length) {
+ if (dcerpc_get_frag_length(data) > data->length) {
return False;
}
return True;
call->replies = NULL;
blob = dce->partial_input;
- blob.length = SVAL(blob.data, DCERPC_FRAG_LEN_OFFSET);
+ blob.length = dcerpc_get_frag_length(&blob);
ndr = ndr_pull_init_blob(&blob, mem_ctx);
if (!ndr) {
return NT_STATUS_NO_MEMORY;
}
+ if (!(CVAL(blob.data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(dce->mem_ctx, dce->partial_input.data);
return False;
}
+ if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
if (!NT_STATUS_IS_OK(status)) {
return False;
/* non-signed packets are simple */
if (!dce->auth_state.auth_info || !dce->auth_state.ntlmssp_state) {
- status = dcerpc_push_auth(blob, call->mem_ctx, pkt, NULL, 0);
+ status = dcerpc_push_auth(blob, call->mem_ctx, pkt, NULL);
return NT_STATUS_IS_OK(status);
}
return False;
}
+ if (pkt->drep[0] & DCERPC_DREP_LE) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
status = ndr_push_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
if (!NT_STATUS_IS_OK(status)) {
return False;
/* 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, dce->auth_state.auth_info->credentials.length);
+ dcerpc_set_frag_length(blob, blob->length);
+ dcerpc_set_auth_length(blob, dce->auth_state.auth_info->credentials.length);
data_blob_free(&dce->auth_state.auth_info->credentials);