summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/hdb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/hdb')
-rw-r--r--source4/heimdal/lib/hdb/dbinfo.c6
-rw-r--r--source4/heimdal/lib/hdb/ext.c14
-rw-r--r--source4/heimdal/lib/hdb/hdb.asn112
-rw-r--r--source4/heimdal/lib/hdb/hdb.c55
-rw-r--r--source4/heimdal/lib/hdb/hdb.h157
-rw-r--r--source4/heimdal/lib/hdb/keys.c13
-rw-r--r--source4/heimdal/lib/hdb/keytab.c7
-rw-r--r--source4/heimdal/lib/hdb/mkey.c29
-rw-r--r--source4/heimdal/lib/hdb/ndbm.c4
9 files changed, 203 insertions, 94 deletions
diff --git a/source4/heimdal/lib/hdb/dbinfo.c b/source4/heimdal/lib/hdb/dbinfo.c
index 2121577bb1..7e2961c614 100644
--- a/source4/heimdal/lib/hdb/dbinfo.c
+++ b/source4/heimdal/lib/hdb/dbinfo.c
@@ -228,10 +228,12 @@ hdb_free_dbinfo(krb5_context context, struct hdb_dbinfo **dbp)
for(di = *dbp; di != NULL; di = ndi) {
ndi = di->next;
+ free (di->label);
free (di->realm);
free (di->dbname);
- if (di->mkey_file)
- free (di->mkey_file);
+ free (di->mkey_file);
+ free (di->acl_file);
+ free (di->log_file);
free(di);
}
*dbp = NULL;
diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c
index f792b85c09..9053fd6633 100644
--- a/source4/heimdal/lib/hdb/ext.c
+++ b/source4/heimdal/lib/hdb/ext.c
@@ -235,6 +235,20 @@ hdb_entry_get_pkinit_hash(const hdb_entry *entry, const HDB_Ext_PKINIT_hash **a)
}
krb5_error_code
+hdb_entry_get_pkinit_cert(const hdb_entry *entry, const HDB_Ext_PKINIT_cert **a)
+{
+ const HDB_extension *ext;
+
+ ext = hdb_find_extension(entry, choice_HDB_extension_data_pkinit_cert);
+ if (ext)
+ *a = &ext->data.u.pkinit_cert;
+ else
+ *a = NULL;
+
+ return 0;
+}
+
+krb5_error_code
hdb_entry_get_pw_change_time(const hdb_entry *entry, time_t *t)
{
const HDB_extension *ext;
diff --git a/source4/heimdal/lib/hdb/hdb.asn1 b/source4/heimdal/lib/hdb/hdb.asn1
index 5cddf8f1d0..c2abd4af73 100644
--- a/source4/heimdal/lib/hdb/hdb.asn1
+++ b/source4/heimdal/lib/hdb/hdb.asn1
@@ -13,7 +13,8 @@ hdb-afs3-salt INTEGER ::= 10
Salt ::= SEQUENCE {
type[0] INTEGER (0..4294967295),
- salt[1] OCTET STRING
+ salt[1] OCTET STRING,
+ opaque[2] OCTET STRING OPTIONAL
}
Key ::= SEQUENCE {
@@ -64,6 +65,10 @@ HDB-Ext-PKINIT-hash ::= SEQUENCE OF SEQUENCE {
digest[1] OCTET STRING
}
+HDB-Ext-PKINIT-cert ::= SEQUENCE OF SEQUENCE {
+ cert[0] OCTET STRING
+}
+
HDB-Ext-Constrained-delegation-acl ::= SEQUENCE OF Principal
-- hdb-ext-referrals ::= PA-SERVER-REFERRAL-DATA
@@ -94,6 +99,7 @@ HDB-extension ::= SEQUENCE {
password[5] HDB-Ext-Password,
aliases[6] HDB-Ext-Aliases,
last-pw-change[7] KerberosTime,
+ pkinit-cert[8] HDB-Ext-PKINIT-cert,
...
},
...
@@ -101,6 +107,10 @@ HDB-extension ::= SEQUENCE {
HDB-extensions ::= SEQUENCE OF HDB-extension
+hdb_keyset ::= SEQUENCE {
+ kvno[1] INTEGER (0..4294967295),
+ keys[0] SEQUENCE OF Key
+}
hdb_entry ::= SEQUENCE {
principal[0] Principal OPTIONAL, -- this is optional only
diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c
index ad2c35a43a..e55b0bed03 100644
--- a/source4/heimdal/lib/hdb/hdb.c
+++ b/source4/heimdal/lib/hdb/hdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,11 +31,6 @@
* SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "krb5.h"
#include "krb5_locl.h"
#include "hdb_locl.h"
RCSID("$Id$");
@@ -44,24 +39,49 @@ RCSID("$Id$");
#include <dlfcn.h>
#endif
+/*! @mainpage Heimdal database backend library
+ *
+ * @section intro Introduction
+ *
+ * Heimdal libhdb library provides the backend support for Heimdal kdc
+ * and kadmind. Its here where plugins for diffrent database engines
+ * can be pluged in and extend support for here Heimdal get the
+ * principal and policy data from.
+ *
+ * Example of Heimdal backend are:
+ * - Berkeley DB 1.85
+ * - Berkeley DB 3.0
+ * - Berkeley DB 4.0
+ * - New Berkeley DB
+ * - LDAP
+ *
+ *
+ * The project web page: http://www.h5l.org/
+ *
+ */
+
+
+
static struct hdb_method methods[] = {
#if HAVE_DB1 || HAVE_DB3
- {HDB_INTERFACE_VERSION, "db:", hdb_db_create},
+ { HDB_INTERFACE_VERSION, "db:", hdb_db_create},
#endif
#if HAVE_NDBM
- {HDB_INTERFACE_VERSION, "ndbm:", hdb_ndbm_create},
+ { HDB_INTERFACE_VERSION, "ndbm:", hdb_ndbm_create},
#endif
#if defined(OPENLDAP) && !defined(OPENLDAP_MODULE)
- {HDB_INTERFACE_VERSION, "ldap:", hdb_ldap_create},
- {HDB_INTERFACE_VERSION, "ldapi:", hdb_ldapi_create},
+ { HDB_INTERFACE_VERSION, "ldap:", hdb_ldap_create},
+ { HDB_INTERFACE_VERSION, "ldapi:", hdb_ldapi_create},
#endif
{0, NULL, NULL}
};
#if HAVE_DB1 || HAVE_DB3
-static struct hdb_method dbmetod = {"", hdb_db_create };
+static struct hdb_method dbmetod =
+ { HDB_INTERFACE_VERSION, "", hdb_db_create };
#elif defined(HAVE_NDBM)
-static struct hdb_method dbmetod = {"", hdb_ndbm_create };
+static struct hdb_method dbmetod =
+ { HDB_INTERFACE_VERSION, "", hdb_ndbm_create };
#endif
@@ -265,9 +285,10 @@ find_dynamic_method (krb5_context context,
len = p - filename;
*rest = filename + len + 1;
- prefix = strndup(filename, len);
+ prefix = malloc(len + 1);
if (prefix == NULL)
krb5_errx(context, 1, "out of memory");
+ strlcpy(prefix, filename, len + 1);
if (asprintf(&path, LIBDIR "/hdb_%s.so", prefix) == -1)
krb5_errx(context, 1, "out of memory");
@@ -390,6 +411,14 @@ hdb_list_builtin(krb5_context context, char **list)
return 0;
}
+/**
+ * Create a handle for a Kerberos database
+ *
+ * Create a handle for a Kerberos database backend specified by a
+ * filename. Doesn't create a file if its doesn't exists, you have to
+ * use O_CREAT to tell the backend to create the file.
+ */
+
krb5_error_code
hdb_create(krb5_context context, HDB **db, const char *filename)
{
diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h
index 53b1defc96..ce219153b3 100644
--- a/source4/heimdal/lib/hdb/hdb.h
+++ b/source4/heimdal/lib/hdb/hdb.h
@@ -66,65 +66,122 @@ typedef struct hdb_entry_ex {
} hdb_entry_ex;
+/**
+ * HDB backend function pointer structure
+ *
+ * The HDB structure is what the KDC and kadmind framework uses to
+ * query the backend database when talking about principals.
+ */
+
typedef struct HDB{
void *hdb_db;
- void *hdb_dbc;
+ void *hdb_dbc; /** don't use, only for DB3 */
char *hdb_name;
int hdb_master_key_set;
hdb_master_key hdb_master_key;
int hdb_openp;
- krb5_error_code (*hdb_open)(krb5_context,
- struct HDB*,
- int,
- mode_t);
- krb5_error_code (*hdb_close)(krb5_context,
- struct HDB*);
- void (*hdb_free)(krb5_context,
- struct HDB*,
- hdb_entry_ex*);
- krb5_error_code (*hdb_fetch)(krb5_context,
- struct HDB*,
- krb5_const_principal,
- unsigned,
- hdb_entry_ex*);
- krb5_error_code (*hdb_store)(krb5_context,
- struct HDB*,
- unsigned,
+ /**
+ * Open (or create) the a Kerberos database.
+ *
+ * Open (or create) the a Kerberos database that was resolved with
+ * hdb_create(). The third and fourth flag to the function are the
+ * same as open(), thus passing O_CREAT will create the data base
+ * if it doesn't exists.
+ *
+ * Then done the caller should call hdb_close(), and to release
+ * all resources hdb_destroy().
+ */
+ krb5_error_code (*hdb_open)(krb5_context, struct HDB*, int, mode_t);
+ /**
+ * Close the database for transaction
+ *
+ * Closes the database for further transactions, wont release any
+ * permanant resources. the database can be ->hdb_open-ed again.
+ */
+ krb5_error_code (*hdb_close)(krb5_context, struct HDB*);
+ /**
+ * Free an entry after use.
+ */
+ void (*hdb_free)(krb5_context, struct HDB*, hdb_entry_ex*);
+ /**
+ * Fetch an entry from the backend
+ *
+ * Fetch an entry from the backend, flags are what type of entry
+ * should be fetch: client, server, krbtgt.
+ */
+ krb5_error_code (*hdb_fetch)(krb5_context, struct HDB*,
+ krb5_const_principal, unsigned,
hdb_entry_ex*);
- krb5_error_code (*hdb_remove)(krb5_context,
- struct HDB*,
+ /**
+ * Store an entry to database
+ */
+ krb5_error_code (*hdb_store)(krb5_context, struct HDB*,
+ unsigned, hdb_entry_ex*);
+ /**
+ * Remove an entry from the database.
+ */
+ krb5_error_code (*hdb_remove)(krb5_context, struct HDB*,
krb5_const_principal);
- krb5_error_code (*hdb_firstkey)(krb5_context,
- struct HDB*,
- unsigned,
- hdb_entry_ex*);
- krb5_error_code (*hdb_nextkey)(krb5_context,
- struct HDB*,
- unsigned,
- hdb_entry_ex*);
- krb5_error_code (*hdb_lock)(krb5_context,
- struct HDB*,
- int operation);
- krb5_error_code (*hdb_unlock)(krb5_context,
- struct HDB*);
- krb5_error_code (*hdb_rename)(krb5_context,
- struct HDB*,
- const char*);
- krb5_error_code (*hdb__get)(krb5_context,
- struct HDB*,
- krb5_data,
- krb5_data*);
- krb5_error_code (*hdb__put)(krb5_context,
- struct HDB*,
- int,
- krb5_data,
- krb5_data);
- krb5_error_code (*hdb__del)(krb5_context,
- struct HDB*,
- krb5_data);
- krb5_error_code (*hdb_destroy)(krb5_context,
- struct HDB*);
+ /**
+ * As part of iteration, fetch one entry
+ */
+ krb5_error_code (*hdb_firstkey)(krb5_context, struct HDB*,
+ unsigned, hdb_entry_ex*);
+ /**
+ * As part of iteration, fetch next entry
+ */
+ krb5_error_code (*hdb_nextkey)(krb5_context, struct HDB*,
+ unsigned, hdb_entry_ex*);
+ /**
+ * Lock database
+ *
+ * A lock can only be held by one consumers. Transaction can still
+ * happen on the database while the lock is held, so the entry is
+ * only useful for syncroning creation of the database and renaming of the database.
+ */
+ krb5_error_code (*hdb_lock)(krb5_context, struct HDB*, int);
+ /**
+ * Unlock database
+ */
+ krb5_error_code (*hdb_unlock)(krb5_context, struct HDB*);
+ /**
+ * Rename the data base.
+ */
+ krb5_error_code (*hdb_rename)(krb5_context, struct HDB*, const char*);
+ /**
+ * Get an hdb_entry from a classical DB backend
+ *
+ * If the database is a classical DB (ie BDB, NDBM, GDBM, etc)
+ * backend, this function will take a principal key (krb5_data)
+ * and return all data related to principal in the return
+ * krb5_data. The returned encoded entry is of type hdb_entry or
+ * hdb_entry_alias.
+ */
+ krb5_error_code (*hdb__get)(krb5_context, struct HDB*,
+ krb5_data, krb5_data*);
+ /**
+ * Store an hdb_entry from a classical DB backend
+ *
+ * Same discussion as in @ref HDB::hdb__get
+ */
+ krb5_error_code (*hdb__put)(krb5_context, struct HDB*, int,
+ krb5_data, krb5_data);
+ /**
+ * Delete and hdb_entry from a classical DB backend
+ *
+ * Same discussion as in @ref HDB::hdb__get
+ */
+ krb5_error_code (*hdb__del)(krb5_context, struct HDB*, krb5_data);
+ /**
+ * Destroy the handle to the database.
+ *
+ * Destroy the handle to the database, deallocate all memory and
+ * related resources. Does not remove any permanent data. Its the
+ * logical reverse of hdb_create() function that is the entry
+ * point for the module.
+ */
+ krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*);
}HDB;
#define HDB_INTERFACE_VERSION 4
diff --git a/source4/heimdal/lib/hdb/keys.c b/source4/heimdal/lib/hdb/keys.c
index b9f294e2eb..50fe7d7fda 100644
--- a/source4/heimdal/lib/hdb/keys.c
+++ b/source4/heimdal/lib/hdb/keys.c
@@ -1,3 +1,4 @@
+
/*
* Copyright (c) 1997 - 2001, 2003 - 2004 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
@@ -172,8 +173,8 @@ parse_key_set(krb5_context context, const char *key,
if(salt->salttype == KRB5_PW_SALT)
ret = krb5_get_pw_salt(context, principal, salt);
else if(salt->salttype == KRB5_AFS3_SALT) {
- krb5_realm *realm = krb5_princ_realm(context, principal);
- salt->saltvalue.data = strdup(*realm);
+ krb5_const_realm realm = krb5_principal_get_realm(context, principal);
+ salt->saltvalue.data = strdup(realm);
if(salt->saltvalue.data == NULL) {
krb5_set_error_message(context, ENOMEM,
"out of memory while "
@@ -181,7 +182,7 @@ parse_key_set(krb5_context context, const char *key,
return ENOMEM;
}
strlwr(salt->saltvalue.data);
- salt->saltvalue.length = strlen(*realm);
+ salt->saltvalue.length = strlen(realm);
}
}
@@ -217,7 +218,7 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset,
key.key.keyvalue.data = NULL;
if (salt) {
- key.salt = malloc(sizeof(*key.salt));
+ key.salt = calloc(1, sizeof(*key.salt));
if (key.salt == NULL) {
free_Key(&key);
return ENOMEM;
@@ -259,7 +260,6 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
Key *k, *key_set;
int i, j;
char *default_keytypes[] = {
- "des:pw-salt",
"aes256-cts-hmac-sha1-96:pw-salt",
"des3-cbc-sha1:pw-salt",
"arcfour-hmac-md5:pw-salt",
@@ -271,9 +271,6 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal,
if (ktypes == NULL)
ktypes = default_keytypes;
- if (ktypes == NULL)
- abort();
-
*ret_key_set = key_set = NULL;
*nkeyset = 0;
diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c
index a890ba62cd..97989a9764 100644
--- a/source4/heimdal/lib/hdb/keytab.c
+++ b/source4/heimdal/lib/hdb/keytab.c
@@ -59,7 +59,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
return ENOMEM;
}
db = name;
- mkey = strrchr(name, ':');
+ mkey = strchr(name, ':');
if(mkey == NULL || mkey[1] == '\0') {
if(*name == '\0')
d->dbname = NULL;
@@ -147,7 +147,7 @@ find_db (krb5_context context,
const krb5_config_binding *top_bind = NULL;
const krb5_config_binding *default_binding = NULL;
const krb5_config_binding *db;
- krb5_realm *prealm = krb5_princ_realm(context, rk_UNCONST(principal));
+ krb5_const_realm realm = krb5_principal_get_realm(context, principal);
*dbname = *mkey = NULL;
@@ -169,7 +169,7 @@ find_db (krb5_context context,
krb5_warnx(context, "WARNING: using the first encountered");
} else
default_binding = db;
- } else if (strcmp (*prealm, p) == 0) {
+ } else if (strcmp (realm, p) == 0) {
set_config (context, db, dbname, mkey);
break;
}
@@ -263,6 +263,7 @@ krb5_kt_ops hdb_kt_ops = {
hdb_resolve,
hdb_get_name,
hdb_close,
+ NULL, /* destroy */
hdb_get_entry,
NULL, /* start_seq_get */
NULL, /* next_entry */
diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c
index ce1aa9aff1..1520c4f7e9 100644
--- a/source4/heimdal/lib/hdb/mkey.c
+++ b/source4/heimdal/lib/hdb/mkey.c
@@ -169,23 +169,24 @@ read_master_mit(krb5_context context, const char *filename,
return errno;
}
krb5_storage_set_flags(sp, KRB5_STORAGE_HOST_BYTEORDER);
-#if 0
/* could possibly use ret_keyblock here, but do it with more
checks for now */
- ret = krb5_ret_keyblock(sp, &key);
-#else
- ret = krb5_ret_int16(sp, &enctype);
- if((htons(enctype) & 0xff00) == 0x3000) {
- ret = HEIM_ERR_BAD_MKEY;
- krb5_set_error_message(context, ret, "unknown keytype in %s: %#x, expected %#x",
- filename, htons(enctype), 0x3000);
- goto out;
+ {
+ ret = krb5_ret_int16(sp, &enctype);
+ if (ret)
+ goto out;
+ if((htons(enctype) & 0xff00) == 0x3000) {
+ ret = HEIM_ERR_BAD_MKEY;
+ krb5_set_error_message(context, ret, "unknown keytype in %s: "
+ "%#x, expected %#x",
+ filename, htons(enctype), 0x3000);
+ goto out;
+ }
+ key.keytype = enctype;
+ ret = krb5_ret_data(sp, &key.keyvalue);
+ if(ret)
+ goto out;
}
- key.keytype = enctype;
- ret = krb5_ret_data(sp, &key.keyvalue);
- if(ret)
- goto out;
-#endif
ret = hdb_process_master_key(context, 0, &key, 0, mkey);
krb5_free_keyblock_contents(context, &key);
out:
diff --git a/source4/heimdal/lib/hdb/ndbm.c b/source4/heimdal/lib/hdb/ndbm.c
index e71125c61f..1e9df81652 100644
--- a/source4/heimdal/lib/hdb/ndbm.c
+++ b/source4/heimdal/lib/hdb/ndbm.c
@@ -53,9 +53,7 @@ struct ndbm_db {
static krb5_error_code
NDBM_destroy(krb5_context context, HDB *db)
{
- krb5_error_code ret;
-
- ret = hdb_clear_master_key (context, db);
+ hdb_clear_master_key (context, db);
free(db->hdb_name);
free(db);
return 0;