[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Tue Aug 17 05:22:23 MDT 2010


The branch, master has been updated
       via  56f0418... s4-ldb: ensure element flags are zero in ldb search return
       via  bb2ba90... s4-ldbwrap: ensure session_info in ldb opaque remains valid
       via  8835a36... s4-rpcserver: log unknown RPC calls at debug level 3
       via  2688375... s4-netlogon: added SEC_CHAN_RODC
       via  82c171a... s4-net: use an encrypted ldap session when setting passwords
       via  896f103... s4-dsdb: check the type of session_info from the opaque
       via  21729b6... s4-drs: allow getncchanges from RODC with WRIT_REP set
       via  45a2b40... s4-drs: added domain_sid to DRS security checks
       via  84bedf4... s4-drs: fixed check for SECURITY_RO_DOMAIN_CONTROLLER
       via  4e9daa0... s4-dsdb: added support for UF_PARTIAL_SECRETS_ACCOUNT
       via  df14f64... s4-dsdb: cope with cracknames of form dnsdomain\account
       via  f6e0b15... s4-dsdb: set LDB_FLAG_INTERNAL_DISABLE_VALIDATION for msDS-SecondaryKrbTgtNumber
       via  0caf347... s4-ldb: added LDB_FLAG_INTERNAL_DISABLE_VALIDATION
       via  9e27201... s4-ldb: added LDB_FLAG_INTERNAL_MASK
       via  6baa834... s4-ldb: use LDB_FLAG_MOD_TYPE() to extract element type from messages
       via  527042f... s4-dsdb: support LDB_CONTROL_RODC_DCPROMO_OID for nTDSDSA add
       via  974279b... s4-dsdb: fixed test for LDB_CONTROL_RODC_DCPROMO_OID
       via  eed3838... s4-ldapserver: support controls on ldap add and rename
       via  191d632... s4-dsdb: added support for LDB_CONTROL_RODC_DCPROMO_OID
       via  dcd9fcc... s4-ldap: use common functions for ldap flag controls encode/decode
      from  16ad1bb... s3-dcerpc: try to fix the non gssapi build.

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


- Log -----------------------------------------------------------------
commit 56f04188df598767901ab918e2be1f23a922c531
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 20:15:28 2010 +1000

    s4-ldb: ensure element flags are zero in ldb search return
    
    the distinguishedName element was getting an uninitialised flags value

commit bb2ba90663609c4051bf9cbedb4246802216126a
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 18:29:42 2010 +1000

    s4-ldbwrap: ensure session_info in ldb opaque remains valid
    
    A DRS DsBind handle can be re-used in a later connection. This implies
    reuse of the session_info for the connection. If the first connection
    is shutdown then the session_info in the sam context on the 2nd
    connection must remain valid.

commit 8835a360cad78feabb17be6802e43fe7aa763fa4
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 18:25:45 2010 +1000

    s4-rpcserver: log unknown RPC calls at debug level 3
    
    This was added as we are occasionally getting an encrypted unknown
    netlogon call, and I'm having trouble looking at it in wireshark

commit 2688375ffeba81ad635ca6bce175b1c849178482
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 18:24:29 2010 +1000

    s4-netlogon: added SEC_CHAN_RODC
    
    This seems to be equivalent to SEC_CHAN_BDC, but for RODCs

commit 82c171aa558c6b9ea0455915c9a2a2286498b8ea
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 15:20:11 2010 +1000

    s4-net: use an encrypted ldap session when setting passwords
    
    this allows for "net setpassword -H ldap://server -Uusername%password USERNAME"
    to set a password remotely on a windows DC
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 896f10301cc3db10793cac115bcbca0f58f0f010
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 14:55:23 2010 +1000

    s4-dsdb: check the type of session_info from the opaque
    
    we saw a crash with a bad pointer here, and this may help track it
    down
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 21729b63f0a43798751517369a032ba8672aeb20
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 14:21:07 2010 +1000

    s4-drs: allow getncchanges from RODC with WRIT_REP set
    
    w2k8r2 is setting this bit as a RODC. Instead of refusing the
    replication, we now remove the bit from req8, which means other places
    in the code that check this bit can stay the same
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 45a2b408ba16ebabedc519a7235b05c104dede6b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 14:12:21 2010 +1000

    s4-drs: added domain_sid to DRS security checks
    
    we need the domain_sid to determine if the account is a RODC for our
    domain
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 84bedf4028a5c841f08c079bfd20b9111fe52777
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 14:11:24 2010 +1000

    s4-drs: fixed check for SECURITY_RO_DOMAIN_CONTROLLER
    
    check more than the user_sid, and also check for the right rid value
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 4e9daa0f032547787a1a1957a6f4f4002aa50371
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 14:10:34 2010 +1000

    s4-dsdb: added support for UF_PARTIAL_SECRETS_ACCOUNT
    
    when this is in user_account_control the account is a RODC, and we
    need to set the primaryGroupID to be DOMAIN_RID_READONLY_DCS
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit df14f645b3c56ca7652463d53731437158d5c4bb
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 13:19:53 2010 +1000

    s4-dsdb: cope with cracknames of form dnsdomain\account
    
    this is used by w2k8r2 when doing a RODC dcpromo
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit f6e0b151a32a2fa450ded3af2fd87d9767cd4540
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 12:06:24 2010 +1000

    s4-dsdb: set LDB_FLAG_INTERNAL_DISABLE_VALIDATION for msDS-SecondaryKrbTgtNumber
    
    msDS-SecondaryKrbTgtNumber is setup with a value that is outside the
    range allowed by the schema (the schema has
    rangeLower==rangeUpper==65536). We need to mark this element as being
    internally generated to avoid the range checks
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 0caf347098913e9d224d1db4b48887e2b78bae03
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 12:04:45 2010 +1000

    s4-ldb: added LDB_FLAG_INTERNAL_DISABLE_VALIDATION
    
    When this flag is set on an element in an add/modify request then the
    normal validate_ldb() call that checks the element against schema
    constraints is disabled
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 9e27201b24106babc7ac2400f7f063f438b0ddcd
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 12:03:47 2010 +1000

    s4-ldb: added LDB_FLAG_INTERNAL_MASK
    
    This ensures that internal bits for the element flags in add/modify
    requests are not set via the ldb API
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 6baa834ebe710d73cfd54e465479a2b2de9d2476
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 11:21:11 2010 +1000

    s4-ldb: use LDB_FLAG_MOD_TYPE() to extract element type from messages
    
    The flags field of message elements is part of a set of flags. We had
    LDB_FLAG_MOD_MASK for extracting the type, but it was only rarely
    being used (only 1 call used it correctly). This adds
    LDB_FLAG_MOD_MASK() to make it more obvious what is going on.
    
    This will allow us to use some of the other flags bits for internal
    markers on elements
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 527042f78bc1672ca9a2f766b232165fb2a81d9f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 11:13:59 2010 +1000

    s4-dsdb: support LDB_CONTROL_RODC_DCPROMO_OID for nTDSDSA add
    
    this control disables the system only check for nTDSDSA add operations
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 974279b67de6aa346f961b4546bfa556b4ab7ece
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 11:12:54 2010 +1000

    s4-dsdb: fixed test for LDB_CONTROL_RODC_DCPROMO_OID
    
    the ldb_msg_add_fmt() call returns LDB_SUCCESS on success

commit eed3838b4806cebd986b07bea21b88974b394d2f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 11:12:09 2010 +1000

    s4-ldapserver: support controls on ldap add and rename
    
    we need to pass the controls down to the add and rename ldb operations
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 191d632e237761004fe0fe79a29a7274b7267d45
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 09:59:18 2010 +1000

    s4-dsdb: added support for LDB_CONTROL_RODC_DCPROMO_OID
    
    this control adds a unique msDS-SecondaryKrbTgtNumber attribute to a
    user object.
    
    There is some 'interesting' interaction with the rangeLower and
    rangeUpper attributes and this add. We don't implementat
    rangeLower/rangeUpper yet, but when we do we'll need an override for
    this control (or be careful about module ordering).
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit dcd9fcc7b395cc2babfa89aa26163e43186ad669
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 17 09:17:17 2010 +1000

    s4-ldap: use common functions for ldap flag controls encode/decode
    
    many controls are simple present/not-present flags, and don't need
    their own parsers
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 libds/common/flags.h                               |    1 +
 librpc/idl/misc.idl                                |    3 +-
 source4/dsdb/common/util.c                         |    6 +-
 source4/dsdb/samdb/cracknames.c                    |   10 +-
 source4/dsdb/samdb/ldb_modules/acl.c               |    6 +-
 source4/dsdb/samdb/ldb_modules/extended_dn_store.c |    2 +-
 source4/dsdb/samdb/ldb_modules/objectclass.c       |   25 +++-
 source4/dsdb/samdb/ldb_modules/objectclass_attrs.c |   16 +-
 source4/dsdb/samdb/ldb_modules/password_hash.c     |   10 +-
 source4/dsdb/samdb/ldb_modules/samldb.c            |   99 ++++++++++-
 source4/dsdb/samdb/ldb_modules/util.c              |    4 +-
 source4/ldap_server/ldap_backend.c                 |   22 ++-
 source4/lib/ldb-samba/ldb_wrap.c                   |   15 ++
 source4/lib/ldb/common/ldb.c                       |   26 +++
 source4/lib/ldb/include/ldb.h                      |   16 ++
 source4/lib/ldb/include/ldb_module.h               |    6 +
 source4/lib/ldb/ldb_tdb/ldb_search.c               |    2 +
 source4/lib/registry/ldb.c                         |    2 +-
 source4/libcli/ldap/ldap_controls.c                |  175 ++------------------
 source4/libcli/security/security_token.c           |   12 +-
 source4/rpc_server/dcerpc_server.c                 |    6 +
 source4/rpc_server/drsuapi/addentry.c              |    2 +-
 source4/rpc_server/drsuapi/dcesrv_drsuapi.c        |    8 +-
 source4/rpc_server/drsuapi/dcesrv_drsuapi.h        |    3 +-
 source4/rpc_server/drsuapi/drsutil.c               |    5 +-
 source4/rpc_server/drsuapi/getncchanges.c          |    7 +-
 source4/rpc_server/drsuapi/updaterefs.c            |    3 +-
 source4/rpc_server/lsa/dcesrv_lsa.c                |    8 +-
 source4/rpc_server/netlogon/dcerpc_netlogon.c      |    5 +
 .../scripting/python/samba/netcmd/setpassword.py   |    3 +
 30 files changed, 279 insertions(+), 229 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libds/common/flags.h b/libds/common/flags.h
index 021db2a..eeb6940 100644
--- a/libds/common/flags.h
+++ b/libds/common/flags.h
@@ -51,6 +51,7 @@
 
 #define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000
 #define UF_NO_AUTH_DATA_REQUIRED		0x02000000
+#define UF_PARTIAL_SECRETS_ACCOUNT		0x04000000
 
 #define UF_MACHINE_ACCOUNT_MASK (\
 		UF_INTERDOMAIN_TRUST_ACCOUNT |\
diff --git a/librpc/idl/misc.idl b/librpc/idl/misc.idl
index a60d30b..e928460 100644
--- a/librpc/idl/misc.idl
+++ b/librpc/idl/misc.idl
@@ -40,7 +40,8 @@ interface misc
 		SEC_CHAN_WKSTA       = 2,
 		SEC_CHAN_DNS_DOMAIN  = 3,
 		SEC_CHAN_DOMAIN      = 4,
-		SEC_CHAN_BDC         = 6
+		SEC_CHAN_BDC         = 6,
+		SEC_CHAN_RODC        = 7
 	} netr_SchannelType;
 
 	typedef [public] struct {
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 701040f..7fcc3bf 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -766,7 +766,7 @@ int samdb_msg_find_old_and_new_ldb_val(const struct ldb_message *msg,
 
 	for (i = 0; i < msg->num_elements; i++) {
 		if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
-			if (msg->elements[i].flags == LDB_FLAG_MOD_DELETE) {
+			if (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE) {
 				*old_val = &msg->elements[i].values[0];
 			} else {
 				*new_val = &msg->elements[i].values[0];
@@ -874,7 +874,7 @@ int samdb_msg_add_addval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
 	for (i = 0; i < msg->num_elements; i++) {
 		el = &msg->elements[i];
 		if ((ldb_attr_cmp(el->name, attr_name) == 0) &&
-		    (el->flags == LDB_FLAG_MOD_ADD)) {
+		    (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_ADD)) {
 			found = true;
 			break;
 		}
@@ -930,7 +930,7 @@ int samdb_msg_add_delval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
 	for (i = 0; i < msg->num_elements; i++) {
 		el = &msg->elements[i];
 		if ((ldb_attr_cmp(el->name, attr_name) == 0) &&
-		    (el->flags == LDB_FLAG_MOD_DELETE)) {
+		    (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE)) {
 			found = true;
 			break;
 		}
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index 99d25c4..63fe345 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -453,6 +453,7 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 	case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: {
 		char *p;
 		char *domain;
+		struct ldb_dn *dn_domain;
 		const char *account = NULL;
 
 		domain = talloc_strdup(mem_ctx, name);
@@ -470,9 +471,14 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
 			account = &p[1];
 		}
 
+		/* it could be in DNS domain form */
+		dn_domain = samdb_dns_domain_to_dn(sam_ctx, mem_ctx, domain);
+		W_ERROR_HAVE_NO_MEMORY(dn_domain);
+
 		domain_filter = talloc_asprintf(mem_ctx, 
-						"(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", 
-						ldb_binary_encode_string(mem_ctx, domain));
+						"(&(&(|(nETBIOSName=%s)(nCName=%s))(objectclass=crossRef))(ncName=*))",
+						ldb_binary_encode_string(mem_ctx, domain),
+						ldb_dn_get_linearized(dn_domain));
 		W_ERROR_HAVE_NO_MEMORY(domain_filter);
 		if (account) {
 			result_filter = talloc_asprintf(mem_ctx, "(sAMAccountName=%s)",
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index 11fffa4..4eb27e9 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -761,13 +761,13 @@ static int acl_check_password_rights(TALLOC_CTX *mem_ctx,
 	}
 	for (l = passwordAttrs; *l != NULL; l++) {
 		while ((el = ldb_msg_find_element(msg, *l)) != NULL) {
-			if (el->flags == LDB_FLAG_MOD_DELETE) {
+			if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
 				++del_attr_cnt;
 			}
-			if (el->flags == LDB_FLAG_MOD_ADD) {
+			if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_ADD) {
 				++add_attr_cnt;
 			}
-			if (el->flags == LDB_FLAG_MOD_REPLACE) {
+			if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE) {
 				++rep_attr_cnt;
 			}
 			ldb_msg_remove_element(msg, el);
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
index 07d106e..3f5f451 100644
--- a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
@@ -425,7 +425,7 @@ static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req
 			 * element, only do a lookup if
 			 * extended_store_replace determines it's an
 			 * input of an extended DN */
-			bool is_delete = ((el->flags & LDB_FLAG_MOD_MASK) == LDB_FLAG_MOD_DELETE);
+			bool is_delete = (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE);
 
 			ret = extended_store_replace(ac, req->op.mod.message->elements, &el->values[j],
 						     is_delete, schema_attr->syntax->ldap_oid);
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 548d51e..cd45963 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -432,6 +432,27 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
 	return ldb_next_request(ac->module, search_req);
 }
 
+
+/*
+  check if this is a special RODC nTDSDSA add
+ */
+static bool check_rodc_ntdsdsa_add(struct oc_context *ac,
+				   const struct dsdb_class *objectclass)
+{
+	struct ldb_control *rodc_control;
+
+	if (strcasecmp(objectclass->lDAPDisplayName, "nTDSDSA") != 0) {
+		return false;
+	}
+	rodc_control = ldb_request_get_control(ac->req, LDB_CONTROL_RODC_DCPROMO_OID);
+	if (!rodc_control) {
+		return false;
+	}
+
+	rodc_control->critical = false;
+	return true;
+}
+
 static int objectclass_do_add(struct oc_context *ac)
 {
 	struct ldb_context *ldb;
@@ -566,7 +587,9 @@ static int objectclass_do_add(struct oc_context *ac)
 			return LDB_ERR_NAMING_VIOLATION;
 		}
 
-		if (objectclass->systemOnly && !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID)) {
+		if (objectclass->systemOnly &&
+		    !ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) &&
+		    !check_rodc_ntdsdsa_add(ac, objectclass)) {
 			ldb_asprintf_errstring(ldb, "objectClass %s is systemOnly, rejecting creation of %s",
 						objectclass->lDAPDisplayName, ldb_dn_get_linearized(msg->dn));
 			return LDB_ERR_UNWILLING_TO_PERFORM;
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
index b9436e3..070d858 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
@@ -113,13 +113,15 @@ static int attr_handler(struct oc_context *ac)
 			return LDB_ERR_UNWILLING_TO_PERFORM;
 		}
 		
-		werr = attr->syntax->validate_ldb(ldb, ac->schema, attr,
-						  &msg->elements[i]);
-		if (!W_ERROR_IS_OK(werr)) {
-			ldb_asprintf_errstring(ldb, "objectclass_attrs: attribute '%s' on entry '%s' contains at least one invalid value!",
-					       msg->elements[i].name,
-					       ldb_dn_get_linearized(msg->dn));
-			return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+		if (!(msg->elements[i].flags & LDB_FLAG_INTERNAL_DISABLE_VALIDATION)) {
+			werr = attr->syntax->validate_ldb(ldb, ac->schema, attr,
+							  &msg->elements[i]);
+			if (!W_ERROR_IS_OK(werr)) {
+				ldb_asprintf_errstring(ldb, "objectclass_attrs: attribute '%s' on entry '%s' contains at least one invalid value!",
+						       msg->elements[i].name,
+						       ldb_dn_get_linearized(msg->dn));
+				return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+			}
 		}
 
 		if ((attr->systemFlags & DS_FLAG_ATTR_IS_CONSTRUCTED) != 0) {
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 60f0c3e..a3c06b6 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -2450,17 +2450,17 @@ static int password_hash_modify(struct ldb_module *module, struct ldb_request *r
 	rep_attr_cnt = 0;
 	for (l = passwordAttrs; *l != NULL; l++) {
 		while ((passwordAttr = ldb_msg_find_element(msg, *l)) != NULL) {
-			if (passwordAttr->flags == LDB_FLAG_MOD_DELETE) {
+			if (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_DELETE) {
 				++del_attr_cnt;
 			}
-			if (passwordAttr->flags == LDB_FLAG_MOD_ADD) {
+			if (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_ADD) {
 				++add_attr_cnt;
 			}
-			if (passwordAttr->flags == LDB_FLAG_MOD_REPLACE) {
+			if (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_REPLACE) {
 				++rep_attr_cnt;
 			}
 			if ((passwordAttr->num_values != 1) &&
-			    (passwordAttr->flags == LDB_FLAG_MOD_ADD)) {
+			    (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_ADD)) {
 				talloc_free(ac);
 				ldb_asprintf_errstring(ldb,
 						       "'%s' attribute must have exactly one value on add operations!",
@@ -2468,7 +2468,7 @@ static int password_hash_modify(struct ldb_module *module, struct ldb_request *r
 				return LDB_ERR_CONSTRAINT_VIOLATION;
 			}
 			if ((passwordAttr->num_values > 1) &&
-			    (passwordAttr->flags == LDB_FLAG_MOD_DELETE)) {
+			    (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_DELETE)) {
 				talloc_free(ac);
 				ldb_asprintf_errstring(ldb,
 						       "'%s' attribute must have zero or one value(s) on delete operations!",
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 9ae308b..a12b189 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -348,6 +348,72 @@ static int samldb_allocate_sid(struct samldb_ctx *ac)
 }
 
 /*
+  see if a krbtgt_number is available
+ */
+static bool samldb_krbtgtnumber_available(struct samldb_ctx *ac, unsigned krbtgt_number)
+{
+	TALLOC_CTX *tmp_ctx = talloc_new(ac);
+	struct ldb_result *res;
+	const char *attrs[] = { NULL };
+	int ret;
+
+	ret = dsdb_module_search(ac->module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
+				 attrs, DSDB_FLAG_NEXT_MODULE,
+				 "msDC-SecondaryKrbTgtNumber=%u", krbtgt_number);
+	if (ret == LDB_SUCCESS && res->count == 0) {
+		talloc_free(tmp_ctx);
+		return true;
+	}
+	talloc_free(tmp_ctx);
+	return false;
+}
+
+/* special handling for add in RODC join */
+static int samldb_rodc_add(struct samldb_ctx *ac)
+{
+	struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+	unsigned krbtgt_number, i_start, i;
+	int ret;
+
+	/* find a unused msDC-SecondaryKrbTgtNumber */
+	i_start = generate_random() & 0xFFFF;
+	if (i_start == 0) {
+		i_start = 1;
+	}
+
+	for (i=i_start; i<=0xFFFF; i++) {
+		if (samldb_krbtgtnumber_available(ac, i)) {
+			krbtgt_number = i;
+			goto found;
+		}
+	}
+	for (i=1; i<i_start; i++) {
+		if (samldb_krbtgtnumber_available(ac, i)) {
+			krbtgt_number = i;
+			goto found;
+		}
+	}
+
+	ldb_asprintf_errstring(ldb_module_get_ctx(ac->module),
+			       "%08X: Unable to find available msDS-SecondaryKrbTgtNumber",
+			       W_ERROR_V(WERR_NO_SYSTEM_RESOURCES));
+	return LDB_ERR_OTHER;
+
+found:
+	ret = ldb_msg_add_empty(ac->msg, "msDS-SecondaryKrbTgtNumber", LDB_FLAG_INTERNAL_DISABLE_VALIDATION, NULL);
+	if (ret != LDB_SUCCESS) {
+		return ldb_operr(ldb);
+	}
+
+	ret = ldb_msg_add_fmt(ac->msg, "msDS-SecondaryKrbTgtNumber", "%u", krbtgt_number);
+	if (ret != LDB_SUCCESS) {
+		return ldb_operr(ldb);
+	}
+
+	return samldb_next_step(ac);
+}
+
+/*
  * samldb_dn_from_sid (async)
  */
 
@@ -744,6 +810,7 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
 	struct loadparm_context *lp_ctx;
 	enum sid_generator sid_generator;
 	int ret;
+	struct ldb_control *rodc_control;
 
 	ldb = ldb_module_get_ctx(ac->module);
 
@@ -957,6 +1024,15 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
 		}
 	}
 
+	rodc_control = ldb_request_get_control(ac->req, LDB_CONTROL_RODC_DCPROMO_OID);
+	if (rodc_control) {
+		/* see [MS-ADTS] 3.1.1.3.4.1.23 LDAP_SERVER_RODC_DCPROMO_OID */
+		rodc_control->critical = false;
+		ret = samldb_add_step(ac, samldb_rodc_add);
+		if (ret != LDB_SUCCESS) return ret;
+	}
+
+
 	/* finally proceed with adding the entry */
 	ret = samldb_add_step(ac, samldb_add_entry);
 	if (ret != LDB_SUCCESS) return ret;
@@ -1352,7 +1428,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 	/* TODO: do not modify original request, create a new one */
 
 	el = ldb_msg_find_element(req->op.mod.message, "groupType");
-	if (el && (el->flags == LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
+	if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
 		uint32_t group_type;
 
 		req->op.mod.message = msg = ldb_msg_copy_shallow(req,
@@ -1369,12 +1445,12 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 		el2 = ldb_msg_find_element(msg, "sAMAccountType");
 		el2->flags = LDB_FLAG_MOD_REPLACE;
 	}
-	if (el && (el->flags == LDB_FLAG_MOD_DELETE)) {
+	if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE)) {
 		return LDB_ERR_UNWILLING_TO_PERFORM;
 	}
 
 	el = ldb_msg_find_element(req->op.mod.message, "primaryGroupID");
-	if (el && (el->flags == LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
+	if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
 		req->op.mod.message = ac->msg = ldb_msg_copy_shallow(req,
 			req->op.mod.message);
 
@@ -1383,12 +1459,12 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 			return ret;
 		}
 	}
-	if (el && (el->flags == LDB_FLAG_MOD_DELETE)) {
+	if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE)) {
 		return LDB_ERR_UNWILLING_TO_PERFORM;
 	}
 
 	el = ldb_msg_find_element(req->op.mod.message, "userAccountControl");
-	if (el && (el->flags == LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
+	if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_REPLACE) && el->num_values == 1) {
 		uint32_t user_account_control;
 
 		req->op.mod.message = msg = ldb_msg_copy_shallow(req,
@@ -1406,7 +1482,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 		el2 = ldb_msg_find_element(msg, "sAMAccountType");
 		el2->flags = LDB_FLAG_MOD_REPLACE;
 
-		if (user_account_control & UF_SERVER_TRUST_ACCOUNT) {
+		if (user_account_control & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) {
 			ret = samdb_msg_add_string(ldb, msg, msg,
 						   "isCriticalSystemObject", "TRUE");
 			if (ret != LDB_SUCCESS) {
@@ -1417,8 +1493,15 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 
 			/* DCs have primaryGroupID of DOMAIN_RID_DCS */
 			if (!ldb_msg_find_element(msg, "primaryGroupID")) {
+				uint32_t rid;
+				if (user_account_control & UF_SERVER_TRUST_ACCOUNT) {
+					rid = DOMAIN_RID_DCS;
+				} else {
+					/* read-only DC */
+					rid = DOMAIN_RID_READONLY_DCS;
+				}
 				ret = samdb_msg_add_uint(ldb, msg, msg,
-							 "primaryGroupID", DOMAIN_RID_DCS);
+							 "primaryGroupID", rid);
 				if (ret != LDB_SUCCESS) {
 					return ret;
 				}
@@ -1427,7 +1510,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
 			}
 		}
 	}
-	if (el && (el->flags == LDB_FLAG_MOD_DELETE)) {
+	if (el && (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE)) {
 		return LDB_ERR_UNWILLING_TO_PERFORM;
 	}
 
diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c
index fda1733..23a8da2 100644
--- a/source4/dsdb/samdb/ldb_modules/util.c
+++ b/source4/dsdb/samdb/ldb_modules/util.c
@@ -906,7 +906,7 @@ bool dsdb_module_am_system(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");
+		= talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info);
 	return security_session_user_level(session_info, NULL) == SECURITY_SYSTEM;
 }
 
@@ -914,7 +914,7 @@ bool dsdb_module_am_administrator(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");
+		= talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info);
 	return security_session_user_level(session_info, NULL) == SECURITY_ADMINISTRATOR;
 }
 
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index e0f9ee1..6faaa30 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -294,9 +294,10 @@ static NTSTATUS ldapsrv_unwilling(struct ldapsrv_call *call, int error)
 	return NT_STATUS_OK;
 }
 
-static int ldb_add_with_context(struct ldb_context *ldb,
-				const struct ldb_message *message,
-				void *context)
+static int ldb_add_with_controls(struct ldb_context *ldb,
+				 const struct ldb_message *message,
+				 struct ldb_control **controls,
+				 void *context)
 {
 	struct ldb_request *req;
 	int ret;
@@ -308,7 +309,7 @@ static int ldb_add_with_context(struct ldb_context *ldb,
 
 	ret = ldb_build_add_req(&req, ldb, ldb,
 					message,
-					NULL,
+					controls,
 					context,
 					ldb_modify_default_callback,
 					NULL);
@@ -421,10 +422,11 @@ static int ldb_del_req_with_controls(struct ldb_context *ldb,
 	return ret;
 }
 
-int ldb_rename_with_context(struct ldb_context *ldb,
-	       struct ldb_dn *olddn,
-	       struct ldb_dn *newdn,
-	       void *context)
+int ldb_rename_with_controls(struct ldb_context *ldb,
+			     struct ldb_dn *olddn,
+			     struct ldb_dn *newdn,
+			     struct ldb_control **controls,
+			     void *context)
 {
 	struct ldb_request *req;
 	int ret;
@@ -851,7 +853,7 @@ reply:
 	if (result == LDAP_SUCCESS) {
 		res = talloc_zero(local_ctx, struct ldb_result);
 		NT_STATUS_HAVE_NO_MEMORY(res);
-		ldb_ret = ldb_add_with_context(samdb, msg, res);
+		ldb_ret = ldb_add_with_controls(samdb, msg, call->request->controls, res);
 		result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
 				       &errstr);
 	}
@@ -1015,7 +1017,7 @@ reply:
 	if (result == LDAP_SUCCESS) {
 		res = talloc_zero(local_ctx, struct ldb_result);
 		NT_STATUS_HAVE_NO_MEMORY(res);
-		ldb_ret = ldb_rename_with_context(samdb, olddn, newdn, res);
+		ldb_ret = ldb_rename_with_controls(samdb, olddn, newdn, call->request->controls, res);
 		result = map_ldb_error(local_ctx, ldb_ret, ldb_errstring(samdb),
 				       &errstr);
 	}
diff --git a/source4/lib/ldb-samba/ldb_wrap.c b/source4/lib/ldb-samba/ldb_wrap.c
index 365b67b..13ab3ed 100644
--- a/source4/lib/ldb-samba/ldb_wrap.c
+++ b/source4/lib/ldb-samba/ldb_wrap.c
@@ -248,6 +248,21 @@ static int ldb_wrap_destructor(struct ldb_wrap *w)
 		return NULL;
 	}
 
+	if (session_info) {
+		/* take a reference to the session_info, as it is
+		 * possible for the ldb to live longer than the
+		 * session_info. This happens when a DRS DsBind call
+		 * reuses a handle, but the original connection is
+		 * shutdown. The token for the new connection is still
+		 * valid, so we need the session_info to remain valid for
+		 * ldb modules to use
+		 */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list