rpcrt4: Implement client impersonation.
This commit is contained in:
parent
95026f9d6b
commit
d918587f1d
|
@ -1052,9 +1052,17 @@ RPC_STATUS RPC_ENTRY RpcBindingReset(RPC_BINDING_HANDLE Binding)
|
|||
*/
|
||||
RPC_STATUS WINAPI RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle)
|
||||
{
|
||||
FIXME("(%p): stub\n", BindingHandle);
|
||||
ImpersonateSelf(SecurityImpersonation);
|
||||
return RPC_S_OK;
|
||||
RpcBinding *bind;
|
||||
|
||||
TRACE("(%p)\n", BindingHandle);
|
||||
|
||||
if (!BindingHandle) BindingHandle = I_RpcGetCurrentCallHandle();
|
||||
if (!BindingHandle) return RPC_S_INVALID_BINDING;
|
||||
|
||||
bind = BindingHandle;
|
||||
if (bind->FromConn)
|
||||
return rpcrt4_conn_impersonate_client(bind->FromConn);
|
||||
return RPC_S_WRONG_KIND_OF_BINDING;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1077,8 +1085,17 @@ RPC_STATUS WINAPI RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle)
|
|||
*/
|
||||
RPC_STATUS WINAPI RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle)
|
||||
{
|
||||
FIXME("(%p): stub\n", BindingHandle);
|
||||
return RPC_S_OK;
|
||||
RpcBinding *bind;
|
||||
|
||||
TRACE("(%p)\n", BindingHandle);
|
||||
|
||||
if (!BindingHandle) BindingHandle = I_RpcGetCurrentCallHandle();
|
||||
if (!BindingHandle) return RPC_S_INVALID_BINDING;
|
||||
|
||||
bind = BindingHandle;
|
||||
if (bind->FromConn)
|
||||
return rpcrt4_conn_revert_to_self(bind->FromConn);
|
||||
return RPC_S_WRONG_KIND_OF_BINDING;
|
||||
}
|
||||
|
||||
static inline BOOL has_nt_auth_identity(ULONG AuthnLevel)
|
||||
|
@ -1431,9 +1448,8 @@ BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQuali
|
|||
*/
|
||||
RPC_STATUS WINAPI RpcRevertToSelf(void)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
RevertToSelf();
|
||||
return RPC_S_OK;
|
||||
TRACE("\n");
|
||||
return RpcRevertToSelfEx(NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -109,6 +109,8 @@ struct connection_ops {
|
|||
BOOL (*is_authorized)(RpcConnection *conn);
|
||||
RPC_STATUS (*authorize)(RpcConnection *conn, BOOL first_time, unsigned char *in_buffer, unsigned int in_len, unsigned char *out_buffer, unsigned int *out_len);
|
||||
RPC_STATUS (*secure_packet)(RpcConnection *Connection, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, unsigned char *stub_data, unsigned int stub_data_size, RpcAuthVerifier *auth_hdr, unsigned char *auth_value, unsigned int auth_value_size);
|
||||
RPC_STATUS (*impersonate_client)(RpcConnection *conn);
|
||||
RPC_STATUS (*revert_to_self)(RpcConnection *conn);
|
||||
};
|
||||
|
||||
/* don't know what MS's structure looks like */
|
||||
|
@ -216,6 +218,18 @@ static inline RPC_STATUS rpcrt4_conn_secure_packet(
|
|||
return conn->ops->secure_packet(conn, dir, hdr, hdr_size, stub_data, stub_data_size, auth_hdr, auth_value, auth_value_size);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_impersonate_client(
|
||||
RpcConnection *conn)
|
||||
{
|
||||
return conn->ops->impersonate_client(conn);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_revert_to_self(
|
||||
RpcConnection *conn)
|
||||
{
|
||||
return conn->ops->revert_to_self(conn);
|
||||
}
|
||||
|
||||
/* floors 3 and up */
|
||||
RPC_STATUS RpcTransport_GetTopOfTower(unsigned char *tower_data, size_t *tower_size, const char *protseq, const char *networkaddr, const char *endpoint);
|
||||
RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t tower_size, char **protseq, char **networkaddr, char **endpoint);
|
||||
|
|
|
@ -1120,6 +1120,62 @@ BOOL RPCRT4_default_is_authorized(RpcConnection *Connection)
|
|||
return Connection->AuthInfo && SecIsValidHandle(&Connection->ctx);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RPCRT4_default_impersonate_client (internal)
|
||||
*
|
||||
*/
|
||||
RPC_STATUS RPCRT4_default_impersonate_client(RpcConnection *conn)
|
||||
{
|
||||
SECURITY_STATUS sec_status;
|
||||
|
||||
TRACE("(%p)\n", conn);
|
||||
|
||||
if (!conn->AuthInfo || !SecIsValidHandle(&conn->ctx))
|
||||
return RPC_S_NO_CONTEXT_AVAILABLE;
|
||||
sec_status = ImpersonateSecurityContext(&conn->ctx);
|
||||
if (sec_status != SEC_E_OK)
|
||||
WARN("ImpersonateSecurityContext returned 0x%08x\n", sec_status);
|
||||
switch (sec_status)
|
||||
{
|
||||
case SEC_E_UNSUPPORTED_FUNCTION:
|
||||
return RPC_S_CANNOT_SUPPORT;
|
||||
case SEC_E_NO_IMPERSONATION:
|
||||
return RPC_S_NO_CONTEXT_AVAILABLE;
|
||||
case SEC_E_OK:
|
||||
return RPC_S_OK;
|
||||
default:
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RPCRT4_default_revert_to_self (internal)
|
||||
*
|
||||
*/
|
||||
RPC_STATUS RPCRT4_default_revert_to_self(RpcConnection *conn)
|
||||
{
|
||||
SECURITY_STATUS sec_status;
|
||||
|
||||
TRACE("(%p)\n", conn);
|
||||
|
||||
if (!conn->AuthInfo || !SecIsValidHandle(&conn->ctx))
|
||||
return RPC_S_NO_CONTEXT_AVAILABLE;
|
||||
sec_status = RevertSecurityContext(&conn->ctx);
|
||||
if (sec_status != SEC_E_OK)
|
||||
WARN("RevertSecurityContext returned 0x%08x\n", sec_status);
|
||||
switch (sec_status)
|
||||
{
|
||||
case SEC_E_UNSUPPORTED_FUNCTION:
|
||||
return RPC_S_CANNOT_SUPPORT;
|
||||
case SEC_E_NO_IMPERSONATION:
|
||||
return RPC_S_NO_CONTEXT_AVAILABLE;
|
||||
case SEC_E_OK:
|
||||
return RPC_S_OK;
|
||||
default:
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RPCRT4_Send (internal)
|
||||
*
|
||||
|
|
|
@ -53,5 +53,7 @@ RPC_STATUS RPCRT4_ServerGetRegisteredAuthInfo(USHORT auth_type, CredHandle *cred
|
|||
RPC_STATUS RPCRT4_default_authorize(RpcConnection *conn, BOOL first_time, unsigned char *in_buffer, unsigned int in_size, unsigned char *out_buffer, unsigned int *out_size);
|
||||
BOOL RPCRT4_default_is_authorized(RpcConnection *Connection);
|
||||
RPC_STATUS RPCRT4_default_secure_packet(RpcConnection *Connection, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, unsigned char *stub_data, unsigned int stub_data_size, RpcAuthVerifier *auth_hdr, unsigned char *auth_value, unsigned int auth_value_size);
|
||||
RPC_STATUS RPCRT4_default_impersonate_client(RpcConnection *conn);
|
||||
RPC_STATUS RPCRT4_default_revert_to_self(RpcConnection *conn);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -586,6 +586,48 @@ static RPC_STATUS rpcrt4_ncacn_np_parse_top_of_tower(const unsigned char *tower_
|
|||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
static RPC_STATUS rpcrt4_conn_np_impersonate_client(RpcConnection *conn)
|
||||
{
|
||||
RpcConnection_np *npc = (RpcConnection_np *)conn;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p)\n", conn);
|
||||
|
||||
if (conn->AuthInfo && SecIsValidHandle(&conn->ctx))
|
||||
return RPCRT4_default_impersonate_client(conn);
|
||||
|
||||
ret = ImpersonateNamedPipeClient(npc->pipe);
|
||||
if (!ret)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
WARN("ImpersonateNamedPipeClient failed with error %u\n", error);
|
||||
switch (error)
|
||||
{
|
||||
case ERROR_CANNOT_IMPERSONATE:
|
||||
return RPC_S_NO_CONTEXT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
static RPC_STATUS rpcrt4_conn_np_revert_to_self(RpcConnection *conn)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p)\n", conn);
|
||||
|
||||
if (conn->AuthInfo && SecIsValidHandle(&conn->ctx))
|
||||
return RPCRT4_default_revert_to_self(conn);
|
||||
|
||||
ret = RevertToSelf();
|
||||
if (!ret)
|
||||
{
|
||||
WARN("RevertToSelf failed with error %u\n", GetLastError());
|
||||
return RPC_S_NO_CONTEXT_AVAILABLE;
|
||||
}
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
typedef struct _RpcServerProtseq_np
|
||||
{
|
||||
RpcServerProtseq common;
|
||||
|
@ -2709,6 +2751,8 @@ static const struct connection_ops conn_protseq_list[] = {
|
|||
RPCRT4_default_is_authorized,
|
||||
RPCRT4_default_authorize,
|
||||
RPCRT4_default_secure_packet,
|
||||
rpcrt4_conn_np_impersonate_client,
|
||||
rpcrt4_conn_np_revert_to_self,
|
||||
},
|
||||
{ "ncalrpc",
|
||||
{ EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE },
|
||||
|
@ -2726,6 +2770,8 @@ static const struct connection_ops conn_protseq_list[] = {
|
|||
rpcrt4_ncalrpc_is_authorized,
|
||||
rpcrt4_ncalrpc_authorize,
|
||||
rpcrt4_ncalrpc_secure_packet,
|
||||
rpcrt4_conn_np_impersonate_client,
|
||||
rpcrt4_conn_np_revert_to_self,
|
||||
},
|
||||
{ "ncacn_ip_tcp",
|
||||
{ EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP },
|
||||
|
@ -2743,6 +2789,8 @@ static const struct connection_ops conn_protseq_list[] = {
|
|||
RPCRT4_default_is_authorized,
|
||||
RPCRT4_default_authorize,
|
||||
RPCRT4_default_secure_packet,
|
||||
RPCRT4_default_impersonate_client,
|
||||
RPCRT4_default_revert_to_self,
|
||||
},
|
||||
{ "ncacn_http",
|
||||
{ EPM_PROTOCOL_NCACN, EPM_PROTOCOL_HTTP },
|
||||
|
@ -2760,6 +2808,8 @@ static const struct connection_ops conn_protseq_list[] = {
|
|||
RPCRT4_default_is_authorized,
|
||||
RPCRT4_default_authorize,
|
||||
RPCRT4_default_secure_packet,
|
||||
RPCRT4_default_impersonate_client,
|
||||
RPCRT4_default_revert_to_self,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue