s4:kdc Push context to hdb_samba4 by way of the 'name' of the DB
authorAndrew Bartlett <abartlet@samba.org>
Mon, 27 Jul 2009 06:09:25 +0000 (16:09 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 27 Jul 2009 12:41:42 +0000 (22:41 +1000)
This overloads the 'name' part of the keytab name to supply a context
pointer, and so avoids 3 global variables!

To do this, we had to stop putting the entry for kpasswd into the
secrets.ldb.  (I don't consider this a big loss, and any entry left
there by an upgrade will be harmless).

Andrew Bartlett

source4/kdc/hdb-samba4.c
source4/kdc/hdb-samba4.h
source4/kdc/kdc.c
source4/kdc/kdc.h
source4/kdc/kpasswdd.c
source4/setup/secrets_dc.ldif

index f5e2f59b56f5dc6de2c382c5bb106df35d3f4d06..1a0e93f7cef333fae593153a7b5b92ba78643ae2 100644 (file)
@@ -1563,8 +1563,14 @@ NTSTATUS hdb_samba4_create_kdc(TALLOC_CTX *mem_ctx,
 static krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db, const char *arg)
 {
        NTSTATUS nt_status;
+       void *ptr;
+       struct hdb_samba4_context *hdb_samba4_context;
+       if (sscanf(arg, "&%p", &ptr) != 1) {
+               return EINVAL;
+       }
+       hdb_samba4_context = talloc_get_type_abort(ptr, struct hdb_samba4_context);
        /* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */
-       nt_status = hdb_samba4_create_kdc(hdb_samba4_mem_ctx, hdb_samba4_ev_ctx, hdb_samba4_lp_ctx,
+       nt_status = hdb_samba4_create_kdc(hdb_samba4_context, hdb_samba4_context->ev_ctx, hdb_samba4_context->lp_ctx,
                                          context, db);
 
        if (NT_STATUS_IS_OK(nt_status)) {
@@ -1574,9 +1580,12 @@ static krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db,
 }
 
 /* Only used in the hdb-backed keytab code
- * for a keytab of 'samba4:', to find
+ * for a keytab of 'samba4&<address>', to find
  * kpasswd's key in the main DB, and to
- * copy all the keys into a file (libnet_keytab_export) */
+ * copy all the keys into a file (libnet_keytab_export)
+ *
+ * The <address> is the string form of a pointer to a talloced struct hdb_samba_context
+ */
 struct hdb_method hdb_samba4 = {
        .interface_version = HDB_INTERFACE_VERSION,
        .prefix = "samba4", 
index 3a377ddf0b01318d03524f110e3945c8b194d9fb..0b39fdfb10d93183802c1f4eb0fec08da414d994 100644 (file)
 */
 
 extern TALLOC_CTX *hdb_samba4_mem_ctx;
-extern struct tevent_context *hdb_samba4_ev_ctx;
-extern struct loadparm_context *hdb_samba4_lp_ctx;
+
+struct hdb_samba4_context {
+       struct tevent_context *ev_ctx;
+       struct loadparm_context *lp_ctx;
+};
+
 extern struct hdb_method hdb_samba4;
 
 struct hdb_samba4_private {
index 28d8da9d9f28c3ae8ac8f87006ae963b81d32522..746781f02d3ff0ccb4d334a4847ce7b233dd70a0 100644 (file)
@@ -729,15 +729,20 @@ static void kdc_task_init(struct task_server *task)
                                       kdc->smb_krb5_context->krb5_context, 
                                       &kdc->config->db[0]);
        if (!NT_STATUS_IS_OK(status)) {
-               task_server_terminate(task, "kdc: hdb_ldb_create (setup KDC database) failed");
+               task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed");
                return; 
        }
 
-       /* Register hdb-samba4 hooks */
+       /* Register hdb-samba4 hooks for use as a keytab */
 
-       hdb_samba4_mem_ctx = kdc->smb_krb5_context;
-       hdb_samba4_ev_ctx = task->event_ctx;
-       hdb_samba4_lp_ctx = task->lp_ctx;
+       kdc->hdb_samba4_context = talloc(kdc, struct hdb_samba4_context);
+       if (!kdc->hdb_samba4_context) {
+               task_server_terminate(task, "kdc: out of memory");
+               return; 
+       }
+
+       kdc->hdb_samba4_context->ev_ctx = task->event_ctx;
+       kdc->hdb_samba4_context->lp_ctx = task->lp_ctx;
 
        ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, 
                                   PLUGIN_TYPE_DATA, "hdb",
index a2bf412f2a35df38fdf350263b602dda2427fa95..e8511d95eb0eaf35e45d7da5bb1cb4ba0ecc206c 100644 (file)
@@ -47,6 +47,7 @@ struct kdc_server {
        struct task_server *task;
        krb5_kdc_configuration *config;
        struct smb_krb5_context *smb_krb5_context;
+       struct hdb_samba4_context *hdb_samba4_context;
 };
 
 
index 8f2cb6812989c4644d347b91feaa91d910524dac..3a39348578594461820adba0cb5d2ced1ee1321c 100644 (file)
@@ -447,7 +447,9 @@ bool kpasswdd_process(struct kdc_server *kdc,
        struct cli_credentials *server_credentials;
        struct gensec_security *gensec_security;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-       
+
+       char *keytab_name;
+
        if (!tmp_ctx) {
                return false;
        }
@@ -489,8 +491,12 @@ bool kpasswdd_process(struct kdc_server *kdc,
         * we already have, rather than a new context */        
        cli_credentials_set_krb5_context(server_credentials, kdc->smb_krb5_context);
        cli_credentials_set_conf(server_credentials, kdc->task->lp_ctx);
-       nt_status = cli_credentials_set_stored_principal(server_credentials, kdc->task->event_ctx, kdc->task->lp_ctx, "kadmin/changepw");
-       if (!NT_STATUS_IS_OK(nt_status)) {
+
+       keytab_name = talloc_asprintf(server_credentials, "HDB:samba4&%p", kdc->hdb_samba4_context);
+
+       cli_credentials_set_username(server_credentials, "kadmin/changepw", CRED_SPECIFIED);
+       ret = cli_credentials_set_keytab_name(server_credentials, kdc->task->event_ctx, kdc->task->lp_ctx, keytab_name, CRED_SPECIFIED);
+       if (ret != 0) {
                ret = kpasswdd_make_unauth_error_reply(kdc, mem_ctx, 
                                                       KRB5_KPASSWD_HARDERROR,
                                                       talloc_asprintf(mem_ctx, 
index 8ae5578e6b4f6820762d4435e3148ebb9e4b6263..b8251eece51ef8d0ed8ffa9f0d8a183b95456234 100644 (file)
@@ -11,22 +11,7 @@ msDS-KeyVersionNumber: 1
 objectSid: ${DOMAINSID}
 privateKeytab: ${SECRETS_KEYTAB}
 
-# A hook from our credentials system into HDB, as we must be on a KDC,
-# we can look directly into the database.
-dn: samAccountName=krbtgt,flatname=${DOMAIN},CN=Principals
-objectClass: top
-objectClass: secret
-objectClass: kerberosSecret
-flatname: ${DOMAIN}
-realm: ${REALM}
-sAMAccountName: krbtgt
-objectSid: ${DOMAINSID}
-servicePrincipalName: kadmin/changepw
-krb5Keytab: HDB:samba4:${SAM_LDB}:
-#The trailing : here is a HACK, but it matches the Heimdal format. 
-
-# A hook from our credentials system into HDB, as we must be on a KDC,
-# we can look directly into the database.
+#Update a keytab for the external DNS server to use 
 dn: servicePrincipalName=DNS/${DNSDOMAIN},CN=Principals
 objectClass: top
 objectClass: secret