summaryrefslogtreecommitdiff
path: root/source4/kdc/sdb_to_hdb.c
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2014-05-08 17:09:08 +0200
committerAndreas Schneider <asn@cryptomilk.org>2015-07-30 10:24:26 +0200
commit99d3719e7d3073989442cffe635c3ac7a0bc200c (patch)
tree76e6b8265b0c28d23798b75bc56d8660bf72f3b4 /source4/kdc/sdb_to_hdb.c
parent85a041bab594d7b4e88995c9a7c6f509d8cc19f3 (diff)
downloadsamba-99d3719e7d3073989442cffe635c3ac7a0bc200c.tar.gz
s4-kdc: Introduce a simple sdb_hdb shim layer
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>
Diffstat (limited to 'source4/kdc/sdb_to_hdb.c')
-rw-r--r--source4/kdc/sdb_to_hdb.c315
1 files changed, 315 insertions, 0 deletions
diff --git a/source4/kdc/sdb_to_hdb.c b/source4/kdc/sdb_to_hdb.c
new file mode 100644
index 00000000000..e11d6162983
--- /dev/null
+++ b/source4/kdc/sdb_to_hdb.c
@@ -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);
+}