diff options
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 69 | ||||
-rw-r--r-- | source4/lib/ldb/include/ldb.h | 6 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap_controls.c | 1 |
3 files changed, 76 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 9ae308b9bc..8bb5f3d30d 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -348,6 +348,65 @@ 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; + + /* 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: + if ( ! ldb_msg_add_fmt(ac->msg, "msDS-SecondaryKrbTgtNumber", "%u", krbtgt_number)) { + return ldb_operr(ldb); + } + + return samldb_next_step(ac); +} + +/* * samldb_dn_from_sid (async) */ @@ -744,6 +803,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 +1017,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; diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 53ae0e4c18..f3ec1ed606 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -679,6 +679,12 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); */ #define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12" +/** + control for RODC join + See [MS-ADTS] section 3.1.1.3.4.1.23 +*/ +#define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341" + /* OID for LDAP Extended Operation PASSWORD_CHANGE. diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 0250c04012..5244975dfc 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -1170,6 +1170,7 @@ static const struct ldap_control_handler ldap_known_controls[] = { { "1.3.6.1.4.1.7165.4.4.1", NULL, NULL }, { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference}, { LDB_CONTROL_RELAX_OID, decode_flag_request, encode_flag_request }, + { LDB_CONTROL_RODC_DCPROMO_OID, decode_flag_request, encode_flag_request }, { NULL, NULL, NULL } }; |