Rob Shearman : rpcrt4: Process control packets in the server synchronously to avoid races when using 3-factor authentication .

Alexandre Julliard julliard at winehq.org
Mon Dec 14 09:51:18 CST 2009


Module: wine
Branch: master
Commit: a65f7b637a7381877b6946b811ffb433eb6d7376
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a65f7b637a7381877b6946b811ffb433eb6d7376

Author: Rob Shearman <robertshearman at gmail.com>
Date:   Sun Dec 13 21:35:43 2009 +0000

rpcrt4: Process control packets in the server synchronously to avoid races when using 3-factor authentication.

The client has nothing to wait for after sending the AUTH3 packet
before sending the first request packet. Therefore, we must ensure
that the AUTH3 packet has finished being processed before we start
processing any request packets.

---

 dlls/rpcrt4/rpc_server.c |   70 +++++++++++++++++++++++++++++++++------------
 1 files changed, 51 insertions(+), 19 deletions(-)

diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
index 55d9783..7f3f0c2 100644
--- a/dlls/rpcrt4/rpc_server.c
+++ b/dlls/rpcrt4/rpc_server.c
@@ -562,6 +562,7 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
 
   for (;;) {
     msg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RPC_MESSAGE));
+    if (!msg) break;
 
     status = RPCRT4_ReceiveWithAuth(conn, &hdr, msg, &auth_data, &auth_length);
     if (status != RPC_S_OK) {
@@ -570,30 +571,61 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
       break;
     }
 
-    packet = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcPacket));
-    if (!packet) {
-      I_RpcFree(msg->Buffer);
-      RPCRT4_FreeHeader(hdr);
-      HeapFree(GetProcessHeap(), 0, msg);
+    switch (hdr->common.ptype) {
+    case PKT_BIND:
+      TRACE("got bind packet\n");
+
+      status = process_bind_packet(conn, &hdr->bind, msg, auth_data,
+                                   auth_length);
       break;
-    }
-    packet->conn = conn;
-    packet->hdr = hdr;
-    packet->msg = msg;
-    packet->auth_data = auth_data;
-    packet->auth_length = auth_length;
-    if (!QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION)) {
-      ERR("couldn't queue work item for worker thread, error was %d\n", GetLastError());
-      I_RpcFree(msg->Buffer);
-      RPCRT4_FreeHeader(hdr);
-      HeapFree(GetProcessHeap(), 0, msg);
-      HeapFree(GetProcessHeap(), 0, packet);
-      HeapFree(GetProcessHeap(), 0, auth_data);
+
+    case PKT_REQUEST:
+      TRACE("got request packet\n");
+
+      packet = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcPacket));
+      if (!packet) {
+        I_RpcFree(msg->Buffer);
+        RPCRT4_FreeHeader(hdr);
+        HeapFree(GetProcessHeap(), 0, msg);
+        HeapFree(GetProcessHeap(), 0, auth_data);
+        goto exit;
+      }
+      packet->conn = conn;
+      packet->hdr = hdr;
+      packet->msg = msg;
+      packet->auth_data = auth_data;
+      packet->auth_length = auth_length;
+      if (!QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION)) {
+        ERR("couldn't queue work item for worker thread, error was %d\n", GetLastError());
+        HeapFree(GetProcessHeap(), 0, packet);
+        status = RPC_S_OUT_OF_RESOURCES;
+      } else {
+        continue;
+      }
+      break;
+
+    case PKT_AUTH3:
+      TRACE("got auth3 packet\n");
+
+      status = process_auth3_packet(conn, &hdr->common, msg, auth_data,
+                                    auth_length);
+      break;
+    default:
+      FIXME("unhandled packet type %u\n", hdr->common.ptype);
       break;
     }
 
-    msg = NULL;
+    I_RpcFree(msg->Buffer);
+    RPCRT4_FreeHeader(hdr);
+    HeapFree(GetProcessHeap(), 0, msg);
+    HeapFree(GetProcessHeap(), 0, auth_data);
+
+    if (status != RPC_S_OK) {
+      WARN("processing packet failed with error %u\n", status);
+      break;
+    }
   }
+exit:
   RPCRT4_DestroyConnection(conn);
   return 0;
 }




More information about the wine-cvs mailing list