The branch, master has been updated via 3e7a3bc9bd33fd7ad490278b910f934415f58a95 (commit) via 9460427c24078aecdce602dd4cbd59a6c49a781c (commit) via 25b68701c1c7541ef6233fae35145844911380ee (commit) via 2ff4764f8fb86842120a2b5de20df641e8821af7 (commit) from 5283ad11bdd87daf2e9ed6d4644bfb1d8c978b04 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 3e7a3bc9bd33fd7ad490278b910f934415f58a95 Author: Andrew Tridgell <tri...@samba.org> Date: Thu Sep 10 17:46:30 2009 +1000 s4/drs: enable attribute encryption This means we now get passwords vampired correctly for s4<->s4 replication. commit 9460427c24078aecdce602dd4cbd59a6c49a781c Author: Andrew Tridgell <tri...@samba.org> Date: Thu Sep 10 17:45:25 2009 +1000 s4: kludge_acl needs to be above repl_meta_data We have to bypass kludge_acl in replication as otherwise we aren't allowed access to the password entries commit 25b68701c1c7541ef6233fae35145844911380ee Author: Andrew Tridgell <tri...@samba.org> Date: Thu Sep 10 17:42:36 2009 +1000 s4/repl: give a useful error message if we can't decode an object commit 2ff4764f8fb86842120a2b5de20df641e8821af7 Author: Andrew Tridgell <tri...@samba.org> Date: Thu Sep 10 17:42:13 2009 +1000 libcli: added a drsuapi attribute encryption function ----------------------------------------------------------------------- Summary of changes: libcli/drsuapi/drsuapi.h | 5 ++ libcli/drsuapi/repl_decrypt.c | 84 +++++++++++++++++++++++---- source4/dsdb/repl/replicated_objects.c | 5 +- source4/rpc_server/drsuapi/getncchanges.c | 47 +++++++++++++-- source4/scripting/python/samba/provision.py | 4 +- 5 files changed, 125 insertions(+), 20 deletions(-) Changeset truncated at 500 lines: diff --git a/libcli/drsuapi/drsuapi.h b/libcli/drsuapi/drsuapi.h index b953507..a4fb15f 100644 --- a/libcli/drsuapi/drsuapi.h +++ b/libcli/drsuapi/drsuapi.h @@ -31,3 +31,8 @@ WERROR drsuapi_decrypt_attribute(TALLOC_CTX *mem_ctx, uint32_t rid, struct drsuapi_DsReplicaAttribute *attr); + +WERROR drsuapi_encrypt_attribute(TALLOC_CTX *mem_ctx, + const DATA_BLOB *gensec_skey, + uint32_t rid, + struct drsuapi_DsReplicaAttribute *attr); diff --git a/libcli/drsuapi/repl_decrypt.c b/libcli/drsuapi/repl_decrypt.c index 33dfbe5..924e799 100644 --- a/libcli/drsuapi/repl_decrypt.c +++ b/libcli/drsuapi/repl_decrypt.c @@ -94,14 +94,14 @@ WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx, */ crc32_given = IVAL(dec_buffer.data, 0); crc32_calc = crc32_calc_buffer(dec_buffer.data + 4 , dec_buffer.length - 4); - if (crc32_given != crc32_calc) { - return WERR_SEC_E_DECRYPT_FAILURE; - } checked_buffer = data_blob_const(dec_buffer.data + 4, dec_buffer.length - 4); plain_buffer = data_blob_talloc(mem_ctx, checked_buffer.data, checked_buffer.length); W_ERROR_HAVE_NO_MEMORY(plain_buffer.data); + if (crc32_given != crc32_calc) { + return WERR_SEC_E_DECRYPT_FAILURE; + } /* * The following rid_crypt obfuscation isn't session specific * and not really needed here, because we allways know the rid of the @@ -188,12 +188,12 @@ WERROR drsuapi_decrypt_attribute(TALLOC_CTX *mem_ctx, return WERR_OK; } -WERROR drsuapi_encrypt_attribute_value(TALLOC_CTX *mem_ctx, - const DATA_BLOB *gensec_skey, - bool rid_crypt, - uint32_t rid, - DATA_BLOB *in, - DATA_BLOB *out) +static WERROR drsuapi_encrypt_attribute_value(TALLOC_CTX *mem_ctx, + const DATA_BLOB *gensec_skey, + bool rid_crypt, + uint32_t rid, + DATA_BLOB *in, + DATA_BLOB *out) { DATA_BLOB rid_crypt_out = data_blob(NULL, 0); DATA_BLOB confounder; @@ -273,7 +273,7 @@ WERROR drsuapi_encrypt_attribute_value(TALLOC_CTX *mem_ctx, * of the remaining bytes */ crc32_calc = crc32_calc_buffer(in->data, in->length); - SIVAL(enc_buffer.data, 4, crc32_calc); + SIVAL(enc_buffer.data, 16, crc32_calc); /* * copy the plain buffer part and @@ -282,9 +282,71 @@ WERROR drsuapi_encrypt_attribute_value(TALLOC_CTX *mem_ctx, memcpy(enc_buffer.data+20, in->data, in->length); talloc_free(rid_crypt_out.data); - arcfour_crypt_blob(enc_buffer.data+20, enc_buffer.length-20, &enc_key); + arcfour_crypt_blob(enc_buffer.data+16, enc_buffer.length-16, &enc_key); *out = enc_buffer; + + return WERR_OK; +} + +/* + encrypt a DRSUAPI attribute ready for sending over the wire + Only some attribute types are encrypted + */ +WERROR drsuapi_encrypt_attribute(TALLOC_CTX *mem_ctx, + const DATA_BLOB *gensec_skey, + uint32_t rid, + struct drsuapi_DsReplicaAttribute *attr) +{ + WERROR status; + DATA_BLOB *plain_data; + DATA_BLOB enc_data; + bool rid_crypt = false; + + if (attr->value_ctr.num_values == 0) { + return WERR_OK; + } + + switch (attr->attid) { + case DRSUAPI_ATTRIBUTE_dBCSPwd: + case DRSUAPI_ATTRIBUTE_unicodePwd: + case DRSUAPI_ATTRIBUTE_ntPwdHistory: + case DRSUAPI_ATTRIBUTE_lmPwdHistory: + rid_crypt = true; + break; + case DRSUAPI_ATTRIBUTE_supplementalCredentials: + case DRSUAPI_ATTRIBUTE_priorValue: + case DRSUAPI_ATTRIBUTE_currentValue: + case DRSUAPI_ATTRIBUTE_trustAuthOutgoing: + case DRSUAPI_ATTRIBUTE_trustAuthIncoming: + case DRSUAPI_ATTRIBUTE_initialAuthOutgoing: + case DRSUAPI_ATTRIBUTE_initialAuthIncoming: + break; + default: + return WERR_OK; + } + + if (attr->value_ctr.num_values > 1) { + return WERR_DS_DRA_INVALID_PARAMETER; + } + + if (!attr->value_ctr.values[0].blob) { + return WERR_DS_DRA_INVALID_PARAMETER; + } + + plain_data = attr->value_ctr.values[0].blob; + + status = drsuapi_encrypt_attribute_value(mem_ctx, + gensec_skey, + rid_crypt, + rid, + plain_data, + &enc_data); + W_ERROR_NOT_OK_RETURN(status); + + talloc_free(attr->value_ctr.values[0].blob->data); + *attr->value_ctr.values[0].blob = enc_data; + return WERR_OK; } diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index 4002ea8..459c7b5 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -243,7 +243,10 @@ WERROR dsdb_extended_replicated_objects_commit(struct ldb_context *ldb, status = dsdb_convert_object_ex(ldb, schema, cur, gensec_skey, out->objects, &out->objects[i]); - W_ERROR_NOT_OK_RETURN(status); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,("Failed to convert object %s\n", cur->object.identifier->dn)); + return status; + } } if (i != out->num_objects) { return WERR_FOOBAR; diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 17bc3ca..2d06970 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; diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ca38a85..0ed2a57 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -577,14 +577,14 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, "objectclass", "samldb", "password_hash", - "operational"] + "operational", + "kludge_acl"] tdb_modules_list = [ "subtree_rename", "subtree_delete", "linked_attributes", "extended_dn_out_ldb"] modules_list2 = ["show_deleted", - "kludge_acl", "partition"] domaindn_ldb = "users.ldb" -- Samba Shared Repository