[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Wed Oct 14 15:21:14 MDT 2009


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 <tridge at 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 <tridge at 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 <tridge at samba.org>
Date:   Wed Oct 14 15:57:15 2009 +1100

    ldb: fixed display of replUpToDateVector

commit f1bf262497d0a0f71bc52b0fac8c8aee8ecf13d9
Author: Andrew Tridgell <tridge at 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 <tridge at 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 <tridge at samba.org>
Date:   Tue Oct 13 19:46:18 2009 +1100

    libds: added nTDSDSA options flags

commit 44866f0df44dbcfd9b19eee560db77e966b92005
Author: Andrew Tridgell <tridge at 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


More information about the samba-cvs mailing list