summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c69
-rw-r--r--source4/lib/ldb/include/ldb.h6
-rw-r--r--source4/libcli/ldap/ldap_controls.c1
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 }
};