From 5d2dfd12cf779c410e041a1815e5e3edf0ea38d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 15 Sep 2009 19:26:33 -0700 Subject: s4-drs: lock down key DRS calls The key DRS calls should only be allowed by administrators or domain controllers --- source4/rpc_server/drsuapi/addentry.c | 7 +++++ source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 13 ++++++-- source4/rpc_server/drsuapi/getncchanges.c | 49 +++++++++++++++++------------ source4/rpc_server/drsuapi/updaterefs.c | 7 +++++ 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/source4/rpc_server/drsuapi/addentry.c b/source4/rpc_server/drsuapi/addentry.c index ae478027a6..edf46aa5fb 100644 --- a/source4/rpc_server/drsuapi/addentry.c +++ b/source4/rpc_server/drsuapi/addentry.c @@ -30,6 +30,7 @@ #include "librpc/gen_ndr/ndr_drsblobs.h" #include "auth/auth.h" #include "rpc_server/drsuapi/dcesrv_drsuapi.h" +#include "libcli/security/security.h" /* @@ -149,6 +150,12 @@ WERROR dcesrv_drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); b_state = h->data; + if (security_session_user_level(dce_call->conn->auth_state.session_info) < + SECURITY_DOMAIN_CONTROLLER) { + DEBUG(0,("DsAddEntry refused for security token\n")); + return WERR_DS_DRA_ACCESS_DENIED; + } + switch (r->in.level) { case 2: ret = ldb_transaction_start(b_state->sam_ctx); diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index a5418a1a93..c01711d2d9 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -30,6 +30,7 @@ #include "librpc/gen_ndr/ndr_drsblobs.h" #include "messaging/irpc.h" #include "rpc_server/drsuapi/dcesrv_drsuapi.h" +#include "libcli/security/security.h" /* drsuapi_DsBind @@ -234,8 +235,10 @@ static WERROR dcesrv_drsuapi_DsReplicaSync(struct dcesrv_call_state *dce_call, T struct server_id *repld; struct irpc_request *ireq; - if (DEBUGLVL(4)) { - NDR_PRINT_IN_DEBUG(drsuapi_DsReplicaSync, r); + if (security_session_user_level(dce_call->conn->auth_state.session_info) < + SECURITY_DOMAIN_CONTROLLER) { + DEBUG(0,("DsReplicaSync refused for security token\n")); + return WERR_DS_DRA_ACCESS_DENIED; } repld = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "dreplsrv"); @@ -474,6 +477,12 @@ static WERROR dcesrv_drsuapi_DsRemoveDSServer(struct dcesrv_call_state *dce_call ZERO_STRUCT(r->out.res); *r->out.level_out = 1; + if (security_session_user_level(dce_call->conn->auth_state.session_info) < + SECURITY_DOMAIN_CONTROLLER) { + DEBUG(0,("DsRemoveDSServer refused for security token\n")); + return WERR_DS_DRA_ACCESS_DENIED; + } + DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); b_state = h->data; diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index a05ddb9a5d..14d4f0d6d1 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -33,6 +33,7 @@ #include "rpc_server/dcerpc_server_proto.h" #include "../libcli/drsuapi/drsuapi.h" #include "../libcli/security/dom_sid.h" +#include "libcli/security/security.h" /* drsuapi_DsGetNCChanges for one object @@ -278,17 +279,15 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ DATA_BLOB session_key; const char *attrs[] = { "*", "parentGUID", NULL }; WERROR werr; + + *r->out.level_out = 6; + /* TODO: linked attributes*/ + r->out.ctr->ctr6.linked_attributes_count = 0; + r->out.ctr->ctr6.linked_attributes = NULL; - /* - * connect to the samdb. TODO: We need to check that the caller - * has the rights to do this. This exposes all attributes, - * including all passwords. - */ - sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); - if (!sam_ctx) { - return WERR_FOOBAR; - } + r->out.ctr->ctr6.object_count = 0; + r->out.ctr->ctr6.more_data = false; + r->out.ctr->ctr6.uptodateness_vector = NULL; /* Check request revision. */ if (r->in.level != 8) { @@ -305,6 +304,23 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ return WERR_DS_DRA_BAD_NC; } + if (security_session_user_level(dce_call->conn->auth_state.session_info) < + SECURITY_DOMAIN_CONTROLLER) { + DEBUG(0,("getncchanges refused for security token\n")); + return WERR_DS_DRA_ACCESS_DENIED; + } + + /* + * connect to the samdb. TODO: We need to check that the caller + * has the rights to do this. This exposes all attributes, + * including all passwords. + */ + sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, + system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); + if (!sam_ctx) { + return WERR_FOOBAR; + } + /* we need the session key for encrypting password attributes */ status = dcesrv_inherited_session_key(dce_call->conn, &session_key); if (!NT_STATUS_IS_OK(status)) { @@ -322,16 +338,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ return WERR_DS_DRA_INTERNAL_ERROR; } - *r->out.level_out = 6; - r->out.ctr->ctr6.naming_context = talloc(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier); - *r->out.ctr->ctr6.naming_context = *ncRoot; - /* TODO: linked attributes*/ - r->out.ctr->ctr6.linked_attributes_count = 0; - r->out.ctr->ctr6.linked_attributes = NULL; - - r->out.ctr->ctr6.object_count = 0; - r->out.ctr->ctr6.more_data = false; - r->out.ctr->ctr6.uptodateness_vector = NULL; /* Prefix mapping */ schema = dsdb_get_schema(sam_ctx); @@ -340,6 +346,9 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ return WERR_DS_DRA_INTERNAL_ERROR; } + r->out.ctr->ctr6.naming_context = talloc(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier); + *r->out.ctr->ctr6.naming_context = *ncRoot; + dsdb_get_oid_mappings_drsuapi(schema, true, mem_ctx, &ctr); r->out.ctr->ctr6.mapping_ctr = *ctr; diff --git a/source4/rpc_server/drsuapi/updaterefs.c b/source4/rpc_server/drsuapi/updaterefs.c index 45244c7801..34ff0caa14 100644 --- a/source4/rpc_server/drsuapi/updaterefs.c +++ b/source4/rpc_server/drsuapi/updaterefs.c @@ -29,6 +29,7 @@ #include "librpc/gen_ndr/ndr_drsblobs.h" #include "auth/auth.h" #include "rpc_server/drsuapi/dcesrv_drsuapi.h" +#include "libcli/security/security.h" struct repsTo { uint32_t count; @@ -109,6 +110,12 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA WERROR werr; struct ldb_dn *dn; + if (security_session_user_level(dce_call->conn->auth_state.session_info) < + SECURITY_DOMAIN_CONTROLLER) { + DEBUG(0,("DsReplicaUpdateRefs refused for security token\n")); + return WERR_DS_DRA_ACCESS_DENIED; + } + if (r->in.level != 1) { DEBUG(0,("DrReplicUpdateRefs - unsupported level %u\n", r->in.level)); return WERR_DS_DRA_INVALID_PARAMETER; -- cgit