From 3e7a3bc9bd33fd7ad490278b910f934415f58a95 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Sep 2009 17:46:30 +1000 Subject: s4/drs: enable attribute encryption This means we now get passwords vampired correctly for s4<->s4 replication. --- source4/rpc_server/drsuapi/getncchanges.c | 47 +++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'source4/rpc_server/drsuapi') diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 17bc3ca89e..2d06970b80 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -30,20 +30,26 @@ #include "librpc/gen_ndr/ndr_drsblobs.h" #include "auth/auth.h" #include "rpc_server/drsuapi/dcesrv_drsuapi.h" +#include "rpc_server/dcerpc_server_proto.h" +#include "../libcli/drsuapi/drsuapi.h" +#include "../libcli/security/dom_sid.h" /* - drsuapi_DsGetNCChanges + drsuapi_DsGetNCChanges for one object */ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItemEx *obj, struct ldb_message *msg, struct ldb_context *sam_ctx, struct ldb_dn *ncRoot_dn, - struct dsdb_schema *schema) + struct dsdb_schema *schema, + DATA_BLOB *session_key) { const struct ldb_val *md_value; int i; struct ldb_dn *obj_dn; struct replPropertyMetaDataBlob md; + struct dom_sid *sid; + uint32_t rid = 0; if (ldb_dn_compare(ncRoot_dn, msg->dn) == 0) { obj->is_nc_prefix = true; @@ -87,7 +93,13 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem obj_dn = ldb_msg_find_attr_as_dn(sam_ctx, obj, msg, "distinguishedName"); obj->object.identifier->dn = ldb_dn_get_linearized(obj_dn); obj->object.identifier->guid = samdb_result_guid(msg, "objectGUID"); - ZERO_STRUCT(obj->object.identifier->sid); + sid = samdb_result_dom_sid(obj, msg, "objectSid"); + if (sid) { + dom_sid_split_rid(NULL, sid, NULL, &rid); + obj->object.identifier->sid = *sid; + } else { + ZERO_STRUCT(obj->object.identifier->sid); + } obj->object.attribute_ctr.num_attributes = obj->meta_data_ctr->count; obj->object.attribute_ctr.attributes = talloc_array(obj, struct drsuapi_DsReplicaAttribute, @@ -122,6 +134,16 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem sa->lDAPDisplayName, win_errstr(werr))); return werr; } + + /* some attributes needs to be encrypted + before being sent */ + werr = drsuapi_encrypt_attribute(obj, session_key, rid, + &obj->object.attribute_ctr.attributes[i]); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("Unable to encrypt %s in DRS object - %s\n", + sa->lDAPDisplayName, win_errstr(werr))); + return werr; + } } } @@ -145,11 +167,16 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ time_t t = time(NULL); NTTIME now; struct drsuapi_DsReplicaObjectListItemEx *currentObject; + NTSTATUS status; + DATA_BLOB session_key; /* - * connect to the samdb + * 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, dce_call->conn->auth_state.session_info); + 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; } @@ -172,6 +199,13 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ DEBUG(4,("DsGetNSChanges with uSNChanged >= %llu\n", (unsigned long long)r->in.req->req8.highwatermark.highest_usn)); + /* 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)) { + DEBUG(0,(__location__ ": Failed to get session key\n")); + return WERR_DS_DRA_INTERNAL_ERROR; + } + /* Construct response. */ ncRoot_dn = ldb_dn_new(mem_ctx, sam_ctx, ncRoot->dn); ret = drsuapi_search_with_extended_dn(sam_ctx, mem_ctx, &site_res, @@ -222,7 +256,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.new_highwatermark.highest_usn = uSN; } - werr = get_nc_changes_build_object(currentObject, site_res->msgs[i], sam_ctx, ncRoot_dn, schema); + werr = get_nc_changes_build_object(currentObject, site_res->msgs[i], sam_ctx, ncRoot_dn, + schema, &session_key); if (!W_ERROR_IS_OK(werr)) { r->out.ctr->ctr6.first_object = NULL; return werr; -- cgit