Robert Shearman : rpcrt4: Store non-connection-specific authentication information in a ref-counted structure that is shared between connections and bindings .

Alexandre Julliard julliard at wine.codeweavers.com
Thu May 18 03:56:56 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 217ec275b8b5d936014545d73f30d488183f737e
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=217ec275b8b5d936014545d73f30d488183f737e

Author: Robert Shearman <rob at codeweavers.com>
Date:   Thu May 18 03:40:42 2006 +0100

rpcrt4: Store non-connection-specific authentication information in a ref-counted structure that is shared between connections and bindings.

---

 dlls/rpcrt4/rpc_binding.c   |   50 +++++++++++++++++++++++++++++++++++++++----
 dlls/rpcrt4/rpc_binding.h   |   22 +++++++++++++++----
 dlls/rpcrt4/rpc_message.c   |   19 ++++++++--------
 dlls/rpcrt4/rpc_server.c    |    3 ++-
 dlls/rpcrt4/rpc_transport.c |   10 +++++++--
 5 files changed, 81 insertions(+), 23 deletions(-)

diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c
index dc22be3..22d9e98 100644
--- a/dlls/rpcrt4/rpc_binding.c
+++ b/dlls/rpcrt4/rpc_binding.c
@@ -257,7 +257,9 @@ RPC_STATUS RPCRT4_OpenBinding(RpcBinding
   }
   
   /* create a new connection */
-  RPCRT4_CreateConnection(&NewConnection, Binding->server, Binding->Protseq, Binding->NetworkAddr, Binding->Endpoint, NULL, Binding);
+  RPCRT4_CreateConnection(&NewConnection, Binding->server, Binding->Protseq,
+                          Binding->NetworkAddr, Binding->Endpoint, NULL,
+                          Binding->AuthInfo, Binding);
   *Connection = NewConnection;
   status = RPCRT4_OpenConnection(NewConnection);
   if (status != RPC_S_OK) {
@@ -922,6 +924,38 @@ RPC_STATUS WINAPI RpcRevertToSelfEx(RPC_
     return RPC_S_OK;
 }
 
+static RPC_STATUS RpcAuthInfo_Create(unsigned long AuthnLevel, unsigned long AuthnSvc, CredHandle cred, TimeStamp exp, RpcAuthInfo **ret)
+{
+    RpcAuthInfo *AuthInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo));
+    if (!AuthInfo)
+        return ERROR_OUTOFMEMORY;
+
+    AuthInfo->AuthnLevel = AuthnLevel;
+    AuthInfo->AuthnSvc = AuthnSvc;
+    AuthInfo->cred = cred;
+    AuthInfo->exp = exp;
+    *ret = AuthInfo;
+    return RPC_S_OK;
+}
+
+ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo)
+{
+    return InterlockedIncrement(&AuthInfo->refs);
+}
+
+ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo)
+{
+    ULONG refs = InterlockedDecrement(&AuthInfo->refs);
+
+    if (!refs)
+    {
+        FreeCredentialsHandle(&AuthInfo->cred);
+        HeapFree(GetProcessHeap(), 0, AuthInfo);
+    }
+
+    return refs;
+}
+
 /***********************************************************************
  *             RpcBindingInqAuthInfoExA (RPCRT4.@)
  */
@@ -983,6 +1017,8 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HA
 {
   RpcBinding* bind = (RpcBinding*)Binding;
   RPC_STATUS r;
+  CredHandle cred;
+  TimeStamp exp;
 
   TRACE("%p %s %lu %lu %p %lu %p\n", Binding, debugstr_a((const char*)ServerPrincName),
         AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos);
@@ -1012,13 +1048,17 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HA
     FIXME("SecurityQos ignored\n");
 
   r = AcquireCredentialsHandleA(NULL, "NTLM", SECPKG_CRED_OUTBOUND, NULL,
-                                AuthIdentity, NULL, NULL, &bind->cred, &bind->exp);
+                                AuthIdentity, NULL, NULL, &cred, &exp);
   if (r == ERROR_SUCCESS)
   {
-    bind->AuthnSvc = AuthnSvc;
-    bind->AuthnLevel = AuthnLevel;
+    if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo);
+    bind->AuthInfo = NULL;
+    r = RpcAuthInfo_Create(AuthnLevel, AuthnSvc, cred, exp, &bind->AuthInfo);
+    if (r != RPC_S_OK)
+      FreeCredentialsHandle(&cred);
   }
