1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

CVE-2016-2118: s4:rpc_server: make it possible to define a min_auth_level on a presentation context

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
This commit is contained in:
Stefan Metzmacher 2015-07-14 09:12:18 +02:00
parent c52097ae17
commit 51aa7bd311
2 changed files with 69 additions and 0 deletions

View File

@ -510,6 +510,35 @@ static int dcesrv_connection_context_destructor(struct dcesrv_connection_context
return 0;
}
static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
{
struct dcesrv_connection_context *context = dce_call->context;
context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
}
NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
const struct dcesrv_interface *iface)
{
if (dce_call->context == NULL) {
return NT_STATUS_INTERNAL_ERROR;
}
dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
return NT_STATUS_OK;
}
NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
const struct dcesrv_interface *iface)
{
if (dce_call->context == NULL) {
return NT_STATUS_INTERNAL_ERROR;
}
dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
return NT_STATUS_OK;
}
/*
handle a bind request
*/
@ -597,6 +626,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
call->context = context;
talloc_set_destructor(context, dcesrv_connection_context_destructor);
dcesrv_prepare_context_auth(call);
status = iface->bind(call, iface, if_version);
if (!NT_STATUS_IS_OK(status)) {
char *uuid_str = GUID_string(call, &uuid);
@ -781,6 +812,8 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_
call->context = context;
talloc_set_destructor(context, dcesrv_connection_context_destructor);
dcesrv_prepare_context_auth(call);
status = iface->bind(call, iface, if_version);
if (!NT_STATUS_IS_OK(status)) {
/* we don't want to trigger the iface->unbind() hook */
@ -982,9 +1015,14 @@ done:
*/
static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
{
const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport(endpoint->ep_description);
struct ndr_pull *pull;
NTSTATUS status;
struct dcesrv_connection_context *context;
uint32_t auth_type = DCERPC_AUTH_TYPE_NONE;
uint32_t auth_level = DCERPC_AUTH_LEVEL_NONE;
/* if authenticated, and the mech we use can't do async replies, don't use them... */
if (call->conn->auth_state.gensec_security &&
@ -997,6 +1035,28 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
return dcesrv_fault(call, DCERPC_FAULT_UNK_IF);
}
if (call->conn->auth_state.auth_info != NULL) {
auth_type = call->conn->auth_state.auth_info->auth_type;
auth_level = call->conn->auth_state.auth_info->auth_level;
}
if (auth_level < context->min_auth_level) {
char *addr;
addr = tsocket_address_string(call->conn->remote_address, call);
DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
"to [%s] with auth[type=0x%x,level=0x%x] "
"on [%s] from [%s]\n",
__func__,
context->min_auth_level,
context->iface->name,
auth_type, auth_level,
derpc_transport_string_by_transport(transport),
addr));
return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
}
pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
NT_STATUS_HAVE_NO_MEMORY(pull);

View File

@ -173,6 +173,11 @@ struct dcesrv_connection_context {
/* private data for the interface implementation */
void *private_data;
/*
* the minimum required auth level for this interface
*/
enum dcerpc_AuthLevel min_auth_level;
};
@ -419,5 +424,9 @@ _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call);
*/
_PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call);
_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
const struct dcesrv_interface *iface);
_PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
const struct dcesrv_interface *iface);
#endif /* SAMBA_DCERPC_SERVER_H */