diff options
author | Günther Deschner <gd@samba.org> | 2014-05-08 17:09:08 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2015-07-30 10:24:26 +0200 |
commit | 99d3719e7d3073989442cffe635c3ac7a0bc200c (patch) | |
tree | 76e6b8265b0c28d23798b75bc56d8660bf72f3b4 /source4/kdc/sdb_to_hdb.c | |
parent | 85a041bab594d7b4e88995c9a7c6f509d8cc19f3 (diff) | |
download | samba-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.c | 315 |
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); +} |