-  TRACE("AcquireCredentialsHandleA returned %08lx\n", r);
+  else
+    ERR("AcquireCredentialsHandleA failed with error 0x%08lx\n", r);
   return r;
 }
 
diff --git a/dlls/rpcrt4/rpc_binding.h b/dlls/rpcrt4/rpc_binding.h
index d9e1576..ad2e360 100644
--- a/dlls/rpcrt4/rpc_binding.h
+++ b/dlls/rpcrt4/rpc_binding.h
@@ -24,6 +24,17 @@ #define __WINE_RPC_BINDING_H
 #include "wine/rpcss_shared.h"
 #include "security.h"
 
+
+typedef struct _RpcAuthInfo
+{
+  LONG refs;
+
+  unsigned long AuthnLevel;
+  unsigned long AuthnSvc;
+  CredHandle cred;
+  TimeStamp exp;
+} RpcAuthInfo;
+
 struct protseq_ops;
 
 typedef struct _RpcConnection
@@ -43,6 +54,7 @@ typedef struct _RpcConnection
   CtxtHandle ctx;
   TimeStamp exp;
   ULONG attr;
+  RpcAuthInfo *AuthInfo;
 } RpcConnection;
 
 struct protseq_ops {
@@ -71,10 +83,7 @@ typedef struct _RpcBinding
   RpcConnection* FromConn;
 
   /* authentication */
-  unsigned long AuthnLevel;
-  unsigned long AuthnSvc;
-  CredHandle cred;
-  TimeStamp exp;
+  RpcAuthInfo *AuthInfo;
 } RpcBinding;
 
 LPSTR RPCRT4_strndupA(LPCSTR src, INT len);
@@ -86,7 +95,10 @@ void RPCRT4_strfree(LPSTR src);
 #define RPCRT4_strdupA(x) RPCRT4_strndupA((x),-1)
 #define RPCRT4_strdupW(x) RPCRT4_strndupW((x),-1)
 
-RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCSTR NetworkOptions, RpcBinding* Binding);
+ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo);
+ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo);
+
+RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcBinding* Binding);
 RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection);
 RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection);
 RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection);
diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c
index a4d92b6..d4ddb41 100644
--- a/dlls/rpcrt4/rpc_message.c
+++ b/dlls/rpcrt4/rpc_message.c
@@ -295,12 +295,12 @@ static RPC_STATUS RPCRT4_SendAuth(RpcCon
     memcpy(pkt + hdr_size, buffer_pos, Header->common.frag_len - hdr_size - alen);
 
     /* add the authorization info */
-    if (Connection->Used && AuthLength)
+    if (Connection->AuthInfo && AuthLength)
     {
       auth_hdr = &pkt[Header->common.frag_len - alen];
 
-      auth_hdr[0] = Connection->Used->AuthnSvc;
-      auth_hdr[1] = Connection->Used->AuthnLevel;
+      auth_hdr[0] = Connection->AuthInfo->AuthnSvc;
+      auth_hdr[1] = Connection->AuthInfo->AuthnLevel;
       auth_hdr[2] = 0x00; /* FIXME: add padding */
       auth_hdr[3] = 0x00;
 
@@ -333,7 +333,6 @@ static void RPCRT4_AuthNegotiate(RpcConn
   SECURITY_STATUS r;
   SecBufferDesc out_desc;
   unsigned char *buffer;
-  RpcBinding *bind = conn->Used;
 
   buffer = HeapAlloc(GetProcessHeap(), 0, 0x100);
 
@@ -349,10 +348,10 @@ static void RPCRT4_AuthNegotiate(RpcConn
   conn->ctx.dwLower = 0;
   conn->ctx.dwUpper = 0;
 
-  r = InitializeSecurityContextA(&bind->cred, NULL, NULL,
+  r = InitializeSecurityContextA(&conn->AuthInfo->cred, NULL, NULL,
         ISC_REQ_CONNECTION | ISC_REQ_USE_DCE_STYLE | ISC_REQ_MUTUAL_AUTH |
         ISC_REQ_DELEGATE, 0, SECURITY_NETWORK_DREP,
-        NULL, 0, &conn->ctx, &out_desc, &conn->attr, &bind->exp);
+        NULL, 0, &conn->ctx, &out_desc, &conn->attr, &conn->exp);
 
   TRACE("r = %08lx cbBuffer = %ld attr = %08lx\n", r, out->cbBuffer, conn->attr);
 }
@@ -388,7 +387,7 @@ static RPC_STATUS RPCRT_AuthorizeConnect
   inp_desc.pBuffers = &inp;
   inp_desc.ulVersion = 0;
 
-  r = InitializeSecurityContextA(&conn->Used->cred, &conn->ctx, NULL,
+  r = InitializeSecurityContextA(&conn->AuthInfo->cred, &conn->ctx, NULL,
         ISC_REQ_CONNECTION | ISC_REQ_USE_DCE_STYLE | ISC_REQ_MUTUAL_AUTH |
         ISC_REQ_DELEGATE, 0, SECURITY_NETWORK_DREP,
         &inp_desc, 0, &conn->ctx, &out_desc, &conn->attr, &conn->exp);
@@ -431,9 +430,9 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Co
     return RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, buffer, sizeof buffer);
   }
 
-  if (Connection->Used == NULL ||
-      Connection->Used->AuthnLevel == RPC_C_AUTHN_LEVEL_DEFAULT ||
-      Connection->Used->AuthnLevel == RPC_C_AUTHN_LEVEL_NONE)
+  if (!Connection->AuthInfo ||
+      Connection->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_DEFAULT ||
+      Connection->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_NONE)
   {
     return RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, NULL, 0);
   }
diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
index 8889540..e9a6da6 100644
--- a/dlls/rpcrt4/rpc_server.c
+++ b/dlls/rpcrt4/rpc_server.c
@@ -624,7 +624,8 @@ static void RPCRT4_stop_listen(BOOL auto
 
 static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps)
 {
-  RPCRT4_CreateConnection(&ps->conn, TRUE, ps->Protseq, NULL, ps->Endpoint, NULL, NULL);
+  RPCRT4_CreateConnection(&ps->conn, TRUE, ps->Protseq, NULL, ps->Endpoint,
+                          NULL, NULL, NULL);
 
   EnterCriticalSection(&server_cs);
   ps->Next = protseqs;
diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c
index 88a7769..ba4e8d3 100644
--- a/dlls/rpcrt4/rpc_transport.c
+++ b/dlls/rpcrt4/rpc_transport.c
@@ -435,7 +435,9 @@ RPC_STATUS RPCRT4_CloseConnection(RpcCon
   return RPC_S_OK;
 }
 
-RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCSTR NetworkOptions, RpcBinding* Binding)
+RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server,
+    LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint,
+    LPCSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcBinding* Binding)
 {
   struct protseq_ops *ops;
   RpcConnection* NewConnection;
@@ -452,6 +454,8 @@ RPC_STATUS RPCRT4_CreateConnection(RpcCo
   NewConnection->Used = Binding;
   NewConnection->MaxTransmissionSize = RPC_MAX_PACKET_SIZE;
   NewConnection->NextCallId = 1;
+  if (AuthInfo) RpcAuthInfo_AddRef(AuthInfo);
+  NewConnection->AuthInfo = AuthInfo;
 
   TRACE("connection: %p\n", NewConnection);
   *Connection = NewConnection;
@@ -466,7 +470,8 @@ RPC_STATUS RPCRT4_SpawnConnection(RpcCon
   err = RPCRT4_CreateConnection(Connection, OldConnection->server,
                                 rpcrt4_conn_get_name(OldConnection),
                                 OldConnection->NetworkAddr,
-                                OldConnection->Endpoint, NULL, NULL);
+                                OldConnection->Endpoint, NULL,
+                                OldConnection->AuthInfo, NULL);
   if (err == RPC_S_OK)
     rpcrt4_conn_handoff(OldConnection, *Connection);
   return err;
@@ -479,6 +484,7 @@ RPC_STATUS RPCRT4_DestroyConnection(RpcC
   RPCRT4_CloseConnection(Connection);
   RPCRT4_strfree(Connection->Endpoint);
   RPCRT4_strfree(Connection->NetworkAddr);
+  RpcAuthInfo_Release(Connection->AuthInfo);
   HeapFree(GetProcessHeap(), 0, Connection);
   return RPC_S_OK;
 }




More information about the wine-cvs mailing list