diff --git a/reactos/dll/win32/rpcrt4_new/ndr_marshall.c b/reactos/dll/win32/rpcrt4_new/ndr_marshall.c index d8395b80d44..de84410d6a3 100644 --- a/reactos/dll/win32/rpcrt4_new/ndr_marshall.c +++ b/reactos/dll/win32/rpcrt4_new/ndr_marshall.c @@ -21,7 +21,6 @@ * TODO: * - Non-conformant strings * - String structs - * - Encapsulated unions * - Byte count pointers * - transmit_as/represent as * - Multi-dimensional arrays @@ -351,6 +350,8 @@ static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat) static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) { ALIGN_POINTER(pStubMsg->Buffer, 4); + if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd) + RpcRaiseException(RPC_X_BAD_STUB_DATA); pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); pStubMsg->Buffer += 4; TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount); @@ -370,6 +371,8 @@ static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_S } ALIGN_POINTER(pStubMsg->Buffer, 4); + if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd) + RpcRaiseException(RPC_X_BAD_STUB_DATA); pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); pStubMsg->Buffer += 4; TRACE("offset is %d\n", pStubMsg->Offset); @@ -571,6 +574,24 @@ static inline ULONG safe_multiply(ULONG a, ULONG b) return ret; } +static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) +{ + if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ + (pStubMsg->Buffer + size > pStubMsg->BufferEnd)) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + pStubMsg->Buffer += size; +} + +/* copies data from the buffer, checking that there is enough data in the buffer + * to do so */ +static inline void safe_buffer_copy(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size) +{ + if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ + (pStubMsg->Buffer + size > pStubMsg->BufferEnd)) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + memcpy(p, pStubMsg->Buffer, size); + pStubMsg->Buffer += size; +} /* * NdrConformantString: @@ -735,6 +756,17 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg RpcRaiseException(RPC_S_INVALID_BOUND); return NULL; } + + /* verify the buffer is safe to access */ + if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || + (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) + { + ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, + pStubMsg->BufferEnd, pStubMsg->Buffer); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + return NULL; + } + for (i = bufsize - esize; i < bufsize; i++) if (pStubMsg->Buffer[i] != 0) { @@ -747,9 +779,7 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg if (fMustAlloc || !*ppMemory) *ppMemory = NdrAllocate(pStubMsg, memsize); - memcpy(*ppMemory, pStubMsg->Buffer, bufsize); - - pStubMsg->Buffer += bufsize; + safe_buffer_copy(pStubMsg, *ppMemory, bufsize); if (*pFormat == RPC_FC_C_CSTRING) { TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); @@ -1539,7 +1569,7 @@ unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, { ALIGN_POINTER(pStubMsg->Buffer, 4); Buffer = pStubMsg->Buffer; - pStubMsg->Buffer += 4; + safe_buffer_increment(pStubMsg, 4); } else Buffer = pStubMsg->Buffer; @@ -1718,7 +1748,7 @@ void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg, } -static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) { switch (*pFormat) { @@ -1894,31 +1924,27 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_CHAR: case RPC_FC_SMALL: case RPC_FC_USMALL: - memcpy(pMemory, pStubMsg->Buffer, 1); + safe_buffer_copy(pStubMsg, pMemory, 1); TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory); - pStubMsg->Buffer += 1; pMemory += 1; break; case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: - memcpy(pMemory, pStubMsg->Buffer, 2); + safe_buffer_copy(pStubMsg, pMemory, 2); TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory); - pStubMsg->Buffer += 2; pMemory += 2; break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: - memcpy(pMemory, pStubMsg->Buffer, 4); + safe_buffer_copy(pStubMsg, pMemory, 4); TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory); - pStubMsg->Buffer += 4; pMemory += 4; break; case RPC_FC_HYPER: - memcpy(pMemory, pStubMsg->Buffer, 8); + safe_buffer_copy(pStubMsg, pMemory, 8); TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); - pStubMsg->Buffer += 8; pMemory += 8; break; case RPC_FC_POINTER: @@ -2547,10 +2573,8 @@ unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, ALIGN_POINTER(pStubMsg->Buffer, alignment); - memcpy(*ppMemory, pStubMsg->Buffer, size); - pStubMsg->BufferMark = pStubMsg->Buffer; - pStubMsg->Buffer += size; + safe_buffer_copy(pStubMsg, *ppMemory, size); EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -2697,8 +2721,7 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS if (!*ppMemory || fMustAlloc) *ppMemory = NdrAllocate(pStubMsg, memsize); - memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize); - pStubMsg->Buffer += bufsize; + safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize); EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -3086,7 +3109,7 @@ void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg, pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL); } -static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg) +static ULONG UserMarshalFlags(const MIDL_STUB_MESSAGE *pStubMsg) { return MAKELONG(pStubMsg->dwDestContext, pStubMsg->RpcMsg->DataRepresentation); @@ -3436,8 +3459,7 @@ unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMs /* now copy the data */ pStubMsg->BufferMark = pStubMsg->Buffer; - memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize); - pStubMsg->Buffer += pCStructFormat->memory_size + bufsize; + safe_buffer_copy(pStubMsg, *ppMemory, pCStructFormat->memory_size + bufsize); if (pCStructFormat->type == RPC_FC_CPSTRUCT) EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -3659,8 +3681,7 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE /* copy the constant data */ pStubMsg->BufferMark = pStubMsg->Buffer; - memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size); - pStubMsg->Buffer += pCVStructFormat->memory_size; + safe_buffer_copy(pStubMsg, *ppMemory, pCVStructFormat->memory_size); pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount); @@ -3688,9 +3709,7 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE } /* copy the array data */ - memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer, - bufsize); - pStubMsg->Buffer += bufsize; + safe_buffer_copy(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize); if (cvarray_type == RPC_FC_C_CSTRING) TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size))); @@ -3999,9 +4018,8 @@ unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, if (fMustAlloc || !*ppMemory) *ppMemory = NdrAllocate(pStubMsg, total_size); - memcpy(*ppMemory, pStubMsg->Buffer, total_size); pStubMsg->BufferMark = pStubMsg->Buffer; - pStubMsg->Buffer += total_size; + safe_buffer_copy(pStubMsg, *ppMemory, total_size); pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -4234,8 +4252,7 @@ unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, if (!*ppMemory || fMustAlloc) *ppMemory = NdrAllocate(pStubMsg, size); - memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize); - pStubMsg->Buffer += bufsize; + safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize); EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -4402,7 +4419,7 @@ void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg, EmbeddedPointerFree(pStubMsg, pMemory, pFormat); } -static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory) +static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory) { switch (fc) { @@ -4410,16 +4427,16 @@ static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory) case RPC_FC_CHAR: case RPC_FC_SMALL: case RPC_FC_USMALL: - return *(UCHAR *)pMemory; + return *(const UCHAR *)pMemory; case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: case RPC_FC_ENUM16: - return *(USHORT *)pMemory; + return *(const USHORT *)pMemory; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: - return *(ULONG *)pMemory; + return *(const ULONG *)pMemory; default: FIXME("Unhandled base type: 0x%02x\n", fc); return 0; @@ -4539,7 +4556,7 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, if((type & 0xff00) == 0x8000) { unsigned char basetype = LOBYTE(type); - return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc); + return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE); } else { @@ -4567,6 +4584,9 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, else pStubMsg->Buffer += 4; /* for pointer ID */ + if (saved_buffer + 4 > pStubMsg->BufferEnd) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, fMustAlloc); if (pointer_buffer_mark_set) { @@ -4900,22 +4920,31 @@ static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_CHAR: case RPC_FC_SMALL: case RPC_FC_USMALL: - discriminant = *(UCHAR *)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(UCHAR); + { + UCHAR d; + safe_buffer_copy(pStubMsg, &d, sizeof(d)); + discriminant = d; break; + } case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: + { + USHORT d; ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); - discriminant = *(USHORT *)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(USHORT); + safe_buffer_copy(pStubMsg, &d, sizeof(d)); + discriminant = d; break; + } case RPC_FC_LONG: case RPC_FC_ULONG: + { + ULONG d; ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG)); - discriminant = *(ULONG *)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(ULONG); + safe_buffer_copy(pStubMsg, &d, sizeof(d)); + discriminant = d; break; + } default: FIXME("Unhandled base type: 0x%02x\n", **ppFormat); } @@ -5354,7 +5383,7 @@ static unsigned char *WINAPI NdrBaseTypeMarshall( break; case RPC_FC_ENUM16: /* only 16-bits on the wire, so do a sanity check */ - if (*(UINT *)pMemory > USHRT_MAX) + if (*(UINT *)pMemory > SHRT_MAX) RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory; @@ -5655,6 +5684,9 @@ void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, ALIGN_POINTER(pStubMsg->Buffer, 4); + if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + NDRCContextUnmarshall(pContextHandle, BindHandle, pStubMsg->Buffer, @@ -5741,7 +5773,7 @@ static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext) return che; } -static struct context_handle_entry *context_entry_from_guid(LPGUID uuid) +static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid) { struct context_handle_entry *che; LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry) @@ -5791,7 +5823,7 @@ void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff) static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext, RPC_BINDING_HANDLE hBinding, - ndr_context_handle *chi) + const ndr_context_handle *chi) { struct context_handle_entry *che = NULL; diff --git a/reactos/dll/win32/rpcrt4_new/rpc_binding.c b/reactos/dll/win32/rpcrt4_new/rpc_binding.c index db30be63ba8..f69d2909c4c 100644 --- a/reactos/dll/win32/rpcrt4_new/rpc_binding.c +++ b/reactos/dll/win32/rpcrt4_new/rpc_binding.c @@ -274,8 +274,8 @@ RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding) } RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, - PRPC_SYNTAX_IDENTIFIER TransferSyntax, - PRPC_SYNTAX_IDENTIFIER InterfaceId) + const RPC_SYNTAX_IDENTIFIER *TransferSyntax, + const RPC_SYNTAX_IDENTIFIER *InterfaceId) { TRACE("(Binding == ^%p)\n", Binding); diff --git a/reactos/dll/win32/rpcrt4_new/rpc_binding.h b/reactos/dll/win32/rpcrt4_new/rpc_binding.h index 5113b27e358..f01ae6e84a6 100644 --- a/reactos/dll/win32/rpcrt4_new/rpc_binding.h +++ b/reactos/dll/win32/rpcrt4_new/rpc_binding.h @@ -161,13 +161,14 @@ RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid); RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection); RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding); RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding); -RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, PRPC_SYNTAX_IDENTIFIER TransferSyntax, PRPC_SYNTAX_IDENTIFIER InterfaceId); +RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, + const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId); RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection); BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply); HANDLE RPCRT4_GetMasterMutex(void); HANDLE RPCRT4_RpcssNPConnect(void); -static inline const char *rpcrt4_conn_get_name(RpcConnection *Connection) +static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection) { return Connection->ops->name; } diff --git a/reactos/dll/win32/rpcrt4_new/rpc_defs.h b/reactos/dll/win32/rpcrt4_new/rpc_defs.h index 7499dcd1c1d..c0c3609f1cc 100644 --- a/reactos/dll/win32/rpcrt4_new/rpc_defs.h +++ b/reactos/dll/win32/rpcrt4_new/rpc_defs.h @@ -177,9 +177,25 @@ typedef struct #define PKT_CO_CANCEL 18 #define PKT_ORPHANED 19 -#define RESULT_ACCEPT 0 +#define RESULT_ACCEPT 0 +#define RESULT_USER_REJECTION 1 +#define RESULT_PROVIDER_REJECTION 2 -#define NO_REASON 0 +#define REASON_NONE 0 +#define REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED 1 +#define REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED 2 +#define REASON_LOCAL_LIMIT_EXCEEDED 3 + +#define REJECT_REASON_NOT_SPECIFIED 0 +#define REJECT_TEMPORARY_CONGESTION 1 +#define REJECT_LOCAL_LIMIT_EXCEEDED 2 +#define REJECT_CALLED_PADDR_UNKNOWN 3 /* not used */ +#define REJECT_PROTOCOL_VERSION_NOT_SUPPORTED 4 +#define REJECT_DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */ +#define REJECT_USER_DATA_NOT_READABLE 6 /* not used */ +#define REJECT_NO_PSAP_AVAILABLE 7 /* not used */ +#define REJECT_UNKNOWN_AUTHN_SERVICE 8 +#define REJECT_INVALID_CHECKSUM 9 #define NCADG_IP_UDP 0x08 #define NCACN_IP_TCP 0x07 diff --git a/reactos/dll/win32/rpcrt4_new/rpc_message.c b/reactos/dll/win32/rpcrt4_new/rpc_message.c index bfd5aece881..37839f7ce87 100644 --- a/reactos/dll/win32/rpcrt4_new/rpc_message.c +++ b/reactos/dll/win32/rpcrt4_new/rpc_message.c @@ -230,6 +230,7 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, RPCRT4_BuildCommonHeader(header, PKT_BIND_NACK, DataRepresentation); header->common.frag_len = sizeof(header->bind_nack); + header->bind_nack.reject_reason = REJECT_REASON_NOT_SPECIFIED; header->bind_nack.protocols_count = 1; header->bind_nack.protocols[0].rpc_ver = RpcVersion; header->bind_nack.protocols[0].rpc_ver_minor = RpcVersionMinor; @@ -301,6 +302,12 @@ NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status) case RPC_S_INVALID_BOUND: return NCA_S_FAULT_INVALID_BOUND; case RPC_S_PROCNUM_OUT_OF_RANGE: return NCA_S_OP_RNG_ERROR; case RPC_X_SS_HANDLES_MISMATCH: return NCA_S_FAULT_CONTEXT_MISMATCH; + case RPC_S_CALL_CANCELLED: return NCA_S_FAULT_CANCEL; + case RPC_S_COMM_FAILURE: return NCA_S_COMM_FAILURE; + case RPC_X_WRONG_PIPE_ORDER: return NCA_S_FAULT_PIPE_ORDER; + case RPC_X_PIPE_CLOSED: return NCA_S_FAULT_PIPE_CLOSED; + case RPC_X_PIPE_DISCIPLINE_ERROR: return NCA_S_FAULT_PIPE_DISCIPLINE; + case RPC_X_PIPE_EMPTY: return NCA_S_FAULT_PIPE_EMPTY; case STATUS_FLOAT_DIVIDE_BY_ZERO: return NCA_S_FAULT_FP_DIV_ZERO; case STATUS_FLOAT_INVALID_OPERATION: return NCA_S_FAULT_FP_ERROR; case STATUS_FLOAT_OVERFLOW: return NCA_S_FAULT_FP_OVERFLOW; @@ -433,7 +440,7 @@ static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection, */ static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength, - void *Auth, unsigned int AuthLength) + const void *Auth, unsigned int AuthLength) { PUCHAR buffer_pos; DWORD hdr_size; @@ -1013,6 +1020,7 @@ static inline BOOL is_hard_error(RPC_STATUS status) case RPC_S_PROTOCOL_ERROR: case RPC_S_CALL_FAILED: case RPC_S_CALL_FAILED_DNE: + case RPC_S_SEC_PKG_ERROR: return TRUE; default: return FALSE; diff --git a/reactos/dll/win32/rpcrt4_new/rpc_server.c b/reactos/dll/win32/rpcrt4_new/rpc_server.c index 328c0d0fc96..b62954bded7 100644 --- a/reactos/dll/win32/rpcrt4_new/rpc_server.c +++ b/reactos/dll/win32/rpcrt4_new/rpc_server.c @@ -119,7 +119,7 @@ static inline UUID *LookupObjType(UUID *ObjUuid) } static RpcServerInterface* RPCRT4_find_interface(UUID* object, - RPC_SYNTAX_IDENTIFIER* if_id, + const RPC_SYNTAX_IDENTIFIER* if_id, BOOL check_object) { UUID* MgrType = NULL; @@ -198,7 +198,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, conn->Endpoint, - RESULT_ACCEPT, NO_REASON, + RESULT_ACCEPT, REASON_NONE, &sif->If->TransferSyntax); /* save the interface for later use */ diff --git a/reactos/dll/win32/rpcrt4_new/rpc_transport.c b/reactos/dll/win32/rpcrt4_new/rpc_transport.c index 071ccb99973..b99f4fc553e 100644 --- a/reactos/dll/win32/rpcrt4_new/rpc_transport.c +++ b/reactos/dll/win32/rpcrt4_new/rpc_transport.c @@ -1211,7 +1211,7 @@ static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq if (!poll_info) return -1; - + ret = poll(poll_info, count, -1); if (ret < 0) { @@ -1484,7 +1484,9 @@ ULONG RpcAssoc_Release(RpcAssoc *assoc) return refs; } -static RPC_STATUS RpcAssoc_BindConnection(RpcAssoc *assoc, RpcConnection *conn, +#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1)) + +static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection *conn, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax) { @@ -1512,23 +1514,98 @@ static RPC_STATUS RpcAssoc_BindConnection(RpcAssoc *assoc, RpcConnection *conn, return status; } - if (response_hdr->common.ptype != PKT_BIND_ACK) + switch (response_hdr->common.ptype) { - ERR("failed to bind for interface %s, %d.%d\n", - debugstr_guid(&InterfaceId->SyntaxGUID), - InterfaceId->SyntaxVersion.MajorVersion, - InterfaceId->SyntaxVersion.MinorVersion); - RPCRT4_FreeHeader(response_hdr); - return RPC_S_PROTOCOL_ERROR; + case PKT_BIND_ACK: + { + RpcAddressString *server_address = msg.Buffer; + if ((msg.BufferLength >= FIELD_OFFSET(RpcAddressString, string[0])) || + (msg.BufferLength >= ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4))) + { + unsigned short remaining = msg.BufferLength - + ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4); + RpcResults *results = (RpcResults*)((ULONG_PTR)server_address + + ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4)); + if ((results->num_results == 1) && (remaining >= sizeof(*results))) + { + switch (results->results[0].result) + { + case RESULT_ACCEPT: + conn->assoc_group_id = response_hdr->bind_ack.assoc_gid; + conn->MaxTransmissionSize = response_hdr->bind_ack.max_tsize; + conn->ActiveInterface = *InterfaceId; + break; + case RESULT_PROVIDER_REJECTION: + switch (results->results[0].reason) + { + case REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED: + ERR("syntax %s, %d.%d not supported\n", + debugstr_guid(&InterfaceId->SyntaxGUID), + InterfaceId->SyntaxVersion.MajorVersion, + InterfaceId->SyntaxVersion.MinorVersion); + status = RPC_S_UNKNOWN_IF; + break; + case REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED: + ERR("transfer syntax not supported\n"); + status = RPC_S_SERVER_UNAVAILABLE; + break; + case REASON_NONE: + default: + status = RPC_S_CALL_FAILED_DNE; + } + break; + case RESULT_USER_REJECTION: + default: + ERR("rejection result %d\n", results->results[0].result); + status = RPC_S_CALL_FAILED_DNE; + } + } + else + { + ERR("incorrect results size\n"); + status = RPC_S_CALL_FAILED_DNE; + } + } + else + { + ERR("bind ack packet too small (%d)\n", msg.BufferLength); + status = RPC_S_PROTOCOL_ERROR; + } + break; + } + case PKT_BIND_NACK: + switch (response_hdr->bind_nack.reject_reason) + { + case REJECT_LOCAL_LIMIT_EXCEEDED: + case REJECT_TEMPORARY_CONGESTION: + ERR("server too busy\n"); + status = RPC_S_SERVER_TOO_BUSY; + break; + case REJECT_PROTOCOL_VERSION_NOT_SUPPORTED: + ERR("protocol version not supported\n"); + status = RPC_S_PROTOCOL_ERROR; + break; + case REJECT_UNKNOWN_AUTHN_SERVICE: + ERR("unknown authentication service\n"); + status = RPC_S_UNKNOWN_AUTHN_SERVICE; + break; + case REJECT_INVALID_CHECKSUM: + ERR("invalid checksum\n"); + status = ERROR_ACCESS_DENIED; + break; + default: + ERR("rejected bind for reason %d\n", response_hdr->bind_nack.reject_reason); + status = RPC_S_CALL_FAILED_DNE; + } + break; + default: + ERR("wrong packet type received %d\n", response_hdr->common.ptype); + status = RPC_S_PROTOCOL_ERROR; + break; } - /* FIXME: do more checks? */ - - conn->assoc_group_id = response_hdr->bind_ack.assoc_gid; - conn->MaxTransmissionSize = response_hdr->bind_ack.max_tsize; - conn->ActiveInterface = *InterfaceId; RPCRT4_FreeHeader(response_hdr); - return RPC_S_OK; + return status; } static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,