diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-09-23 13:56:10 -0700 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-09-23 14:01:30 -0700 |
commit | 10f86114debaff6ca4c8baac38e39db49615d027 (patch) | |
tree | 0ca8e621d87cd841a6a7d24312c21cbef8711f4c | |
parent | 075f9e2c2919207fdf28cf0a7c19df12f5a809d2 (diff) | |
download | samba-10f86114debaff6ca4c8baac38e39db49615d027.tar.gz samba-10f86114debaff6ca4c8baac38e39db49615d027.tar.bz2 samba-10f86114debaff6ca4c8baac38e39db49615d027.zip |
s4-drs: fill in more guids and SIDs, plus filter rDN
In DsGetNCChanges we need to fill in the parentGUID and objectGUID of
each object, plus we need to filter out the rDN from the meta data,
and always send the instanceType
-rw-r--r-- | source4/rpc_server/drsuapi/getncchanges.c | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 56a37e9928..f38f95c044 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -51,6 +51,8 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem uint32_t rid = 0; enum ndr_err_code ndr_err; uint32_t *attids; + const char *rdn; + const struct dsdb_attribute *rdn_sa; if (ldb_dn_compare(ncRoot_dn, msg->dn) == 0) { obj->is_nc_prefix = true; @@ -59,6 +61,21 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem obj->is_nc_prefix = false; obj->parent_object_guid = talloc(obj, struct GUID); *obj->parent_object_guid = samdb_result_guid(msg, "parentGUID"); + if (GUID_all_zero(obj->parent_object_guid)) { + struct ldb_dn *parent_dn = ldb_dn_copy(msg, msg->dn); + if (parent_dn == NULL) { + return WERR_DS_DRA_INTERNAL_ERROR; + } + if (ldb_dn_remove_child_components(parent_dn, 1) != true) { + DEBUG(0,(__location__ ": Unable to remove DN component\n")); + return WERR_DS_DRA_INTERNAL_ERROR; + } + if (dsdb_find_guid_by_dn(sam_ctx, parent_dn, obj->parent_object_guid) != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Unable to find parent DN %s %s\n", + ldb_dn_get_linearized(msg->dn), ldb_dn_get_linearized(parent_dn))); + } + talloc_free(parent_dn); + } } obj->next_object = NULL; @@ -79,12 +96,30 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem return WERR_DS_DRA_INTERNAL_ERROR; } + rdn = ldb_dn_get_rdn_name(msg->dn); + if (rdn == NULL) { + DEBUG(0,(__location__ ": No rDN for %s\n", ldb_dn_get_linearized(msg->dn))); + return WERR_DS_DRA_INTERNAL_ERROR; + } + + rdn_sa = dsdb_attribute_by_lDAPDisplayName(schema, rdn); + if (rdn_sa == NULL) { + DEBUG(0,(__location__ ": Can't find dsds_attribute for rDN %s in %s\n", + rdn, ldb_dn_get_linearized(msg->dn))); + return WERR_DS_DRA_INTERNAL_ERROR; + } + obj->meta_data_ctr = talloc(obj, struct drsuapi_DsReplicaMetaDataCtr); attids = talloc_array(obj, uint32_t, md.ctr.ctr1.count); obj->meta_data_ctr->meta_data = talloc_array(obj, struct drsuapi_DsReplicaMetaData, md.ctr.ctr1.count); for (n=i=0; i<md.ctr.ctr1.count; i++) { - if (md.ctr.ctr1.array[i].local_usn < highest_usn) continue; + /* if the attribute has not changed, and it is not the + instanceType then don't include it */ + if (md.ctr.ctr1.array[i].local_usn < highest_usn && + md.ctr.ctr1.array[i].attid != DRSUAPI_ATTRIBUTE_instanceType) continue; + /* don't include the rDN */ + if (md.ctr.ctr1.array[i].attid == rdn_sa->attributeID_id) continue; obj->meta_data_ctr->meta_data[n].originating_change_time = md.ctr.ctr1.array[i].originating_change_time; obj->meta_data_ctr->meta_data[n].version = md.ctr.ctr1.array[i].version; obj->meta_data_ctr->meta_data[n].originating_invocation_id = md.ctr.ctr1.array[i].originating_invocation_id; @@ -113,6 +148,7 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem ZERO_STRUCT(obj->object.identifier->sid); } + obj->object.flags = DRSUAPI_DS_REPLICA_OBJECT_FROM_MASTER; obj->object.attribute_ctr.num_attributes = obj->meta_data_ctr->count; obj->object.attribute_ctr.attributes = talloc_array(obj, struct drsuapi_DsReplicaAttribute, obj->object.attribute_ctr.num_attributes); @@ -122,10 +158,10 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem * be the same size and in the same order */ for (i=0; i<obj->object.attribute_ctr.num_attributes; i++) { - const struct dsdb_attribute *sa; struct ldb_message_element *el; WERROR werr; - + const struct dsdb_attribute *sa; + sa = dsdb_attribute_by_attributeID_id(schema, attids[i]); if (!sa) { DEBUG(0,("Unable to find attributeID %u in schema\n", attids[i])); @@ -340,6 +376,15 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.naming_context = talloc(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier); *r->out.ctr->ctr6.naming_context = *ncRoot; + if (dsdb_find_guid_by_dn(sam_ctx, ncRoot_dn, &r->out.ctr->ctr6.naming_context->guid) != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to find GUID of ncRoot_dn %s\n", + ldb_dn_get_linearized(ncRoot_dn))); + return WERR_DS_DRA_INTERNAL_ERROR; + } + + /* find the SID if there is one */ + dsdb_find_sid_by_dn(sam_ctx, ncRoot_dn, &r->out.ctr->ctr6.naming_context->sid); + dsdb_get_oid_mappings_drsuapi(schema, true, mem_ctx, &ctr); r->out.ctr->ctr6.mapping_ctr = *ctr; |