struct dcesrv_auth *auth = call->auth_state;
NTSTATUS status;
- if (pkt->auth_length == 0) {
+ if (pkt->frag_length > call->conn->transport_max_recv_frag) {
+ /*
+ * Note that we don't check against the negotiated
+ * max_recv_frag, but a hard coded value from
+ * the transport.
+ */
+ call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+ return false;
+ }
+
+ if (pkt->auth_length > 4096) {
+ call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
return false;
}
if (auth->auth_finished) {
+ call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+ return false;
+ }
+
+ if (!auth->auth_started) {
+ call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+ return false;
+ }
+
+ if (auth->auth_invalid) {
+ call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+ return false;
+ }
+
+ if (pkt->auth_length == 0) {
+ call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
return false;
}
status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info,
&call->in_auth_info, NULL, true);
if (!NT_STATUS_IS_OK(status)) {
+ struct dcerpc_auth *auth_info = &call->in_auth_info;
+ uint32_t nr = auth_info->auth_context_id;
+
/*
* Windows returns DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY
- * instead of DCERPC_NCA_S_PROTO_ERROR.
+ * instead of DCERPC_NCA_S_PROTO_ERROR in most cases.
*/
call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR) &&
+ nr != DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED)
+ {
+ call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
+ }
+
return false;
}
if (call->in_auth_info.auth_type != auth->auth_type) {
+ call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
return false;
}
if (call->in_auth_info.auth_level != auth->auth_level) {
+ call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
return false;
}
if (call->in_auth_info.auth_context_id != auth->auth_context_id) {
+ call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
return false;
}
struct tevent_req *subreq = NULL;
NTSTATUS status;
- if (!auth->auth_started) {
- return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
- }
-
- if (auth->auth_finished) {
- return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
- }
-
status = dcerpc_verify_ncacn_packet_header(&call->pkt,
DCERPC_PKT_AUTH3,
call->pkt.u.auth3.auth_info.length,