diff options
Diffstat (limited to 'third_party/heimdal/lib/hdb')
23 files changed, 884 insertions, 780 deletions
diff --git a/third_party/heimdal/lib/hdb/Makefile.am b/third_party/heimdal/lib/hdb/Makefile.am index 342aaffbe96..89ab15d9d3e 100644 --- a/third_party/heimdal/lib/hdb/Makefile.am +++ b/third_party/heimdal/lib/hdb/Makefile.am @@ -2,6 +2,8 @@ include $(top_srcdir)/Makefile.am.common +WFLAGS += $(WFLAGS_ENUM_CONV) + AM_CPPFLAGS += -I../asn1 -I$(srcdir)/../asn1 AM_CPPFLAGS += $(INCLUDE_openldap) -DHDB_DB_DIR=\"$(DIR_hdbdir)\" AM_CPPFLAGS += -I$(srcdir)/../krb5 @@ -13,38 +15,40 @@ AM_CPPFLAGS += -I$(DBHEADER) endif BUILT_SOURCES = \ - $(gen_files_hdb:.x=.c) \ + $(gen_files_hdb) \ hdb_err.c \ hdb_err.h gen_files_hdb = \ - asn1_Salt.x \ - asn1_Key.x \ - asn1_Event.x \ - asn1_HDBFlags.x \ - asn1_GENERATION.x \ - asn1_HDB_Ext_PKINIT_acl.x \ - asn1_HDB_Ext_PKINIT_cert.x \ - asn1_HDB_Ext_PKINIT_hash.x \ - asn1_HDB_Ext_Constrained_delegation_acl.x \ - asn1_HDB_Ext_KeyRotation.x \ - asn1_HDB_Ext_Lan_Manager_OWF.x \ - asn1_HDB_Ext_Password.x \ - asn1_HDB_Ext_Aliases.x \ - asn1_HDB_Ext_KeySet.x \ - asn1_HDB_extension.x \ - asn1_HDB_extensions.x \ - asn1_HDB_EncTypeList.x \ - asn1_HDB_EntryOrAlias.x \ - asn1_KeyRotation.x \ - asn1_KeyRotationFlags.x \ - asn1_HDB_entry.x \ - asn1_HDB_entry_alias.x \ - asn1_HDB_keyset.x \ - asn1_Keys.x + asn1_Event.c \ + asn1_GENERATION.c \ + asn1_HDB_EncTypeList.c \ + asn1_HDB_Ext_Aliases.c \ + asn1_HDB_Ext_Constrained_delegation_acl.c \ + asn1_HDB_Ext_KeyRotation.c \ + asn1_HDB_Ext_KeySet.c \ + asn1_HDB_Ext_Lan_Manager_OWF.c \ + asn1_HDB_Ext_Password.c \ + asn1_HDB_Ext_PKINIT_acl.c \ + asn1_HDB_Ext_PKINIT_cert.c \ + asn1_HDB_Ext_PKINIT_hash.c \ + asn1_HDB_EntryOrAlias.c \ + asn1_HDB_entry_alias.c \ + asn1_HDB_entry.c \ + asn1_HDB_extension.c \ + asn1_HDB_extensions.c \ + asn1_HDB_keyset.c \ + asn1_HDBFlags.c \ + asn1_Key.c \ + asn1_KeyRotation.c \ + asn1_KeyRotationFlags.c \ + asn1_Keys.c \ + asn1_Salt.c CLEANFILES = $(BUILT_SOURCES) $(gen_files_hdb) \ - hdb_asn1{,-priv}.h* hdb_asn1_files hdb_asn1-template.[cx] + hdb_asn1{,-priv}.h hdb_asn1_files hdb_asn1-template.c \ + hdb_asn1_syms.c hdb_asn1_oids.c hdb_asn1.json \ + testhdb-* LDADD = libhdb.la \ ../krb5/libkrb5.la \ @@ -139,13 +143,14 @@ $(srcdir)/hdb-protos.h: $(dist_libhdb_la_SOURCES) $(srcdir)/hdb-private.h: $(dist_libhdb_la_SOURCES) cd $(srcdir); perl ../../cf/make-proto.pl -q -P comment -p hdb-private.h $(dist_libhdb_la_SOURCES) || rm -f hdb-private.h -$(gen_files_hdb) hdb_asn1.hx hdb_asn1-priv.hx: hdb_asn1_files +$(gen_files_hdb) hdb_asn1.h hdb_asn1-priv.h: hdb_asn1_files + for genfile in '$(gen_files_hdb)'; do \ + $(CLANG_FORMAT) -style=$(CLANG_FORMAT_STYLE) -i $${genfile}; \ + done hdb_asn1_files: $(ASN1_COMPILE_DEP) $(srcdir)/hdb.asn1 - $(ASN1_COMPILE) --sequence=HDB-extensions \ - --sequence=HDB-Ext-KeyRotation \ - --sequence=HDB-Ext-KeySet \ - --sequence=Keys $(srcdir)/hdb.asn1 hdb_asn1 + $(ASN1_COMPILE) --option-file=$(srcdir)/hdb.opt $(srcdir)/hdb.asn1 hdb_asn1 + @$(CLANG_FORMAT) -style=$(CLANG_FORMAT_STYLE) -i $$(cat hdb_asn1_files) # to help stupid solaris make diff --git a/third_party/heimdal/lib/hdb/NTMakefile b/third_party/heimdal/lib/hdb/NTMakefile index 5ad9d9c5742..f4801f7c54e 100644 --- a/third_party/heimdal/lib/hdb/NTMakefile +++ b/third_party/heimdal/lib/hdb/NTMakefile @@ -31,17 +31,15 @@ RELDIR=lib\hdb -!include ../../windows/NTMakefile.w32 +intcflags=-DASN1_LIB -gen_files_hdb = $(OBJ)\asn1_hdb_asn1.x +!include ../../windows/NTMakefile.w32 -$(gen_files_hdb) $(OBJ)\hdb_asn1.hx $(OBJ)\hdb_asn1-priv.hx: $(BINDIR)\asn1_compile.exe hdb.asn1 +$(OBJ)\asn1_hdb_asn1.c $(OBJ)\hdb_asn1.h $(OBJ)\hdb_asn1-priv.h: $(BINDIR)\asn1_compile.exe hdb.asn1 cd $(OBJ) - $(BINDIR)\asn1_compile.exe --sequence=HDB-extensions --sequence=HDB-Ext-KeyRotation --sequence=HDB-Ext-KeySet --sequence=Keys --one-code-file $(SRCDIR)\hdb.asn1 hdb_asn1 + $(BINDIR)\asn1_compile.exe --one-code-file --option-file=$(SRCDIR)\hdb.opt $(SRCDIR)\hdb.asn1 hdb_asn1 cd $(SRCDIR) -$(gen_files_hdb:.x=.c): $$(@R).x - !ifdef OPENLDAP_MODULE ldap_dll = $(BINDIR)\hdb_ldap.dll @@ -98,7 +96,7 @@ libhdb_OBJs = \ $(OBJ)\mkey.obj \ $(OBJ)\ndbm.obj \ $(OBJ)\print.obj \ - $(gen_files_hdb:.x=.obj) \ + $(OBJ)\asn1_hdb_asn1.obj \ $(OBJ)\hdb_err.obj $(OBJ)\hdb_err.c $(OBJ)\hdb_err.h: hdb_err.et diff --git a/third_party/heimdal/lib/hdb/common.c b/third_party/heimdal/lib/hdb/common.c index 251eb9b7714..a92cc1372db 100644 --- a/third_party/heimdal/lib/hdb/common.c +++ b/third_party/heimdal/lib/hdb/common.c @@ -148,7 +148,7 @@ fetch_entry_or_alias(krb5_context context, HDB *db, krb5_const_principal principal, unsigned flags, - hdb_entry_ex *entry) + hdb_entry *entry) { HDB_EntryOrAlias eoa; krb5_principal enterprise_principal = NULL; @@ -180,7 +180,7 @@ fetch_entry_or_alias(krb5_context context, if (ret == 0) ret = decode_HDB_EntryOrAlias(value.data, value.length, &eoa, NULL); if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_entry) { - entry->entry = eoa.u.entry; + *entry = eoa.u.entry; } else if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_alias) { krb5_data_free(&key); ret = hdb_principal2key(context, eoa.u.alias.principal, &key); @@ -190,7 +190,7 @@ fetch_entry_or_alias(krb5_context context, } if (ret == 0) /* No alias chaining */ - ret = hdb_value2entry(context, &value, &entry->entry); + ret = hdb_value2entry(context, &value, entry); krb5_free_principal(context, eoa.u.alias.principal); } else if (ret == 0) ret = ENOTSUP; @@ -200,7 +200,7 @@ fetch_entry_or_alias(krb5_context context, * the canonicalize flag is unset, the original specification in * draft-ietf-krb-wg-kerberos-referrals-03.txt says we should. */ - entry->entry.flags.force_canonicalize = 1; + entry->flags.force_canonicalize = 1; } /* HDB_F_GET_ANY indicates request originated from KDC (not kadmin) */ @@ -208,7 +208,7 @@ fetch_entry_or_alias(krb5_context context, (flags & (HDB_F_CANON|HDB_F_GET_ANY)) == 0) { /* `principal' was alias but canon not req'd */ - free_HDB_entry(&entry->entry); + free_HDB_entry(entry); ret = HDB_ERR_NOENTRY; } @@ -221,7 +221,7 @@ fetch_entry_or_alias(krb5_context context, krb5_error_code _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, - unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry) + unsigned flags, krb5_kvno kvno, hdb_entry *entry) { krb5_error_code ret; @@ -231,23 +231,23 @@ _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, if ((flags & HDB_F_DECRYPT) && (flags & HDB_F_ALL_KVNOS)) { /* Decrypt the current keys */ - ret = hdb_unseal_keys(context, db, &entry->entry); + ret = hdb_unseal_keys(context, db, entry); if (ret) { - hdb_free_entry(context, entry); + hdb_free_entry(context, db, entry); return ret; } /* Decrypt the key history too */ - ret = hdb_unseal_keys_kvno(context, db, 0, flags, &entry->entry); + ret = hdb_unseal_keys_kvno(context, db, 0, flags, entry); if (ret) { - hdb_free_entry(context, entry); + hdb_free_entry(context, db, entry); return ret; } } else if ((flags & HDB_F_DECRYPT)) { - if ((flags & HDB_F_KVNO_SPECIFIED) == 0 || kvno == entry->entry.kvno) { + if ((flags & HDB_F_KVNO_SPECIFIED) == 0 || kvno == entry->kvno) { /* Decrypt the current keys */ - ret = hdb_unseal_keys(context, db, &entry->entry); + ret = hdb_unseal_keys(context, db, entry); if (ret) { - hdb_free_entry(context, entry); + hdb_free_entry(context, db, entry); return ret; } } else { @@ -257,9 +257,9 @@ _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, * Find and decrypt the keys from the history that we want, * and swap them with the current keys */ - ret = hdb_unseal_keys_kvno(context, db, kvno, flags, &entry->entry); + ret = hdb_unseal_keys_kvno(context, db, kvno, flags, entry); if (ret) { - hdb_free_entry(context, entry); + hdb_free_entry(context, db, entry); return ret; } } @@ -271,9 +271,9 @@ _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, * key was generated, but given the salt will be ignored by a keytab * client it doesn't hurt to include the default salt. */ - ret = add_default_salts(context, db, &entry->entry); + ret = add_default_salts(context, db, entry); if (ret) { - hdb_free_entry(context, entry); + hdb_free_entry(context, db, entry); return ret; } } @@ -325,20 +325,20 @@ hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key) static krb5_error_code hdb_add_aliases(krb5_context context, HDB *db, - unsigned flags, hdb_entry_ex *entry) + unsigned flags, hdb_entry *entry) { const HDB_Ext_Aliases *aliases; krb5_error_code code; krb5_data key, value; size_t i; - code = hdb_entry_get_aliases(&entry->entry, &aliases); + code = hdb_entry_get_aliases(entry, &aliases); if (code || aliases == NULL) return code; for (i = 0; i < aliases->aliases.len; i++) { hdb_entry_alias entryalias; - entryalias.principal = entry->entry.principal; + entryalias.principal = entry->principal; code = hdb_entry_alias2value(context, &entryalias, &value); if (code) @@ -358,7 +358,7 @@ hdb_add_aliases(krb5_context context, HDB *db, /* Check if new aliases are already used for other entries */ static krb5_error_code -hdb_check_aliases(krb5_context context, HDB *db, hdb_entry_ex *entry) +hdb_check_aliases(krb5_context context, HDB *db, hdb_entry *entry) { const HDB_Ext_Aliases *aliases = NULL; HDB_EntryOrAlias eoa; @@ -370,7 +370,7 @@ hdb_check_aliases(krb5_context context, HDB *db, hdb_entry_ex *entry) krb5_data_zero(&value); akey = value; - ret = hdb_entry_get_aliases(&entry->entry, &aliases); + ret = hdb_entry_get_aliases(entry, &aliases); for (i = 0; ret == 0 && aliases && i < aliases->aliases.len; i++) { ret = hdb_principal2key(context, &aliases->aliases.val[i], &akey); if (ret == 0) @@ -385,7 +385,7 @@ hdb_check_aliases(krb5_context context, HDB *db, hdb_entry_ex *entry) ret = HDB_ERR_EXISTS; if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_alias && !krb5_principal_compare(context, eoa.u.alias.principal, - entry->entry.principal)) + entry->principal)) /* New alias names an existing alias of a different entry */ ret = HDB_ERR_EXISTS; if (ret == HDB_ERR_NOENTRY) /* from db->hdb__get */ @@ -433,14 +433,8 @@ hdb_derive_etypes(krb5_context context, hdb_entry *e, HDB_Ext_KeySet *base_keys) free(e->etypes->val); e->etypes->len = 0; e->etypes->val = 0; - } - - if (e->etypes == NULL && - (e->etypes = malloc(sizeof(e->etypes[0]))) == NULL) + } else if ((e->etypes = calloc(1, sizeof(e->etypes[0]))) == NULL) { ret = krb5_enomem(context); - if (ret == 0) { - e->etypes->len = 0; - e->etypes->val = 0; } if (ret == 0 && (e->etypes->val = calloc(netypes, sizeof(e->etypes->val[0]))) == NULL) @@ -465,13 +459,13 @@ hdb_derive_etypes(krb5_context context, hdb_entry *e, HDB_Ext_KeySet *base_keys) } krb5_error_code -_hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +_hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { krb5_data key, value; int code; - if (entry->entry.flags.do_not_store || - entry->entry.flags.force_canonicalize) + if (entry->flags.do_not_store || + entry->flags.force_canonicalize) return HDB_ERR_MISUSE; /* check if new aliases already is used */ code = hdb_check_aliases(context, db, entry); @@ -482,7 +476,7 @@ _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) return 0; if ((flags & HDB_F_PRECHECK)) { - code = hdb_principal2key(context, entry->entry.principal, &key); + code = hdb_principal2key(context, entry->principal, &key); if (code) return code; code = db->hdb__get(context, db, key, &value); @@ -494,29 +488,31 @@ _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) return code ? code : HDB_ERR_EXISTS; } - if ((entry->entry.etypes == NULL || entry->entry.etypes->len == 0) && - (code = hdb_derive_etypes(context, &entry->entry, NULL))) + if ((entry->etypes == NULL || entry->etypes->len == 0) && + (code = hdb_derive_etypes(context, entry, NULL))) return code; - if (entry->entry.generation == NULL) { + if (entry->generation == NULL) { struct timeval t; - entry->entry.generation = malloc(sizeof(*entry->entry.generation)); - if(entry->entry.generation == NULL) { + entry->generation = malloc(sizeof(*entry->generation)); + if(entry->generation == NULL) { krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } gettimeofday(&t, NULL); - entry->entry.generation->time = t.tv_sec; - entry->entry.generation->usec = t.tv_usec; - entry->entry.generation->gen = 0; + entry->generation->time = t.tv_sec; + entry->generation->usec = t.tv_usec; + entry->generation->gen = 0; } else - entry->entry.generation->gen++; + entry->generation->gen++; - code = hdb_seal_keys(context, db, &entry->entry); + code = hdb_seal_keys(context, db, entry); if (code) return code; - hdb_principal2key(context, entry->entry.principal, &key); + code = hdb_principal2key(context, entry->principal, &key); + if (code) + return code; /* remove aliases */ code = hdb_remove_aliases(context, db, &key); @@ -524,8 +520,9 @@ _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) krb5_data_free(&key); return code; } - hdb_entry2value(context, &entry->entry, &value); - code = db->hdb__put(context, db, flags & HDB_F_REPLACE, key, value); + code = hdb_entry2value(context, entry, &value); + if (code == 0) + code = db->hdb__put(context, db, flags & HDB_F_REPLACE, key, value); krb5_data_free(&value); krb5_data_free(&key); if (code) @@ -554,8 +551,9 @@ _hdb_remove(krb5_context context, HDB *db, * HDB_entry_alias instead and assume it's an entry if decoding fails... */ - hdb_principal2key(context, principal, &key); - code = db->hdb__get(context, db, key, &value); + code = hdb_principal2key(context, principal, &key); + if (code == 0) + code = db->hdb__get(context, db, key, &value); if (code == 0) { code = decode_HDB_EntryOrAlias(value.data, value.length, &eoa, NULL); krb5_data_free(&value); @@ -573,7 +571,8 @@ _hdb_remove(krb5_context context, HDB *db, return code; } - code = hdb_remove_aliases(context, db, &key); + if (code == 0) + code = hdb_remove_aliases(context, db, &key); if (code == 0) code = db->hdb__del(context, db, key); krb5_data_free(&key); @@ -714,7 +713,7 @@ derive_keyset(krb5_context context, { dks->kvno = kvno; dks->keys.val = 0; - dks->set_time = malloc(sizeof(*dks->set_time)); + dks->set_time = malloc(sizeof(*(dks->set_time))); if (dks->set_time == NULL) return krb5_enomem(context); *dks->set_time = set_time; @@ -724,7 +723,7 @@ derive_keyset(krb5_context context, /* Possibly derive and install in `h' a keyset identified by `t' */ static krb5_error_code derive_keys_for_kr(krb5_context context, - hdb_entry_ex *h, + hdb_entry *h, HDB_Ext_KeySet *base_keys, int is_current_keyset, int rotation_period_offset, @@ -798,7 +797,7 @@ derive_keys_for_kr(krb5_context context, ret = derive_keyset(context, &base_keys->val[i].keys, princ, etype, kvno, set_time, &dks); if (ret == 0) - ret = hdb_install_keyset(context, &h->entry, is_current_keyset, &dks); + ret = hdb_install_keyset(context, h, is_current_keyset, &dks); free_HDB_keyset(&dks); return ret; @@ -807,7 +806,7 @@ derive_keys_for_kr(krb5_context context, /* Derive and install current keys, and possibly preceding or next keys */ static krb5_error_code derive_keys_for_current_kr(krb5_context context, - hdb_entry_ex *h, + hdb_entry *h, HDB_Ext_KeySet *base_keys, const char *princ, unsigned int flags, @@ -873,12 +872,12 @@ derive_keys_for_current_kr(krb5_context context, * Arguments: * * - `flags' is the flags passed to `hdb_fetch_kvno()' - * - `princ' is the name of the principal we'll end up with in `h->entry' + * - `princ' is the name of the principal we'll end up with in `entry' * - `h_is_namespace' indicates whether `h' is for a namespace or a concrete * principal (that might nonetheless have virtual/derived keys) * - `t' is the time such that the derived keys are for kvnos needed at `t' * - `etype' indicates what enctype to derive keys for (0 for all enctypes in - * `h->entry.etypes') + * `entry->etypes') * - `kvno' requests a particular kvno, or all if zero * * The caller doesn't know if the principal needs key derivation -- we make @@ -970,7 +969,7 @@ derive_keys(krb5_context context, krb5_timestamp t, krb5int32 etype, krb5uint32 kvno, - hdb_entry_ex *h) + hdb_entry *h) { HDB_Ext_KeyRotation kr; HDB_Ext_KeySet base_keys; @@ -979,14 +978,9 @@ derive_keys(krb5_context context, char *p = NULL; int valid = 1; - if (!h_is_namespace && !h->entry.flags.virtual_keys) + if (!h_is_namespace && !h->flags.virtual_keys) return 0; - h->entry.flags.virtual = 1; - if (h_is_namespace) { - /* Set the entry's principal name */ - free_Principal(h->entry.principal); - ret = copy_Principal(princ, h->entry.principal); - } + h->flags.virtual = 1; kr.len = 0; kr.val = 0; @@ -994,7 +988,7 @@ derive_keys(krb5_context context, const HDB_Ext_KeyRotation *ckr; /* Installing keys invalidates `ckr', so we copy it */ - ret = hdb_entry_get_key_rotation(context, &h->entry, &ckr); + ret = hdb_entry_get_key_rotation(context, h, &ckr); if (!ckr) return ret; if (ret == 0) @@ -1005,11 +999,11 @@ derive_keys(krb5_context context, base_keys.val = 0; base_keys.len = 0; if (ret == 0) - ret = hdb_remove_base_keys(context, &h->entry, &base_keys); + ret = _hdb_remove_base_keys(context, h, &base_keys, &kr); - /* Make sure we have h->entry.etypes */ - if (ret == 0 && !h->entry.etypes) - ret = hdb_derive_etypes(context, &h->entry, &base_keys); + /* Make sure we have h->etypes */ + if (ret == 0 && !h->etypes) + ret = hdb_derive_etypes(context, h, &base_keys); /* Keys not desired? Don't derive them! */ if (ret || !(flags & HDB_F_DECRYPT)) { @@ -1019,7 +1013,7 @@ derive_keys(krb5_context context, } /* The principal name will be used in key derivation and error messages */ - if (ret == 0 && h_is_namespace) + if (ret == 0) ret = krb5_unparse_name(context, princ, &p); /* Sanity check key rotations, determine current & last kr */ @@ -1101,10 +1095,10 @@ derive_keys(krb5_context context, /* * Derive and set in `h' its current kvno and current keys. * - * This will set h->entry.kvno as well. + * This will set h->kvno as well. * * This may set up to TWO keysets for the current key rotation period: - * - current keys (h->entry.keys and h->entry.kvno) + * - current keys (h->keys and h->kvno) * - possibly one future * OR * possibly one past keyset in hist_keys for the current_kr @@ -1137,14 +1131,14 @@ derive_keys(krb5_context context, kr.val[current_kr].epoch - 1, &kr.val[past_kr]); /* - * Impose a bound on h->entry.max_life so that [when the KDC is the caller] + * Impose a bound on h->max_life so that [when the KDC is the caller] * the KDC won't issue tickets longer lived than this. */ - if (ret == 0 && !h->entry.max_life && - (h->entry.max_life = malloc(sizeof(h->entry.max_life[0]))) == NULL) + if (ret == 0 && !h->max_life && + (h->max_life = calloc(1, sizeof(h->max_life[0]))) == NULL) ret = krb5_enomem(context); - if (ret == 0 && *h->entry.max_life > kr.val[current_kr].period >> 1) - *h->entry.max_life = kr.val[current_kr].period >> 1; + if (ret == 0 && *h->max_life > kr.val[current_kr].period >> 1) + *h->max_life = kr.val[current_kr].period >> 1; free_HDB_Ext_KeyRotation(&kr); free_HDB_Ext_KeySet(&base_keys); @@ -1153,6 +1147,10 @@ derive_keys(krb5_context context, } /* + * Pick a best kvno for the given principal at the given time. + * + * Implements the [hdb] new_service_key_delay configuration parameter. + * * In order for disparate keytab provisioning systems such as OSKT and our own * kadmin ext_keytab and httpkadmind's get-keys to coexist, we need to be able * to force keys set by the former to not become current keys until users of @@ -1163,9 +1161,9 @@ derive_keys(krb5_context context, * The context is that OSKT's krb5_keytab is very happy to change keys in a way * that requires all members of a cluster to rekey together. If one also * wishes to have cluster members that opt out of this and just fetch current, - * past, and future keys periodically, then the keys set by OSKT need to not - * come into effect until all the opt-out members have had a chance to fetch - * the new keys. + * past, and future keys periodically, then the keys set by OSKT must not come + * into effect until all the opt-out members have had a chance to fetch the new + * keys. * * The assumption is that services will fetch new keys periodically, say, every * four hours. Then one can set `[hdb] new_service_key_delay = 8h' in the @@ -1175,12 +1173,12 @@ derive_keys(krb5_context context, * Naturally, this applies only to concrete principals with concrete keys. */ static krb5_error_code -fix_keys(krb5_context context, - HDB *db, - unsigned flags, - krb5_timestamp now, - krb5uint32 kvno, - hdb_entry_ex *h) +pick_kvno(krb5_context context, + HDB *db, + unsigned flags, + krb5_timestamp now, + krb5uint32 kvno, + hdb_entry *h) { HDB_extension *ext; HDB_Ext_KeySet keys; @@ -1193,25 +1191,25 @@ fix_keys(krb5_context context, * delayed, or if there's no new-key delay configured, or we're not * fetching for use as a service principal, then we're out. */ - if (!(flags & HDB_F_DELAY_NEW_KEYS) || kvno || h->entry.flags.virtual || - h->entry.flags.virtual_keys || db->new_service_key_delay <= 0) + if (!(flags & HDB_F_DELAY_NEW_KEYS) || kvno || h->flags.virtual || + h->flags.virtual_keys || db->new_service_key_delay <= 0) return 0; /* No history -> current keyset is the only one and therefore the best */ - ext = hdb_find_extension(&h->entry, choice_HDB_extension_data_hist_keys); + ext = hdb_find_extension(h, choice_HDB_extension_data_hist_keys); if (!ext) return 0; /* Assume the current keyset is the best to start with */ - (void) hdb_entry_get_pw_change_time(&h->entry, ¤t); - if (current == 0 && h->entry.modified_by) - current = h->entry.modified_by->time; + (void) hdb_entry_get_pw_change_time(h, ¤t); + if (current == 0 && h->modified_by) + current = h->modified_by->time; if (current == 0) - current = h->entry.created_by.time; + current = h->created_by.time; /* Current keyset starts out as best */ best = current; - kvno = h->entry.kvno; + kvno = h->kvno; /* Look for a better keyset in the history */ keys = ext->data.u.hist_keys; @@ -1251,7 +1249,7 @@ fix_keys(krb5_context context, best = keys.val[i].set_time[0]; kvno = keys.val[i].kvno; } - return hdb_change_kvno(context, kvno, &h->entry); + return hdb_change_kvno(context, kvno, h); } /* @@ -1296,7 +1294,7 @@ make_namespace_princ(krb5_context context, /* First go around, need a namespace princ. Make it! */ ret = krb5_build_principal(context, namespace, strlen(realm), - realm, "WELLKNOWN", + realm, KRB5_WELLKNOWN_NAME, HDB_WK_NAMESPACE, comp0, NULL); if (ret == 0) ret = krb5_principal_set_comp_string(context, *namespace, 3, comp1); @@ -1307,6 +1305,138 @@ make_namespace_princ(krb5_context context, return ret; } +static int +is_namespace_princ_p(krb5_context context, + krb5_const_principal princ) +{ + return + krb5_principal_get_num_comp(context, princ) >= 4 + && strcmp(krb5_principal_get_comp_string(context, princ, 0), + KRB5_WELLKNOWN_NAME) == 0 + && strcmp(krb5_principal_get_comp_string(context, princ, 1), + HDB_WK_NAMESPACE) == 0; +} + +/* See call site */ +static krb5_error_code +rewrite_hostname(krb5_context context, + krb5_const_principal wanted_princ, + krb5_const_principal ns_princ, + krb5_const_principal found_ns_princ, + char **s) +{ + const char *ns_host_part, *wanted_host_part, *found_host_part; + const char *p, *r; + size_t ns_host_part_len, wanted_host_part_len; + + wanted_host_part = krb5_principal_get_comp_string(context, wanted_princ, 1); + wanted_host_part_len = strlen(wanted_host_part); + if (wanted_host_part_len > 256) { + krb5_set_error_message(context, HDB_ERR_NOENTRY, + "Aliases of host-based principals longer than " + "256 bytes not supported"); + return HDB_ERR_NOENTRY; + } + + ns_host_part = krb5_principal_get_comp_string(context, ns_princ, 3); + ns_host_part_len = strlen(ns_host_part); + + /* Find `ns_host_part' as the tail of `wanted_host_part' */ + for (r = p = strstr(wanted_host_part, ns_host_part); + r && strnlen(r, ns_host_part_len + 1) > ns_host_part_len; + p = (r = strstr(r, ns_host_part)) ? r : p) + ; + if (!p || strnlen(p, ns_host_part_len + 1) != ns_host_part_len) + return HDB_ERR_NOENTRY; /* Can't happen */ + if (p == wanted_host_part || p[-1] != '.') + return HDB_ERR_NOENTRY; + + found_host_part = + krb5_principal_get_comp_string(context, found_ns_princ, 3); + return + asprintf(s, "%.*s%s", (int)(p - wanted_host_part), wanted_host_part, + found_host_part) < 0 || + *s == NULL ? krb5_enomem(context) : 0; +} + +/* + * Fix `h->principal' to match the desired `princ' in the namespace + * `nsprinc' (which is either the same as `h->principal' or an alias + * of it). + */ +static krb5_error_code +fix_princ_name(krb5_context context, + krb5_const_principal princ, + krb5_const_principal nsprinc, + hdb_entry *h) +{ + krb5_error_code ret = 0; + char *s = NULL; + + if (!nsprinc) + return 0; + if (krb5_principal_get_num_comp(context, princ) < 2) + return HDB_ERR_NOENTRY; + + /* `nsprinc' must be a namespace principal */ + + if (krb5_principal_compare(context, nsprinc, h->principal)) { + /* + * `h' is the HDB entry for `nsprinc', and `nsprinc' is its canonical + * name. + * + * Set the entry's principal name to the desired name. The keys will + * be fixed next (upstairs, but don't forget to!). + */ + free_Principal(h->principal); + return copy_Principal(princ, h->principal); + } + + if (!is_namespace_princ_p(context, h->principal)) { + /* + * The alias is a namespace, but the canonical name is not. WAT. + * + * Well, the KDC will just issue a referral anyways, so we can leave + * `h->principal' as is... + * + * Remove all of `h's keys just in case, and leave + * `h->principal' as-is. + */ + free_Keys(&h->keys); + (void) hdb_entry_clear_password(context, h); + return hdb_clear_extension(context, h, + choice_HDB_extension_data_hist_keys); + } + + /* + * A namespace alias of a namespace entry. + * + * We'll want to rewrite the original principal accordingly. + * + * E.g., if the caller wanted host/foo.ns.test.h5l.se and we + * found WELLKNOWN/HOSTBASED-NAMESPACE/ns.test.h5l.se is an + * alias of WELLKNOWN/HOSTBASED-NAMESPACE/ns.example.org, then + * we'll want to treat host/foo.ns.test.h5l.se as an alias of + * host/foo.ns.example.org. + */ + if (krb5_principal_get_num_comp(context, h->principal) != + 2 + krb5_principal_get_num_comp(context, princ)) + ret = HDB_ERR_NOENTRY; /* Only host-based services for now */ + if (ret == 0) + ret = rewrite_hostname(context, princ, nsprinc, h->principal, &s); + if (ret == 0) { + krb5_free_principal(context, h->principal); + h->principal = NULL; + ret = krb5_make_principal(context, &h->principal, + krb5_principal_get_realm(context, princ), + krb5_principal_get_comp_string(context, + princ, 0), + s, + NULL); + } + return ret; +} + /* Wrapper around db->hdb_fetch_kvno() that implements virtual princs/keys */ static krb5_error_code fetch_it(krb5_context context, @@ -1316,10 +1446,10 @@ fetch_it(krb5_context context, krb5_timestamp t, krb5int32 etype, krb5uint32 kvno, - hdb_entry_ex *ent) + hdb_entry *ent) { krb5_const_principal tmpprinc = princ; - krb5_principal baseprinc = NULL; + krb5_principal nsprinc = NULL; krb5_error_code ret = 0; const char *comp0 = krb5_principal_get_comp_string(context, princ, 0); const char *comp1 = krb5_principal_get_comp_string(context, princ, 1); @@ -1330,8 +1460,10 @@ fetch_it(krb5_context context, char *host = NULL; int do_search = 0; + if (!db->enable_virtual_hostbased_princs) + maxdots = mindots = 0; if (db->enable_virtual_hostbased_princs && comp1 && - strcmp("krbtgt", comp0) != 0 && strcmp("WELLKNOWN", comp0) != 0) { + strcmp("krbtgt", comp0) != 0 && strcmp(KRB5_WELLKNOWN_NAME, comp0) != 0) { char *htmp; if ((host = strdup(comp1)) == NULL) @@ -1358,7 +1490,7 @@ fetch_it(krb5_context context, } tmp = host ? host : comp1; - for (ret = HDB_ERR_NOENTRY; ret == HDB_ERR_NOENTRY; tmpprinc = baseprinc) { + for (ret = HDB_ERR_NOENTRY; ret == HDB_ERR_NOENTRY; tmpprinc = nsprinc) { krb5_error_code ret2 = 0; /* @@ -1376,7 +1508,7 @@ fetch_it(krb5_context context, ret = db->hdb_fetch_kvno(context, db, tmpprinc, flags, kvno, ent); if (ret != HDB_ERR_NOENTRY || hdots == 0 || hdots < mindots || !tmp || !do_search) - break; + break; /* * Breadcrumb: @@ -1398,17 +1530,22 @@ fetch_it(krb5_context context, */ while (maxdots && hdots > maxdots && tmp) { tmp = strchr(tmp, '.'); - /* tmp != NULL because maxdots > 0 */ + /* tmp != NULL because maxdots > 0; we check to quiet linters */ + if (tmp == NULL) { + ret = HDB_ERR_NOENTRY; + goto out; + } tmp++; hdots--; } - if (baseprinc == NULL) + if (nsprinc == NULL) /* First go around, need a namespace princ. Make it! */ - ret2 = make_namespace_princ(context, db, tmpprinc, &baseprinc); - /* Update the hostname component */ + ret2 = make_namespace_princ(context, db, tmpprinc, &nsprinc); + + /* Update the hostname component of the namespace principal */ if (ret2 == 0) - ret2 = krb5_principal_set_comp_string(context, baseprinc, 3, tmp); + ret2 = krb5_principal_set_comp_string(context, nsprinc, 3, tmp); if (ret2) ret = ret2; @@ -1425,14 +1562,22 @@ fetch_it(krb5_context context, * key derivation to do, but that's decided in derive_keys(). */ if (ret == 0) { - ret = derive_keys(context, flags, princ, !!baseprinc, t, etype, kvno, - ent); + /* Fix the principal name if namespaced */ + ret = fix_princ_name(context, princ, nsprinc, ent); + + /* Derive keys if namespaced or virtual */ if (ret == 0) - ret = fix_keys(context, db, flags, t, kvno, ent); - if (ret) - hdb_free_entry(context, ent); + ret = derive_keys(context, flags, princ, !!nsprinc, t, etype, kvno, + ent); + /* Pick the best kvno for this principal at the given time */ + if (ret == 0) + ret = pick_kvno(context, db, flags, t, kvno, ent); } - krb5_free_principal(context, baseprinc); + +out: + if (ret != 0 && ret != HDB_ERR_WRONG_REALM) + hdb_free_entry(context, db, ent); + krb5_free_principal(context, nsprinc); free(host); return ret; } @@ -1468,7 +1613,7 @@ hdb_fetch_kvno(krb5_context context, krb5_timestamp t, krb5int32 etype, krb5uint32 kvno, - hdb_entry_ex *h) + hdb_entry *h) { krb5_error_code ret = HDB_ERR_NOENTRY; @@ -1485,8 +1630,8 @@ hdb_fetch_kvno(krb5_context context, * independently of principal aliases (used by Samba). */ if (ret == 0 && !(flags & HDB_F_ADMIN_DATA) && - !h->entry.flags.force_canonicalize && - !krb5_realm_compare(context, principal, h->entry.principal)) + !h->flags.force_canonicalize && + !krb5_realm_compare(context, principal, h->principal)) ret = HDB_ERR_WRONG_REALM; return ret; } diff --git a/third_party/heimdal/lib/hdb/db.c b/third_party/heimdal/lib/hdb/db.c index 6e415b95f16..5fcce7b8e8b 100644 --- a/third_party/heimdal/lib/hdb/db.c +++ b/third_party/heimdal/lib/hdb/db.c @@ -114,7 +114,7 @@ DB_unlock(krb5_context context, HDB *db) static krb5_error_code DB_seq(krb5_context context, HDB *db, - unsigned flags, hdb_entry_ex *entry, int flag) + unsigned flags, hdb_entry *entry, int flag) { DB *d = (DB*)db->hdb_db; DBT key, value; @@ -138,21 +138,21 @@ DB_seq(krb5_context context, HDB *db, data.data = value.data; data.length = value.size; memset(entry, 0, sizeof(*entry)); - if (hdb_value2entry(context, &data, &entry->entry)) + if (hdb_value2entry(context, &data, entry)) return DB_seq(context, db, flags, entry, R_NEXT); if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { - code = hdb_unseal_keys (context, db, &entry->entry); + code = hdb_unseal_keys (context, db, entry); if (code) - hdb_free_entry (context, entry); + hdb_free_entry (context, db, entry); } - if (code == 0 && entry->entry.principal == NULL) { - entry->entry.principal = malloc(sizeof(*entry->entry.principal)); - if (entry->entry.principal == NULL) { + if (code == 0 && entry->principal == NULL) { + entry->principal = malloc(sizeof(*entry->principal)); + if (entry->principal == NULL) { code = ENOMEM; krb5_set_error_message(context, code, "malloc: out of memory"); - hdb_free_entry (context, entry); + hdb_free_entry (context, db, entry); } else { - hdb_key2principal(context, &key_data, entry->entry.principal); + hdb_key2principal(context, &key_data, entry->principal); } } return code; @@ -160,14 +160,14 @@ DB_seq(krb5_context context, HDB *db, static krb5_error_code -DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { return DB_seq(context, db, flags, entry, R_FIRST); } static krb5_error_code -DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { return DB_seq(context, db, flags, entry, R_NEXT); } diff --git a/third_party/heimdal/lib/hdb/db3.c b/third_party/heimdal/lib/hdb/db3.c index 0daa25bbec4..9d0c0a97d9a 100644 --- a/third_party/heimdal/lib/hdb/db3.c +++ b/third_party/heimdal/lib/hdb/db3.c @@ -136,7 +136,7 @@ DB_unlock(krb5_context context, HDB *db) static krb5_error_code DB_seq(krb5_context context, HDB *db, - unsigned flags, hdb_entry_ex *entry, int flag) + unsigned flags, hdb_entry *entry, int flag) { DBT key, value; DBC *dbcp = db->hdb_dbc; @@ -156,21 +156,21 @@ DB_seq(krb5_context context, HDB *db, data.data = value.data; data.length = value.size; memset(entry, 0, sizeof(*entry)); - if (hdb_value2entry(context, &data, &entry->entry)) + if (hdb_value2entry(context, &data, entry)) return DB_seq(context, db, flags, entry, DB_NEXT); if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { - code = hdb_unseal_keys (context, db, &entry->entry); + code = hdb_unseal_keys (context, db, entry); if (code) - hdb_free_entry (context, entry); + hdb_free_entry (context, db, entry); } - if (entry->entry.principal == NULL) { - entry->entry.principal = malloc(sizeof(*entry->entry.principal)); - if (entry->entry.principal == NULL) { - hdb_free_entry (context, entry); + if (entry->principal == NULL) { + entry->principal = malloc(sizeof(*entry->principal)); + if (entry->principal == NULL) { + hdb_free_entry (context, db, entry); krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } else { - hdb_key2principal(context, &key_data, entry->entry.principal); + hdb_key2principal(context, &key_data, entry->principal); } } return 0; @@ -178,14 +178,14 @@ DB_seq(krb5_context context, HDB *db, static krb5_error_code -DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { return DB_seq(context, db, flags, entry, DB_FIRST); } static krb5_error_code -DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { return DB_seq(context, db, flags, entry, DB_NEXT); } diff --git a/third_party/heimdal/lib/hdb/ext.c b/third_party/heimdal/lib/hdb/ext.c index ec52d35dcba..48683ef1607 100644 --- a/third_party/heimdal/lib/hdb/ext.c +++ b/third_party/heimdal/lib/hdb/ext.c @@ -712,7 +712,7 @@ hdb_entry_add_key_rotation(krb5_context context, { krb5_error_code ret; HDB_extension new_ext; - HDB_extension *ext = 0; + HDB_extension *ext = &new_ext; KeyRotation tmp; size_t i, sz; @@ -734,8 +734,6 @@ hdb_entry_add_key_rotation(krb5_context context, ext = hdb_find_extension(entry, choice_HDB_extension_data_key_rotation); if (!ext) ext = &new_ext; - else - krs = &ext->data.u.key_rotation; } else { const KeyRotation *prev_kr = &krs->val[0]; unsigned int last_kvno = 0; diff --git a/third_party/heimdal/lib/hdb/hdb-keytab.c b/third_party/heimdal/lib/hdb/hdb-keytab.c index f3cb8fbe61d..c9b469cb1a8 100644 --- a/third_party/heimdal/lib/hdb/hdb-keytab.c +++ b/third_party/heimdal/lib/hdb/hdb-keytab.c @@ -90,14 +90,14 @@ hkt_unlock(krb5_context context, HDB *db) static krb5_error_code hkt_firstkey(krb5_context context, HDB *db, - unsigned flags, hdb_entry_ex *entry) + unsigned flags, hdb_entry *entry) { return HDB_ERR_DB_INUSE; } static krb5_error_code hkt_nextkey(krb5_context context, HDB * db, unsigned flags, - hdb_entry_ex * entry) + hdb_entry * entry) { return HDB_ERR_DB_INUSE; } @@ -119,7 +119,7 @@ hkt_open(krb5_context context, HDB * db, int flags, mode_t mode) static krb5_error_code hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, - unsigned flags, krb5_kvno kvno, hdb_entry_ex * entry) + unsigned flags, krb5_kvno kvno, hdb_entry * entry) { hdb_keytab k = (hdb_keytab)db->hdb_db; krb5_error_code ret; @@ -132,13 +132,13 @@ hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, memset(&ktentry, 0, sizeof(ktentry)); - entry->entry.flags.server = 1; - entry->entry.flags.forwardable = 1; - entry->entry.flags.renewable = 1; + entry->flags.server = 1; + entry->flags.forwardable = 1; + entry->flags.renewable = 1; /* Not recorded in the OD backend, make something up */ ret = krb5_parse_name(context, "hdb/keytab@WELL-KNOWN:KEYTAB-BACKEND", - &entry->entry.created_by.principal); + &entry->created_by.principal); if (ret) goto out; @@ -155,7 +155,7 @@ hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, goto out; } - ret = krb5_copy_principal(context, principal, &entry->entry.principal); + ret = krb5_copy_principal(context, principal, &entry->principal); if (ret) goto out; @@ -163,8 +163,8 @@ hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, out: if (ret) { - free_HDB_entry(&entry->entry); - memset(&entry->entry, 0, sizeof(entry->entry)); + free_HDB_entry(entry); + memset(entry, 0, sizeof(*entry)); } krb5_kt_free_entry(context, &ktentry); @@ -173,7 +173,7 @@ hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, static krb5_error_code hkt_store(krb5_context context, HDB * db, unsigned flags, - hdb_entry_ex * entry) + hdb_entry * entry) { return HDB_ERR_DB_INUSE; } diff --git a/third_party/heimdal/lib/hdb/hdb-ldap.c b/third_party/heimdal/lib/hdb/hdb-ldap.c index 1dbb00d3e5f..6a2876c51d7 100644 --- a/third_party/heimdal/lib/hdb/hdb-ldap.c +++ b/third_party/heimdal/lib/hdb/hdb-ldap.c @@ -47,7 +47,7 @@ static krb5_error_code LDAP_close(krb5_context context, HDB *); static krb5_error_code LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, - int flags, hdb_entry_ex * ent); + int flags, hdb_entry * ent); static const char *default_structural_object = "account"; static char *structural_object; @@ -388,14 +388,14 @@ bervalstrcmp(struct berval *v, const char *str) static krb5_error_code -LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, +LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, LDAPMessage * msg, LDAPMod *** pmods, krb5_boolean *pis_new_entry) { krb5_error_code ret; krb5_boolean is_new_entry = FALSE; char *tmp = NULL; LDAPMod **mods = NULL; - hdb_entry_ex orig; + hdb_entry orig; unsigned long oflags, nflags; int i; @@ -477,12 +477,12 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } if (is_new_entry || - krb5_principal_compare(context, ent->entry.principal, orig.entry.principal) + krb5_principal_compare(context, ent->principal, orig.principal) == FALSE) { if (is_heimdal_principal || is_heimdal_entry) { - ret = krb5_unparse_name(context, ent->entry.principal, &tmp); + ret = krb5_unparse_name(context, ent->principal, &tmp); if (ret) goto out; @@ -496,7 +496,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } if (is_account || is_samba_account) { - ret = krb5_unparse_name_short(context, ent->entry.principal, &tmp); + ret = krb5_unparse_name_short(context, ent->principal, &tmp); if (ret) goto out; ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "uid", tmp); @@ -508,15 +508,15 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } } - if (is_heimdal_entry && (ent->entry.kvno != orig.entry.kvno || is_new_entry)) { + if (is_heimdal_entry && (ent->kvno != orig.kvno || is_new_entry)) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "krb5KeyVersionNumber", - ent->entry.kvno); + ent->kvno); if (ret) goto out; } - if (is_heimdal_entry && ent->entry.extensions) { + if (is_heimdal_entry && ent->extensions) { if (!is_new_entry) { vals = ldap_get_values_len(HDB2LDAP(db), msg, "krb5ExtendedAttributes"); if (vals) { @@ -527,11 +527,11 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } } - for (i = 0; i < ent->entry.extensions->len; i++) { + for (i = 0; i < ent->extensions->len; i++) { unsigned char *buf; size_t size, sz = 0; - ASN1_MALLOC_ENCODE(HDB_extension, buf, size, &ent->entry.extensions->val[i], &sz, ret); + ASN1_MALLOC_ENCODE(HDB_extension, buf, size, &ent->extensions->val[i], &sz, ret); if (ret) goto out; if (size != sz) @@ -543,42 +543,42 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } } - if (is_heimdal_entry && ent->entry.valid_start) { - if (orig.entry.valid_end == NULL - || (*(ent->entry.valid_start) != *(orig.entry.valid_start))) { + if (is_heimdal_entry && ent->valid_start) { + if (orig.valid_end == NULL + || (*(ent->valid_start) != *(orig.valid_start))) { ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, "krb5ValidStart", - ent->entry.valid_start); + ent->valid_start); if (ret) goto out; } } - if (ent->entry.valid_end) { - if (orig.entry.valid_end == NULL || (*(ent->entry.valid_end) != *(orig.entry.valid_end))) { + if (ent->valid_end) { + if (orig.valid_end == NULL || (*(ent->valid_end) != *(orig.valid_end))) { if (is_heimdal_entry) { ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, "krb5ValidEnd", - ent->entry.valid_end); + ent->valid_end); if (ret) goto out; } if (is_samba_account) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "sambaKickoffTime", - *(ent->entry.valid_end)); + *(ent->valid_end)); if (ret) goto out; } } } - if (ent->entry.pw_end) { - if (orig.entry.pw_end == NULL || (*(ent->entry.pw_end) != *(orig.entry.pw_end))) { + if (ent->pw_end) { + if (orig.pw_end == NULL || (*(ent->pw_end) != *(orig.pw_end))) { if (is_heimdal_entry) { ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, "krb5PasswordEnd", - ent->entry.pw_end); + ent->pw_end); if (ret) goto out; } @@ -586,7 +586,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, if (is_samba_account) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "sambaPwdMustChange", - *(ent->entry.pw_end)); + *(ent->pw_end)); if (ret) goto out; } @@ -595,43 +595,43 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, #if 0 /* we we have last_pw_change */ - if (is_samba_account && ent->entry.last_pw_change) { - if (orig.entry.last_pw_change == NULL || (*(ent->entry.last_pw_change) != *(orig.entry.last_pw_change))) { + if (is_samba_account && ent->last_pw_change) { + if (orig.last_pw_change == NULL || (*(ent->last_pw_change) != *(orig.last_pw_change))) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "sambaPwdLastSet", - *(ent->entry.last_pw_change)); + *(ent->last_pw_change)); if (ret) goto out; } } #endif - if (is_heimdal_entry && ent->entry.max_life) { - if (orig.entry.max_life == NULL - || (*(ent->entry.max_life) != *(orig.entry.max_life))) { + if (is_heimdal_entry && ent->max_life) { + if (orig.max_life == NULL + || (*(ent->max_life) != *(orig.max_life))) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "krb5MaxLife", - *(ent->entry.max_life)); + *(ent->max_life)); if (ret) goto out; } } - if (is_heimdal_entry && ent->entry.max_renew) { - if (orig.entry.max_renew == NULL - || (*(ent->entry.max_renew) != *(orig.entry.max_renew))) { + if (is_heimdal_entry && ent->max_renew) { + if (orig.max_renew == NULL + || (*(ent->max_renew) != *(orig.max_renew))) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, "krb5MaxRenew", - *(ent->entry.max_renew)); + *(ent->max_renew)); if (ret) goto out; } } - oflags = HDBFlags2int(orig.entry.flags); - nflags = HDBFlags2int(ent->entry.flags); + oflags = HDBFlags2int(orig.flags); + nflags = HDBFlags2int(ent->flags); if (is_heimdal_entry && oflags != nflags) { @@ -643,7 +643,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } /* Remove keys if they exists, and then replace keys. */ - if (!is_new_entry && orig.entry.keys.len > 0) { + if (!is_new_entry && orig.keys.len > 0) { vals = ldap_get_values_len(HDB2LDAP(db), msg, "krb5Key"); if (vals) { ldap_value_free_len(vals); @@ -654,21 +654,21 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } } - for (i = 0; i < ent->entry.keys.len; i++) { + for (i = 0; i < ent->keys.len; i++) { if (is_samba_account - && ent->entry.keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { + && ent->keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { char *ntHexPassword; char *nt; time_t now = time(NULL); /* the key might have been 'sealed', but samba passwords are clear in the directory */ - ret = hdb_unseal_key(context, db, &ent->entry.keys.val[i]); + ret = hdb_unseal_key(context, db, &ent->keys.val[i]); if (ret) goto out; - nt = ent->entry.keys.val[i].key.keyvalue.data; + nt = ent->keys.val[i].key.keyvalue.data; /* store in ntPassword, not krb5key */ ret = hex_encode(nt, 16, &ntHexPassword); if (ret < 0) { @@ -701,7 +701,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, unsigned char *buf; size_t len, buf_size; - ASN1_MALLOC_ENCODE(Key, buf, buf_size, &ent->entry.keys.val[i], &len, ret); + ASN1_MALLOC_ENCODE(Key, buf, buf_size, &ent->keys.val[i], &len, ret); if (ret) goto out; if(buf_size != len) @@ -714,7 +714,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } } - if (ent->entry.etypes) { + if (ent->etypes) { int add_krb5EncryptionType = 0; /* @@ -736,15 +736,15 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, add_krb5EncryptionType = 1; if (add_krb5EncryptionType) { - for (i = 0; i < ent->entry.etypes->len; i++) { + for (i = 0; i < ent->etypes->len; i++) { if (is_samba_account && - ent->entry.keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) + ent->keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { ; } else if (is_heimdal_entry) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_ADD, "krb5EncryptionType", - ent->entry.etypes->val[i]); + ent->etypes->val[i]); if (ret) goto out; } @@ -767,7 +767,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } if (msg) - hdb_free_entry(context, &orig); + hdb_free_entry(context, db, &orig); return ret; } @@ -1005,7 +1005,7 @@ LDAP_principal2message(krb5_context context, HDB * db, */ static krb5_error_code LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, - int flags, hdb_entry_ex * ent) + int flags, hdb_entry * ent) { char *unparsed_name = NULL, *dn = NULL, *ntPasswordIN = NULL; char *samba_acct_flags = NULL; @@ -1015,18 +1015,18 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, int tmp, tmp_time, i, ret, have_arcfour = 0; memset(ent, 0, sizeof(*ent)); - ent->entry.flags = int2HDBFlags(0); + ent->flags = int2HDBFlags(0); ret = LDAP_get_string_value(db, msg, "krb5PrincipalName", &unparsed_name); if (ret == 0) { - ret = krb5_parse_name(context, unparsed_name, &ent->entry.principal); + ret = krb5_parse_name(context, unparsed_name, &ent->principal); if (ret) goto out; } else { ret = LDAP_get_string_value(db, msg, "uid", &unparsed_name); if (ret == 0) { - ret = krb5_parse_name(context, unparsed_name, &ent->entry.principal); + ret = krb5_parse_name(context, unparsed_name, &ent->principal); if (ret) goto out; } else { @@ -1042,25 +1042,25 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ret = LDAP_get_integer_value(db, msg, "krb5KeyVersionNumber", &integer); if (ret) - ent->entry.kvno = 0; + ent->kvno = 0; else - ent->entry.kvno = integer; + ent->kvno = integer; } keys = ldap_get_values_len(HDB2LDAP(db), msg, "krb5Key"); if (keys != NULL) { size_t l; - ent->entry.keys.len = ldap_count_values_len(keys); - ent->entry.keys.val = (Key *) calloc(ent->entry.keys.len, sizeof(Key)); - if (ent->entry.keys.val == NULL) { + ent->keys.len = ldap_count_values_len(keys); + ent->keys.val = (Key *) calloc(ent->keys.len, sizeof(Key)); + if (ent->keys.val == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "calloc: out of memory"); goto out; } - for (i = 0; i < ent->entry.keys.len; i++) { + for (i = 0; i < ent->keys.len; i++) { decode_Key((unsigned char *) keys[i]->bv_val, - (size_t) keys[i]->bv_len, &ent->entry.keys.val[i], &l); + (size_t) keys[i]->bv_len, &ent->keys.val[i], &l); } ber_bvecfree(keys); } else { @@ -1070,8 +1070,8 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, * be related to a general directory entry without creating * the keys. Hopefully it's OK. */ - ent->entry.keys.len = 0; - ent->entry.keys.val = NULL; + ent->keys.len = 0; + ent->keys.val = NULL; #else ret = HDB_ERR_NOENTRY; goto out; @@ -1082,47 +1082,47 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, if (extensions != NULL) { size_t l; - ent->entry.extensions = calloc(1, sizeof(*(ent->entry.extensions))); - if (ent->entry.extensions == NULL) { + ent->extensions = calloc(1, sizeof(*(ent->extensions))); + if (ent->extensions == NULL) { ret = krb5_enomem(context); goto out; } - ent->entry.extensions->len = ldap_count_values_len(extensions); - ent->entry.extensions->val = (HDB_extension *) calloc(ent->entry.extensions->len, sizeof(HDB_extension)); - if (ent->entry.extensions->val == NULL) { - ent->entry.extensions->len = 0; + ent->extensions->len = ldap_count_values_len(extensions); + ent->extensions->val = (HDB_extension *) calloc(ent->extensions->len, sizeof(HDB_extension)); + if (ent->extensions->val == NULL) { + ent->extensions->len = 0; ret = krb5_enomem(context); goto out; } - for (i = 0; i < ent->entry.extensions->len; i++) { + for (i = 0; i < ent->extensions->len; i++) { ret = decode_HDB_extension((unsigned char *) extensions[i]->bv_val, - (size_t) extensions[i]->bv_len, &ent->entry.extensions->val[i], &l); + (size_t) extensions[i]->bv_len, &ent->extensions->val[i], &l); if (ret) krb5_set_error_message(context, ret, "decode_HDB_extension failed"); } ber_bvecfree(extensions); } else { - ent->entry.extensions = NULL; + ent->extensions = NULL; } vals = ldap_get_values_len(HDB2LDAP(db), msg, "krb5EncryptionType"); if (vals != NULL) { - ent->entry.etypes = malloc(sizeof(*(ent->entry.etypes))); - if (ent->entry.etypes == NULL) { + ent->etypes = malloc(sizeof(*(ent->etypes))); + if (ent->etypes == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret,"malloc: out of memory"); goto out; } - ent->entry.etypes->len = ldap_count_values_len(vals); - ent->entry.etypes->val = calloc(ent->entry.etypes->len, - sizeof(ent->entry.etypes->val[0])); - if (ent->entry.etypes->val == NULL) { + ent->etypes->len = ldap_count_values_len(vals); + ent->etypes->val = calloc(ent->etypes->len, + sizeof(ent->etypes->val[0])); + if (ent->etypes->val == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); - ent->entry.etypes->len = 0; + ent->etypes->len = 0; goto out; } - for (i = 0; i < ent->entry.etypes->len; i++) { + for (i = 0; i < ent->etypes->len; i++) { char *buf; buf = malloc(vals[i]->bv_len + 1); @@ -1133,14 +1133,14 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, } memcpy(buf, vals[i]->bv_val, vals[i]->bv_len); buf[vals[i]->bv_len] = '\0'; - ent->entry.etypes->val[i] = atoi(buf); + ent->etypes->val[i] = atoi(buf); free(buf); } ldap_value_free_len(vals); } - for (i = 0; i < ent->entry.keys.len; i++) { - if (ent->entry.keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { + for (i = 0; i < ent->keys.len; i++) { + if (ent->keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { have_arcfour = 1; break; } @@ -1152,146 +1152,151 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, unsigned *etypes; Key *ks; - ks = realloc(ent->entry.keys.val, - (ent->entry.keys.len + 1) * - sizeof(ent->entry.keys.val[0])); + ks = realloc(ent->keys.val, + (ent->keys.len + 1) * + sizeof(ent->keys.val[0])); if (ks == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } - ent->entry.keys.val = ks; - memset(&ent->entry.keys.val[ent->entry.keys.len], 0, sizeof(Key)); - ent->entry.keys.val[ent->entry.keys.len].key.keytype = ETYPE_ARCFOUR_HMAC_MD5; - ret = krb5_data_alloc (&ent->entry.keys.val[ent->entry.keys.len].key.keyvalue, 16); + ent->keys.val = ks; + memset(&ent->keys.val[ent->keys.len], 0, sizeof(Key)); + ent->keys.val[ent->keys.len].key.keytype = ETYPE_ARCFOUR_HMAC_MD5; + ret = krb5_data_alloc (&ent->keys.val[ent->keys.len].key.keyvalue, 16); if (ret) { krb5_set_error_message(context, ret, "malloc: out of memory"); ret = ENOMEM; goto out; } ret = hex_decode(ntPasswordIN, - ent->entry.keys.val[ent->entry.keys.len].key.keyvalue.data, 16); - ent->entry.keys.len++; - - if (ent->entry.etypes == NULL) { - ent->entry.etypes = malloc(sizeof(*(ent->entry.etypes))); - if (ent->entry.etypes == NULL) { + ent->keys.val[ent->keys.len].key.keyvalue.data, 16); + ent->keys.len++; + if (ret == -1) { + krb5_set_error_message(context, ret = EINVAL, + "invalid hex encoding of password"); + goto out; + } + + if (ent->etypes == NULL) { + ent->etypes = malloc(sizeof(*(ent->etypes))); + if (ent->etypes == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } - ent->entry.etypes->val = NULL; - ent->entry.etypes->len = 0; + ent->etypes->val = NULL; + ent->etypes->len = 0; } - for (i = 0; i < ent->entry.etypes->len; i++) - if (ent->entry.etypes->val[i] == ETYPE_ARCFOUR_HMAC_MD5) + for (i = 0; i < ent->etypes->len; i++) + if (ent->etypes->val[i] == ETYPE_ARCFOUR_HMAC_MD5) break; /* If there is no ARCFOUR enctype, add one */ - if (i == ent->entry.etypes->len) { - etypes = realloc(ent->entry.etypes->val, - (ent->entry.etypes->len + 1) * - sizeof(ent->entry.etypes->val[0])); + if (i == ent->etypes->len) { + etypes = realloc(ent->etypes->val, + (ent->etypes->len + 1) * + sizeof(ent->etypes->val[0])); if (etypes == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } - ent->entry.etypes->val = etypes; - ent->entry.etypes->val[ent->entry.etypes->len] = + ent->etypes->val = etypes; + ent->etypes->val[ent->etypes->len] = ETYPE_ARCFOUR_HMAC_MD5; - ent->entry.etypes->len++; + ent->etypes->len++; } } ret = LDAP_get_generalized_time_value(db, msg, "createTimestamp", - &ent->entry.created_by.time); + &ent->created_by.time); if (ret) - ent->entry.created_by.time = time(NULL); + ent->created_by.time = time(NULL); - ent->entry.created_by.principal = NULL; + ent->created_by.principal = NULL; if (flags & HDB_F_ADMIN_DATA) { ret = LDAP_get_string_value(db, msg, "creatorsName", &dn); if (ret == 0) { - LDAP_dn2principal(context, db, dn, &ent->entry.created_by.principal); + LDAP_dn2principal(context, db, dn, &ent->created_by.principal); free(dn); } - ent->entry.modified_by = calloc(1, sizeof(*ent->entry.modified_by)); - if (ent->entry.modified_by == NULL) { + ent->modified_by = calloc(1, sizeof(*ent->modified_by)); + if (ent->modified_by == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_generalized_time_value(db, msg, "modifyTimestamp", - &ent->entry.modified_by->time); + &ent->modified_by->time); if (ret == 0) { ret = LDAP_get_string_value(db, msg, "modifiersName", &dn); if (ret == 0) { - LDAP_dn2principal(context, db, dn, &ent->entry.modified_by->principal); + LDAP_dn2principal(context, db, dn, &ent->modified_by->principal); free(dn); } else { - free(ent->entry.modified_by); - ent->entry.modified_by = NULL; + free(ent->modified_by); + ent->modified_by = NULL; } } } - ent->entry.valid_start = malloc(sizeof(*ent->entry.valid_start)); - if (ent->entry.valid_start == NULL) { + ent->valid_start = malloc(sizeof(*ent->valid_start)); + if (ent->valid_start == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_generalized_time_value(db, msg, "krb5ValidStart", - ent->entry.valid_start); + ent->valid_start); if (ret) { /* OPTIONAL */ - free(ent->entry.valid_start); - ent->entry.valid_start = NULL; + free(ent->valid_start); + ent->valid_start = NULL; } - ent->entry.valid_end = malloc(sizeof(*ent->entry.valid_end)); - if (ent->entry.valid_end == NULL) { + ent->valid_end = malloc(sizeof(*ent->valid_end)); + if (ent->valid_end == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_generalized_time_value(db, msg, "krb5ValidEnd", - ent->entry.valid_end); + ent->valid_end); if (ret) { /* OPTIONAL */ - free(ent->entry.valid_end); - ent->entry.valid_end = NULL; + free(ent->valid_end); + ent->valid_end = NULL; } ret = LDAP_get_integer_value(db, msg, "sambaKickoffTime", &tmp_time); if (ret == 0) { - if (ent->entry.valid_end == NULL) { - ent->entry.valid_end = malloc(sizeof(*ent->entry.valid_end)); - if (ent->entry.valid_end == NULL) { + if (ent->valid_end == NULL) { + ent->valid_end = malloc(sizeof(*ent->valid_end)); + if (ent->valid_end == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } } - *ent->entry.valid_end = tmp_time; + *ent->valid_end = tmp_time; } - ent->entry.pw_end = malloc(sizeof(*ent->entry.pw_end)); - if (ent->entry.pw_end == NULL) { + ent->pw_end = malloc(sizeof(*ent->pw_end)); + if (ent->pw_end == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_generalized_time_value(db, msg, "krb5PasswordEnd", - ent->entry.pw_end); + ent->pw_end); if (ret) { /* OPTIONAL */ - free(ent->entry.pw_end); - ent->entry.pw_end = NULL; + free(ent->pw_end); + ent->pw_end = NULL; } ret = LDAP_get_integer_value(db, msg, "sambaPwdLastSet", &tmp_time); @@ -1305,76 +1310,76 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, NULL); if (delta) { - if (ent->entry.pw_end == NULL) { - ent->entry.pw_end = malloc(sizeof(*ent->entry.pw_end)); - if (ent->entry.pw_end == NULL) { + if (ent->pw_end == NULL) { + ent->pw_end = malloc(sizeof(*ent->pw_end)); + if (ent->pw_end == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } } - *ent->entry.pw_end = tmp_time + delta; + *ent->pw_end = tmp_time + delta; } } ret = LDAP_get_integer_value(db, msg, "sambaPwdMustChange", &tmp_time); if (ret == 0) { - if (ent->entry.pw_end == NULL) { - ent->entry.pw_end = malloc(sizeof(*ent->entry.pw_end)); - if (ent->entry.pw_end == NULL) { + if (ent->pw_end == NULL) { + ent->pw_end = malloc(sizeof(*ent->pw_end)); + if (ent->pw_end == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } } - *ent->entry.pw_end = tmp_time; + *ent->pw_end = tmp_time; } /* OPTIONAL */ ret = LDAP_get_integer_value(db, msg, "sambaPwdLastSet", &tmp_time); if (ret == 0) - hdb_entry_set_pw_change_time(context, &ent->entry, tmp_time); + hdb_entry_set_pw_change_time(context, ent, tmp_time); { int max_life; - ent->entry.max_life = malloc(sizeof(*ent->entry.max_life)); - if (ent->entry.max_life == NULL) { + ent->max_life = malloc(sizeof(*ent->max_life)); + if (ent->max_life == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_integer_value(db, msg, "krb5MaxLife", &max_life); if (ret) { - free(ent->entry.max_life); - ent->entry.max_life = NULL; + free(ent->max_life); + ent->max_life = NULL; } else - *ent->entry.max_life = max_life; + *ent->max_life = max_life; } { int max_renew; - ent->entry.max_renew = malloc(sizeof(*ent->entry.max_renew)); - if (ent->entry.max_renew == NULL) { + ent->max_renew = malloc(sizeof(*ent->max_renew)); + if (ent->max_renew == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_integer_value(db, msg, "krb5MaxRenew", &max_renew); if (ret) { - free(ent->entry.max_renew); - ent->entry.max_renew = NULL; + free(ent->max_renew); + ent->max_renew = NULL; } else - *ent->entry.max_renew = max_renew; + *ent->max_renew = max_renew; } ret = LDAP_get_integer_value(db, msg, "krb5KDCFlags", &tmp); if (ret) tmp = 0; - ent->entry.flags = int2HDBFlags(tmp); + ent->flags = int2HDBFlags(tmp); /* Try and find Samba flags to put into the mix */ ret = LDAP_get_string_value(db, msg, "sambaAcctFlags", &samba_acct_flags); @@ -1406,7 +1411,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, /* Allow forwarding */ if (samba_forwardable) - ent->entry.flags.forwardable = TRUE; + ent->flags.forwardable = TRUE; for (i=0; i < flags_len; i++) { switch (samba_acct_flags[i]) { @@ -1418,36 +1423,36 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, /* how to handle no password in kerberos? */ break; case 'D': - ent->entry.flags.invalid = TRUE; + ent->flags.invalid = TRUE; break; case 'H': break; case 'T': /* temp duplicate */ - ent->entry.flags.invalid = TRUE; + ent->flags.invalid = TRUE; break; case 'U': - ent->entry.flags.client = TRUE; + ent->flags.client = TRUE; break; case 'M': break; case 'W': case 'S': - ent->entry.flags.server = TRUE; - ent->entry.flags.client = TRUE; + ent->flags.server = TRUE; + ent->flags.client = TRUE; break; case 'L': - ent->entry.flags.invalid = TRUE; + ent->flags.invalid = TRUE; break; case 'X': - if (ent->entry.pw_end) { - free(ent->entry.pw_end); - ent->entry.pw_end = NULL; + if (ent->pw_end) { + free(ent->pw_end); + ent->pw_end = NULL; } break; case 'I': - ent->entry.flags.server = TRUE; - ent->entry.flags.client = TRUE; + ent->flags.server = TRUE; + ent->flags.client = TRUE; break; } } @@ -1462,7 +1467,7 @@ out: free(ntPasswordIN); if (ret) - hdb_free_entry(context, ent); + hdb_free_entry(context, db, ent); return ret; } @@ -1491,7 +1496,7 @@ LDAP_unlock(krb5_context context, HDB * db) } static krb5_error_code -LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry_ex * entry) +LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry * entry) { int msgid, rc, parserc; krb5_error_code ret; @@ -1545,9 +1550,9 @@ LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry_ex * entry) if (ret == 0) { if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { - ret = hdb_unseal_keys(context, db, &entry->entry); + ret = hdb_unseal_keys(context, db, entry); if (ret) - hdb_free_entry(context, entry); + hdb_free_entry(context, db, entry); } } @@ -1556,7 +1561,7 @@ LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry_ex * entry) static krb5_error_code LDAP_firstkey(krb5_context context, HDB *db, unsigned flags, - hdb_entry_ex *entry) + hdb_entry *entry) { krb5_error_code ret; int msgid; @@ -1584,7 +1589,7 @@ LDAP_firstkey(krb5_context context, HDB *db, unsigned flags, static krb5_error_code LDAP_nextkey(krb5_context context, HDB * db, unsigned flags, - hdb_entry_ex * entry) + hdb_entry * entry) { return LDAP_seq(context, db, flags, entry); } @@ -1687,7 +1692,7 @@ LDAP_open(krb5_context context, HDB * db, int flags, mode_t mode) static krb5_error_code LDAP_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, - unsigned flags, krb5_kvno kvno, hdb_entry_ex * entry) + unsigned flags, krb5_kvno kvno, hdb_entry * entry) { LDAPMessage *msg, *e; krb5_error_code ret; @@ -1705,9 +1710,9 @@ LDAP_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, ret = LDAP_message2entry(context, db, e, flags, entry); if (ret == 0) { if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { - ret = hdb_unseal_keys(context, db, &entry->entry); + ret = hdb_unseal_keys(context, db, entry); if (ret) - hdb_free_entry(context, entry); + hdb_free_entry(context, db, entry); } } @@ -1720,7 +1725,7 @@ LDAP_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, #if 0 static krb5_error_code LDAP_fetch(krb5_context context, HDB * db, krb5_const_principal principal, - unsigned flags, hdb_entry_ex * entry) + unsigned flags, hdb_entry * entry) { return LDAP_fetch_kvno(context, db, principal, flags & (~HDB_F_KVNO_SPECIFIED), 0, entry); @@ -1729,7 +1734,7 @@ LDAP_fetch(krb5_context context, HDB * db, krb5_const_principal principal, static krb5_error_code LDAP_store(krb5_context context, HDB * db, unsigned flags, - hdb_entry_ex * entry) + hdb_entry * entry) { LDAPMod **mods = NULL; krb5_error_code ret; @@ -1742,17 +1747,17 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, if ((flags & HDB_F_PRECHECK)) return 0; /* we can't guarantee whether we'll be able to perform it */ - ret = LDAP_principal2message(context, db, entry->entry.principal, &msg); + ret = LDAP_principal2message(context, db, entry->principal, &msg); if (ret == 0) e = ldap_first_entry(HDB2LDAP(db), msg); - ret = krb5_unparse_name(context, entry->entry.principal, &name); + ret = krb5_unparse_name(context, entry->principal, &name); if (ret) { free(name); return ret; } - ret = hdb_seal_keys(context, db, &entry->entry); + ret = hdb_seal_keys(context, db, entry); if (ret) goto out; diff --git a/third_party/heimdal/lib/hdb/hdb-mdb.c b/third_party/heimdal/lib/hdb/hdb-mdb.c index cabda277f4e..6aa5201eb8a 100644 --- a/third_party/heimdal/lib/hdb/hdb-mdb.c +++ b/third_party/heimdal/lib/hdb/hdb-mdb.c @@ -383,7 +383,7 @@ DB_unlock(krb5_context context, HDB *db) static krb5_error_code DB_seq(krb5_context context, HDB *db, - unsigned flags, hdb_entry_ex *entry, int flag) + unsigned flags, hdb_entry *entry, int flag) { mdb_info *mi = db->hdb_db; MDB_val key, value; @@ -406,21 +406,21 @@ DB_seq(krb5_context context, HDB *db, data.data = value.mv_data; data.length = value.mv_size; memset(entry, 0, sizeof(*entry)); - if (hdb_value2entry(context, &data, &entry->entry)) + if (hdb_value2entry(context, &data, entry)) return DB_seq(context, db, flags, entry, MDB_NEXT); if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { - code = hdb_unseal_keys (context, db, &entry->entry); + code = hdb_unseal_keys (context, db, entry); if (code) - hdb_free_entry (context, entry); + hdb_free_entry (context, db, entry); } - if (entry->entry.principal == NULL) { - entry->entry.principal = malloc(sizeof(*entry->entry.principal)); - if (entry->entry.principal == NULL) { - hdb_free_entry (context, entry); + if (entry->principal == NULL) { + entry->principal = malloc(sizeof(*entry->principal)); + if (entry->principal == NULL) { + hdb_free_entry (context, db, entry); krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } else { - hdb_key2principal(context, &key_data, entry->entry.principal); + hdb_key2principal(context, &key_data, entry->principal); } } return 0; @@ -428,7 +428,7 @@ DB_seq(krb5_context context, HDB *db, static krb5_error_code -DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { krb5_error_code ret = 0; mdb_info *mi = db->hdb_db; @@ -462,7 +462,7 @@ DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) static krb5_error_code -DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { return DB_seq(context, db, flags, entry, MDB_NEXT); } diff --git a/third_party/heimdal/lib/hdb/hdb-mitdb.c b/third_party/heimdal/lib/hdb/hdb-mitdb.c index 1ae013157c2..7436f39edbb 100644 --- a/third_party/heimdal/lib/hdb/hdb-mitdb.c +++ b/third_party/heimdal/lib/hdb/hdb-mitdb.c @@ -555,7 +555,7 @@ _hdb_mdb_value2entry(krb5_context context, krb5_data *data, goto out; } CHECK(ret = krb5_parse_name(context, p, &modby)); - ret = hdb_set_last_modified_by(context, entry, modby, u32); + CHECK(ret = hdb_set_last_modified_by(context, entry, modby, u32)); krb5_free_principal(context, modby); free(p); break; @@ -765,7 +765,7 @@ mdb_unlock(krb5_context context, HDB *db) static krb5_error_code mdb_seq(krb5_context context, HDB *db, - unsigned flags, hdb_entry_ex *entry, int flag) + unsigned flags, hdb_entry *entry, int flag) { DB *d = (DB*)db->hdb_db; DBT key, value; @@ -796,13 +796,13 @@ mdb_seq(krb5_context context, HDB *db, data.length = value.size; memset(entry, 0, sizeof(*entry)); - if (_hdb_mdb_value2entry(context, &data, 0, &entry->entry)) + if (_hdb_mdb_value2entry(context, &data, 0, entry)) return mdb_seq(context, db, flags, entry, R_NEXT); if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { - code = hdb_unseal_keys (context, db, &entry->entry); + code = hdb_unseal_keys (context, db, entry); if (code) - hdb_free_entry (context, entry); + hdb_free_entry (context, db, entry); } return code; @@ -810,14 +810,14 @@ mdb_seq(krb5_context context, HDB *db, static krb5_error_code -mdb_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +mdb_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { return mdb_seq(context, db, flags, entry, R_FIRST); } static krb5_error_code -mdb_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +mdb_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { return mdb_seq(context, db, flags, entry, R_NEXT); } @@ -941,7 +941,7 @@ mdb__del(krb5_context context, HDB *db, krb5_data key) static krb5_error_code mdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, - unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry) + unsigned flags, krb5_kvno kvno, hdb_entry *entry) { krb5_data key, value; krb5_error_code ret; @@ -953,15 +953,15 @@ mdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, krb5_data_free(&key); if(ret) return ret; - ret = _hdb_mdb_value2entry(context, &value, kvno, &entry->entry); + ret = _hdb_mdb_value2entry(context, &value, kvno, entry); krb5_data_free(&value); if (ret) return ret; if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { - ret = hdb_unseal_keys (context, db, &entry->entry); + ret = hdb_unseal_keys (context, db, entry); if (ret) { - hdb_free_entry(context, entry); + hdb_free_entry(context, db, entry); return ret; } } @@ -970,7 +970,7 @@ mdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, } static krb5_error_code -mdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +mdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { krb5_error_code ret; krb5_storage *sp = NULL; @@ -985,7 +985,7 @@ mdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) return 0; if ((flags & HDB_F_PRECHECK)) { - ret = mdb_principal2key(context, entry->entry.principal, &key); + ret = mdb_principal2key(context, entry->principal, &key); if (ret) return ret; ret = db->hdb__get(context, db, key, &value); krb5_data_free(&key); @@ -999,9 +999,9 @@ mdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) sp = krb5_storage_emem(); if (!sp) return ENOMEM; ret = _hdb_set_master_key_usage(context, db, 0); /* MIT KDB uses KU 0 */ - ret = hdb_seal_keys(context, db, &entry->entry); + ret = hdb_seal_keys(context, db, entry); if (ret) return ret; - ret = entry2mit_string_int(context, sp, &entry->entry); + ret = entry2mit_string_int(context, sp, entry); if (ret) goto out; sz = krb5_storage_write(sp, "\n", 2); /* NUL-terminate */ ret = ENOMEM; @@ -1016,7 +1016,7 @@ mdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) if (ret) goto out; ret = krb5_storage_to_data(spent, &kdb_ent); if (ret) goto out; - ret = mdb_principal2key(context, entry->entry.principal, &key); + ret = mdb_principal2key(context, entry->principal, &key); if (ret) goto out; ret = mdb__put(context, db, 1, key, kdb_ent); @@ -1253,17 +1253,16 @@ getdata(char **p, unsigned char *buf, size_t len, const char *what) } static int -getint(char **p, const char *what) +getint(char **p, const char *what, int *val) { - int val; char *q = nexttoken(p, 0, what); if (!q) { warnx("Failed to find a signed integer (%s) in dump", what); - return -1; + return 1; } - if (sscanf(q, "%d", &val) != 1) - return -1; - return val; + if (sscanf(q, "%d", val) != 1) + return 1; + return 0; } static unsigned int @@ -1327,7 +1326,7 @@ _hdb_mit_dump2mitdb_entry(krb5_context context, char *line, krb5_storage *sp) "'policy', nor 'princ'"); return -1; } - if (getint(&p, "constant '38'") != 38) { + if (getint(&p, "constant '38'", &tmp) || tmp != 38) { warnx("Dump entry does not start with '38<TAB>'"); return EINVAL; } @@ -1343,7 +1342,7 @@ _hdb_mit_dump2mitdb_entry(krb5_context context, char *line, krb5_storage *sp) } num_tl_data = getuint(&p, "number of TL data"); num_key_data = getuint(&p, "number of key data"); - getint(&p, "5th field, length of 'extra data'"); + (void) getint(&p, "5th field, length of 'extra data'", &tmp); princ = nexttoken(&p, (int)princ_len, "principal name"); if (princ == NULL) { warnx("Failed to read principal name (expected length %llu)", @@ -1355,38 +1354,31 @@ _hdb_mit_dump2mitdb_entry(krb5_context context, char *line, krb5_storage *sp) ret = krb5_store_uint32(sp, attributes); if (ret) return ret; - tmp = getint(&p, "max life"); - CHECK_UINT(tmp); + if (getint(&p, "max life", &tmp)) return EINVAL; ret = krb5_store_uint32(sp, tmp); if (ret) return ret; - tmp = getint(&p, "max renewable life"); - CHECK_UINT(tmp); + if (getint(&p, "max renewable life", &tmp)) return EINVAL; ret = krb5_store_uint32(sp, tmp); if (ret) return ret; - tmp = getint(&p, "expiration"); - CHECK_UINT(tmp); + if (getint(&p, "expiration", &tmp)) return EINVAL; ret = krb5_store_uint32(sp, tmp); if (ret) return ret; - tmp = getint(&p, "pw expiration"); - CHECK_UINT(tmp); + if (getint(&p, "pw expiration", &tmp)) return EINVAL; ret = krb5_store_uint32(sp, tmp); if (ret) return ret; - tmp = getint(&p, "last auth"); - CHECK_UINT(tmp); + if (getint(&p, "last auth", &tmp)) return EINVAL; ret = krb5_store_uint32(sp, tmp); if (ret) return ret; - tmp = getint(&p, "last failed auth"); - CHECK_UINT(tmp); + if (getint(&p, "last failed auth", &tmp)) return EINVAL; ret = krb5_store_uint32(sp, tmp); if (ret) return ret; - tmp = getint(&p,"fail auth count"); - CHECK_UINT(tmp); + if (getint(&p,"fail auth count", &tmp)) return EINVAL; ret = krb5_store_uint32(sp, tmp); if (ret) return ret; @@ -1414,8 +1406,9 @@ _hdb_mit_dump2mitdb_entry(krb5_context context, char *line, krb5_storage *sp) int tl_type, tl_length; unsigned char *buf; - tl_type = getint(&p, "TL data type"); - tl_length = getint(&p, "data length"); + if (getint(&p, "TL data type", &tl_type) || + getint(&p, "data length", &tl_length)) + return EINVAL; if (asprintf(&reading_what, "TL data type %d (length %d)", tl_type, tl_length) < 0) @@ -1435,8 +1428,10 @@ _hdb_mit_dump2mitdb_entry(krb5_context context, char *line, krb5_storage *sp) if (tl_length) { buf = malloc(tl_length); if (!buf) return ENOMEM; - if (getdata(&p, buf, tl_length, reading_what) != tl_length) + if (getdata(&p, buf, tl_length, reading_what) != tl_length) { + free(buf); return EINVAL; + } sz = krb5_storage_write(sp, buf, tl_length); free(buf); if (sz != tl_length) return ENOMEM; @@ -1454,23 +1449,23 @@ _hdb_mit_dump2mitdb_entry(krb5_context context, char *line, krb5_storage *sp) int keylen; size_t k; - key_versions = getint(&p, "key data 'version'"); + if (getint(&p, "key data 'version'", &key_versions)) return EINVAL; CHECK_UINT16(key_versions); ret = krb5_store_int16(sp, key_versions); if (ret) return ret; - kvno = getint(&p, "kvno"); + if (getint(&p, "kvno", &kvno)) return EINVAL; CHECK_UINT16(kvno); ret = krb5_store_int16(sp, kvno); if (ret) return ret; for (k = 0; k < key_versions; k++) { - keytype = getint(&p, "enctype"); + if (getint(&p, "enctype", &keytype)) return EINVAL; CHECK_UINT16(keytype); ret = krb5_store_int16(sp, keytype); if (ret) return ret; - keylen = getint(&p, "encrypted key length"); + if (getint(&p, "encrypted key length", &keylen)) return EINVAL; CHECK_UINT16(keylen); ret = krb5_store_int16(sp, keylen); if (ret) return ret; @@ -1478,8 +1473,10 @@ _hdb_mit_dump2mitdb_entry(krb5_context context, char *line, krb5_storage *sp) if (keylen) { buf = malloc(keylen); if (!buf) return ENOMEM; - if (getdata(&p, buf, keylen, "key (or salt) data") != keylen) + if (getdata(&p, buf, keylen, "key (or salt) data") != keylen) { + free(buf); return EINVAL; + } sz = krb5_storage_write(sp, buf, keylen); free(buf); if (sz != keylen) return ENOMEM; diff --git a/third_party/heimdal/lib/hdb/hdb-sqlite.c b/third_party/heimdal/lib/hdb/hdb-sqlite.c index 3cab9178965..4bb2f8e8553 100644 --- a/third_party/heimdal/lib/hdb/hdb-sqlite.c +++ b/third_party/heimdal/lib/hdb/hdb-sqlite.c @@ -495,7 +495,7 @@ hdb_sqlite_make_database(krb5_context context, HDB *db, const char *filename) */ static krb5_error_code hdb_sqlite_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, - unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry) + unsigned flags, krb5_kvno kvno, hdb_entry *entry) { int sqlite_error; krb5_error_code ret; @@ -541,14 +541,14 @@ hdb_sqlite_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal princi value.length = sqlite3_column_bytes(fetch, 0); value.data = (void *) sqlite3_column_blob(fetch, 0); - ret = hdb_value2entry(context, &value, &entry->entry); + ret = hdb_value2entry(context, &value, entry); if(ret) goto out; if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { - ret = hdb_unseal_keys(context, db, &entry->entry); + ret = hdb_unseal_keys(context, db, entry); if(ret) { - hdb_free_entry(context, entry); + hdb_free_entry(context, db, entry); goto out; } } @@ -600,7 +600,7 @@ hdb_sqlite_step_once(krb5_context context, HDB *db, sqlite3_stmt *statement) */ static krb5_error_code hdb_sqlite_store(krb5_context context, HDB *db, unsigned flags, - hdb_entry_ex *entry) + hdb_entry *entry) { int ret; int i; @@ -624,17 +624,17 @@ hdb_sqlite_store(krb5_context context, HDB *db, unsigned flags, goto rollback; } - ret = hdb_seal_keys(context, db, &entry->entry); + ret = hdb_seal_keys(context, db, entry); if(ret) { goto rollback; } - ret = hdb_entry2value(context, &entry->entry, &value); + ret = hdb_entry2value(context, entry, &value); if(ret) { goto rollback; } - ret = bind_principal(context, entry->entry.principal, get_ids, 1); + ret = bind_principal(context, entry->principal, get_ids, 1); if (ret) goto rollback; @@ -656,7 +656,7 @@ hdb_sqlite_store(krb5_context context, HDB *db, unsigned flags, goto rollback; } - ret = bind_principal(context, entry->entry.principal, hsdb->add_principal, 1); + ret = bind_principal(context, entry->principal, hsdb->add_principal, 1); if (ret) goto rollback; @@ -684,8 +684,10 @@ hdb_sqlite_store(krb5_context context, HDB *db, unsigned flags, } else if(ret == SQLITE_ROW) { /* Found a principal */ - if(! (flags & HDB_F_REPLACE)) /* Not allowed to replace it */ + if(!(flags & HDB_F_REPLACE)) { + ret = HDB_ERR_EXISTS; goto rollback; + } entry_id = sqlite3_column_int64(get_ids, 1); @@ -711,7 +713,7 @@ hdb_sqlite_store(krb5_context context, HDB *db, unsigned flags, goto rollback; } - ret = hdb_entry_get_aliases(&entry->entry, &aliases); + ret = hdb_entry_get_aliases(entry, &aliases); if(ret || aliases == NULL) goto commit; @@ -862,7 +864,7 @@ hdb_sqlite_unlock(krb5_context context, HDB *db) */ static krb5_error_code hdb_sqlite_nextkey(krb5_context context, HDB *db, unsigned flags, - hdb_entry_ex *entry) + hdb_entry *entry) { krb5_error_code ret = 0; int sqlite_error; @@ -876,7 +878,7 @@ hdb_sqlite_nextkey(krb5_context context, HDB *db, unsigned flags, value.length = sqlite3_column_bytes(hsdb->get_all_entries, 0); value.data = (void *) sqlite3_column_blob(hsdb->get_all_entries, 0); memset(entry, 0, sizeof(*entry)); - ret = hdb_value2entry(context, &value, &entry->entry); + ret = hdb_value2entry(context, &value, entry); } else if(sqlite_error == SQLITE_DONE) { /* No more entries */ @@ -900,7 +902,7 @@ hdb_sqlite_nextkey(krb5_context context, HDB *db, unsigned flags, */ static krb5_error_code hdb_sqlite_firstkey(krb5_context context, HDB *db, unsigned flags, - hdb_entry_ex *entry) + hdb_entry *entry) { hdb_sqlite_db *hsdb = (hdb_sqlite_db *) db->hdb_db; krb5_error_code ret; @@ -950,11 +952,12 @@ hdb_sqlite_remove(krb5_context context, HDB *db, sqlite3_stmt *get_ids = hsdb->get_ids; sqlite3_stmt *rm = hsdb->remove; - bind_principal(context, principal, rm, 1); + ret = bind_principal(context, principal, rm, 1); - ret = hdb_sqlite_exec_stmt(context, hsdb, - "BEGIN IMMEDIATE TRANSACTION", - HDB_ERR_UK_SERROR); + if (ret == 0) + ret = hdb_sqlite_exec_stmt(context, hsdb, + "BEGIN IMMEDIATE TRANSACTION", + HDB_ERR_UK_SERROR); if (ret != SQLITE_OK) { ret = HDB_ERR_UK_SERROR; (void) hdb_sqlite_exec_stmt(context, hsdb, "ROLLBACK", 0); diff --git a/third_party/heimdal/lib/hdb/hdb.asn1 b/third_party/heimdal/lib/hdb/hdb.asn1 index f6490783a6c..9eb96be73d0 100644 --- a/third_party/heimdal/lib/hdb/hdb.asn1 +++ b/third_party/heimdal/lib/hdb/hdb.asn1 @@ -4,7 +4,7 @@ BEGIN IMPORTS EncryptionKey, KerberosTime, Principal FROM krb5; -HDB_DB_FORMAT INTEGER ::= 2 -- format of database, +hdb_db_format INTEGER ::= 2 -- format of database, -- update when making changes -- these must have the same value as the pa-* counterparts diff --git a/third_party/heimdal/lib/hdb/hdb.c b/third_party/heimdal/lib/hdb/hdb.c index 3978048ad17..56c403842e6 100644 --- a/third_party/heimdal/lib/hdb/hdb.c +++ b/third_party/heimdal/lib/hdb/hdb.c @@ -232,38 +232,25 @@ hdb_remove_keys(krb5_context context, * @param context Context * @param e The HDB entry * @param ks A pointer to a variable of type HDB_Ext_KeySet + * @param ckr A pointer to stable (copied) HDB_Ext_KeyRotation * * @return Zero on success, an error code otherwise. */ krb5_error_code -hdb_remove_base_keys(krb5_context context, - hdb_entry *e, - HDB_Ext_KeySet *base_keys) +_hdb_remove_base_keys(krb5_context context, + hdb_entry *e, + HDB_Ext_KeySet *base_keys, + const HDB_Ext_KeyRotation *ckr) { - krb5_error_code ret; - const HDB_Ext_KeyRotation *ckr; - HDB_Ext_KeyRotation kr; + krb5_error_code ret = 0; size_t i, k; - ret = hdb_entry_get_key_rotation(context, e, &ckr); - if (!ckr) - return 0; - - if (ret == 0) { - /* - * Changing the entry's extensions invalidates extensions obtained - * before the change. - */ - ret = copy_HDB_Ext_KeyRotation(ckr, &kr); - ckr = NULL; - } base_keys->len = 0; - if (ret == 0 && - (base_keys->val = calloc(kr.len, sizeof(base_keys->val[0]))) == NULL) + if ((base_keys->val = calloc(ckr->len, sizeof(base_keys->val[0]))) == NULL) ret = krb5_enomem(context); - for (k = i = 0; ret == 0 && i < kr.len; i++) { - const KeyRotation *krp = &kr.val[i]; + for (k = i = 0; ret == 0 && i < ckr->len; i++) { + const KeyRotation *krp = &ckr->val[i]; /* * WARNING: O(N * M) where M is number of keysets and N is the number @@ -284,7 +271,6 @@ hdb_remove_base_keys(krb5_context context, base_keys->len = k; else free_HDB_Ext_KeySet(base_keys); - free_HDB_Ext_KeyRotation(&kr); return 0; } @@ -312,12 +298,12 @@ hdb_install_keyset(krb5_context context, (ret = hdb_add_current_keys_to_history(context, e))) return ret; free_Keys(&e->keys); + e->kvno = ks->kvno; if (ret == 0) ret = copy_Keys(&ks->keys, &e->keys); - e->kvno = ks->kvno; - if (ks->set_time) - return hdb_entry_set_pw_change_time(context, e, *ks->set_time); - return 0; + if (ret == 0 && ks->set_time) + ret = hdb_entry_set_pw_change_time(context, e, *ks->set_time); + return ret; } return hdb_add_history_keyset(context, e, ks); } @@ -359,9 +345,10 @@ hdb_enctype2key(krb5_context context, void hdb_free_key(Key *key) { - memset(key->key.keyvalue.data, - 0, - key->key.keyvalue.length); + memset_s(key->key.keyvalue.data, + key->key.keyvalue.length, + 0, + key->key.keyvalue.length); free_Key(key); free(key); } @@ -396,20 +383,23 @@ hdb_unlock(int fd) } void -hdb_free_entry(krb5_context context, hdb_entry_ex *ent) +hdb_free_entry(krb5_context context, HDB *db, hdb_entry *ent) { Key *k; size_t i; - if (ent->free_entry) - (*ent->free_entry)(context, ent); + if (db && db->hdb_free_entry_context) + db->hdb_free_entry_context(context, db, ent); - for(i = 0; i < ent->entry.keys.len; i++) { - k = &ent->entry.keys.val[i]; + for(i = 0; i < ent->keys.len; i++) { + k = &ent->keys.val[i]; - memset (k->key.keyvalue.data, 0, k->key.keyvalue.length); + memset_s(k->key.keyvalue.data, + k->key.keyvalue.length, + 0, + k->key.keyvalue.length); } - free_HDB_entry(&ent->entry); + free_HDB_entry(ent); } krb5_error_code @@ -420,13 +410,13 @@ hdb_foreach(krb5_context context, void *data) { krb5_error_code ret; - hdb_entry_ex entry; + hdb_entry entry; ret = db->hdb_firstkey(context, db, flags, &entry); if (ret == 0) krb5_clear_error_message(context); while(ret == 0){ ret = (*func)(context, db, &entry, data); - hdb_free_entry(context, &entry); + hdb_free_entry(context, db, &entry); if(ret == 0) ret = db->hdb_nextkey(context, db, flags, &entry); } @@ -661,22 +651,22 @@ hdb_list_builtin(krb5_context context, char **list) krb5_error_code _hdb_keytab2hdb_entry(krb5_context context, const krb5_keytab_entry *ktentry, - hdb_entry_ex *entry) + hdb_entry *entry) { - entry->entry.kvno = ktentry->vno; - entry->entry.created_by.time = ktentry->timestamp; + entry->kvno = ktentry->vno; + entry->created_by.time = ktentry->timestamp; - entry->entry.keys.val = calloc(1, sizeof(entry->entry.keys.val[0])); - if (entry->entry.keys.val == NULL) + entry->keys.val = calloc(1, sizeof(entry->keys.val[0])); + if (entry->keys.val == NULL) return ENOMEM; - entry->entry.keys.len = 1; + entry->keys.len = 1; - entry->entry.keys.val[0].mkvno = NULL; - entry->entry.keys.val[0].salt = NULL; + entry->keys.val[0].mkvno = NULL; + entry->keys.val[0].salt = NULL; return krb5_copy_keyblock_contents(context, &ktentry->keyblock, - &entry->entry.keys.val[0].key); + &entry->keys.val[0].key); } static krb5_error_code @@ -789,7 +779,7 @@ hdb_create(krb5_context context, HDB **db, const char *filename) return ret; } for (cb_ctx.h = methods; cb_ctx.h->prefix != NULL; cb_ctx.h++) { - if (cb_ctx.h->is_file_based && !pathish) + if (cb_ctx.h->is_file_based) continue; if (!cb_ctx.h->can_taste) continue; @@ -805,9 +795,11 @@ hdb_create(krb5_context context, HDB **db, const char *filename) (*db)->hdb_destroy(context, *db); *db = NULL; } + if (cb_ctx.h->prefix == NULL) + cb_ctx.h = NULL; } #ifdef HDB_DEFAULT_DB_TYPE - if (cb_ctx.h == NULL || cb_ctx.h->prefix == NULL) { + if (cb_ctx.h == NULL) { /* * If still we've not picked a backend, use a build configuration time * default. @@ -815,12 +807,14 @@ hdb_create(krb5_context context, HDB **db, const char *filename) for (cb_ctx.h = methods; cb_ctx.h->prefix != NULL; cb_ctx.h++) if (strcmp(cb_ctx.h->prefix, HDB_DEFAULT_DB_TYPE) == 0) break; + if (cb_ctx.h->prefix == NULL) + cb_ctx.h = NULL; } #endif - if (cb_ctx.h == NULL || cb_ctx.h->prefix == NULL) + if (cb_ctx.h == NULL) /* Last resort default */ cb_ctx.h = &default_dbmethod; - if (cb_ctx.h == NULL || cb_ctx.h->prefix == NULL) { + if (cb_ctx.h->prefix == NULL) { krb5_set_error_message(context, ENOTSUP, "Could not determine default DB backend for %s", filename); diff --git a/third_party/heimdal/lib/hdb/hdb.h b/third_party/heimdal/lib/hdb/hdb.h index 97ca70c0a7e..0f2c92151e5 100644 --- a/third_party/heimdal/lib/hdb/hdb.h +++ b/third_party/heimdal/lib/hdb/hdb.h @@ -42,8 +42,12 @@ #include <hdb_err.h> +#include <heimbase-svc.h> #include <heim_asn1.h> #include <hdb_asn1.h> + +#define HDB_DB_FORMAT hdb_db_format + typedef HDB_keyset hdb_keyset; typedef HDB_entry hdb_entry; typedef HDB_entry_alias hdb_entry_alias; @@ -53,25 +57,26 @@ struct hdb_dbinfo; enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; /* flags for various functions */ -#define HDB_F_DECRYPT 1 /* decrypt keys */ -#define HDB_F_REPLACE 2 /* replace entry */ -#define HDB_F_GET_CLIENT 4 /* fetch client */ -#define HDB_F_GET_SERVER 8 /* fetch server */ -#define HDB_F_GET_KRBTGT 16 /* fetch krbtgt */ -#define HDB_F_GET_ANY 28 /* fetch any of client,server,krbtgt */ -#define HDB_F_CANON 32 /* want canonicalition */ -#define HDB_F_ADMIN_DATA 64 /* want data that kdc don't use */ -#define HDB_F_KVNO_SPECIFIED 128 /* we want a particular KVNO */ -#define HDB_F_CURRENT_KVNO 256 /* we want the current KVNO */ -#define HDB_F_LIVE_CLNT_KVNOS 512 /* we want all live keys for pre-auth */ -#define HDB_F_LIVE_SVC_KVNOS 1024 /* we want all live keys for tix */ -#define HDB_F_ALL_KVNOS 2048 /* we want all the keys, live or not */ -#define HDB_F_FOR_AS_REQ 4096 /* fetch is for a AS REQ */ -#define HDB_F_FOR_TGS_REQ 8192 /* fetch is for a TGS REQ */ -#define HDB_F_PRECHECK 16384 /* check that the operation would succeed */ -#define HDB_F_DELAY_NEW_KEYS 32768 /* apply [hdb] new_service_key_delay */ -#define HDB_F_SYNTHETIC_OK 65536 /* synthetic principal for PKINIT or GSS preauth OK */ -#define HDB_F_GET_FAST_COOKIE 131072 /* fetch the FX-COOKIE key (not a normal principal) */ +#define HDB_F_DECRYPT 0x00001 /* decrypt keys */ +#define HDB_F_REPLACE 0x00002 /* replace entry */ +#define HDB_F_GET_CLIENT 0x00004 /* fetch client */ +#define HDB_F_GET_SERVER 0x00008 /* fetch server */ +#define HDB_F_GET_KRBTGT 0x00010 /* fetch krbtgt */ +#define HDB_F_GET_ANY ( HDB_F_GET_CLIENT | \ + HDB_F_GET_SERVER | \ + HDB_F_GET_KRBTGT ) /* fetch any of client,server,krbtgt */ +#define HDB_F_CANON 0x00020 /* want canonicalition */ +#define HDB_F_ADMIN_DATA 0x00040 /* want data that kdc don't use */ +#define HDB_F_KVNO_SPECIFIED 0x00080 /* we want a particular KVNO */ +#define HDB_F_LIVE_CLNT_KVNOS 0x00200 /* we want all live keys for pre-auth */ +#define HDB_F_LIVE_SVC_KVNOS 0x00400 /* we want all live keys for tix */ +#define HDB_F_ALL_KVNOS 0x00800 /* we want all the keys, live or not */ +#define HDB_F_FOR_AS_REQ 0x01000 /* fetch is for a AS REQ */ +#define HDB_F_FOR_TGS_REQ 0x02000 /* fetch is for a TGS REQ */ +#define HDB_F_PRECHECK 0x04000 /* check that the operation would succeed */ +#define HDB_F_DELAY_NEW_KEYS 0x08000 /* apply [hdb] new_service_key_delay */ +#define HDB_F_SYNTHETIC_OK 0x10000 /* synthetic principal for PKINIT or GSS preauth OK */ +#define HDB_F_GET_FAST_COOKIE 0x20000 /* fetch the FX-COOKIE key (not a normal principal) */ /* hdb_capability_flags */ #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1 @@ -79,78 +84,15 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; #define HDB_CAP_F_PASSWORD_UPDATE_KEYS 4 #define HDB_CAP_F_SHARED_DIRECTORY 8 -/* auth status values */ - -/* - * Un-initialised value, not permitted, used to indicate that a value - * wasn't set for the benifit of logic in the caller, must not be - * passed to hdb_auth_status() - */ - -#define HDB_AUTHSTATUS_INVALID 0 +#define heim_pcontext krb5_context +#define heim_pconfig void * -/* - * A ticket was issued after authorization was successfully completed - * (eg flags on the entry and expiry times were checked) - */ -#define HDB_AUTHSTATUS_AUTHORIZATION_SUCCESS 1 +typedef struct hdb_request_desc { + HEIM_SVC_REQUEST_DESC_COMMON_ELEMENTS; +} *hdb_request_t; -/* - * The user supplied the wrong password to a password-based - * authentication mechanism (eg ENC-TS, ENC-CHAL) - * - * The HDB backend might increment a bad password count. - */ -#define HDB_AUTHSTATUS_WRONG_PASSWORD 2 - -/* - * The user supplied a correct password to a password-based - * authentication mechanism (eg ENC-TS, ENC-CHAL) - * - * The HDB backend might reset a bad password count. - */ -#define HDB_AUTHSTATUS_CORRECT_PASSWORD 3 - -/* - * Attempted authenticaton with an unknown user - */ -#define HDB_AUTHSTATUS_CLIENT_UNKNOWN 4 - -/* - * Attempted authenticaton with an known user that is already locked - * out. - */ -#define HDB_AUTHSTATUS_CLIENT_LOCKED_OUT 5 - -/* - * Successful authentication with a pre-authentication mechanism - */ -#define HDB_AUTHSTATUS_GENERIC_SUCCESS 6 - -/* - * Failed authentication with a pre-authentication mechanism - */ -#define HDB_AUTHSTATUS_GENERIC_FAILURE 7 - -/* - * Successful pre-authentication with PKINIT (smart card login etc) - */ -#define HDB_AUTHSTATUS_PKINIT_SUCCESS 8 - -/* - * Failed pre-authentication with PKINIT (smart card login etc) - */ -#define HDB_AUTHSTATUS_PKINIT_FAILURE 9 - -/* - * Successful pre-authentication with GSS pre-authentication - */ -#define HDB_AUTHSTATUS_GSS_SUCCESS 10 - -/* - * Failed pre-authentication with GSS pre-authentication - */ -#define HDB_AUTHSTATUS_GSS_FAILURE 11 +#undef heim_pcontext +#undef heim_pconfig /* key usage for master key */ #define HDB_KU_MKEY 0x484442 @@ -164,20 +106,6 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; typedef struct hdb_master_key_data *hdb_master_key; /** - * hdb_entry_ex is a wrapper structure around the hdb_entry structure - * that allows backends to keep a pointer to the backing store, ie in - * ->hdb_fetch_kvno(), so that we the kadmin/kpasswd backend gets around to - * ->hdb_store(), the backend doesn't need to lookup the entry again. - */ - -typedef struct hdb_entry_ex { - void *ctx; - hdb_entry entry; - void (*free_entry)(krb5_context, struct hdb_entry_ex *); -} hdb_entry_ex; - - -/** * HDB backend function pointer structure * * The HDB structure is what the KDC and kadmind framework uses to @@ -226,9 +154,9 @@ typedef struct HDB { */ krb5_error_code (*hdb_close)(krb5_context, struct HDB*); /** - * Free an entry after use. + * Free backend-specific entry context. */ - void (*hdb_free)(krb5_context, struct HDB*, hdb_entry_ex*); + void (*hdb_free_entry_context)(krb5_context, struct HDB*, hdb_entry*); /** * Fetch an entry from the backend * @@ -238,12 +166,12 @@ typedef struct HDB { */ krb5_error_code (*hdb_fetch_kvno)(krb5_context, struct HDB*, krb5_const_principal, unsigned, krb5_kvno, - hdb_entry_ex*); + hdb_entry*); /** * Store an entry to database */ krb5_error_code (*hdb_store)(krb5_context, struct HDB*, - unsigned, hdb_entry_ex*); + unsigned, hdb_entry*); /** * Remove an entry from the database. */ @@ -253,12 +181,12 @@ typedef struct HDB { * As part of iteration, fetch one entry */ krb5_error_code (*hdb_firstkey)(krb5_context, struct HDB*, - unsigned, hdb_entry_ex*); + unsigned, hdb_entry*); /** * As part of iteration, fetch next entry */ krb5_error_code (*hdb_nextkey)(krb5_context, struct HDB*, - unsigned, hdb_entry_ex*); + unsigned, hdb_entry*); /** * Lock database * @@ -337,40 +265,35 @@ typedef struct HDB { * The backend needs to call _kadm5_set_keys() and perform password * quality checks. */ - krb5_error_code (*hdb_password)(krb5_context, struct HDB*, hdb_entry_ex*, const char *, int); + krb5_error_code (*hdb_password)(krb5_context, struct HDB*, hdb_entry*, const char *, int); /** - * Auth feedback + * Authentication auditing. Note that this function is called by + * both the AS and TGS, but currently only the AS sets the auth + * event type. This may change in a future version. * - * This is a feedback call that allows backends that provides - * lockout functionality to register failure and/or successes. + * Event details are available by querying the request using + * heim_audit_getkv(HDB_REQUEST_KV_...). * * In case the entry is locked out, the backend should set the * hdb_entry.flags.locked-out flag. */ - krb5_error_code (*hdb_auth_status)(krb5_context, - struct HDB *, - hdb_entry_ex *, - const struct timeval *start_time, - const struct sockaddr *from_addr, - const char *original_client_name, - int auth_type, - const char *auth_details, - const char *pa_type); + krb5_error_code (*hdb_audit)(krb5_context, struct HDB *, hdb_entry *, hdb_request_t); + /** * Check if delegation is allowed. */ - krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal); + krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry *, krb5_const_principal); /** * Check if this name is an alias for the supplied client for PKINIT userPrinicpalName logins */ - krb5_error_code (*hdb_check_pkinit_ms_upn_match)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal); + krb5_error_code (*hdb_check_pkinit_ms_upn_match)(krb5_context, struct HDB *, hdb_entry *, krb5_const_principal); /** * Check if s4u2self is allowed from this client to this server or the SPN is a valid SPN of this client (for user2user) */ - krb5_error_code (*hdb_check_client_matches_target_service)(krb5_context, struct HDB *, hdb_entry_ex *, hdb_entry_ex *); + krb5_error_code (*hdb_check_client_matches_target_service)(krb5_context, struct HDB *, hdb_entry *, hdb_entry *); /** * Enable/disable synchronous updates @@ -405,7 +328,7 @@ struct hdb_print_entry_arg { }; typedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*, - hdb_entry_ex*, void*); + hdb_entry*, void*); extern krb5_kt_ops hdb_kt_ops; extern krb5_kt_ops hdb_get_kt_ops; diff --git a/third_party/heimdal/lib/hdb/hdb.opt b/third_party/heimdal/lib/hdb/hdb.opt new file mode 100644 index 00000000000..626f8c7b07a --- /dev/null +++ b/third_party/heimdal/lib/hdb/hdb.opt @@ -0,0 +1,5 @@ +--sequence=HDB-extensions +--sequence=HDB-Ext-KeyRotation +--sequence=HDB-Ext-KeySet +--sequence=Keys +--decorate=HDB_entry:void:context?::: diff --git a/third_party/heimdal/lib/hdb/keys.c b/third_party/heimdal/lib/hdb/keys.c index ae0b067f79b..457e5daf7a7 100644 --- a/third_party/heimdal/lib/hdb/keys.c +++ b/third_party/heimdal/lib/hdb/keys.c @@ -305,7 +305,7 @@ hdb_add_history_keyset(krb5_context context, HDB_Ext_KeySet *hist_keys; HDB_extension ext; HDB_extension *extp; - krb5_error_code ret; + krb5_error_code ret = 0; memset(&ext, 0, sizeof (ext)); diff --git a/third_party/heimdal/lib/hdb/keytab.c b/third_party/heimdal/lib/hdb/keytab.c index 83cc851d91f..b1aa0207c97 100644 --- a/third_party/heimdal/lib/hdb/keytab.c +++ b/third_party/heimdal/lib/hdb/keytab.c @@ -42,7 +42,7 @@ struct hdb_data { struct hdb_cursor { HDB *db; - hdb_entry_ex hdb_entry; + hdb_entry hdb_entry; int first, next; int key_idx; }; @@ -160,8 +160,11 @@ find_db (krb5_context context, } hdb_free_dbinfo(context, &head); if (*dbname == NULL && - (*dbname = strdup(hdb_default_db(context))) == NULL) + (*dbname = strdup(hdb_default_db(context))) == NULL) { + free(*mkey); + *mkey = NULL; return krb5_enomem(context); + } return 0; } @@ -178,7 +181,7 @@ hdb_get_entry(krb5_context context, krb5_enctype enctype, krb5_keytab_entry *entry) { - hdb_entry_ex ent; + hdb_entry ent; krb5_error_code ret; struct hdb_data *d = id->data; const char *dbname = d->dbname; @@ -187,6 +190,9 @@ hdb_get_entry(krb5_context context, HDB *db; size_t i; + if (!principal) + return KRB5_KT_NOTFOUND; + memset(&ent, 0, sizeof(ent)); if (dbname == NULL) { @@ -223,27 +229,27 @@ hdb_get_entry(krb5_context context, }else if(ret) goto out; - if(kvno && (krb5_kvno)ent.entry.kvno != kvno) { - hdb_free_entry(context, &ent); + if(kvno && (krb5_kvno)ent.kvno != kvno) { + hdb_free_entry(context, db, &ent); ret = KRB5_KT_NOTFOUND; goto out; } if(enctype == 0) - if(ent.entry.keys.len > 0) - enctype = ent.entry.keys.val[0].key.keytype; + if(ent.keys.len > 0) + enctype = ent.keys.val[0].key.keytype; ret = KRB5_KT_NOTFOUND; - for(i = 0; i < ent.entry.keys.len; i++) { - if(ent.entry.keys.val[i].key.keytype == enctype) { + for(i = 0; i < ent.keys.len; i++) { + if(ent.keys.val[i].key.keytype == enctype) { krb5_copy_principal(context, principal, &entry->principal); - entry->vno = ent.entry.kvno; + entry->vno = ent.kvno; krb5_copy_keyblock_contents(context, - &ent.entry.keys.val[i].key, + &ent.keys.val[i].key, &entry->keyblock); ret = 0; break; } } - hdb_free_entry(context, &ent); + hdb_free_entry(context, db, &ent); out: (*db->hdb_close)(context, db); (*db->hdb_destroy)(context, db); @@ -333,8 +339,8 @@ hdb_next_entry(krb5_context context, else if (ret) return ret; - if (c->hdb_entry.entry.keys.len == 0) - hdb_free_entry(context, &c->hdb_entry); + if (c->hdb_entry.keys.len == 0) + hdb_free_entry(context, c->db, &c->hdb_entry); else c->next = FALSE; } @@ -350,8 +356,8 @@ hdb_next_entry(krb5_context context, return ret; /* If no keys on this entry, try again */ - if (c->hdb_entry.entry.keys.len == 0) - hdb_free_entry(context, &c->hdb_entry); + if (c->hdb_entry.keys.len == 0) + hdb_free_entry(context, c->db, &c->hdb_entry); else c->next = FALSE; } @@ -362,14 +368,14 @@ hdb_next_entry(krb5_context context, */ ret = krb5_copy_principal(context, - c->hdb_entry.entry.principal, + c->hdb_entry.principal, &entry->principal); if (ret) return ret; - entry->vno = c->hdb_entry.entry.kvno; + entry->vno = c->hdb_entry.kvno; ret = krb5_copy_keyblock_contents(context, - &c->hdb_entry.entry.keys.val[c->key_idx].key, + &c->hdb_entry.keys.val[c->key_idx].key, &entry->keyblock); if (ret) { krb5_free_principal(context, entry->principal); @@ -383,8 +389,8 @@ hdb_next_entry(krb5_context context, * next entry */ - if ((size_t)c->key_idx == c->hdb_entry.entry.keys.len) { - hdb_free_entry(context, &c->hdb_entry); + if ((size_t)c->key_idx == c->hdb_entry.keys.len) { + hdb_free_entry(context, c->db, &c->hdb_entry); c->next = TRUE; c->key_idx = 0; } @@ -401,7 +407,7 @@ hdb_end_seq_get(krb5_context context, struct hdb_cursor *c = cursor->data; if (!c->next) - hdb_free_entry(context, &c->hdb_entry); + hdb_free_entry(context, c->db, &c->hdb_entry); (c->db->hdb_close)(context, c->db); (c->db->hdb_destroy)(context, c->db); diff --git a/third_party/heimdal/lib/hdb/libhdb-exports.def b/third_party/heimdal/lib/hdb/libhdb-exports.def index a124f93f645..72a7fb7aaad 100644 --- a/third_party/heimdal/lib/hdb/libhdb-exports.def +++ b/third_party/heimdal/lib/hdb/libhdb-exports.def @@ -69,7 +69,6 @@ EXPORTS hdb_prune_keys hdb_prune_keys_kvno hdb_read_master_key - hdb_remove_base_keys hdb_remove_keys hdb_replace_extension hdb_seal_key diff --git a/third_party/heimdal/lib/hdb/ndbm.c b/third_party/heimdal/lib/hdb/ndbm.c index 4e3a340fe55..52c52c890dc 100644 --- a/third_party/heimdal/lib/hdb/ndbm.c +++ b/third_party/heimdal/lib/hdb/ndbm.c @@ -76,7 +76,7 @@ NDBM_unlock(krb5_context context, HDB *db) static krb5_error_code NDBM_seq(krb5_context context, HDB *db, - unsigned flags, hdb_entry_ex *entry, int first) + unsigned flags, hdb_entry *entry, int first) { struct ndbm_db *d = (struct ndbm_db *)db->hdb_db; @@ -99,21 +99,21 @@ NDBM_seq(krb5_context context, HDB *db, data.data = value.dptr; data.length = value.dsize; memset(entry, 0, sizeof(*entry)); - if(hdb_value2entry(context, &data, &entry->entry)) + if(hdb_value2entry(context, &data, entry)) return NDBM_seq(context, db, flags, entry, 0); if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { - ret = hdb_unseal_keys (context, db, &entry->entry); + ret = hdb_unseal_keys (context, db, entry); if (ret) - hdb_free_entry (context, entry); + hdb_free_entry (context, db, entry); } - if (ret == 0 && entry->entry.principal == NULL) { - entry->entry.principal = malloc (sizeof(*entry->entry.principal)); - if (entry->entry.principal == NULL) { - hdb_free_entry (context, entry); + if (ret == 0 && entry->principal == NULL) { + entry->principal = malloc (sizeof(*entry->principal)); + if (entry->principal == NULL) { + hdb_free_entry (context, db, entry); ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); } else { - hdb_key2principal (context, &key_data, entry->entry.principal); + hdb_key2principal (context, &key_data, entry->principal); } } return ret; @@ -121,14 +121,14 @@ NDBM_seq(krb5_context context, HDB *db, static krb5_error_code -NDBM_firstkey(krb5_context context, HDB *db,unsigned flags,hdb_entry_ex *entry) +NDBM_firstkey(krb5_context context, HDB *db,unsigned flags,hdb_entry *entry) { return NDBM_seq(context, db, flags, entry, 1); } static krb5_error_code -NDBM_nextkey(krb5_context context, HDB *db, unsigned flags,hdb_entry_ex *entry) +NDBM_nextkey(krb5_context context, HDB *db, unsigned flags,hdb_entry *entry) { return NDBM_seq(context, db, flags, entry, 0); } @@ -140,8 +140,7 @@ open_lock_file(krb5_context context, const char *db_name, int *fd) int ret = 0; /* lock old and new databases */ - asprintf(&lock_file, "%s.lock", db_name); - if(lock_file == NULL) { + if (asprintf(&lock_file, "%s.lock", db_name) == -1) { krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -161,7 +160,8 @@ static krb5_error_code NDBM_rename(krb5_context context, HDB *db, const char *new_name) { int ret; - char *old_dir, *old_pag, *new_dir, *new_pag; + char *old_dir = NULL, *old_pag = NULL; + char *new_dir = NULL, *new_pag = NULL; int old_lock_fd, new_lock_fd; /* lock old and new databases */ @@ -190,10 +190,26 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) return ret; } - asprintf(&old_dir, "%s.dir", db->hdb_name); - asprintf(&old_pag, "%s.pag", db->hdb_name); - asprintf(&new_dir, "%s.dir", new_name); - asprintf(&new_pag, "%s.pag", new_name); + if (asprintf(&old_dir, "%s.dir", db->hdb_name) == -1) { + old_dir = NULL; + ret = ENOMEM; + goto out; + } + if (asprintf(&old_pag, "%s.pag", db->hdb_name) == -1) { + old_pag = NULL; + ret = ENOMEM; + goto out; + } + if (asprintf(&new_dir, "%s.dir", new_name) == -1) { + new_dir = NULL; + ret = ENOMEM; + goto out; + } + if (asprintf(&new_pag, "%s.pag", new_name) == -1) { + new_pag = NULL; + ret = ENOMEM; + goto out; + } ret = rename(old_dir, new_dir) || rename(old_pag, new_pag); if (ret) { @@ -203,6 +219,7 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) krb5_set_error_message(context, ret, "rename: %s", strerror(ret)); } + out: free(old_dir); free(old_pag); free(new_dir); diff --git a/third_party/heimdal/lib/hdb/print.c b/third_party/heimdal/lib/hdb/print.c index 0d1e2855217..7f253588189 100644 --- a/third_party/heimdal/lib/hdb/print.c +++ b/third_party/heimdal/lib/hdb/print.c @@ -453,7 +453,8 @@ entry2mit_string_int(krb5_context context, krb5_storage *sp, hdb_entry *ent) unsigned char *ptr; ptr = (unsigned char *)&last_pw_chg; - val = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); + val = ((unsigned long)ptr[3] << 24) | (ptr[2] << 16) + | (ptr[1] << 8) | ptr[0]; d.data = &val; d.length = sizeof (last_pw_chg); sz = append_string(context, sp, "\t%u\t%u\t", @@ -474,12 +475,16 @@ entry2mit_string_int(krb5_context context, krb5_storage *sp, hdb_entry *ent) d.data = &val; d.length = sizeof (ent->modified_by->time); ret = krb5_unparse_name(context, ent->modified_by->principal, &modby_p); - if (ret) return ret; + if (ret) + return ret; plen = strlen(modby_p); sz = append_string(context, sp, "\t%u\t%u\t", mit_KRB5_TL_MOD_PRINC, d.length + plen + 1 /* NULL counted */); - if (sz == -1) return ENOMEM; + if (sz == -1) { + free(modby_p); + return ENOMEM; + } sz = append_hex(context, sp, 1, 1, &d); if (sz == -1) { free(modby_p); @@ -489,7 +494,8 @@ entry2mit_string_int(krb5_context context, krb5_storage *sp, hdb_entry *ent) d.length = plen + 1; sz = append_hex(context, sp, 1, 1, &d); free(modby_p); - if (sz == -1) return ENOMEM; + if (sz == -1) + return ENOMEM; } /* * Dump keys (remembering to not include any with kvno higher than @@ -556,7 +562,7 @@ hdb_entry2string(krb5_context context, hdb_entry *ent, char **str) /* print a hdb_entry to (FILE*)data; suitable for hdb_foreach */ krb5_error_code -hdb_print_entry(krb5_context context, HDB *db, hdb_entry_ex *entry, +hdb_print_entry(krb5_context context, HDB *db, hdb_entry *entry, void *data) { struct hdb_print_entry_arg *parg = data; @@ -572,10 +578,10 @@ hdb_print_entry(krb5_context context, HDB *db, hdb_entry_ex *entry, switch (parg->fmt) { case HDB_DUMP_HEIMDAL: - ret = entry2string_int(context, sp, &entry->entry); + ret = entry2string_int(context, sp, entry); break; case HDB_DUMP_MIT: - ret = entry2mit_string_int(context, sp, &entry->entry); + ret = entry2mit_string_int(context, sp, entry); break; default: heim_abort("Only two dump formats supported: Heimdal and MIT"); diff --git a/third_party/heimdal/lib/hdb/test_concurrency.c b/third_party/heimdal/lib/hdb/test_concurrency.c index 9c95e6390f4..35c01f59f59 100644 --- a/third_party/heimdal/lib/hdb/test_concurrency.c +++ b/third_party/heimdal/lib/hdb/test_concurrency.c @@ -70,7 +70,7 @@ threaded_reader(void *d) krb5_error_code ret; krb5_context context; struct tsync *s = d; - hdb_entry_ex entr; + hdb_entry entr; HDB *dbr = NULL; printf("Reader thread opening HDB\n"); @@ -101,7 +101,7 @@ threaded_reader(void *d) //(void) unlink(s->fname); krb5_err(context, 1, ret, "Could not iterate HDB %s", s->hdb_name); } - free_HDB_entry(&entr.entry); + free_HDB_entry(&entr); /* Tell the writer to go ahead and write */ printf("Reader thread iterated one entry; telling writer to write more\n"); @@ -124,7 +124,7 @@ threaded_reader(void *d) "Could not iterate while writing to HDB %s", s->hdb_name); } printf("Reader thread iterated another entry\n"); - free_HDB_entry(&entr.entry); + free_HDB_entry(&entr); if ((ret = dbr->hdb_nextkey(context, dbr, 0, &entr)) == 0) { //(void) unlink(s->fname); krb5_warn(context, ret, @@ -154,7 +154,7 @@ forked_reader(struct tsync *s) { krb5_error_code ret; krb5_context context; - hdb_entry_ex entr; + hdb_entry entr; ssize_t bytes; char b[1]; HDB *dbr = NULL; @@ -172,6 +172,8 @@ forked_reader(struct tsync *s) while ((bytes = read(s->reader_go_pipe[0], b, sizeof(b))) == -1 && errno == EINTR) ; + if (bytes == -1) + err(1, "Could not read from reader-go pipe (error)"); /* Open a new HDB handle to read */ if ((ret = hdb_create(context, &dbr, s->hdb_name))) { @@ -188,13 +190,15 @@ forked_reader(struct tsync *s) krb5_err(context, 1, ret, "Could not iterate HDB %s", s->hdb_name); } printf("Reader process iterated one entry\n"); - free_HDB_entry(&entr.entry); + free_HDB_entry(&entr); /* Tell the writer to go ahead and write */ printf("Reader process iterated one entry; telling writer to write more\n"); while ((bytes = write(s->writer_go_pipe[1], "", sizeof(""))) == -1 && errno == EINTR) ; + if (bytes == -1) + err(1, "Could not write to writer-go pipe (error)"); /* Wait for the writer to have written one more entry to the HDB */ @@ -213,13 +217,13 @@ forked_reader(struct tsync *s) krb5_err(context, 1, ret, "Could not iterate while writing to HDB %s", s->hdb_name); } - free_HDB_entry(&entr.entry); + free_HDB_entry(&entr); printf("Reader process iterated another entry\n"); if ((ret = dbr->hdb_nextkey(context, dbr, 0, &entr)) == 0) { //(void) unlink(s->fname); krb5_warn(context, ret, "HDB %s sees writes committed since starting iteration (%s)", - s->hdb_name, entr.entry.principal->name.name_string.val[0]); + s->hdb_name, entr.principal->name.name_string.val[0]); } else if (ret != HDB_ERR_NOENTRY) { //(void) unlink(s->fname); krb5_err(context, 1, ret, @@ -231,6 +235,8 @@ forked_reader(struct tsync *s) while ((bytes = write(s->writer_go_pipe[1], "", sizeof(""))) == -1 && errno == EINTR) ; + if (bytes == -1) + err(1, "Could not write to writer-go pipe (error)"); dbr->hdb_close(context, dbr); dbr->hdb_destroy(context, dbr); @@ -242,27 +248,27 @@ forked_reader(struct tsync *s) } static krb5_error_code -make_entry(krb5_context context, hdb_entry_ex *entry, const char *name) +make_entry(krb5_context context, hdb_entry *entry, const char *name) { krb5_error_code ret; memset(entry, 0, sizeof(*entry)); - entry->entry.kvno = 2; - entry->entry.keys.len = 0; - entry->entry.keys.val = NULL; - entry->entry.created_by.time = time(NULL); - entry->entry.modified_by = NULL; - entry->entry.valid_start = NULL; - entry->entry.valid_end = NULL; - entry->entry.max_life = NULL; - entry->entry.max_renew = NULL; - entry->entry.etypes = NULL; - entry->entry.generation = NULL; - entry->entry.extensions = NULL; - if ((ret = krb5_make_principal(context, &entry->entry.principal, + entry->kvno = 2; + entry->keys.len = 0; + entry->keys.val = NULL; + entry->created_by.time = time(NULL); + entry->modified_by = NULL; + entry->valid_start = NULL; + entry->valid_end = NULL; + entry->max_life = NULL; + entry->max_renew = NULL; + entry->etypes = NULL; + entry->generation = NULL; + entry->extensions = NULL; + if ((ret = krb5_make_principal(context, &entry->principal, "TEST.H5L.SE", name, NULL))) return ret; - if ((ret = krb5_make_principal(context, &entry->entry.created_by.principal, + if ((ret = krb5_make_principal(context, &entry->created_by.principal, "TEST.H5L.SE", "tester", NULL))) return ret; return 0; @@ -320,7 +326,7 @@ test_hdb_concurrency(char *name, const char *ext, int threaded) char *fname_ext = NULL; pthread_t reader_thread; struct tsync ts; - hdb_entry_ex entw; + hdb_entry entw; pid_t child = getpid(); HDB *dbw = NULL; int status; @@ -387,14 +393,14 @@ test_hdb_concurrency(char *name, const char *ext, int threaded) krb5_err(context, 1, ret, "Could not store entry for \"foo\" in HDB %s", name); } - free_HDB_entry(&entw.entry); + free_HDB_entry(&entw); if ((ret = make_entry(context, &entw, "bar")) || (ret = dbw->hdb_store(context, dbw, 0, &entw))) { (void) unlink(fname_ext); krb5_err(context, 1, ret, "Could not store entry for \"foo\" in HDB %s", name); } - free_HDB_entry(&entw.entry); + free_HDB_entry(&entw); /* Tell the reader to start reading */ readers_turn(&ts, child, threaded); @@ -407,7 +413,7 @@ test_hdb_concurrency(char *name, const char *ext, int threaded) "Could not store entry for \"foobar\" in HDB %s " "while iterating it", name); } - free_HDB_entry(&entw.entry); + free_HDB_entry(&entw); /* Tell the reader to go again */ readers_turn(&ts, child, threaded); diff --git a/third_party/heimdal/lib/hdb/test_namespace.c b/third_party/heimdal/lib/hdb/test_namespace.c index 6aaecc083ec..a4c44ba190e 100644 --- a/third_party/heimdal/lib/hdb/test_namespace.c +++ b/third_party/heimdal/lib/hdb/test_namespace.c @@ -106,7 +106,7 @@ TDB_unlock(krb5_context context, HDB *db) } static krb5_error_code -TDB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +TDB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { /* XXX Implement */ /* Tricky thing: heim_dict_iterate_f() is inconvenient here */ @@ -115,7 +115,7 @@ TDB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) } static krb5_error_code -TDB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +TDB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) { /* XXX Implement */ /* Tricky thing: heim_dict_iterate_f() is inconvenient here */ @@ -151,14 +151,13 @@ TDB__put(krb5_context context, HDB *db, int rplc, krb5_data kd, krb5_data vd) { krb5_error_code ret = 0; TEST_HDB *tdb = (void *)db; - heim_object_t e = NULL; heim_object_t k = NULL; heim_object_t v = NULL; if ((k = heim_data_create(kd.data, kd.length)) == NULL || (v = heim_data_create(vd.data, vd.length)) == NULL) ret = krb5_enomem(context); - if (ret == 0 && !rplc && (e = heim_dict_get_value(tdb->dict, k)) != NULL) + if (ret == 0 && !rplc && heim_dict_get_value(tdb->dict, k) != NULL) ret = HDB_ERR_EXISTS; if (ret == 0 && heim_dict_set_value(tdb->dict, k, v)) ret = krb5_enomem(context); @@ -172,11 +171,11 @@ TDB__del(krb5_context context, HDB *db, krb5_data key) { krb5_error_code ret = 0; TEST_HDB *tdb = (void *)db; - heim_object_t k, v; + heim_object_t k; if ((k = heim_data_create(key.data, key.length)) == NULL) ret = krb5_enomem(context); - if (ret == 0 && (v = heim_dict_get_value(tdb->dict, k)) == NULL) + if (ret == 0 && heim_dict_get_value(tdb->dict, k) == NULL) ret = HDB_ERR_NOENTRY; if (ret == 0) heim_dict_delete_key(tdb->dict, k); @@ -198,7 +197,8 @@ hdb_test_create(krb5_context context, struct HDB **db, const char *arg) if ((tdb = calloc(1, sizeof(tdb[0]))) == NULL || (tdb->hdb.hdb_name = strdup(arg)) == NULL || (tdb->dict = heim_dict_create(10)) == NULL) { - free(tdb->hdb.hdb_name); + if (tdb) + free(tdb->hdb.hdb_name); free(tdb); return krb5_enomem(context); } @@ -337,7 +337,7 @@ static void make_namespace(krb5_context context, HDB *db, const char *name) { krb5_error_code ret = 0; - hdb_entry_ex e; + hdb_entry e; Key k; memset(&k, 0, sizeof(k)); @@ -346,85 +346,83 @@ make_namespace(krb5_context context, HDB *db, const char *name) /* Setup the HDB entry */ memset(&e, 0, sizeof(e)); - e.ctx = 0; - e.free_entry = 0; - e.entry.created_by.time = krs[0].epoch; - e.entry.valid_start = e.entry.valid_end = e.entry.pw_end = 0; - e.entry.generation = 0; - e.entry.flags = int2HDBFlags(0); - e.entry.flags.server = e.entry.flags.client = 1; - e.entry.flags.virtual = 1; + e.created_by.time = krs[0].epoch; + e.valid_start = e.valid_end = e.pw_end = 0; + e.generation = 0; + e.flags = int2HDBFlags(0); + e.flags.server = e.flags.client = 1; + e.flags.virtual = 1; /* Setup etypes */ if (ret == 0 && - (e.entry.etypes = malloc(sizeof(*e.entry.etypes))) == NULL) + (e.etypes = malloc(sizeof(*e.etypes))) == NULL) ret = krb5_enomem(context); if (ret == 0) - e.entry.etypes->len = 3; + e.etypes->len = 3; if (ret == 0 && - (e.entry.etypes->val = calloc(e.entry.etypes->len, - sizeof(e.entry.etypes->val[0]))) == NULL) + (e.etypes->val = calloc(e.etypes->len, + sizeof(e.etypes->val[0]))) == NULL) ret = krb5_enomem(context); if (ret == 0) { - e.entry.etypes->val[0] = KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128; - e.entry.etypes->val[1] = KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192; - e.entry.etypes->val[2] = KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96; + e.etypes->val[0] = KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128; + e.etypes->val[1] = KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192; + e.etypes->val[2] = KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96; } /* Setup max_life and max_renew */ if (ret == 0 && - (e.entry.max_life = malloc(sizeof(*e.entry.max_life))) == NULL) + (e.max_life = malloc(sizeof(*e.max_life))) == NULL) ret = krb5_enomem(context); if (ret == 0 && - (e.entry.max_renew = malloc(sizeof(*e.entry.max_renew))) == NULL) + (e.max_renew = malloc(sizeof(*e.max_renew))) == NULL) ret = krb5_enomem(context); if (ret == 0) /* Make it long, so we see the clamped max */ - *e.entry.max_renew = 2 * ((*e.entry.max_life = 15 * 24 * 3600)); + *e.max_renew = 2 * ((*e.max_life = 15 * 24 * 3600)); /* Setup principal name and created_by */ if (ret == 0) - ret = krb5_parse_name(context, name, &e.entry.principal); + ret = krb5_parse_name(context, name, &e.principal); if (ret == 0) ret = krb5_parse_name(context, "admin@BAR.EXAMPLE", - &e.entry.created_by.principal); + &e.created_by.principal); /* Make base keys for first epoch */ if (ret == 0) - ret = make_base_key(context, e.entry.principal, base_pw[0], &k.key); + ret = make_base_key(context, e.principal, base_pw[0], &k.key); if (ret == 0) - add_Keys(&e.entry.keys, &k); + add_Keys(&e.keys, &k); if (ret == 0) - ret = hdb_entry_set_pw_change_time(context, &e.entry, krs[0].epoch); + ret = hdb_entry_set_pw_change_time(context, &e, krs[0].epoch); free_Key(&k); - e.entry.kvno = krs[0].base_key_kvno; + e.kvno = krs[0].base_key_kvno; /* Move them to history */ if (ret == 0) - ret = hdb_add_current_keys_to_history(context, &e.entry); - free_Keys(&e.entry.keys); + ret = hdb_add_current_keys_to_history(context, &e); + free_Keys(&e.keys); /* Make base keys for second epoch */ if (ret == 0) - ret = make_base_key(context, e.entry.principal, base_pw[1], &k.key); + ret = make_base_key(context, e.principal, base_pw[1], &k.key); if (ret == 0) - add_Keys(&e.entry.keys, &k); - e.entry.kvno = krs[1].base_key_kvno; + add_Keys(&e.keys, &k); + e.kvno = krs[1].base_key_kvno; if (ret == 0) - ret = hdb_entry_set_pw_change_time(context, &e.entry, krs[1].epoch); + ret = hdb_entry_set_pw_change_time(context, &e, krs[1].epoch); /* Add the key rotation metadata */ if (ret == 0) - ret = hdb_entry_add_key_rotation(context, &e.entry, 0, &krs[0]); + ret = hdb_entry_add_key_rotation(context, &e, 0, &krs[0]); if (ret == 0) - ret = hdb_entry_add_key_rotation(context, &e.entry, 0, &krs[1]); + ret = hdb_entry_add_key_rotation(context, &e, 0, &krs[1]); if (ret == 0) ret = db->hdb_store(context, db, 0, &e); if (ret) krb5_err(context, 1, ret, "failed to setup a namespace principal"); free_Key(&k); - hdb_free_entry(context, &e); + hdb_free_entry(context, db, &e); } #define WK_PREFIX "WELLKNOWN/" HDB_WK_NAMESPACE "/" @@ -449,7 +447,7 @@ static const char *unexpected[] = { * different time offsets in each period. */ #define NUM_OFFSETS 5 -static hdb_entry_ex e[ +static hdb_entry e[ (sizeof(expected) / sizeof(expected[0])) * (sizeof(krs) / sizeof(krs[0])) * NUM_OFFSETS @@ -481,8 +479,8 @@ fetch_entries(krb5_context context, krb5_error_code ret = 0; krb5_principal p = NULL; krb5_keyblock base_key, dk; - hdb_entry_ex *ep; - hdb_entry_ex no; + hdb_entry *ep; + hdb_entry no; size_t i, b; int toffset = 0; @@ -543,14 +541,14 @@ fetch_entries(krb5_context context, } } else { if (ret == 0 && - !krb5_principal_compare(context, p, ep->entry.principal)) + !krb5_principal_compare(context, p, ep->principal)) krb5_errx(context, 1, "wrong principal in fetched entry"); } { HDB_Ext_KeySet *hist_keys; HDB_extension *ext; - ext = hdb_find_extension(&ep->entry, + ext = hdb_find_extension(ep, choice_HDB_extension_data_hist_keys); if (ext) { /* Sort key history by kvno, why not */ @@ -613,23 +611,23 @@ fetch_entries(krb5_context context, if (ret) krb5_err(context, 1, ret, "deriving keys for comparison"); - if (kvno != ep->entry.kvno) - krb5_errx(context, 1, "kvno mismatch (%u != %u)", kvno, ep->entry.kvno); - (void) hdb_entry_get_pw_change_time(&ep->entry, &chg_time); + if (kvno != ep->kvno) + krb5_errx(context, 1, "kvno mismatch (%u != %u)", kvno, ep->kvno); + (void) hdb_entry_get_pw_change_time(ep, &chg_time); if (set_time != chg_time) krb5_errx(context, 1, "key change time mismatch"); - if (ep->entry.keys.len == 0) + if (ep->keys.len == 0) krb5_errx(context, 1, "no keys!"); - if (ep->entry.keys.val[0].key.keytype != dk.keytype) + if (ep->keys.val[0].key.keytype != dk.keytype) krb5_errx(context, 1, "enctype mismatch!"); - if (ep->entry.keys.val[0].key.keyvalue.length != + if (ep->keys.val[0].key.keyvalue.length != dk.keyvalue.length) krb5_errx(context, 1, "key length mismatch!"); - if (memcmp(ep->entry.keys.val[0].key.keyvalue.data, + if (memcmp(ep->keys.val[0].key.keyvalue.data, dk.keyvalue.data, dk.keyvalue.length) != 0) krb5_errx(context, 1, "key mismatch!"); - if (memcmp(ep->entry.keys.val[0].key.keyvalue.data, - e[b + i - 1].entry.keys.val[0].key.keyvalue.data, + if (memcmp(ep->keys.val[0].key.keyvalue.data, + e[b + i - 1].keys.val[0].key.keyvalue.data, dk.keyvalue.length) == 0) krb5_errx(context, 1, "different virtual principals have the same keys!"); /* XXX Add check that we have the expected number of history keys */ @@ -655,14 +653,14 @@ check_kvnos(krb5_context context) for (k = 0; k < sizeof(e)/sizeof(e[0]); k++) { HDB_Ext_KeySet *hist_keys; HDB_extension *ext; - hdb_entry_ex *ep; + hdb_entry *ep; int match = 0; if ((k % NUM_OFFSETS) != i) continue; ep = &e[k]; - if (ep->entry.principal == NULL) + if (ep->principal == NULL) continue; /* Didn't fetch this one */ /* @@ -670,15 +668,15 @@ check_kvnos(krb5_context context) * or else add them to `keysets'. */ for (m = 0; m < keysets.len; m++) { - if (ep->entry.kvno == keysets.val[m].kvno) { + if (ep->kvno == keysets.val[m].kvno) { /* Check the key is the same */ - if (ep->entry.keys.val[0].key.keytype != + if (ep->keys.val[0].key.keytype != keysets.val[m].keys.val[0].key.keytype || - ep->entry.keys.val[0].key.keyvalue.length != + ep->keys.val[0].key.keyvalue.length != keysets.val[m].keys.val[0].key.keyvalue.length || - memcmp(ep->entry.keys.val[0].key.keyvalue.data, + memcmp(ep->keys.val[0].key.keyvalue.data, keysets.val[m].keys.val[0].key.keyvalue.data, - ep->entry.keys.val[0].key.keyvalue.length) != 0) + ep->keys.val[0].key.keyvalue.length) != 0) krb5_errx(context, 1, "key mismatch for same princ & kvno"); match = 1; @@ -687,8 +685,8 @@ check_kvnos(krb5_context context) if (m == keysets.len) { hdb_keyset ks; - ks.kvno = ep->entry.kvno; - ks.keys = ep->entry.keys; + ks.kvno = ep->kvno; + ks.keys = ep->keys; ks.set_time = 0; if (add_HDB_Ext_KeySet(&keysets, &ks)) krb5_err(context, 1, ENOMEM, "out of memory"); @@ -698,7 +696,7 @@ check_kvnos(krb5_context context) continue; /* For all non-current keysets, repeat the above */ - ext = hdb_find_extension(&ep->entry, + ext = hdb_find_extension(ep, choice_HDB_extension_data_hist_keys); if (!ext) continue; @@ -706,20 +704,20 @@ check_kvnos(krb5_context context) for (p = 0; p < hist_keys->len; p++) { for (m = 0; m < keysets.len; m++) { if (keysets.val[m].kvno == hist_keys->val[p].kvno) - if (ep->entry.keys.val[0].key.keytype != + if (ep->keys.val[0].key.keytype != keysets.val[m].keys.val[0].key.keytype || - ep->entry.keys.val[0].key.keyvalue.length != + ep->keys.val[0].key.keyvalue.length != keysets.val[m].keys.val[0].key.keyvalue.length || - memcmp(ep->entry.keys.val[0].key.keyvalue.data, + memcmp(ep->keys.val[0].key.keyvalue.data, keysets.val[m].keys.val[0].key.keyvalue.data, - ep->entry.keys.val[0].key.keyvalue.length) != 0) + ep->keys.val[0].key.keyvalue.length) != 0) krb5_errx(context, 1, "key mismatch for same princ & kvno"); } if (m == keysets.len) { hdb_keyset ks; - ks.kvno = ep->entry.kvno; - ks.keys = ep->entry.keys; + ks.kvno = ep->kvno; + ks.keys = ep->keys; ks.set_time = 0; if (add_HDB_Ext_KeySet(&keysets, &ks)) krb5_err(context, 1, ENOMEM, "out of memory"); @@ -743,15 +741,14 @@ print_em(krb5_context context) if (0 == i % (sizeof(expected)/sizeof(expected[0]))) continue; - if (e[i].entry.principal == NULL) + if (e[i].principal == NULL) continue; - hex_encode(e[i].entry.keys.val[0].key.keyvalue.data, - e[i].entry.keys.val[0].key.keyvalue.length, &x); - printf("%s %u %s\n", x, e[i].entry.kvno, name); + hex_encode(e[i].keys.val[0].key.keyvalue.data, + e[i].keys.val[0].key.keyvalue.length, &x); + printf("%s %u %s\n", x, e[i].kvno, name); free(x); - ext = hdb_find_extension(&e[i].entry, - choice_HDB_extension_data_hist_keys); + ext = hdb_find_extension(&e[i], choice_HDB_extension_data_hist_keys); if (!ext) continue; hist_keys = &ext->data.u.hist_keys; @@ -759,6 +756,7 @@ print_em(krb5_context context) hex_encode(hist_keys->val[p].keys.val[0].key.keyvalue.data, hist_keys->val[p].keys.val[0].key.keyvalue.length, &x); printf("%s %u %s\n", x, hist_keys->val[p].kvno, name); + free(x); } } } @@ -773,12 +771,12 @@ check_expected_kvnos(krb5_context context) for (i = 0; i < sizeof(expected)/sizeof(expected[0]); i++) { for (k = 0; k < sizeof(krs)/sizeof(krs[0]); k++) { - hdb_entry_ex *ep = &e[k * sizeof(expected)/sizeof(expected[0]) + i]; + hdb_entry *ep = &e[k * sizeof(expected)/sizeof(expected[0]) + i]; - if (ep->entry.principal == NULL) + if (ep->principal == NULL) continue; for (m = 0; m < NUM_OFFSETS; m++) { - ext = hdb_find_extension(&ep->entry, + ext = hdb_find_extension(ep, choice_HDB_extension_data_hist_keys); if (!ext) continue; @@ -789,7 +787,7 @@ check_expected_kvnos(krb5_context context) } } fprintf(stderr, "%s at %lu: kvno %u\n", expected[i], k, - ep->entry.kvno); + ep->kvno); } } } @@ -936,7 +934,7 @@ main(int argc, char **argv) /* Cleanup */ for (i = 0; ret == 0 && i < sizeof(e) / sizeof(e[0]); i++) - hdb_free_entry(context, &e[i]); + hdb_free_entry(context, db, &e[i]); db->hdb_destroy(context, db); krb5_free_context(context); return 0; diff --git a/third_party/heimdal/lib/hdb/version-script.map b/third_party/heimdal/lib/hdb/version-script.map index 0846f733743..058060dae0c 100644 --- a/third_party/heimdal/lib/hdb/version-script.map +++ b/third_party/heimdal/lib/hdb/version-script.map @@ -70,7 +70,6 @@ HEIMDAL_HDB_1.0 { hdb_prune_keys; hdb_prune_keys_kvno; hdb_read_master_key; - hdb_remove_base_keys; hdb_remove_keys; hdb_replace_extension; hdb_seal_key; |