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 <tri...@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 <tri...@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 <tri...@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 <tri...@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 <tri...@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 <abart...@samba.org> commit 896f10301cc3db10793cac115bcbca0f58f0f010 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 21729b63f0a43798751517369a032ba8672aeb20 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 45a2b408ba16ebabedc519a7235b05c104dede6b Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 84bedf4028a5c841f08c079bfd20b9111fe52777 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 4e9daa0f032547787a1a1957a6f4f4002aa50371 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit df14f645b3c56ca7652463d53731437158d5c4bb Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit f6e0b151a32a2fa450ded3af2fd87d9767cd4540 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 0caf347098913e9d224d1db4b48887e2b78bae03 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 9e27201b24106babc7ac2400f7f063f438b0ddcd Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 6baa834ebe710d73cfd54e465479a2b2de9d2476 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 527042f78bc1672ca9a2f766b232165fb2a81d9f Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit 974279b67de6aa346f961b4546bfa556b4ab7ece Author: Andrew Tridgell <tri...@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 <tri...@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 <abart...@samba.org> commit 191d632e237761004fe0fe79a29a7274b7267d45 Author: Andrew Tridgell <tri...@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 <abart...@samba.org> commit dcd9fcc7b395cc2babfa89aa26163e43186ad669 Author: Andrew Tridgell <tri...@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 <abart...@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