Rob Shearman : rpcrt4:
Convert bind ack and nack reject reasons into RPC status codes when
binding .
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jul 23 05:55:31 CDT 2007
Module: wine
Branch: master
Commit: 8a87d916b41b256e3abe32ff240acfc1b39f2a60
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8a87d916b41b256e3abe32ff240acfc1b39f2a60
Author: Rob Shearman <rob at codeweavers.com>
Date: Fri Jul 20 11:35:34 2007 +0100
rpcrt4: Convert bind ack and nack reject reasons into RPC status codes when binding.
---
dlls/rpcrt4/rpc_defs.h | 22 ++++++++-
dlls/rpcrt4/rpc_message.c | 1 +
dlls/rpcrt4/rpc_server.c | 2 +-
dlls/rpcrt4/rpc_transport.c | 103 +++++++++++++++++++++++++++++++++++++-----
4 files changed, 111 insertions(+), 17 deletions(-)
diff --git a/dlls/rpcrt4/rpc_defs.h b/dlls/rpcrt4/rpc_defs.h
index 7499dcd..c0c3609 100644
--- a/dlls/rpcrt4/rpc_defs.h
+++ b/dlls/rpcrt4/rpc_defs.h
@@ -177,9 +177,25 @@ typedef struct
#define PKT_CO_CANCEL 18
#define PKT_ORPHANED 19
-#define RESULT_ACCEPT 0
-
-#define NO_REASON 0
+#define RESULT_ACCEPT 0
+#define RESULT_USER_REJECTION 1
+#define RESULT_PROVIDER_REJECTION 2
+
+#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/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c
index 03e0737..b19e7f1 100644
--- a/dlls/rpcrt4/rpc_message.c
+++ b/dlls/rpcrt4/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;
diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
index 328c0d0..8a72ab3 100644
--- a/dlls/rpcrt4/rpc_server.c
+++ b/dlls/rpcrt4/rpc_server.c
@@ -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/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c
index 413bcbb..cc33e5e 100644
--- a/dlls/rpcrt4/rpc_transport.c
+++ b/dlls/rpcrt4/rpc_transport.c
@@ -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)
+ {
+ case PKT_BIND_ACK:
{
- 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;
+ 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,
More information about the wine-cvs
mailing list