s4-kdc: Introduce a simple sdb_hdb shim layer
authorGünther Deschner <gd@samba.org>
Thu, 8 May 2014 15:09:08 +0000 (17:09 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 30 Jul 2015 08:24:26 +0000 (10:24 +0200)
Guenther

Pair-Programmed-With: Andreas Schneider <asn@samba.org>
Signed-off-by: Guenther Deschner <gd@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
source4/kdc/sdb_to_hdb.c [new file with mode: 0644]
source4/kdc/wscript_build

diff --git a/source4/kdc/sdb_to_hdb.c b/source4/kdc/sdb_to_hdb.c
new file mode 100644 (file)
index 0000000..e11d616
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Database Glue between Samba and the KDC
+
+   Copyright (C) Guenther Deschner <gd@samba.org> 2014
+   Copyright (C) Andreas Schneider <asn@samba.org> 2014
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include <hdb.h>
+#include "sdb.h"
+#include "sdb_hdb.h"
+#include "lib/krb5_wrap/krb5_samba.h"
+#include "kdc/samba_kdc.h"
+
+static void sdb_flags_to_hdb_flags(const struct SDBFlags *s,
+                                  HDBFlags *h)
+{
+       /* as long as we are a 100% copy... */
+       memcpy(h, s, sizeof(*s));
+}
+
+static int sdb_salt_to_Salt(const struct sdb_salt *s, Salt *h)
+{
+       int ret;
+
+       h->type = s->type;
+       ret = krb5_copy_data_contents(&h->salt, s->salt.data, s->salt.length);
+       if (ret != 0) {
+               free_Salt(h);
+               return ENOMEM;
+       }
+       h->opaque = NULL;
+
+       return 0;
+}
+
+static int sdb_key_to_Key(const struct sdb_key *s, Key *h)
+{
+       int rc;
+
+       if (s->mkvno != NULL) {
+               h->mkvno = malloc(sizeof(unsigned int));
+               if (h->mkvno == NULL) {
+                       goto error_nomem;
+               }
+               *h->mkvno = *s->mkvno;
+       } else {
+               h->mkvno = NULL;
+       }
+
+       h->key.keytype = s->key.keytype;
+       rc = krb5_copy_data_contents(&h->key.keyvalue,
+                                     s->key.keyvalue.data,
+                                     s->key.keyvalue.length);
+       if (rc != 0) {
+               goto error_nomem;
+       }
+
+       if (s->salt != NULL) {
+               h->salt = malloc(sizeof(Salt));
+               if (h->salt == NULL) {
+                       goto error_nomem;
+               }
+
+               rc = sdb_salt_to_Salt(s->salt,
+                                     h->salt);
+               if (rc != 0) {
+                       goto error_nomem;
+               }
+       } else {
+               h->salt = NULL;
+       }
+
+       return 0;
+
+error_nomem:
+       free_Key(h);
+       return ENOMEM;
+}
+
+static int sdb_keys_to_Keys(const struct sdb_keys *s, Keys *h)
+{
+       int ret, i;
+
+       h->len = s->len;
+       if (s->val != NULL) {
+               h->val = malloc(h->len * sizeof(Key));
+               if (h->val == NULL) {
+                       return ENOMEM;
+               }
+               for (i = 0; i < h->len; i++) {
+                       ret = sdb_key_to_Key(&s->val[i],
+                                            &h->val[i]);
+                       if (ret != 0) {
+                               free_Keys(h);
+                               return ENOMEM;
+                       }
+               }
+       } else {
+               h->val = NULL;
+       }
+
+       return 0;
+}
+
+static int sdb_event_to_Event(krb5_context context,
+                             const struct sdb_event *s, Event *h)
+{
+       int ret;
+
+       if (s->principal != NULL) {
+               ret = krb5_copy_principal(context,
+                                         s->principal,
+                                         &h->principal);
+               if (ret != 0) {
+                       free_Event(h);
+                       return ret;
+               }
+       } else {
+               h->principal = NULL;
+       }
+       h->time = s->time;
+
+       return 0;
+}
+
+
+static int sdb_entry_to_hdb_entry(krb5_context context,
+                                 const struct sdb_entry *s,
+                                 struct hdb_entry *h)
+{
+       unsigned int i;
+       int rc;
+
+       ZERO_STRUCTP(h);
+
+       rc = krb5_copy_principal(context,
+                                s->principal,
+                                &h->principal);
+       if (rc != 0) {
+               return rc;
+       }
+
+       h->kvno = s->kvno;
+
+       rc = sdb_keys_to_Keys(&s->keys, &h->keys);
+       if (rc != 0) {
+               goto error;
+       }
+
+       rc = sdb_event_to_Event(context,
+                                &s->created_by,
+                                &h->created_by);
+       if (rc != 0) {
+               goto error;
+       }
+
+       if (s->modified_by) {
+               h->modified_by = malloc(sizeof(Event));
+               if (h->modified_by == NULL) {
+                       rc = ENOMEM;
+                       goto error;
+               }
+
+               rc = sdb_event_to_Event(context,
+                                        s->modified_by,
+                                        h->modified_by);
+               if (rc != 0) {
+                       goto error;
+               }
+       } else {
+               h->modified_by = NULL;
+       }
+
+       if (s->valid_start != NULL) {
+               h->valid_start = malloc(sizeof(KerberosTime));
+               if (h->valid_start == NULL) {
+                       rc = ENOMEM;
+                       goto error;
+               }
+               *h->valid_start = *s->valid_start;
+       } else {
+               h->valid_start = NULL;
+       }
+
+       if (s->valid_end != NULL) {
+               h->valid_end = malloc(sizeof(KerberosTime));
+               if (h->valid_end == NULL) {
+                       rc = ENOMEM;
+                       goto error;
+               }
+               *h->valid_end = *s->valid_end;
+       } else {
+               h->valid_end = NULL;
+       }
+
+       if (s->pw_end != NULL) {
+               h->pw_end = malloc(sizeof(KerberosTime));
+               if (h->pw_end == NULL) {
+                       rc = ENOMEM;
+                       goto error;
+               }
+               *h->pw_end = *s->pw_end;
+       } else {
+               h->pw_end = NULL;
+       }
+
+       if (s->max_life != NULL) {
+               h->max_life = malloc(sizeof(unsigned int));
+               if (h->max_life == NULL) {
+                       rc = ENOMEM;
+                       goto error;
+               }
+               *h->max_life = *s->max_life;
+       } else {
+               h->max_life = NULL;
+       }
+
+       if (s->max_renew != NULL) {
+               h->max_renew = malloc(sizeof(unsigned int));
+               if (h->max_renew == NULL) {
+                       rc = ENOMEM;
+                       goto error;
+               }
+               *h->max_renew = *s->max_renew;
+       } else {
+               h->max_renew = NULL;
+       }
+
+       sdb_flags_to_hdb_flags(&s->flags, &h->flags);
+
+       if (s->etypes) {
+               h->etypes = malloc(sizeof(*h->etypes));
+               if (h->etypes == NULL) {
+                       rc = ENOMEM;
+                       goto error;
+               }
+               h->etypes->len = s->etypes->len;
+               h->etypes->val = calloc(h->etypes->len, sizeof(int));
+               if (h->etypes->val == NULL) {
+                       rc = ENOMEM;
+                       goto error;
+               }
+               for (i = 0; i < h->etypes->len; i++) {
+                       h->etypes->val[i] = s->etypes->val[i];
+               }
+       } else {
+               h->etypes = NULL;
+       }
+       h->generation = NULL;
+       h->extensions = NULL; /* really sure ? FIXME */
+
+       return 0;
+error:
+       free_hdb_entry(h);
+       return rc;
+}
+
+static int samba_kdc_hdb_entry_destructor(struct samba_kdc_entry *p)
+{
+       struct hdb_entry_ex *entry_ex = p->entry_ex;
+       free_hdb_entry(&entry_ex->entry);
+
+       return 0;
+}
+
+static void samba_kdc_free_hdb_entry(krb5_context context,
+                                    struct hdb_entry_ex *entry_ex)
+{
+       /* this function is called only from hdb_free_entry().
+        * Make sure we neutralize the destructor or we will
+        * get a double free later when hdb_free_entry() will
+        * try to call free_hdb_entry() */
+       talloc_set_destructor(entry_ex->ctx, NULL);
+
+       /* now proceed to free the talloc part */
+       talloc_free(entry_ex->ctx);
+}
+
+int sdb_entry_ex_to_hdb_entry_ex(krb5_context context,
+                                const struct sdb_entry_ex *s,
+                                struct hdb_entry_ex *h)
+{
+       struct samba_kdc_entry *skdc_entry;
+
+       ZERO_STRUCTP(h);
+
+       if (s->ctx != NULL) {
+               skdc_entry = talloc_get_type(s->ctx, struct samba_kdc_entry);
+
+               h->ctx          = skdc_entry;
+               h->free_entry   = samba_kdc_free_hdb_entry;
+
+               talloc_set_destructor(skdc_entry,
+                                     samba_kdc_hdb_entry_destructor);
+       }
+
+       return sdb_entry_to_hdb_entry(context, &s->entry, &h->entry);
+}
index b7006750f716921265a7433d55f1948fadc20f63..d29ff77134165dd4f5ffe10daa55a4b2ef788281 100755 (executable)
@@ -64,6 +64,13 @@ bld.SAMBA_SUBSYSTEM('sdb',
        deps='krb5',
        )
 
+bld.SAMBA_SUBSYSTEM('sdb_hdb',
+       source='sdb_to_hdb.c',
+       includes=kdc_include,
+       deps='sdb hdb',
+       autoproto='sdb_hdb.h',
+       enabled=bld.CONFIG_SET('SAMBA4_USES_HEIMDAL')
+       )
 
 bld.SAMBA_SUBSYSTEM('PAC_GLUE',
        source='pac-glue.c',