summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/kdc/db-glue.c135
-rw-r--r--source4/kdc/db-glue.h3
-rw-r--r--source4/kdc/hdb-samba4.c46
-rw-r--r--source4/kdc/mit_samba.c42
-rw-r--r--source4/kdc/samba_kdc.h3
5 files changed, 156 insertions, 73 deletions
diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
index bad3253502..2cda04bca8 100644
--- a/source4/kdc/db-glue.c
+++ b/source4/kdc/db-glue.c
@@ -1565,3 +1565,138 @@ samba_kdc_check_pkinit_ms_upn_match(krb5_context context,
return ret;
}
+NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_context *base_ctx,
+ struct samba_kdc_db_context **kdc_db_ctx_out)
+{
+ NTSTATUS nt_status;
+ int ldb_ret;
+ struct ldb_message *msg;
+ struct auth_session_info *session_info;
+ struct samba_kdc_db_context *kdc_db_ctx;
+ /* The idea here is very simple. Using Kerberos to
+ * authenticate the KDC to the LDAP server is higly likely to
+ * be circular.
+ *
+ * In future we may set this up to use EXERNAL and SSL
+ * certificates, for now it will almost certainly be NTLMSSP_SET_USERNAME
+ */
+
+ kdc_db_ctx = talloc_zero(mem_ctx, struct samba_kdc_db_context);
+ if (kdc_db_ctx == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ kdc_db_ctx->ev_ctx = base_ctx->ev_ctx;
+ kdc_db_ctx->lp_ctx = base_ctx->lp_ctx;
+
+#if 1
+ /* we would prefer to use system_session(), as that would
+ * allow us to share the samdb backend context with other parts of the
+ * system. For now we can't as we need to override the
+ * credentials to set CRED_DONT_USE_KERBEROS, which would
+ * break other users of the system_session */
+ DEBUG(0,("FIXME: Using new system session for hdb\n"));
+ nt_status = auth_system_session_info(kdc_db_ctx, base_ctx->lp_ctx, &session_info);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+#else
+ session_info = system_session(kdc_db_ctx->lp_ctx);
+ if (session_info == NULL) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+#endif
+
+ cli_credentials_set_kerberos_state(session_info->credentials,
+ CRED_DONT_USE_KERBEROS);
+
+ /* Setup the link to LDB */
+ kdc_db_ctx->samdb = samdb_connect(kdc_db_ctx, base_ctx->ev_ctx,
+ base_ctx->lp_ctx, session_info);
+ if (kdc_db_ctx->samdb == NULL) {
+ DEBUG(1, ("hdb_samba4_create: Cannot open samdb for KDC backend!"));
+ talloc_free(kdc_db_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ /* Find out our own krbtgt kvno */
+ ldb_ret = samdb_rodc(kdc_db_ctx->samdb, &kdc_db_ctx->rodc);
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(1, ("hdb_samba4_create: Cannot determine if we are an RODC in KDC backend: %s\n",
+ ldb_errstring(kdc_db_ctx->samdb)));
+ talloc_free(kdc_db_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ if (kdc_db_ctx->rodc) {
+ int my_krbtgt_number;
+ const char *secondary_keytab[] = { "msDS-SecondaryKrbTgtNumber", NULL };
+ struct ldb_dn *account_dn;
+ struct ldb_dn *server_dn = samdb_server_dn(kdc_db_ctx->samdb, kdc_db_ctx);
+ if (!server_dn) {
+ DEBUG(1, ("hdb_samba4_create: Cannot determine server DN in KDC backend: %s\n",
+ ldb_errstring(kdc_db_ctx->samdb)));
+ talloc_free(kdc_db_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ ldb_ret = samdb_reference_dn(kdc_db_ctx->samdb, kdc_db_ctx, server_dn,
+ "serverReference", &account_dn);
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(1, ("hdb_samba4_create: Cannot determine server account in KDC backend: %s\n",
+ ldb_errstring(kdc_db_ctx->samdb)));
+ talloc_free(kdc_db_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ ldb_ret = samdb_reference_dn(kdc_db_ctx->samdb, kdc_db_ctx, account_dn,
+ "msDS-KrbTgtLink", &kdc_db_ctx->krbtgt_dn);
+ talloc_free(account_dn);
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(1, ("hdb_samba4_create: Cannot determine RODC krbtgt account in KDC backend: %s\n",
+ ldb_errstring(kdc_db_ctx->samdb)));
+ talloc_free(kdc_db_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ ldb_ret = dsdb_search_one(kdc_db_ctx->samdb, kdc_db_ctx,
+ &msg, kdc_db_ctx->krbtgt_dn, LDB_SCOPE_BASE,
+ secondary_keytab,
+ 0,
+ "(&(objectClass=user)(msDS-SecondaryKrbTgtNumber=*))");
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(1, ("hdb_samba4_create: Cannot read krbtgt account %s in KDC backend to get msDS-SecondaryKrbTgtNumber: %s: %s\n",
+ ldb_dn_get_linearized(kdc_db_ctx->krbtgt_dn),
+ ldb_errstring(kdc_db_ctx->samdb),
+ ldb_strerror(ldb_ret)));
+ talloc_free(kdc_db_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ my_krbtgt_number = ldb_msg_find_attr_as_int(msg, "msDS-SecondaryKrbTgtNumber", -1);
+ if (my_krbtgt_number == -1) {
+ DEBUG(1, ("hdb_samba4_create: Cannot read msDS-SecondaryKrbTgtNumber from krbtgt account %s in KDC backend: got %d\n",
+ ldb_dn_get_linearized(kdc_db_ctx->krbtgt_dn),
+ my_krbtgt_number));
+ talloc_free(kdc_db_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ kdc_db_ctx->my_krbtgt_number = my_krbtgt_number;
+
+ } else {
+ kdc_db_ctx->my_krbtgt_number = 0;
+ ldb_ret = dsdb_search_one(kdc_db_ctx->samdb, kdc_db_ctx,
+ &msg, NULL, LDB_SCOPE_SUBTREE,
+ krbtgt_attrs,
+ DSDB_SEARCH_SHOW_EXTENDED_DN,
+ "(&(objectClass=user)(samAccountName=krbtgt))");
+
+ if (ldb_ret != LDB_SUCCESS) {
+ DEBUG(1, ("samba_kdc_fetch: could not find own KRBTGT in DB: %s\n", ldb_errstring(kdc_db_ctx->samdb)));
+ talloc_free(kdc_db_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ kdc_db_ctx->krbtgt_dn = talloc_steal(kdc_db_ctx, msg->dn);
+ kdc_db_ctx->my_krbtgt_number = 0;
+ talloc_free(msg);
+ }
+ *kdc_db_ctx_out = kdc_db_ctx;
+ return NT_STATUS_OK;
+}
diff --git a/source4/kdc/db-glue.h b/source4/kdc/db-glue.h
index 33ba707822..5f9c39dfb6 100644
--- a/source4/kdc/db-glue.h
+++ b/source4/kdc/db-glue.h
@@ -46,3 +46,6 @@ samba_kdc_check_pkinit_ms_upn_match(krb5_context context,
struct samba_kdc_db_context *kdc_db_ctx,
hdb_entry_ex *entry,
krb5_const_principal certificate_principal);
+
+NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_context *base_ctx,
+ struct samba_kdc_db_context **kdc_db_ctx_out);
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index 6534dbd27a..cbc00df0ae 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -162,7 +162,6 @@ NTSTATUS hdb_samba4_create_kdc(struct samba_kdc_base_context *base_ctx,
krb5_context context, struct HDB **db)
{
struct samba_kdc_db_context *kdc_db_ctx;
- struct auth_session_info *session_info;
NTSTATUS nt_status;
*db = talloc(base_ctx, HDB);
@@ -175,50 +174,11 @@ NTSTATUS hdb_samba4_create_kdc(struct samba_kdc_base_context *base_ctx,
(*db)->hdb_db = NULL;
(*db)->hdb_capability_flags = 0;
-#if 1
- /* we would prefer to use system_session(), as that would
- * allow us to share the samdb backend context with other parts of the
- * system. For now we can't as we need to override the
- * credentials to set CRED_DONT_USE_KERBEROS, which would
- * break other users of the system_session */
- DEBUG(0,("FIXME: Using new system session for hdb\n"));
- nt_status = auth_system_session_info(*db, base_ctx->lp_ctx, &session_info);
+ nt_status = samba_kdc_setup_db_ctx(*db, base_ctx, &kdc_db_ctx);
if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
+ talloc_free(*db);
+ return nt_status;
}
-#else
- session_info = system_session(kdc_db_ctx->lp_ctx);
- if (session_info == NULL) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-#endif
-
- /* The idea here is very simple. Using Kerberos to
- * authenticate the KDC to the LDAP server is higly likely to
- * be circular.
- *
- * In future we may set this up to use EXERNAL and SSL
- * certificates, for now it will almost certainly be NTLMSSP_SET_USERNAME
- */
-
- cli_credentials_set_kerberos_state(session_info->credentials,
- CRED_DONT_USE_KERBEROS);
-
- kdc_db_ctx = talloc_zero(*db, struct samba_kdc_db_context);
- if (kdc_db_ctx == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
- kdc_db_ctx->ev_ctx = base_ctx->ev_ctx;
- kdc_db_ctx->lp_ctx = base_ctx->lp_ctx;
-
- /* Setup the link to LDB */
- kdc_db_ctx->samdb = samdb_connect(kdc_db_ctx, base_ctx->ev_ctx,
- base_ctx->lp_ctx, session_info);
- if (kdc_db_ctx->samdb == NULL) {
- DEBUG(1, ("hdb_samba4_create: Cannot open samdb for KDC backend!"));
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
(*db)->hdb_db = kdc_db_ctx;
(*db)->hdb_dbc = NULL;
diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
index 58ab1673ff..217f0983ae 100644
--- a/source4/kdc/mit_samba.c
+++ b/source4/kdc/mit_samba.c
@@ -53,10 +53,11 @@ static void mit_samba_context_free(struct mit_samba_context *ctx)
static int mit_samba_context_init(struct mit_samba_context **_ctx)
{
+ NTSTATUS status;
struct mit_samba_context *ctx;
const char *s4_conf_file;
int ret;
-
+ struct samba_kdc_base_context base_ctx;
ctx = talloc(NULL, struct mit_samba_context);
if (!ctx) {
@@ -64,46 +65,27 @@ static int mit_samba_context_init(struct mit_samba_context **_ctx)
goto done;
}
- ctx->db_ctx = talloc_zero(ctx, struct samba_kdc_db_context);
- if (!ctx->db_ctx) {
- ret = ENOMEM;
- goto done;
- }
-
- ctx->db_ctx->ev_ctx = tevent_context_init(ctx);
- if (!ctx->db_ctx->ev_ctx) {
+ base_ctx.ev_ctx = tevent_context_init(ctx);
+ if (!base_ctx.ev_ctx) {
ret = ENOMEM;
goto done;
}
- ctx->db_ctx->lp_ctx = loadparm_init(ctx);
- if (!ctx->db_ctx->lp_ctx) {
+ base_ctx.lp_ctx = loadparm_init(ctx);
+ if (!base_ctx.lp_ctx) {
ret = ENOMEM;
goto done;
}
-
/* init s4 configuration */
- s4_conf_file = lpcfg_configfile(ctx->db_ctx->lp_ctx);
+ s4_conf_file = lpcfg_configfile(base_ctx.lp_ctx);
if (s4_conf_file) {
- lpcfg_load(ctx->db_ctx->lp_ctx, s4_conf_file);
+ lpcfg_load(base_ctx.lp_ctx, s4_conf_file);
} else {
- lpcfg_load_default(ctx->db_ctx->lp_ctx);
+ lpcfg_load_default(base_ctx.lp_ctx);
}
- ctx->session_info = system_session(ctx->db_ctx->lp_ctx);
- if (!ctx->session_info) {
- ret = EFAULT;
- goto done;
- }
-
- cli_credentials_set_kerberos_state(ctx->session_info->credentials,
- CRED_DONT_USE_KERBEROS);
-
- ctx->db_ctx->samdb = samdb_connect(ctx->db_ctx,
- ctx->db_ctx->ev_ctx,
- ctx->db_ctx->lp_ctx,
- ctx->session_info);
- if (!ctx->db_ctx->samdb) {
- ret = EFAULT;
+ status = samba_kdc_setup_db_ctx(ctx, &base_ctx, &ctx->db_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = EINVAL;
goto done;
}
diff --git a/source4/kdc/samba_kdc.h b/source4/kdc/samba_kdc.h
index bfa868f422..72b5cc42e4 100644
--- a/source4/kdc/samba_kdc.h
+++ b/source4/kdc/samba_kdc.h
@@ -33,6 +33,9 @@ struct samba_kdc_db_context {
struct loadparm_context *lp_ctx;
struct ldb_context *samdb;
struct samba_kdc_seq *seq_ctx;
+ bool rodc;
+ unsigned int my_krbtgt_number;
+ struct ldb_dn *krbtgt_dn;
};
struct samba_kdc_entry {