diff options
Diffstat (limited to 'source4/librpc')
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 142 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_util.c | 29 |
2 files changed, 103 insertions, 68 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 9d58fafcb8..ef63cb381b 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -192,6 +192,7 @@ static NTSTATUS ncacn_pull(struct dcerpc_connection *c, DATA_BLOB *blob, TALLOC_ 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) { @@ -202,7 +203,12 @@ static NTSTATUS ncacn_pull(struct dcerpc_connection *c, DATA_BLOB *blob, TALLOC_ 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; } /* @@ -242,6 +248,7 @@ static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX 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) { @@ -270,11 +277,12 @@ static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX 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: @@ -333,6 +341,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, 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 || @@ -353,10 +362,11 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, 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 */ @@ -398,10 +408,11 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, } /* 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); @@ -651,11 +662,15 @@ 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) { - 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, 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; @@ -1155,8 +1170,8 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c, 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) { @@ -1169,11 +1184,13 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c, } 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); @@ -1181,11 +1198,13 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c, 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); @@ -1195,9 +1214,9 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c, 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; @@ -1221,10 +1240,10 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c, 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) { @@ -1237,11 +1256,13 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c, 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); @@ -1252,11 +1273,13 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c, } 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); @@ -1264,11 +1287,13 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c, 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); @@ -1278,9 +1303,9 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c, 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 @@ -1299,8 +1324,9 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c, file_save("gen.dat", s2, strlen(s2)); system("diff -u wire.dat gen.dat"); #endif - return ndr_push_error(push, NDR_ERR_VALIDATE, - "failed output validation strings doesn't match"); + 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; @@ -1322,6 +1348,7 @@ 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]; @@ -1336,8 +1363,9 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p, } /* 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); @@ -1392,6 +1420,7 @@ _PUBLIC_ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req) 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 */ @@ -1427,8 +1456,9 @@ _PUBLIC_ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req) 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; @@ -1547,11 +1577,15 @@ 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) { - 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, 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); diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index aa65861c3f..6c23ec20a0 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -53,8 +53,8 @@ NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct ncacn_packet *pkt, struct dcerpc_auth *auth_info) { - NTSTATUS status; struct ndr_push *ndr; + enum ndr_err_code ndr_err; ndr = ndr_push_init_ctx(mem_ctx); if (!ndr) { @@ -75,15 +75,15 @@ NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, pkt->auth_length = 0; } - 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); } if (auth_info) { - status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth_info); - if (!NT_STATUS_IS_OK(status)) { - return status; + 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); } } @@ -440,22 +440,23 @@ NTSTATUS dcerpc_floor_get_lhs_data(struct epm_floor *epm_floor, struct ndr_synta { TALLOC_CTX *mem_ctx = talloc_init("floor_get_lhs_data"); struct ndr_pull *ndr = ndr_pull_init_blob(&epm_floor->lhs.lhs_data, mem_ctx); - NTSTATUS status; + enum ndr_err_code ndr_err; uint16_t if_version=0; ndr->flags |= LIBNDR_FLAG_NOALIGN; - status = ndr_pull_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_pull_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(mem_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } - status = ndr_pull_uint16(ndr, NDR_SCALARS, &if_version); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_pull_uint16(ndr, NDR_SCALARS, &if_version); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(mem_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } + syntax->if_version = if_version; talloc_free(mem_ctx); |