mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 10:44:47 +00:00
rpcrt4: Store non-connection-specific authentication information in a ref-counted structure that is shared between connections and bindings.
This commit is contained in:
parent
9b3cecaeb5
commit
217ec275b8
5 changed files with 81 additions and 23 deletions
|
@ -257,7 +257,9 @@ RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
|
|||
}
|
||||
|
||||
/* 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_BINDING_HANDLE BindingHandle)
|
|||
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_HANDLE Binding, unsigned char *ServerPrinc
|
|||
{
|
||||
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_HANDLE Binding, unsigned char *ServerPrinc
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,17 @@
|
|||
#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);
|
||||
|
|
|
@ -295,12 +295,12 @@ static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
|
|||
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(RpcConnection *conn, SecBuffer *out)
|
|||
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(RpcConnection *conn, SecBuffer *out)
|
|||
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_AuthorizeConnection(RpcConnection* conn,
|
|||
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 *Connection, RpcPktHdr *Header,
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -624,7 +624,8 @@ static void RPCRT4_stop_listen(BOOL auto_listen)
|
|||
|
||||
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;
|
||||
|
|
|
@ -435,7 +435,9 @@ RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection)
|
|||
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(RpcConnection** Connection, BOOL server, LPCS
|
|||
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(RpcConnection** Connection, RpcConnection* Old
|
|||
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(RpcConnection* Connection)
|
|||
RPCRT4_CloseConnection(Connection);
|
||||
RPCRT4_strfree(Connection->Endpoint);
|
||||
RPCRT4_strfree(Connection->NetworkAddr);
|
||||
RpcAuthInfo_Release(Connection->AuthInfo);
|
||||
HeapFree(GetProcessHeap(), 0, Connection);
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue