diff options
author | Andrew Bartlett <abartlet@samba.org> | 2010-09-28 13:05:37 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2010-09-29 04:23:07 +1000 |
commit | 3021af2777ffd28f595835630510e367e7286c1c (patch) | |
tree | ed8c1c75492c6dd79c2d7a2639d944193db15951 /source4/kdc | |
parent | 88abf441d021e753f149a534a232090634652367 (diff) | |
download | samba-3021af2777ffd28f595835630510e367e7286c1c.tar.gz samba-3021af2777ffd28f595835630510e367e7286c1c.tar.bz2 samba-3021af2777ffd28f595835630510e367e7286c1c.zip |
s4-kdc Add common setup, handle RODC setup case
This means we just set up the system_session etc in one place
and don't diverge between the MIT and Heimdal plugins.
We also now determine if we are an RODC and store some details
that we will need later.
Andrew Bartlett
Diffstat (limited to 'source4/kdc')
-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 { |