The branch, master has been updated via d1784e7... s4-drs: support DRSUAPI_DRS_ADD_REF flag via 59818f2... s4-drs: implement more of DsUpdateRefs via 41ba2f8... ldb: fixed display of replUpToDateVector via f1bf262... drs: improved error checking via 94897d7... s4-dsdb: added samdb_rodc() and samdb_ntds_options() via 424c464... libds: added nTDSDSA options flags via 44866f0... idl: added WSPP DrsOptions bit names from 1c1a883... Fix the build, missing ->. Jeremy.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit d1784e7ca92ba8c6579da6a6238a3f95d67a463d Author: Andrew Tridgell <tri...@samba.org> Date: Wed Oct 14 20:29:39 2009 +1100 s4-drs: support DRSUAPI_DRS_ADD_REF flag The DRSUAPI_DRS_ADD_REF flag tells the DRS server to run an UpdateRefs call on behalf of the client after the DsGetNCChanges call. The lack of support for this option may explain why the repsTo attribute was not being created for w2k8-r2 replication partners. commit 59818f2f793ecc6349b87ee0debc7dd558272552 Author: Andrew Tridgell <tri...@samba.org> Date: Wed Oct 14 20:25:48 2009 +1100 s4-drs: implement more of DsUpdateRefs The DsUpdateRefs calls takes a set of flags that indicates if the server should ignore specific add/delete error codes. This patch also exposes the core UpdateRefs call into a public function, so that it can be called from DsGetNCChanges commit 41ba2f81895a8d7d0ccdd5bcbbf7a7d1f415ebaa Author: Andrew Tridgell <tri...@samba.org> Date: Wed Oct 14 15:57:15 2009 +1100 ldb: fixed display of replUpToDateVector commit f1bf262497d0a0f71bc52b0fac8c8aee8ecf13d9 Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 13 19:49:08 2009 +1100 drs: improved error checking Check the validity of the requested options in DsGetNCChanges commit 94897d7a7c5925983f362f498f78a32a26aa088b Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 13 19:48:13 2009 +1100 s4-dsdb: added samdb_rodc() and samdb_ntds_options() Later we will need to make samdb_rodc() look in the database, but for now we should at least have the function in a central place commit 424c464b7f34c91280c60953f6f81b0d3361e9e3 Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 13 19:46:18 2009 +1100 libds: added nTDSDSA options flags commit 44866f0df44dbcfd9b19eee560db77e966b92005 Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 13 18:31:21 2009 +1100 idl: added WSPP DrsOptions bit names This should make it much easier to work through the logic in MS-DRSR ----------------------------------------------------------------------- Summary of changes: libds/common/flags.h | 7 ++ librpc/gen_ndr/drsuapi.h | 32 +++++++++ librpc/gen_ndr/ndr_drsuapi.c | 51 ++++++++++++++ librpc/gen_ndr/ndr_drsuapi.h | 3 + librpc/idl/drsuapi.idl | 36 ++++++++++ source4/dsdb/common/util.c | 50 ++++++++++++++ source4/dsdb/repl/drepl_out_helpers.c | 2 +- source4/lib/ldb-samba/ldif_handlers.c | 2 +- source4/rpc_server/drsuapi/dcesrv_drsuapi.h | 2 + source4/rpc_server/drsuapi/getncchanges.c | 99 +++++++++++++++++++++------ source4/rpc_server/drsuapi/updaterefs.c | 88 ++++++++++++++++------- 11 files changed, 322 insertions(+), 50 deletions(-) Changeset truncated at 500 lines: diff --git a/libds/common/flags.h b/libds/common/flags.h index 37103bc..46d0372 100644 --- a/libds/common/flags.h +++ b/libds/common/flags.h @@ -183,3 +183,10 @@ /* sa->systemFlags on attributes */ #define DS_FLAG_ATTR_NOT_REPLICATED 0x00000001 #define DS_FLAG_ATTR_IS_CONSTRUCTED 0x00000004 + +/* 7.1.1.2.2.1.2.1.1 nTDSDSA Object options flags */ +#define DS_NTDSDSA_OPT_IS_GC 0x00000001 +#define DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL 0x00000002 +#define DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL 0x00000004 +#define DS_NTDSDSA_OPT_DISABLE_NTDSCONN_XLATE 0x00000008 +#define DS_NTDSDSA_OPT_DISABLE_SPN_REGISTRATION 0x00000010 diff --git a/librpc/gen_ndr/drsuapi.h b/librpc/gen_ndr/drsuapi.h index 52b6ee9..0a03004 100644 --- a/librpc/gen_ndr/drsuapi.h +++ b/librpc/gen_ndr/drsuapi.h @@ -15,6 +15,38 @@ #define DRSUAPI_DS_BIND_GUID_W2K3 ( "6afab99c-6e26-464a-975f-f58f105218bc" ) #define DRSUAPI_DS_MEMBERSHIP_FLAG_GROUP_ATTR ( 0x1 ) #define DRSUAPI_NTDSDSA_KRB5_SERVICE_GUID ( "E3514235-4B06-11D1-AB04-00C04FC2DCD2" ) +/* bitmap drsuapi_DrsOptions */ +#define DRSUAPI_DRS_ASYNC_OP ( 0x00000001 ) +#define DRSUAPI_DRS_GETCHG_CHECK ( 0x00000002 ) +#define DRSUAPI_DRS_ADD_REF ( 0x00000004 ) +#define DRSUAPI_DRS_SYNC_ALL ( 0x00000008 ) +#define DRSUAPI_DRS_DEL_REF ( 0x00000008 ) +#define DRSUAPI_DRS_WRIT_REP ( 0x00000010 ) +#define DRSUAPI_DRS_INIT_SYNC ( 0x00000020 ) +#define DRSUAPI_DRS_PER_SYNC ( 0x00000040 ) +#define DRSUAPI_DRS_MAIL_REP ( 0x00000080 ) +#define DRSUAPI_DRS_ASYNC_REP ( 0x00000100 ) +#define DRSUAPI_DRS_IGNORE_ERROR ( 0x00000100 ) +#define DRSUAPI_DRS_TWOWAY_SYNC ( 0x00000200 ) +#define DRSUAPI_DRS_CRITICAL_ONLY ( 0x00000400 ) +#define DRSUAPI_DRS_GET_ANC ( 0x00000800 ) +#define DRSUAPI_DRS_GET_NC_SIZE ( 0x00001000 ) +#define DRSUAPI_DRS_LOCAL_ONLY ( 0x00001000 ) +#define DRSUAPI_DRS_SYNC_BYNAME ( 0x00004000 ) +#define DRSUAPI_DRS_REF_OK ( 0x00004000 ) +#define DRSUAPI_DRS_FULL_SYNC_NOW ( 0x00008000 ) +#define DRSUAPI_DRS_NO_SOURCE ( 0x00008000 ) +#define DRSUAPI_DRS_FULL_SYNC_PACKET ( 0x00020000 ) +#define DRSUAPI_DRS_REF_GCSPN ( 0x00100000 ) +#define DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING ( 0x00800000 ) +#define DRSUAPI_DRS_SYNC_FORCED ( 0x02000000 ) +#define DRSUAPI_DRS_DISABLE_AUTO_SYNC ( 0x04000000 ) +#define DRSUAPI_DRS_DISABLE_PERIODIC_SYNC ( 0x08000000 ) +#define DRSUAPI_DRS_USE_COMPRESSION ( 0x10000000 ) +#define DRSUAPI_DRS_NEVER_NOTIFY ( 0x20000000 ) +#define DRSUAPI_DRS_SYNC_PAS ( 0x40000000 ) +#define DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP ( 0x80000000 ) + /* bitmap drsuapi_SupportedExtensions */ #define DRSUAPI_SUPPORTED_EXTENSION_BASE ( 0x00000001 ) #define DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION ( 0x00000002 ) diff --git a/librpc/gen_ndr/ndr_drsuapi.c b/librpc/gen_ndr/ndr_drsuapi.c index 700306c..ec799b6 100644 --- a/librpc/gen_ndr/ndr_drsuapi.c +++ b/librpc/gen_ndr/ndr_drsuapi.c @@ -7,6 +7,57 @@ #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_samr.h" #include "librpc/ndr/ndr_compression.h" +_PUBLIC_ enum ndr_err_code ndr_push_drsuapi_DrsOptions(struct ndr_push *ndr, int ndr_flags, uint32_t r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_drsuapi_DrsOptions(struct ndr_pull *ndr, int ndr_flags, uint32_t *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_drsuapi_DrsOptions(struct ndr_print *ndr, const char *name, uint32_t r) +{ + ndr_print_uint32(ndr, name, r); + ndr->depth++; + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_ASYNC_OP", DRSUAPI_DRS_ASYNC_OP, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_GETCHG_CHECK", DRSUAPI_DRS_GETCHG_CHECK, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_ADD_REF", DRSUAPI_DRS_ADD_REF, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_SYNC_ALL", DRSUAPI_DRS_SYNC_ALL, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_DEL_REF", DRSUAPI_DRS_DEL_REF, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_WRIT_REP", DRSUAPI_DRS_WRIT_REP, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_INIT_SYNC", DRSUAPI_DRS_INIT_SYNC, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_PER_SYNC", DRSUAPI_DRS_PER_SYNC, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_MAIL_REP", DRSUAPI_DRS_MAIL_REP, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_ASYNC_REP", DRSUAPI_DRS_ASYNC_REP, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_IGNORE_ERROR", DRSUAPI_DRS_IGNORE_ERROR, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_TWOWAY_SYNC", DRSUAPI_DRS_TWOWAY_SYNC, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_CRITICAL_ONLY", DRSUAPI_DRS_CRITICAL_ONLY, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_GET_ANC", DRSUAPI_DRS_GET_ANC, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_GET_NC_SIZE", DRSUAPI_DRS_GET_NC_SIZE, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_LOCAL_ONLY", DRSUAPI_DRS_LOCAL_ONLY, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_SYNC_BYNAME", DRSUAPI_DRS_SYNC_BYNAME, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_REF_OK", DRSUAPI_DRS_REF_OK, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_FULL_SYNC_NOW", DRSUAPI_DRS_FULL_SYNC_NOW, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_NO_SOURCE", DRSUAPI_DRS_NO_SOURCE, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_FULL_SYNC_PACKET", DRSUAPI_DRS_FULL_SYNC_PACKET, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_REF_GCSPN", DRSUAPI_DRS_REF_GCSPN, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING", DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_SYNC_FORCED", DRSUAPI_DRS_SYNC_FORCED, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_DISABLE_AUTO_SYNC", DRSUAPI_DRS_DISABLE_AUTO_SYNC, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_DISABLE_PERIODIC_SYNC", DRSUAPI_DRS_DISABLE_PERIODIC_SYNC, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_USE_COMPRESSION", DRSUAPI_DRS_USE_COMPRESSION, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_NEVER_NOTIFY", DRSUAPI_DRS_NEVER_NOTIFY, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_SYNC_PAS", DRSUAPI_DRS_SYNC_PAS, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP", DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP, r); + ndr->depth--; +} + static enum ndr_err_code ndr_push_drsuapi_SupportedExtensions(struct ndr_push *ndr, int ndr_flags, uint32_t r) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); diff --git a/librpc/gen_ndr/ndr_drsuapi.h b/librpc/gen_ndr/ndr_drsuapi.h index f157cc5..8c4a9e3 100644 --- a/librpc/gen_ndr/ndr_drsuapi.h +++ b/librpc/gen_ndr/ndr_drsuapi.h @@ -63,6 +63,9 @@ extern const struct ndr_interface_table ndr_table_drsuapi; #define NDR_DRSUAPI_QUERYSITESBYCOST (0x18) #define NDR_DRSUAPI_CALL_COUNT (25) +enum ndr_err_code ndr_push_drsuapi_DrsOptions(struct ndr_push *ndr, int ndr_flags, uint32_t r); +enum ndr_err_code ndr_pull_drsuapi_DrsOptions(struct ndr_pull *ndr, int ndr_flags, uint32_t *r); +void ndr_print_drsuapi_DrsOptions(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_drsuapi_SupportedExtensions(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_drsuapi_SupportedExtensionsExt(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_drsuapi_DsBindInfo24(struct ndr_print *ndr, const char *name, const struct drsuapi_DsBindInfo24 *r); diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl index 9d2d153..27cb14e 100644 --- a/librpc/idl/drsuapi.idl +++ b/librpc/idl/drsuapi.idl @@ -15,6 +15,40 @@ interface drsuapi { typedef bitmap samr_GroupAttrs samr_GroupAttrs; + /* see MS-DRSR section 5.37 */ + typedef [public,bitmap32bit] bitmap { + DRSUAPI_DRS_ASYNC_OP = 0x00000001, + DRSUAPI_DRS_GETCHG_CHECK = 0x00000002, + DRSUAPI_DRS_ADD_REF = 0x00000004, + DRSUAPI_DRS_SYNC_ALL = 0x00000008, + DRSUAPI_DRS_DEL_REF = 0x00000008, + DRSUAPI_DRS_WRIT_REP = 0x00000010, + DRSUAPI_DRS_INIT_SYNC = 0x00000020, + DRSUAPI_DRS_PER_SYNC = 0x00000040, + DRSUAPI_DRS_MAIL_REP = 0x00000080, + DRSUAPI_DRS_ASYNC_REP = 0x00000100, + DRSUAPI_DRS_IGNORE_ERROR = 0x00000100, + DRSUAPI_DRS_TWOWAY_SYNC = 0x00000200, + DRSUAPI_DRS_CRITICAL_ONLY = 0x00000400, + DRSUAPI_DRS_GET_ANC = 0x00000800, + DRSUAPI_DRS_GET_NC_SIZE = 0x00001000, + DRSUAPI_DRS_LOCAL_ONLY = 0x00001000, + DRSUAPI_DRS_SYNC_BYNAME = 0x00004000, + DRSUAPI_DRS_REF_OK = 0x00004000, + DRSUAPI_DRS_FULL_SYNC_NOW = 0x00008000, + DRSUAPI_DRS_NO_SOURCE = 0x00008000, + DRSUAPI_DRS_FULL_SYNC_PACKET = 0x00020000, + DRSUAPI_DRS_REF_GCSPN = 0x00100000, + DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING = 0x00800000, + DRSUAPI_DRS_SYNC_FORCED = 0x02000000, + DRSUAPI_DRS_DISABLE_AUTO_SYNC = 0x04000000, + DRSUAPI_DRS_DISABLE_PERIODIC_SYNC = 0x08000000, + DRSUAPI_DRS_USE_COMPRESSION = 0x10000000, + DRSUAPI_DRS_NEVER_NOTIFY = 0x20000000, + DRSUAPI_DRS_SYNC_PAS = 0x40000000, + DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP = 0x80000000 + } drsuapi_DrsOptions; + /*****************/ /* Function 0x00 */ typedef [bitmap32bit] bitmap { @@ -219,6 +253,8 @@ interface drsuapi /* the _WRITEABLE flag indicates a replication with all attributes * * --metze + * + * See drsuapi_DrsOptions for the WSPP bit names */ DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE = 0x00000010, DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP = 0x00000020, diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index f86a842..c9562b0 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -2528,3 +2528,53 @@ int drsuapi_DsReplicaCursor2_compare(const struct drsuapi_DsReplicaCursor2 *c1, { return GUID_compare(&c1->source_dsa_invocation_id, &c2->source_dsa_invocation_id); } + +/* + see if we are a RODC + + TODO: This should take a sam_ctx, and lookup the right object (with + a cache) +*/ +bool samdb_rodc(struct loadparm_context *lp_ctx) +{ + return lp_parm_bool(lp_ctx, NULL, "repl", "RODC", false); +} + + +/* + return NTDS options flags. See MS-ADTS 7.1.1.2.2.1.2.1.1 + + flags are DS_NTDS_OPTION_* +*/ +int samdb_ntds_options(struct ldb_context *ldb, uint32_t *options) +{ + TALLOC_CTX *tmp_ctx; + const char *attrs[] = { "options", NULL }; + int ret; + struct ldb_result *res; + + tmp_ctx = talloc_new(ldb); + if (tmp_ctx == NULL) { + goto failed; + } + + ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL); + if (ret) { + goto failed; + } + + if (res->count != 1) { + goto failed; + } + + *options = samdb_result_uint(res->msgs[0], "options", 0); + + talloc_free(tmp_ctx); + + return LDB_SUCCESS; + +failed: + DEBUG(1,("Failed to find our own NTDS Settings objectGUID in the ldb!\n")); + talloc_free(tmp_ctx); + return LDB_ERR_NO_SUCH_OBJECT; +} diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index 598ceb5..c86956c 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -519,7 +519,7 @@ static void dreplsrv_update_refs_send(struct dreplsrv_op_pull_source_state *st) r->in.req.req1.options = DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE | DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE; - if (!lp_parm_bool(service->task->lp_ctx, NULL, "repl", "RODC", false)) { + if (!samdb_rodc(service->task->lp_ctx)) { r->in.req.req1.options |= DRSUAPI_DS_REPLICA_UPDATE_WRITEABLE; } diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c index 43a1045..4d8af75 100644 --- a/source4/lib/ldb-samba/ldif_handlers.c +++ b/source4/lib/ldb-samba/ldif_handlers.c @@ -756,7 +756,7 @@ static int ldif_write_replUpToDateVector(struct ldb_context *ldb, void *mem_ctx, return ldif_write_NDR(ldb, mem_ctx, in, out, sizeof(struct replUpToDateVectorBlob), (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob, - (ndr_print_fn_t)ndr_print_replPropertyMetaDataBlob); + (ndr_print_fn_t)ndr_print_replUpToDateVectorBlob); } diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.h b/source4/rpc_server/drsuapi/dcesrv_drsuapi.h index 82899c8..e42d956 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.h +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.h @@ -39,6 +39,8 @@ struct drsuapi_bind_state { /* prototypes of internal functions */ +WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx, + struct drsuapi_DsReplicaUpdateRefsRequest1 *req); WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsReplicaUpdateRefs *r); WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index ae1b2e6..90ddab0 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -141,8 +141,10 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem 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; @@ -205,12 +207,10 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem sa->lDAPDisplayName, win_errstr(werr))); return werr; } - /* if DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING is set + /* if DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING is set * check if attribute is secret and send a null value - * TODO: check if we can make this in the database layer */ - if ((replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING) - == DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING) { + if (replica_flags & DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) { drsuapi_process_secret_attribute(&obj->object.attribute_ctr.attributes[i], &obj->meta_data_ctr->meta_data[i]); } @@ -328,6 +328,8 @@ struct drsuapi_getncchanges_state { /* drsuapi_DsGetNCChanges + + see MS-DRSR 4.1.10.5.2 for basic logic of this function */ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsGetNCChanges *r) @@ -345,6 +347,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ struct dcesrv_handle *h; struct drsuapi_bind_state *b_state; struct drsuapi_getncchanges_state *getnc_state; + struct drsuapi_DsGetNCChangesRequest8 *req8; + uint32_t options; DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); b_state = h->data; @@ -359,25 +363,43 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.more_data = false; r->out.ctr->ctr6.uptodateness_vector = NULL; - /* Check request revision. */ + /* a RODC doesn't allow for any replication */ + if (samdb_rodc(ldb_get_opaque(b_state->sam_ctx, "loadparm"))) { + DEBUG(0,(__location__ ": DsGetNCChanges attempt on RODC\n")); + return WERR_DS_DRA_SOURCE_DISABLED; + } + + /* Check request revision. + TODO: Adding mappings to req8 from the other levels + */ if (r->in.level != 8) { + DEBUG(0,(__location__ ": Request for DsGetNCChanges with unsupported level %u\n", + r->in.level)); return WERR_REVISION_MISMATCH; } + req8 = &r->in.req->req8; + /* Perform access checks. */ - if (r->in.req->req8.naming_context == NULL) { + ncRoot = req8->naming_context; + if (ncRoot == NULL) { + DEBUG(0,(__location__ ": Request for DsGetNCChanges with no NC\n")); return WERR_DS_DRA_INVALID_PARAMETER; } - ncRoot = r->in.req->req8.naming_context; - if (ncRoot == NULL) { - return WERR_DS_DRA_BAD_NC; + if (samdb_ntds_options(b_state->sam_ctx, &options) != LDB_SUCCESS) { + return WERR_DS_DRA_INTERNAL_ERROR; + } + + if ((options & DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL) && + !(req8->replica_flags & DRSUAPI_DRS_SYNC_FORCED)) { + return WERR_DS_DRA_SOURCE_DISABLED; } - if ((r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) - == DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) { + + if (req8->replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) { /* Ignore the _in_ uptpdateness vector*/ - r->in.req->req8.uptodateness_vector = NULL; + req8->uptodateness_vector = NULL; } werr = drs_security_level_check(dce_call, "DsGetNCChanges"); @@ -401,25 +423,36 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ return WERR_DS_DRA_INTERNAL_ERROR; } + /* we don't yet support extended operations */ + if (req8->extended_op != DRSUAPI_EXOP_NONE) { + DEBUG(0,(__location__ ": Request for DsGetNCChanges extended op 0x%x\n", + (unsigned)req8->extended_op)); + return WERR_DS_DRA_NOT_SUPPORTED; + } + + /* + TODO: MS-DRSR section 4.1.10.1.1 + Work out if this is the start of a new cycle */ + if (getnc_state->site_res == NULL) { char* search_filter; enum ldb_scope scope = LDB_SCOPE_SUBTREE; - getnc_state->min_usn = r->in.req->req8.highwatermark.highest_usn; + getnc_state->min_usn = req8->highwatermark.highest_usn; /* Construct response. */ search_filter = talloc_asprintf(mem_ctx, "(uSNChanged>=%llu)", (unsigned long long)(getnc_state->min_usn+1)); - if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_CRITICAL_ONLY) { + if (req8->replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_CRITICAL_ONLY) { search_filter = talloc_asprintf(mem_ctx, "(&%s(isCriticalSystemObject=TRUE))", search_filter); } getnc_state->ncRoot_dn = ldb_dn_new(getnc_state, b_state->sam_ctx, ncRoot->dn); - if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_ASYNC_REP) { + if (req8->replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_ASYNC_REP) { scope = LDB_SCOPE_BASE; } @@ -473,15 +506,15 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.source_dsa_guid = *(samdb_ntds_objectGUID(b_state->sam_ctx)); r->out.ctr->ctr6.source_dsa_invocation_id = *(samdb_ntds_invocation_id(b_state->sam_ctx)); - r->out.ctr->ctr6.old_highwatermark = r->in.req->req8.highwatermark; - r->out.ctr->ctr6.new_highwatermark = r->in.req->req8.highwatermark; + r->out.ctr->ctr6.old_highwatermark = req8->highwatermark; + r->out.ctr->ctr6.new_highwatermark = req8->highwatermark; r->out.ctr->ctr6.first_object = NULL; currentObject = &r->out.ctr->ctr6.first_object; for(i=getnc_state->num_sent; i<getnc_state->site_res->count && - (r->out.ctr->ctr6.object_count < r->in.req->req8.max_object_count); + (r->out.ctr->ctr6.object_count < req8->max_object_count); i++) { int uSN; struct drsuapi_DsReplicaObjectListItemEx *obj; @@ -495,7 +528,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ werr = get_nc_changes_build_object(obj, getnc_state->site_res->msgs[i], b_state->sam_ctx, getnc_state->ncRoot_dn, schema, &session_key, getnc_state->min_usn, - r->in.req->req8.replica_flags); + req8->replica_flags); if (!W_ERROR_IS_OK(werr)) { return werr; } @@ -518,6 +551,29 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.nc_object_count = getnc_state->site_res->count; + /* the client can us to call UpdateRefs on its behalf to + re-establish monitoring of the NC */ + if ((req8->replica_flags & DRSUAPI_DRS_ADD_REF) && + !GUID_all_zero(&req8->destination_dsa_guid)) { + struct drsuapi_DsReplicaUpdateRefsRequest1 ureq; + ureq.naming_context = ncRoot; + ureq.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "%s._msdcs.%s", + GUID_string(mem_ctx, &req8->destination_dsa_guid), + lp_realm(dce_call->conn->dce_ctx->lp_ctx)); + if (!ureq.dest_dsa_dns_name) { + return WERR_NOMEM; + } + ureq.dest_dsa_guid = req8->destination_dsa_guid; + ureq.options = DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE | + DRSUAPI_DS_REPLICA_UPDATE_ASYNCHRONOUS_OPERATION | + DRSUAPI_DS_REPLICA_UPDATE_GETCHG_CHECK; + werr = drsuapi_UpdateRefs(b_state, mem_ctx, &ureq); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,(__location__ ": Failed UpdateRefs in DsGetNCChanges - %s\n", + win_errstr(werr))); + } + } + if (i < getnc_state->site_res->count) { r->out.ctr->ctr6.more_data = true; } else { @@ -538,8 +594,9 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ b_state->getncchanges_state = NULL; } - DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n", - (unsigned long long)(r->in.req->req8.highwatermark.highest_usn+1), + DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu flags 0x%08x on %s gave %u objects\n", + (unsigned long long)(req8->highwatermark.highest_usn+1), + req8->replica_flags, ncRoot->dn, r->out.ctr->ctr6.object_count)); return WERR_OK; diff --git a/source4/rpc_server/drsuapi/updaterefs.c b/source4/rpc_server/drsuapi/updaterefs.c index d01fabf..60a70c5 100644 --- a/source4/rpc_server/drsuapi/updaterefs.c +++ b/source4/rpc_server/drsuapi/updaterefs.c @@ -35,16 +35,29 @@ struct repsTo { -- Samba Shared Repository