Module: wine Branch: refs/heads/master Commit: 217ec275b8b5d936014545d73f30d488183f737e URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=217ec275b8b5d936014545d7...
Author: Robert Shearman rob@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; }