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