diff options
-rw-r--r-- | source4/kdc/db-glue.c | 135 | ||||
-rw-r--r-- | source4/kdc/db-glue.h | 3 | ||||
-rw-r--r-- | source4/kdc/hdb-samba4.c | 46 | ||||
-rw-r--r-- | source4/kdc/mit_samba.c | 42 | ||||
-rw-r--r-- | source4/kdc/samba_kdc.h | 3 |
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 { |