rpcrt4: Convert bind ack and nack reject reasons into RPC status codes when binding.

This commit is contained in:
Rob Shearman 2007-07-20 11:35:34 +01:00 committed by Alexandre Julliard
parent 433393fd51
commit 8a87d916b4
4 changed files with 110 additions and 16 deletions

View File

@ -178,8 +178,24 @@ typedef struct
#define PKT_ORPHANED 19
#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

View File

@ -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;

View File

@ -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 */

View File

@ -1473,6 +1473,8 @@ ULONG RpcAssoc_Release(RpcAssoc *assoc)
return refs;
}
#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
static RPC_STATUS RpcAssoc_BindConnection(RpcAssoc *assoc, RpcConnection *conn,
const RPC_SYNTAX_IDENTIFIER *InterfaceId,
const RPC_SYNTAX_IDENTIFIER *TransferSyntax)
@ -1501,23 +1503,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;
}
/* FIXME: do more checks? */
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;
}
RPCRT4_FreeHeader(response_hdr);
return RPC_S_OK;
return status;
}
static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,