[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Thu Apr 22 03:37:46 MDT 2010


The branch, master has been updated
       via  404f7ac... s4-cldap: we should set the w2k8 flags even if not the PDC emulator
       via  e7262b5... s4-drs: validate RODC credentials via the user_sid
       via  bb1ba4f... s4-drs: added new SECURITY_RO_DOMAIN_CONTROLLER level
       via  ec0bb2f... s4-net: fixed two compiler warnings
       via  ec3d1de... s4-torture: fixed a initialiser
       via  47712ab... s4-libnet: fixed two compiler warnings
       via  1f92df9... s4-drs: removed dsdb_validate_client_flags()
       via  90230ce... s4-drs: only allow replication with the right invocationId
       via  0d3823b... s4-dsdb: removed an unused variable
       via  a06b537... s4-dsdb: added dsdb_validate_invocation_id()
       via  1ecefd7... s4-dsdb: added dsdb_get_extended_dn_sid()
       via  6669152... build: we don't need this makefile magic any more
       via  70cc9fd... s4-dsdb: moved rodc schema validation to samldb.c
       via  73513fb... s4-drs: Use new samdb_rodc() function in s4 code
       via  d940a44... s4-drs: Do not send RODC filtered attributes to RODCs on GetNCChanges reply
       via  59aa0a0... s40-drs: Do not send GetNCChanges messages to RODCs
       via  fbdbd67... s4-drs: dsdb_validate_client_flags() function
       via  57bcdf0... s4-drs: samdb_is_rodc() function and new samdb_rodc() function
       via  c023fc2... s4-drs: Do not allow system-critical attributes to be RODC filtered
      from  e11f92b... s4:provision Make OpenLDAP backend more robust

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 404f7ac0292c91ef3101e9bc32b8aea3b2aec4be
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 17:53:25 2010 +1000

    s4-cldap: we should set the w2k8 flags even if not the PDC emulator
    
    these two tests are independent
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit e7262b51d1a8905ba3b874f5d48eab4292ebca4d
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 16:56:40 2010 +1000

    s4-drs: validate RODC credentials via the user_sid
    
    This checks whether a replication client is a RODC by inclusion of the
    the DOMAIN_RID_ENTERPRISE_READONLY_DCS sid in the users token
    
    Pair-Programmed-With: Rusty Russell <rusty at samba.org>
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit bb1ba4ff76eb90d0d62dd3edbe288f45cf7a0a1e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 16:48:01 2010 +1000

    s4-drs: added new SECURITY_RO_DOMAIN_CONTROLLER level
    
    This is used for allowing operations by RODCs, and denying them
    operations that should only be allowed for a full DC
    
    This required a new domain_sid argument to
    security_session_user_level()
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    Pair-Programmed-With: Rusty Russell <rusty at samba.org>

commit ec0bb2f46b855d44cccb71a5511c2acb7d8eae09
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 16:44:53 2010 +1000

    s4-net: fixed two compiler warnings

commit ec3d1de61dd81f042b9ac65ff4f94db5b4ae643c
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 16:44:30 2010 +1000

    s4-torture: fixed a initialiser
    
    we were not initialising the whole array
    
    Pair-Programmed-With: Rusty Russell <rusty at samba.org>
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 47712ab3dd63d3da408d37f6efea08cc34407b1d
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 16:43:21 2010 +1000

    s4-libnet: fixed two compiler warnings

commit 1f92df90fdb0ade233af52df1fbc9e76bddb4fd0
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 16:41:32 2010 +1000

    s4-drs: removed dsdb_validate_client_flags()
    
    This test is in the wrong place. We end up validating our own flags.
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 90230ce27eaa81e02273f0120b7cdc99879514ac
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 14:56:19 2010 +1000

    s4-drs: only allow replication with the right invocationId
    
    Non-administrator replication checks the invocationId matches
    the sid of the user token being used
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 0d3823b15248ed6269bb0a513d862ef694bfde64
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 14:55:54 2010 +1000

    s4-dsdb: removed an unused variable

commit a06b537cc30cb21e77f58b5e9ea2a8f89c4683e0
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 14:54:52 2010 +1000

    s4-dsdb: added dsdb_validate_invocation_id()
    
    this validates that a invocationID matches an account sid
    
    This will be used to ensure that we don't allow DRS replication
    from someone a non-DC or administrator
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 1ecefd74a2b7a6cec0c6ef765669eab0635e5568
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 14:53:53 2010 +1000

    s4-dsdb: added dsdb_get_extended_dn_sid()
    
    This will be used by the RODC code
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 6669152a4a5919ecad633b594708d6b95577b4dc
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 14:52:19 2010 +1000

    build: we don't need this makefile magic any more
    
    The waf build now checks for all A=B variables passed via make
    and sets the same waf internal variable. This means all waf options
    are available via make.
    
    Removing this from the Makefile makes us less reliant on a modern
    version of make.
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 70cc9fd5c62f385d6e94380597f02da80cea3649
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Apr 22 13:32:55 2010 +1000

    s4-dsdb: moved rodc schema validation to samldb.c
    
    This means we are only doing the checks for schema changes
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 73513fb7e7145e9abe1a155acd47c27bc09c5092
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date:   Thu Apr 15 18:54:13 2010 -0300

    s4-drs: Use new samdb_rodc() function in s4 code
    
    This patch fits the calling to the new samdb_rodc() function and
    fix a little bug in this function.
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit d940a44496f184073fe036fc1977796c901ec96d
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date:   Thu Apr 15 17:42:08 2010 -0300

    s4-drs: Do not send RODC filtered attributes to RODCs on GetNCChanges reply
    
    During building an object to send it on a GetNCChanges reply, it checks
    the attributes and if any of them is a RODC filtered and the recipient
    is a RODC, then such attribute is not sent.
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit 59aa0a07d24bfb9ff9795ffe90801577043058a5
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date:   Thu Apr 15 17:39:54 2010 -0300

    s40-drs: Do not send GetNCChanges messages to RODCs
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit fbdbd67c7640757f80a2ffd70a17c6ab50491844
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date:   Thu Apr 15 17:38:47 2010 -0300

    s4-drs: dsdb_validate_client_flags() function
    
    This function is intended to check if some client is not lying about
    his flags. At this moment, it only checks for RODC flags.
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit 57bcdf008fa44d4c550819cbceada968b11be63c
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date:   Thu Apr 15 17:37:40 2010 -0300

    s4-drs: samdb_is_rodc() function and new samdb_rodc() function
    
    This patch creates the samdb_is_rodc() function, which looks for
    the NTDSDSA object for a DC that has a specific invocationId
    and if msDS-isRODC is present on such object and it is TRUE, then
    consider the DC as a RODC.
    The new samdb_rodc() function uses the samdb_is_rodc() function
    for the local server.
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit c023fc217ed370e5c890c1984da533e0133060d9
Author: Fernando J V da Silva <fernandojvsilva at yahoo.com.br>
Date:   Thu Mar 25 16:58:58 2010 -0300

    s4-drs: Do not allow system-critical attributes to be RODC filtered
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 buildtools/scripts/Makefile.waf                 |    4 +-
 libds/common/flags.h                            |    3 +
 source4/cldap_server/netlogon.c                 |    7 +-
 source4/dsdb/common/util.c                      |  189 +++++++++++++++++++----
 source4/dsdb/kcc/kcc_topology.c                 |   18 ++-
 source4/dsdb/repl/drepl_out_helpers.c           |    9 +-
 source4/dsdb/repl/drepl_service.c               |    5 +-
 source4/dsdb/samdb/ldb_modules/descriptor.c     |    1 -
 source4/dsdb/samdb/ldb_modules/kludge_acl.c     |    2 +-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |    2 +-
 source4/dsdb/samdb/ldb_modules/rootdse.c        |    2 +-
 source4/dsdb/samdb/ldb_modules/samldb.c         |   37 +++++
 source4/dsdb/samdb/ldb_modules/util.c           |    2 +-
 source4/dsdb/schema/schema_syntax.c             |   17 +--
 source4/libcli/security/security.h              |   11 +-
 source4/libcli/security/security_token.c        |   13 ++-
 source4/libnet/libnet_become_dc.c               |    5 +-
 source4/rpc_server/drsuapi/addentry.c           |    4 +-
 source4/rpc_server/drsuapi/dcesrv_drsuapi.c     |   10 +-
 source4/rpc_server/drsuapi/dcesrv_drsuapi.h     |    3 +-
 source4/rpc_server/drsuapi/drsutil.c            |    8 +-
 source4/rpc_server/drsuapi/getncchanges.c       |   42 +++++-
 source4/rpc_server/drsuapi/updaterefs.c         |   23 +++-
 source4/rpc_server/lsa/dcesrv_lsa.c             |   18 ++-
 source4/rpc_server/winreg/rpc_winreg.c          |   16 +-
 source4/torture/smb2/acls.c                     |    2 +-
 source4/utils/net/drs/net_drs_replicate.c       |   10 +-
 27 files changed, 352 insertions(+), 111 deletions(-)


Changeset truncated at 500 lines:

diff --git a/buildtools/scripts/Makefile.waf b/buildtools/scripts/Makefile.waf
index ac5c013..f9c3fbb 100644
--- a/buildtools/scripts/Makefile.waf
+++ b/buildtools/scripts/Makefile.waf
@@ -12,10 +12,10 @@ uninstall:
 	$(WAF) uninstall
 
 test:
-	$(WAF) test $(if $(TESTS),--tests="$(TESTS)")
+	$(WAF) test
 
 quicktest:
-	$(WAF) test --quick $(if $(TESTS),--tests="$(TESTS)")
+	$(WAF) test --quick
 
 dist:
 	$(WAF) dist
diff --git a/libds/common/flags.h b/libds/common/flags.h
index aa88487..de3e71c 100644
--- a/libds/common/flags.h
+++ b/libds/common/flags.h
@@ -155,6 +155,9 @@
 #define SYSTEM_FLAG_CONFIG_ALLOW_RENAME		0x40000000
 #define SYSTEM_FLAG_DISALLOW_DELETE		0x80000000
 
+/* schemaFlags_Ex */
+#define SCHEMA_FLAG_ATTR_IS_CRITICAL	0x0000001
+
 /* "searchFlags" */
 #define SEARCH_FLAG_ATTINDEX		0x0000001
 #define SEARCH_FLAG_PDNTATTINDEX	0x0000002
diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c
index 139c1ca..8f445d0 100644
--- a/source4/cldap_server/netlogon.c
+++ b/source4/cldap_server/netlogon.c
@@ -226,9 +226,10 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
 
 	if (samdb_is_pdc(sam_ctx)) {
 		server_type |= DS_SERVER_PDC;
-		if (dsdb_functional_level(sam_ctx) >= DS_DOMAIN_FUNCTION_2008) {
-			server_type |= DS_SERVER_FULL_SECRET_DOMAIN_6;
-		}
+	}
+
+	if (dsdb_functional_level(sam_ctx) >= DS_DOMAIN_FUNCTION_2008) {
+		server_type |= DS_SERVER_FULL_SECRET_DOMAIN_6;
 	}
 
 	if (samdb_is_gc(sam_ctx)) {
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 30cb5c5..3a04797 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2413,7 +2413,6 @@ int dsdb_find_sid_by_dn(struct ldb_context *ldb,
 }
 
 
-
 /*
   load a repsFromTo blob list for a given partition GUID
   attr must be "repsFrom" or "repsTo"
@@ -2618,50 +2617,59 @@ int drsuapi_DsReplicaCursor_compare(const struct drsuapi_DsReplicaCursor *c1,
 	return GUID_compare(&c1->source_dsa_invocation_id, &c2->source_dsa_invocation_id);
 }
 
+
 /*
-  see if we are a RODC
+  see if a computer identified by its invocationId is a RODC
 */
-bool samdb_rodc(struct ldb_context *sam_ctx)
-{
-	TALLOC_CTX *tmp_ctx;
-	const char *obj_category;
-	struct ldb_dn *obj_category_dn;
-	const struct ldb_val *obj_category_dn_rdn_val;
+int samdb_is_rodc(struct ldb_context *sam_ctx, const struct GUID *invocationId, bool *is_rodc)
+{
+	/* 1) find the DN for this servers NTDSDSA object
+	   2) search for the msDS-isRODC attribute
+	   3) if not present then not a RODC
+	   4) if present and TRUE then is a RODC
+	*/
+	struct ldb_dn *config_dn;
+	const char *attrs[] = { "msDS-isRODC", NULL };
+	int ret;
+	struct ldb_result *res;
+	TALLOC_CTX *tmp_ctx = talloc_new(sam_ctx);
 
-	tmp_ctx = talloc_new(sam_ctx);
-	if (tmp_ctx == NULL) {
-		DEBUG(1,("samdb_rodc: Failed to talloc new context.\n"));
-		goto failed;
+	config_dn = ldb_get_config_basedn(sam_ctx);
+	if (!config_dn) {
+		talloc_free(tmp_ctx);
+		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
-	obj_category = samdb_ntds_object_category(tmp_ctx, sam_ctx);
-	if (!obj_category) {
-		DEBUG(1,("samdb_rodc: Failed to get object category.\n"));
-		goto failed;
+	ret = dsdb_search(sam_ctx, tmp_ctx, &res, config_dn, LDB_SCOPE_SUBTREE, attrs,
+			  DSDB_SEARCH_ONE_ONLY, "invocationID=%s", GUID_string(tmp_ctx, invocationId));
+	if (ret != LDB_SUCCESS) {
+		talloc_free(tmp_ctx);
+		return ret;
 	}
 
-	obj_category_dn = ldb_dn_new(tmp_ctx, sam_ctx, obj_category);
-	if (!obj_category_dn) {
-		DEBUG(1,("samdb_rodc: Failed to create object category dn.\n"));
-		goto failed;
-	}
+	ret = ldb_msg_find_attr_as_bool(res->msgs[0], "msDS-isRODC", 0);
+	*is_rodc = (ret == 1);
 
-	obj_category_dn_rdn_val = ldb_dn_get_rdn_val(obj_category_dn);
-	if (!obj_category_dn_rdn_val) {
-		DEBUG(1, ("samdb_rodc: Failed to get object category dn rdn value.\n"));
-		goto failed;
-	}
+	talloc_free(tmp_ctx);
+	return LDB_SUCCESS;
+}
 
-	if (strequal((const char*)obj_category_dn_rdn_val->data, "NTDS-DSA-RO")) {
-		talloc_free(tmp_ctx);
-		return true;
-	}
 
-failed:
-	talloc_free(tmp_ctx);
-	return false;
+/*
+  see if we are a RODC
+*/
+int samdb_rodc(struct ldb_context *sam_ctx, bool *am_rodc)
+{
+	const struct GUID *invocationId;
+	invocationId = samdb_ntds_invocation_id(sam_ctx);
+	if (!invocationId) {
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	return samdb_is_rodc(sam_ctx, invocationId, am_rodc);
 }
 
+
+
 /*
   return NTDS options flags. See MS-ADTS 7.1.1.2.2.1.2.1.1 
 
@@ -2850,6 +2858,35 @@ NTSTATUS dsdb_get_extended_dn_uint32(struct ldb_dn *dn, uint32_t *val, const cha
 }
 
 /*
+  return a dom_sid from a extended DN structure
+ */
+NTSTATUS dsdb_get_extended_dn_sid(struct ldb_dn *dn, struct dom_sid *sid, const char *component_name)
+{
+	const struct ldb_val *sid_blob;
+	struct TALLOC_CTX *tmp_ctx;
+	enum ndr_err_code ndr_err;
+
+	sid_blob = ldb_dn_get_extended_component(dn, "SID");
+	if (!sid_blob) {
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	tmp_ctx = talloc_new(NULL);
+
+	ndr_err = ndr_pull_struct_blob_all(sid_blob, tmp_ctx, NULL, sid,
+					   (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+		talloc_free(tmp_ctx);
+		return status;
+	}
+
+	talloc_free(tmp_ctx);
+	return NT_STATUS_OK;
+}
+
+
+/*
   return RMD_FLAGS directly from a ldb_dn
   returns 0 if not found
  */
@@ -3531,3 +3568,89 @@ const char *samdb_forest_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
 
 	return forest_name;
 }
+
+/*
+   validate that an invocationID belongs to the specified user sid.
+   The user SID must be a domain controller account (either RODC or
+   RWDC)
+ */
+int dsdb_validate_invocation_id(struct ldb_context *ldb,
+				const struct GUID *invocation_id,
+				const struct dom_sid *sid)
+{
+	/* strategy:
+	    - find DN of record with the invocationID in the
+	      configuration partition
+            - remote "NTDS Settings" component from DN
+	    - do a base search on that DN for serverReference with
+	      extended-dn enabled
+            - extract objectSID from resulting serverReference
+              attribute
+	    - check this sid matches the sid argument
+	*/
+	struct ldb_dn *config_dn;
+	TALLOC_CTX *tmp_ctx = talloc_new(ldb);
+	struct ldb_message *msg;
+	const char *attrs1[] = { NULL };
+	const char *attrs2[] = { "serverReference", NULL };
+	int ret;
+	struct ldb_dn *dn, *account_dn;
+	struct dom_sid sid2;
+	NTSTATUS status;
+
+	config_dn = ldb_get_config_basedn(ldb);
+
+	ret = dsdb_search_one(ldb, tmp_ctx, &msg, config_dn, LDB_SCOPE_SUBTREE,
+			      attrs1, 0, "(&(invocationID=%s)(objectClass=nTDSDSA))", GUID_string(tmp_ctx, invocation_id));
+	if (ret != LDB_SUCCESS) {
+		DEBUG(1,(__location__ ": Failed to find invocationID %s for sid %s\n",
+			 GUID_string(tmp_ctx, invocation_id), dom_sid_string(tmp_ctx, sid)));
+		talloc_free(tmp_ctx);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	dn = msg->dn;
+
+	if (!ldb_dn_remove_child_components(dn, 1)) {
+		talloc_free(tmp_ctx);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	ret = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE,
+			      attrs2, DSDB_SEARCH_SHOW_EXTENDED_DN,
+			      "(objectClass=server)");
+	if (ret != LDB_SUCCESS) {
+		DEBUG(1,(__location__ ": Failed to find server record for invocationID %s, sid %s\n",
+			 GUID_string(tmp_ctx, invocation_id), dom_sid_string(tmp_ctx, sid)));
+		talloc_free(tmp_ctx);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	account_dn = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, msg, "serverReference");
+	if (account_dn == NULL) {
+		DEBUG(1,(__location__ ": Failed to find account_dn for invocationID %s, sid %s\n",
+			 GUID_string(tmp_ctx, invocation_id), dom_sid_string(tmp_ctx, sid)));
+		talloc_free(tmp_ctx);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	status = dsdb_get_extended_dn_sid(account_dn, &sid2, "SID");
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1,(__location__ ": Failed to find SID for invocationID %s, sid %s\n",
+			 GUID_string(tmp_ctx, invocation_id), dom_sid_string(tmp_ctx, sid)));
+		talloc_free(tmp_ctx);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	if (!dom_sid_equal(sid, &sid2)) {
+		/* someone is trying to spoof another account */
+		DEBUG(0,(__location__ ": Bad invocationID invocationID %s for sid %s - expected sid %s\n",
+			 GUID_string(tmp_ctx, invocation_id),
+			 dom_sid_string(tmp_ctx, sid),
+			 dom_sid_string(tmp_ctx, &sid2)));
+		talloc_free(tmp_ctx);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	talloc_free(tmp_ctx);
+	return LDB_SUCCESS;
+}
diff --git a/source4/dsdb/kcc/kcc_topology.c b/source4/dsdb/kcc/kcc_topology.c
index 72eb5e1..215cc4d 100644
--- a/source4/dsdb/kcc/kcc_topology.c
+++ b/source4/dsdb/kcc/kcc_topology.c
@@ -1155,7 +1155,13 @@ static NTSTATUS kcctpl_get_all_bridgehead_dcs(struct ldb_context *ldb,
 
 	el = ldb_msg_find_element(transport, "bridgeheadServerListBL");
 
-	rodc = samdb_rodc(ldb);
+	ret = samdb_rodc(ldb, &rodc);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(1, (__location__ ": unable to tell if we are an RODC: %s\n",
+			  ldb_strerror(ret)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
 
 	transport_name = samdb_result_string(transport, "name", NULL);
 	if (!transport_name) {
@@ -3155,6 +3161,7 @@ static NTSTATUS kcctpl_create_connections(struct ldb_context *ldb,
 	struct ldb_dn *transports_dn;
 	const char * const attrs[] = { "bridgeheadServerListBL", "name",
 				       "transportAddressAttribute", NULL };
+	int ret;
 
 	connected = true;
 
@@ -3223,14 +3230,19 @@ static NTSTATUS kcctpl_create_connections(struct ldb_context *ldb,
 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
 	}
 
-	rodc = samdb_rodc(ldb);
+	ret = samdb_rodc(ldb, &rodc);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(1, (__location__ ": Unable to tell if we are an RODC: %s\n",
+			  ldb_strerror(ret)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
 
 	for (i = 0; i < st_edge_list.count; i++) {
 		struct kcctpl_multi_edge *edge;
 		struct GUID other_site_id;
 		struct kcctpl_vertex *other_site_vertex;
 		struct ldb_result *res;
-		int ret;
 		struct ldb_message *transport, *r_bridgehead, *l_bridgehead;
 		uint8_t schedule[84];
 		uint32_t first_available, j, interval;
diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c
index a12481b..60dccff 100644
--- a/source4/dsdb/repl/drepl_out_helpers.c
+++ b/source4/dsdb/repl/drepl_out_helpers.c
@@ -272,6 +272,10 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
 	struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector;
 	struct tevent_req *subreq;
 
+	if ((rf1->replica_flags & DRSUAPI_DRS_WRIT_REP) == 0) {
+		return;
+	}
+
 	r = talloc(state, struct drsuapi_DsGetNCChanges);
 	if (tevent_req_nomem(r, req)) {
 		return;
@@ -542,6 +546,8 @@ static void dreplsrv_update_refs_trigger(struct tevent_req *req)
 	char *ntds_guid_str;
 	char *ntds_dns_name;
 	struct tevent_req *subreq;
+	bool am_rodc;
+	int ret;
 
 	r = talloc(state, struct drsuapi_DsReplicaUpdateRefs);
 	if (tevent_req_nomem(r, req)) {
@@ -566,7 +572,8 @@ static void dreplsrv_update_refs_trigger(struct tevent_req *req)
 	r->in.req.req1.dest_dsa_dns_name  = ntds_dns_name;
 	r->in.req.req1.dest_dsa_guid	  = service->ntds_guid;
 	r->in.req.req1.options	          = DRSUAPI_DRS_ADD_REF | DRSUAPI_DRS_DEL_REF;
-	if (!samdb_rodc(service->samdb)) {
+	ret = samdb_rodc(service->samdb, &am_rodc);
+	if (ret == LDB_SUCCESS && !am_rodc) {
 		r->in.req.req1.options |= DRSUAPI_DRS_WRIT_REP;
 	}
 
diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c
index 4196f94..59436d6 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -132,6 +132,8 @@ static void dreplsrv_task_init(struct task_server *task)
 	WERROR status;
 	struct dreplsrv_service *service;
 	uint32_t periodic_startup_interval;
+	bool am_rodc;
+	int ret;
 
 	switch (lp_server_role(task->lp_ctx)) {
 	case ROLE_STANDALONE:
@@ -194,7 +196,8 @@ static void dreplsrv_task_init(struct task_server *task)
 	}
 
 	/* if we are a RODC then we do not send DSReplicaSync*/
-	if (!samdb_rodc(service->samdb)) {
+	ret = samdb_rodc(service->samdb, &am_rodc);
+	if (ret == LDB_SUCCESS && !am_rodc) {
 		service->notify.interval = lp_parm_int(task->lp_ctx, NULL, "dreplsrv",
 							   "notify_interval", 5); /* in seconds */
 		status = dreplsrv_notify_schedule(service, service->notify.interval);
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
index cdfab3c..70b02e8 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -64,7 +64,6 @@ struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
 {
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 	struct ldb_dn *root_base_dn = ldb_get_root_basedn(ldb);
-	struct ldb_dn *default_base_dn = ldb_get_default_basedn(ldb);
 	struct ldb_dn *schema_base_dn = ldb_get_schema_basedn(ldb);
 	struct ldb_dn *config_base_dn = ldb_get_config_basedn(ldb);
 	const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
index 72863ad..42f0a30 100644
--- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c
+++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
@@ -56,7 +56,7 @@ static enum security_user_level what_is_user(struct ldb_module *module)
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	struct auth_session_info *session_info
 		= (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
-	return security_session_user_level(session_info);
+	return security_session_user_level(session_info, NULL);
 }
 
 static const char *user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module) 
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 75aed6a..efb44bf 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -2402,7 +2402,7 @@ static int replmd_delete(struct ldb_module *module, struct ldb_request *req)
 	if (next_deletion_state == OBJECT_REMOVED) {
 		struct auth_session_info *session_info =
 				(struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
-		if (security_session_user_level(session_info) != SECURITY_SYSTEM) {
+		if (security_session_user_level(session_info, NULL) != SECURITY_SYSTEM) {
 			ldb_asprintf_errstring(ldb, "Refusing to delete deleted object %s",
 					ldb_dn_get_linearized(old_msg->dn));
 			return LDB_ERR_UNWILLING_TO_PERFORM;
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index f10a125..5fffef7 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -884,7 +884,7 @@ static int rootdse_enableoptionalfeature(struct ldb_module *module, struct ldb_r
 	int ret;
 	const char *guid_string;
 
-	if (security_session_user_level(session_info) != SECURITY_SYSTEM) {
+	if (security_session_user_level(session_info, NULL) != SECURITY_SYSTEM) {
 		ldb_asprintf_errstring(ldb, "rootdse: Insufficient rights for enableoptionalfeature");
 		return LDB_ERR_UNWILLING_TO_PERFORM;
 	}
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index c3a95f1..375b624 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -826,6 +826,26 @@ static int samldb_add_entry(struct samldb_ctx *ac)
 	return ldb_next_request(ac->module, req);
 }
 
+/*
+ * return true if msg carries an attributeSchema that is intended to be RODC
+ * filtered but is also a system-critical attribute.
+ */
+static bool check_rodc_critical_attribute(struct ldb_message *msg)
+{
+	uint32_t schemaFlagsEx, searchFlags, rodc_filtered_flags;
+
+	schemaFlagsEx = ldb_msg_find_attr_as_uint(msg, "schemaFlagsEx", 0);
+	searchFlags = ldb_msg_find_attr_as_uint(msg, "searchFlags", 0);
+	rodc_filtered_flags = (SEARCH_FLAG_RODC_ATTRIBUTE | SEARCH_FLAG_CONFIDENTIAL);
+
+	if ((schemaFlagsEx & SCHEMA_FLAG_ATTR_IS_CRITICAL) &&
+		((searchFlags & rodc_filtered_flags) == rodc_filtered_flags)) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
 
 static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
 {
@@ -885,6 +905,15 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
 						  "rdnAttId", "cn");
 		if (ret != LDB_SUCCESS) return ret;
 
+		/* do not allow to mark an attributeSchema as RODC filtered if it
+		 * is system-critical */
+		if (check_rodc_critical_attribute(ac->msg)) {
+			ldb_asprintf_errstring(ldb, "Refusing schema add of %s - cannot combine critical class with RODC filtering",
+					       ldb_dn_get_linearized(ac->msg->dn));
+			return LDB_ERR_UNWILLING_TO_PERFORM;
+		}
+
+
 		rdn_value = ldb_dn_get_rdn_val(ac->msg->dn);
 		if (!ldb_msg_find_element(ac->msg, "lDAPDisplayName")) {
 			/* the RDN has prefix "CN" */
@@ -932,6 +961,14 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
 			}
 		}
 
+		/* do not allow to mark an attributeSchema as RODC filtered if it
+		 * is system-critical */
+		if (check_rodc_critical_attribute(ac->msg)) {
+			ldb_asprintf_errstring(ldb, "Refusing schema add of %s - cannot combine critical attribute with RODC filtering",
+					       ldb_dn_get_linearized(ac->msg->dn));
+			return LDB_ERR_UNWILLING_TO_PERFORM;
+		}
+
 		ret = samdb_find_or_add_attribute(ldb, ac->msg,
 						  "isSingleValued", "FALSE");
 		if (ret != LDB_SUCCESS) return ret;
diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c
index fe0ff75..7913ac8 100644


-- 
Samba Shared Repository


More information about the samba-cvs mailing list