mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
s4-rpc: be more careful about DCERPC auth padding
Cope with a wider range of auth padding in dcerpc bind_ack and alter_context packets. We now use a helper function that calculates the right auth padding.
This commit is contained in:
parent
3ae75a4248
commit
da86f08605
@ -51,7 +51,6 @@ struct dcerpc_bind {
|
||||
uint32_t assoc_group_id;
|
||||
uint8_t num_contexts;
|
||||
struct dcerpc_ctx_list *ctx_list;
|
||||
DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_ALIGN4)] */
|
||||
DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */
|
||||
};
|
||||
|
||||
@ -181,17 +180,14 @@ struct dcerpc_auth {
|
||||
}/* [public] */;
|
||||
|
||||
struct dcerpc_auth3 {
|
||||
uint32_t _pad;
|
||||
DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */
|
||||
}/* [public] */;
|
||||
|
||||
struct dcerpc_orphaned {
|
||||
uint32_t _pad;
|
||||
DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */
|
||||
}/* [public] */;
|
||||
|
||||
struct dcerpc_co_cancel {
|
||||
uint32_t _pad;
|
||||
DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */
|
||||
}/* [public] */;
|
||||
|
||||
|
@ -78,12 +78,6 @@ static enum ndr_err_code ndr_push_dcerpc_bind(struct ndr_push *ndr, int ndr_flag
|
||||
for (cntr_ctx_list_0 = 0; cntr_ctx_list_0 < r->num_contexts; cntr_ctx_list_0++) {
|
||||
NDR_CHECK(ndr_push_dcerpc_ctx_list(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0]));
|
||||
}
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4);
|
||||
NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad));
|
||||
ndr->flags = _flags_save_DATA_BLOB;
|
||||
}
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
|
||||
@ -114,12 +108,6 @@ static enum ndr_err_code ndr_pull_dcerpc_bind(struct ndr_pull *ndr, int ndr_flag
|
||||
NDR_CHECK(ndr_pull_dcerpc_ctx_list(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0]));
|
||||
}
|
||||
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ctx_list_0, 0);
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4);
|
||||
NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad));
|
||||
ndr->flags = _flags_save_DATA_BLOB;
|
||||
}
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
|
||||
@ -152,7 +140,6 @@ _PUBLIC_ void ndr_print_dcerpc_bind(struct ndr_print *ndr, const char *name, con
|
||||
}
|
||||
}
|
||||
ndr->depth--;
|
||||
ndr_print_DATA_BLOB(ndr, "_pad", r->_pad);
|
||||
ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info);
|
||||
ndr->depth--;
|
||||
}
|
||||
@ -879,7 +866,6 @@ _PUBLIC_ enum ndr_err_code ndr_push_dcerpc_auth3(struct ndr_push *ndr, int ndr_f
|
||||
{
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
NDR_CHECK(ndr_push_align(ndr, 4));
|
||||
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_pad));
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
|
||||
@ -897,7 +883,6 @@ _PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_auth3(struct ndr_pull *ndr, int ndr_f
|
||||
{
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
NDR_CHECK(ndr_pull_align(ndr, 4));
|
||||
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad));
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
|
||||
@ -915,7 +900,6 @@ _PUBLIC_ void ndr_print_dcerpc_auth3(struct ndr_print *ndr, const char *name, co
|
||||
{
|
||||
ndr_print_struct(ndr, name, "dcerpc_auth3");
|
||||
ndr->depth++;
|
||||
ndr_print_uint32(ndr, "_pad", r->_pad);
|
||||
ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info);
|
||||
ndr->depth--;
|
||||
}
|
||||
@ -924,7 +908,6 @@ _PUBLIC_ enum ndr_err_code ndr_push_dcerpc_orphaned(struct ndr_push *ndr, int nd
|
||||
{
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
NDR_CHECK(ndr_push_align(ndr, 4));
|
||||
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_pad));
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
|
||||
@ -942,7 +925,6 @@ _PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_orphaned(struct ndr_pull *ndr, int nd
|
||||
{
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
NDR_CHECK(ndr_pull_align(ndr, 4));
|
||||
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad));
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
|
||||
@ -960,7 +942,6 @@ _PUBLIC_ void ndr_print_dcerpc_orphaned(struct ndr_print *ndr, const char *name,
|
||||
{
|
||||
ndr_print_struct(ndr, name, "dcerpc_orphaned");
|
||||
ndr->depth++;
|
||||
ndr_print_uint32(ndr, "_pad", r->_pad);
|
||||
ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info);
|
||||
ndr->depth--;
|
||||
}
|
||||
@ -969,7 +950,6 @@ _PUBLIC_ enum ndr_err_code ndr_push_dcerpc_co_cancel(struct ndr_push *ndr, int n
|
||||
{
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
NDR_CHECK(ndr_push_align(ndr, 4));
|
||||
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_pad));
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
|
||||
@ -987,7 +967,6 @@ _PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_co_cancel(struct ndr_pull *ndr, int n
|
||||
{
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
NDR_CHECK(ndr_pull_align(ndr, 4));
|
||||
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad));
|
||||
{
|
||||
uint32_t _flags_save_DATA_BLOB = ndr->flags;
|
||||
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
|
||||
@ -1005,7 +984,6 @@ _PUBLIC_ void ndr_print_dcerpc_co_cancel(struct ndr_print *ndr, const char *name
|
||||
{
|
||||
ndr_print_struct(ndr, name, "dcerpc_co_cancel");
|
||||
ndr->depth++;
|
||||
ndr_print_uint32(ndr, "_pad", r->_pad);
|
||||
ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info);
|
||||
ndr->depth--;
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ interface dcerpc
|
||||
uint32 assoc_group_id;
|
||||
uint8 num_contexts;
|
||||
dcerpc_ctx_list ctx_list[num_contexts];
|
||||
[flag(NDR_ALIGN4)] DATA_BLOB _pad;
|
||||
[flag(NDR_REMAINING)] DATA_BLOB auth_info;
|
||||
} dcerpc_bind;
|
||||
|
||||
@ -156,17 +155,14 @@ interface dcerpc
|
||||
const uint8 DCERPC_AUTH_TRAILER_LENGTH = 8;
|
||||
|
||||
typedef [public] struct {
|
||||
uint32 _pad;
|
||||
[flag(NDR_REMAINING)] DATA_BLOB auth_info;
|
||||
} dcerpc_auth3;
|
||||
|
||||
typedef [public] struct {
|
||||
uint32 _pad;
|
||||
[flag(NDR_REMAINING)] DATA_BLOB auth_info;
|
||||
} dcerpc_orphaned;
|
||||
|
||||
typedef [public] struct {
|
||||
uint32 _pad;
|
||||
[flag(NDR_REMAINING)] DATA_BLOB auth_info;
|
||||
} dcerpc_co_cancel;
|
||||
|
||||
|
@ -223,11 +223,9 @@ static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX
|
||||
DATA_BLOB *raw_packet,
|
||||
struct ncacn_packet *pkt)
|
||||
{
|
||||
struct ndr_pull *ndr;
|
||||
NTSTATUS status;
|
||||
struct dcerpc_auth auth;
|
||||
DATA_BLOB auth_blob;
|
||||
enum ndr_err_code ndr_err;
|
||||
uint32_t auth_length;
|
||||
|
||||
if (!c->security_state.auth_info ||
|
||||
!c->security_state.generic_state) {
|
||||
@ -254,33 +252,12 @@ static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX
|
||||
return NT_STATUS_INVALID_LEVEL;
|
||||
}
|
||||
|
||||
auth_blob.length = 8 + pkt->auth_length;
|
||||
status = dcerpc_pull_auth_trailer(pkt, mem_ctx,
|
||||
&pkt->u.response.stub_and_verifier,
|
||||
&auth, &auth_length, false);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
/* check for a valid length */
|
||||
if (pkt->u.response.stub_and_verifier.length < auth_blob.length) {
|
||||
return NT_STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
auth_blob.data =
|
||||
pkt->u.response.stub_and_verifier.data +
|
||||
pkt->u.response.stub_and_verifier.length - auth_blob.length;
|
||||
pkt->u.response.stub_and_verifier.length -= auth_blob.length;
|
||||
|
||||
/* pull the auth structure */
|
||||
ndr = ndr_pull_init_flags(c, &auth_blob, mem_ctx);
|
||||
if (!ndr) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
|
||||
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
|
||||
}
|
||||
|
||||
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;
|
||||
pkt->u.response.stub_and_verifier.length -= auth_length;
|
||||
|
||||
/* check signature or unseal the packet */
|
||||
switch (c->security_state.auth_info->auth_level) {
|
||||
@ -317,7 +294,7 @@ static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX
|
||||
break;
|
||||
}
|
||||
|
||||
/* remove the indicated amount of paddiing */
|
||||
/* remove the indicated amount of padding */
|
||||
if (pkt->u.response.stub_and_verifier.length < auth.auth_pad_length) {
|
||||
return NT_STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
@ -600,7 +577,6 @@ static void dcerpc_recv_data(struct dcerpc_connection *conn, DATA_BLOB *blob, NT
|
||||
dcerpc_request_recv_data(conn, blob, &pkt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Receive a bind reply from the transport
|
||||
*/
|
||||
@ -643,17 +619,14 @@ static void dcerpc_bind_recv_handler(struct rpc_request *req,
|
||||
}
|
||||
|
||||
/* the bind_ack might contain a reply set of credentials */
|
||||
if (conn->security_state.auth_info &&
|
||||
pkt->u.bind_ack.auth_info.length) {
|
||||
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 (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
c->status = ndr_map_error2ntstatus(ndr_err);
|
||||
if (!composite_is_ok(c)) return;
|
||||
if (conn->security_state.auth_info && pkt->u.bind_ack.auth_info.length) {
|
||||
NTSTATUS status;
|
||||
uint32_t auth_length;
|
||||
status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.bind_ack.auth_info,
|
||||
conn->security_state.auth_info, &auth_length, true);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
composite_error(c, status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,7 +764,6 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
|
||||
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
|
||||
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) {
|
||||
@ -1610,15 +1582,14 @@ static void dcerpc_alter_recv_handler(struct rpc_request *req,
|
||||
/* 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) {
|
||||
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 (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
c->status = ndr_map_error2ntstatus(ndr_err);
|
||||
if (!composite_is_ok(c)) return;
|
||||
struct dcerpc_connection *conn = recv_pipe->conn;
|
||||
NTSTATUS status;
|
||||
uint32_t auth_length;
|
||||
status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.alter_resp.auth_info,
|
||||
conn->security_state.auth_info, &auth_length, true);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
composite_error(c, status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,10 @@ NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
if (auth_info) {
|
||||
ndr_err = ndr_push_zero(ndr, auth_info->auth_pad_length);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
return ndr_map_error2ntstatus(ndr_err);
|
||||
}
|
||||
ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth_info);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
return ndr_map_error2ntstatus(ndr_err);
|
||||
@ -750,3 +754,59 @@ _PUBLIC_ NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p,
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
pull an dcerpc_auth structure, taking account of any auth padding in
|
||||
the blob at the end of the structure
|
||||
*/
|
||||
NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *pkt_auth_blob,
|
||||
struct dcerpc_auth *auth,
|
||||
uint32_t *auth_length,
|
||||
bool check_pad)
|
||||
{
|
||||
struct ndr_pull *ndr;
|
||||
enum ndr_err_code ndr_err;
|
||||
uint32_t pad;
|
||||
|
||||
pad = pkt_auth_blob->length - (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length);
|
||||
*auth_length = pkt_auth_blob->length - pad;
|
||||
|
||||
ndr = ndr_pull_init_blob(pkt_auth_blob, mem_ctx, NULL);
|
||||
if (!ndr) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
|
||||
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_advance(ndr, pad);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
talloc_free(ndr);
|
||||
return ndr_map_error2ntstatus(ndr_err);
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
talloc_free(ndr);
|
||||
return ndr_map_error2ntstatus(ndr_err);
|
||||
}
|
||||
|
||||
if (check_pad && pad != auth->auth_pad_length) {
|
||||
DEBUG(1,(__location__ ": WARNING: pad length mismatch. Calculated %u got %u\n",
|
||||
(unsigned)pad, (unsigned)auth->auth_pad_length));
|
||||
}
|
||||
|
||||
DEBUG(6,(__location__ ": auth_pad_length %u\n",
|
||||
(unsigned)auth->auth_pad_length));
|
||||
|
||||
talloc_steal(mem_ctx, auth->credentials.data);
|
||||
talloc_free(ndr);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,7 +42,7 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call)
|
||||
struct dcesrv_connection *dce_conn = call->conn;
|
||||
struct dcesrv_auth *auth = &dce_conn->auth_state;
|
||||
NTSTATUS status;
|
||||
enum ndr_err_code ndr_err;
|
||||
uint32_t auth_length;
|
||||
|
||||
if (pkt->u.bind.auth_info.length == 0) {
|
||||
dce_conn->auth_state.auth_info = NULL;
|
||||
@ -54,14 +54,9 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call)
|
||||
return false;
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_struct_blob(&pkt->u.bind.auth_info,
|
||||
call, NULL,
|
||||
dce_conn->auth_state.auth_info,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info,
|
||||
dce_conn->auth_state.auth_info,
|
||||
&auth_length, false);
|
||||
server_credentials
|
||||
= cli_credentials_init(call);
|
||||
if (!server_credentials) {
|
||||
@ -155,7 +150,7 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call)
|
||||
struct ncacn_packet *pkt = &call->pkt;
|
||||
struct dcesrv_connection *dce_conn = call->conn;
|
||||
NTSTATUS status;
|
||||
enum ndr_err_code ndr_err;
|
||||
uint32_t auth_length;
|
||||
|
||||
/* We can't work without an existing gensec state, and an new blob to feed it */
|
||||
if (!dce_conn->auth_state.auth_info ||
|
||||
@ -164,11 +159,9 @@ bool dcesrv_auth_auth3(struct dcesrv_call_state *call)
|
||||
return false;
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_struct_blob(&pkt->u.auth3.auth_info,
|
||||
call, NULL,
|
||||
dce_conn->auth_state.auth_info,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info,
|
||||
dce_conn->auth_state.auth_info, &auth_length, true);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -205,7 +198,8 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call)
|
||||
{
|
||||
struct ncacn_packet *pkt = &call->pkt;
|
||||
struct dcesrv_connection *dce_conn = call->conn;
|
||||
enum ndr_err_code ndr_err;
|
||||
NTSTATUS status;
|
||||
uint32_t auth_length;
|
||||
|
||||
/* on a pure interface change there is no auth blob */
|
||||
if (pkt->u.alter.auth_info.length == 0) {
|
||||
@ -222,11 +216,10 @@ bool dcesrv_auth_alter(struct dcesrv_call_state *call)
|
||||
return false;
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_struct_blob(&pkt->u.alter.auth_info,
|
||||
call, NULL,
|
||||
dce_conn->auth_state.auth_info,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info,
|
||||
dce_conn->auth_state.auth_info,
|
||||
&auth_length, true);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -286,11 +279,9 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet)
|
||||
{
|
||||
struct ncacn_packet *pkt = &call->pkt;
|
||||
struct dcesrv_connection *dce_conn = call->conn;
|
||||
DATA_BLOB auth_blob;
|
||||
struct dcerpc_auth auth;
|
||||
struct ndr_pull *ndr;
|
||||
NTSTATUS status;
|
||||
enum ndr_err_code ndr_err;
|
||||
uint32_t auth_length;
|
||||
size_t hdr_size = DCERPC_REQUEST_LENGTH;
|
||||
|
||||
if (!dce_conn->auth_state.auth_info ||
|
||||
@ -298,6 +289,10 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
|
||||
hdr_size += 16;
|
||||
}
|
||||
|
||||
switch (dce_conn->auth_state.auth_info->auth_level) {
|
||||
case DCERPC_AUTH_LEVEL_PRIVACY:
|
||||
case DCERPC_AUTH_LEVEL_INTEGRITY:
|
||||
@ -318,38 +313,14 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet)
|
||||
return false;
|
||||
}
|
||||
|
||||
auth_blob.length = 8 + pkt->auth_length;
|
||||
|
||||
/* check for a valid length */
|
||||
if (pkt->u.request.stub_and_verifier.length < auth_blob.length) {
|
||||
status = dcerpc_pull_auth_trailer(pkt, call,
|
||||
&pkt->u.request.stub_and_verifier,
|
||||
&auth, &auth_length, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auth_blob.data =
|
||||
pkt->u.request.stub_and_verifier.data +
|
||||
pkt->u.request.stub_and_verifier.length - auth_blob.length;
|
||||
pkt->u.request.stub_and_verifier.length -= auth_blob.length;
|
||||
|
||||
/* pull the auth structure */
|
||||
ndr = ndr_pull_init_blob(&auth_blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx));
|
||||
if (!ndr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
|
||||
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
|
||||
}
|
||||
|
||||
if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
|
||||
ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
|
||||
hdr_size += 16;
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
talloc_free(ndr);
|
||||
return false;
|
||||
}
|
||||
pkt->u.request.stub_and_verifier.length -= auth_length;
|
||||
|
||||
/* check signature or unseal the packet */
|
||||
switch (dce_conn->auth_state.auth_info->auth_level) {
|
||||
@ -388,11 +359,9 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet)
|
||||
|
||||
/* remove the indicated amount of padding */
|
||||
if (pkt->u.request.stub_and_verifier.length < auth.auth_pad_length) {
|
||||
talloc_free(ndr);
|
||||
return false;
|
||||
}
|
||||
pkt->u.request.stub_and_verifier.length -= auth.auth_pad_length;
|
||||
talloc_free(ndr);
|
||||
|
||||
return NT_STATUS_IS_OK(status);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user