s4:torture: Adapt KDC canon test to Heimdal upstream changes
[metze/samba/wip.git] / third_party / heimdal / lib / hdb / common.c
1 /*
2  * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include "krb5_locl.h"
35 #include "hdb_locl.h"
36
37 int
38 hdb_principal2key(krb5_context context, krb5_const_principal p, krb5_data *key)
39 {
40     Principal new;
41     size_t len = 0;
42     int ret;
43
44     ret = copy_Principal(p, &new);
45     if(ret)
46         return ret;
47     new.name.name_type = 0;
48
49     ASN1_MALLOC_ENCODE(Principal, key->data, key->length, &new, &len, ret);
50     if (ret == 0 && key->length != len)
51         krb5_abortx(context, "internal asn.1 encoder error");
52     free_Principal(&new);
53     return ret;
54 }
55
56 int
57 hdb_key2principal(krb5_context context, krb5_data *key, krb5_principal p)
58 {
59     return decode_Principal(key->data, key->length, p, NULL);
60 }
61
62 int
63 hdb_entry2value(krb5_context context, const hdb_entry *ent, krb5_data *value)
64 {
65     size_t len = 0;
66     int ret;
67
68     ASN1_MALLOC_ENCODE(HDB_entry, value->data, value->length, ent, &len, ret);
69     if (ret == 0 && value->length != len)
70         krb5_abortx(context, "internal asn.1 encoder error");
71     return ret;
72 }
73
74 int
75 hdb_value2entry(krb5_context context, krb5_data *value, hdb_entry *ent)
76 {
77     return decode_HDB_entry(value->data, value->length, ent, NULL);
78 }
79
80 int
81 hdb_entry_alias2value(krb5_context context,
82                       const hdb_entry_alias *alias,
83                       krb5_data *value)
84 {
85     size_t len = 0;
86     int ret;
87
88     ASN1_MALLOC_ENCODE(HDB_entry_alias, value->data, value->length,
89                        alias, &len, ret);
90     if (ret == 0 && value->length != len)
91         krb5_abortx(context, "internal asn.1 encoder error");
92     return ret;
93 }
94
95 int
96 hdb_value2entry_alias(krb5_context context, krb5_data *value,
97                       hdb_entry_alias *ent)
98 {
99     return decode_HDB_entry_alias(value->data, value->length, ent, NULL);
100 }
101
102 /*
103  * Some old databases may not have stored the salt with each key, which will
104  * break clients when aliases or canonicalization are used. Generate a
105  * default salt based on the real principal name in the entry to handle
106  * this case.
107  */
108 static krb5_error_code
109 add_default_salts(krb5_context context, HDB *db, hdb_entry *entry)
110 {
111     krb5_error_code ret;
112     size_t i;
113     krb5_salt pwsalt;
114
115     ret = krb5_get_pw_salt(context, entry->principal, &pwsalt);
116     if (ret)
117         return ret;
118
119     for (i = 0; i < entry->keys.len; i++) {
120         Key *key = &entry->keys.val[i];
121
122         if (key->salt != NULL ||
123             _krb5_enctype_requires_random_salt(context, key->key.keytype))
124             continue;
125
126         key->salt = calloc(1, sizeof(*key->salt));
127         if (key->salt == NULL) {
128             ret = krb5_enomem(context);
129             break;
130         }
131
132         key->salt->type = KRB5_PADATA_PW_SALT;
133
134         ret = krb5_data_copy(&key->salt->salt,
135                              pwsalt.saltvalue.data,
136                              pwsalt.saltvalue.length);
137         if (ret)
138             break;
139     }
140
141     krb5_free_salt(context, pwsalt);
142
143     return ret;
144 }
145
146 static krb5_error_code
147 fetch_entry_or_alias(krb5_context context,
148                      HDB *db,
149                      krb5_const_principal principal,
150                      unsigned flags,
151                      hdb_entry_ex *entry)
152 {
153     HDB_EntryOrAlias eoa;
154     krb5_principal enterprise_principal = NULL;
155     krb5_data key, value;
156     krb5_error_code ret;
157
158     value.length = 0;
159     value.data = 0;
160     key = value;
161
162     if (principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
163         if (principal->name.name_string.len != 1) {
164             ret = KRB5_PARSE_MALFORMED;
165             krb5_set_error_message(context, ret, "malformed principal: "
166                                    "enterprise name with %d name components",
167                                    principal->name.name_string.len);
168             return ret;
169         }
170         ret = krb5_parse_name(context, principal->name.name_string.val[0],
171                               &enterprise_principal);
172         if (ret)
173             return ret;
174         principal = enterprise_principal;
175     }
176
177     ret = hdb_principal2key(context, principal, &key);
178     if (ret == 0)
179         ret = db->hdb__get(context, db, key, &value);
180     if (ret == 0)
181         ret = decode_HDB_EntryOrAlias(value.data, value.length, &eoa, NULL);
182     if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_entry) {
183         entry->entry = eoa.u.entry;
184     } else if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_alias) {
185         krb5_data_free(&key);
186         ret = hdb_principal2key(context, eoa.u.alias.principal, &key);
187         if (ret == 0) {
188             krb5_data_free(&value);
189             ret = db->hdb__get(context, db, key, &value);
190         }
191         if (ret == 0)
192             /* No alias chaining */
193             ret = hdb_value2entry(context, &value, &entry->entry);
194         krb5_free_principal(context, eoa.u.alias.principal);
195     } else if (ret == 0)
196         ret = ENOTSUP;
197     if (ret == 0 && enterprise_principal) {
198         /*
199          * Whilst Windows does not canonicalize enterprise principal names if
200          * the canonicalize flag is unset, the original specification in
201          * draft-ietf-krb-wg-kerberos-referrals-03.txt says we should.
202          */
203         entry->entry.flags.force_canonicalize = 1;
204     }
205
206     /* HDB_F_GET_ANY indicates request originated from KDC (not kadmin) */
207     if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_alias &&
208         (flags & (HDB_F_CANON|HDB_F_GET_ANY)) == 0) {
209
210         /* `principal' was alias but canon not req'd */
211         free_HDB_entry(&entry->entry);
212         ret = HDB_ERR_NOENTRY;
213     }
214
215     krb5_free_principal(context, enterprise_principal);
216     krb5_data_free(&value);
217     krb5_data_free(&key);
218     principal = enterprise_principal = NULL;
219     return ret;
220 }
221
222 krb5_error_code
223 _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal,
224                 unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry)
225 {
226     krb5_error_code ret;
227
228     ret = fetch_entry_or_alias(context, db, principal, flags, entry);
229     if (ret)
230         return ret;
231
232     if ((flags & HDB_F_DECRYPT) && (flags & HDB_F_ALL_KVNOS)) {
233         /* Decrypt the current keys */
234         ret = hdb_unseal_keys(context, db, &entry->entry);
235         if (ret) {
236             hdb_free_entry(context, entry);
237             return ret;
238         }
239         /* Decrypt the key history too */
240         ret = hdb_unseal_keys_kvno(context, db, 0, flags, &entry->entry);
241         if (ret) {
242             hdb_free_entry(context, entry);
243             return ret;
244         }
245     } else if ((flags & HDB_F_DECRYPT)) {
246         if ((flags & HDB_F_KVNO_SPECIFIED) == 0 || kvno == entry->entry.kvno) {
247             /* Decrypt the current keys */
248             ret = hdb_unseal_keys(context, db, &entry->entry);
249             if (ret) {
250                 hdb_free_entry(context, entry);
251                 return ret;
252             }
253         } else {
254             if ((flags & HDB_F_ALL_KVNOS))
255                 kvno = 0;
256             /*
257              * Find and decrypt the keys from the history that we want,
258              * and swap them with the current keys
259              */
260             ret = hdb_unseal_keys_kvno(context, db, kvno, flags, &entry->entry);
261             if (ret) {
262                 hdb_free_entry(context, entry);
263                 return ret;
264             }
265         }
266     }
267     if ((flags & HDB_F_FOR_AS_REQ) && (flags & HDB_F_GET_CLIENT)) {
268         /*
269          * Generate default salt for any principals missing one; note such
270          * principals could include those for which a random (non-password)
271          * key was generated, but given the salt will be ignored by a keytab
272          * client it doesn't hurt to include the default salt.
273          */
274         ret = add_default_salts(context, db, &entry->entry);
275         if (ret) {
276             hdb_free_entry(context, entry);
277             return ret;
278         }
279     }
280
281     return 0;
282 }
283
284 static krb5_error_code
285 hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key)
286 {
287     const HDB_Ext_Aliases *aliases;
288     krb5_error_code code;
289     hdb_entry oldentry;
290     krb5_data value;
291     size_t i;
292
293     code = db->hdb__get(context, db, *key, &value);
294     if (code == HDB_ERR_NOENTRY)
295         return 0;
296     else if (code)
297         return code;
298
299     code = hdb_value2entry(context, &value, &oldentry);
300     krb5_data_free(&value);
301     if (code)
302         return code;
303
304     code = hdb_entry_get_aliases(&oldentry, &aliases);
305     if (code || aliases == NULL) {
306         free_HDB_entry(&oldentry);
307         return code;
308     }
309     for (i = 0; i < aliases->aliases.len; i++) {
310         krb5_data akey;
311
312         code = hdb_principal2key(context, &aliases->aliases.val[i], &akey);
313         if (code == 0) {
314             code = db->hdb__del(context, db, akey);
315             krb5_data_free(&akey);
316         }
317         if (code) {
318             free_HDB_entry(&oldentry);
319             return code;
320         }
321     }
322     free_HDB_entry(&oldentry);
323     return 0;
324 }
325
326 static krb5_error_code
327 hdb_add_aliases(krb5_context context, HDB *db,
328                 unsigned flags, hdb_entry_ex *entry)
329 {
330     const HDB_Ext_Aliases *aliases;
331     krb5_error_code code;
332     krb5_data key, value;
333     size_t i;
334
335     code = hdb_entry_get_aliases(&entry->entry, &aliases);
336     if (code || aliases == NULL)
337         return code;
338
339     for (i = 0; i < aliases->aliases.len; i++) {
340         hdb_entry_alias entryalias;
341         entryalias.principal = entry->entry.principal;
342
343         code = hdb_entry_alias2value(context, &entryalias, &value);
344         if (code)
345             return code;
346
347         code = hdb_principal2key(context, &aliases->aliases.val[i], &key);
348         if (code == 0) {
349             code = db->hdb__put(context, db, flags, key, value);
350             krb5_data_free(&key);
351         }
352         krb5_data_free(&value);
353         if (code)
354             return code;
355     }
356     return 0;
357 }
358
359 /* Check if new aliases are already used for other entries */
360 static krb5_error_code
361 hdb_check_aliases(krb5_context context, HDB *db, hdb_entry_ex *entry)
362 {
363     const HDB_Ext_Aliases *aliases = NULL;
364     HDB_EntryOrAlias eoa;
365     krb5_data akey, value;
366     size_t i;
367     int ret;
368
369     memset(&eoa, 0, sizeof(eoa));
370     krb5_data_zero(&value);
371     akey = value;
372
373     ret = hdb_entry_get_aliases(&entry->entry, &aliases);
374     for (i = 0; ret == 0 && aliases && i < aliases->aliases.len; i++) {
375         ret = hdb_principal2key(context, &aliases->aliases.val[i], &akey);
376         if (ret == 0)
377             ret = db->hdb__get(context, db, akey, &value);
378         if (ret == 0)
379             ret = decode_HDB_EntryOrAlias(value.data, value.length, &eoa, NULL);
380         if (ret == 0 && eoa.element != choice_HDB_EntryOrAlias_entry &&
381             eoa.element != choice_HDB_EntryOrAlias_alias)
382             ret = ENOTSUP;
383         if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_entry)
384             /* New alias names an existing non-alias entry in the HDB */
385             ret = HDB_ERR_EXISTS;
386         if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_alias &&
387             !krb5_principal_compare(context, eoa.u.alias.principal,
388                                     entry->entry.principal))
389             /* New alias names an existing alias of a different entry */
390             ret = HDB_ERR_EXISTS;
391         if (ret == HDB_ERR_NOENTRY) /* from db->hdb__get */
392             /* New alias is a name that doesn't exist in the HDB */
393             ret = 0;
394
395         free_HDB_EntryOrAlias(&eoa);
396         krb5_data_free(&value);
397         krb5_data_free(&akey);
398     }
399     return ret;
400 }
401
402 /*
403  * Many HDB entries don't have `etypes' setup.  Historically we use the
404  * enctypes of the selected keyset as the entry's supported enctypes, but that
405  * is problematic.  By doing this at store time and, if need be, at fetch time,
406  * we can make sure to stop deriving supported etypes from keys in the long
407  * run.  We also need kadm5/kadmin support for etypes.  We'll use this function
408  * there to derive etypes when using a kadm5_principal_ent_t that lacks the new
409  * TL data for etypes.
410  */
411 krb5_error_code
412 hdb_derive_etypes(krb5_context context, hdb_entry *e, HDB_Ext_KeySet *base_keys)
413 {
414     krb5_error_code ret = 0;
415     size_t i, k, netypes;
416     HDB_extension *ext;
417
418     if (!base_keys &&
419         (ext = hdb_find_extension(e, choice_HDB_extension_data_hist_keys)))
420         base_keys = &ext->data.u.hist_keys;
421
422     netypes = e->keys.len;
423     if (netypes == 0 && base_keys) {
424         /* There's no way that base_keys->val[i].keys.len == 0, but hey */
425         for (i = 0; netypes == 0 && i < base_keys->len; i++)
426             netypes = base_keys->val[i].keys.len;
427     }
428
429     if (netypes == 0)
430         return 0;
431
432     if (e->etypes != NULL) {
433         free(e->etypes->val);
434         e->etypes->len = 0;
435         e->etypes->val = 0;
436     }
437
438     if (e->etypes == NULL &&
439         (e->etypes = malloc(sizeof(e->etypes[0]))) == NULL)
440         ret = krb5_enomem(context);
441     if (ret == 0) {
442         e->etypes->len = 0;
443         e->etypes->val = 0;
444     }
445     if (ret == 0 &&
446         (e->etypes->val = calloc(netypes, sizeof(e->etypes->val[0]))) == NULL)
447         ret = krb5_enomem(context);
448     if (ret) {
449         free(e->etypes);
450         e->etypes = 0;
451         return ret;
452     }
453     e->etypes->len = netypes;
454     for (i = 0; i < e->keys.len && i < netypes; i++)
455         e->etypes->val[i] = e->keys.val[i].key.keytype;
456     if (!base_keys || i)
457         return 0;
458     for (k = 0; i == 0 && k < base_keys->len; k++) {
459         if (!base_keys->val[k].keys.len)
460             continue;
461         for (; i < base_keys->val[k].keys.len; i++)
462             e->etypes->val[i] = base_keys->val[k].keys.val[i].key.keytype;
463     }
464     return 0;
465 }
466
467 krb5_error_code
468 _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
469 {
470     krb5_data key, value;
471     int code;
472
473     if (entry->entry.flags.do_not_store ||
474         entry->entry.flags.force_canonicalize)
475         return HDB_ERR_MISUSE;
476     /* check if new aliases already is used */
477     code = hdb_check_aliases(context, db, entry);
478     if (code)
479         return code;
480
481     if ((flags & HDB_F_PRECHECK) && (flags & HDB_F_REPLACE))
482         return 0;
483
484     if ((flags & HDB_F_PRECHECK)) {
485         code = hdb_principal2key(context, entry->entry.principal, &key);
486         if (code)
487             return code;
488         code = db->hdb__get(context, db, key, &value);
489         krb5_data_free(&key);
490         if (code == 0)
491             krb5_data_free(&value);
492         if (code == HDB_ERR_NOENTRY)
493             return 0;
494         return code ? code : HDB_ERR_EXISTS;
495     }
496
497     if ((entry->entry.etypes == NULL || entry->entry.etypes->len == 0) &&
498         (code = hdb_derive_etypes(context, &entry->entry, NULL)))
499         return code;
500
501     if (entry->entry.generation == NULL) {
502         struct timeval t;
503         entry->entry.generation = malloc(sizeof(*entry->entry.generation));
504         if(entry->entry.generation == NULL) {
505             krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
506             return ENOMEM;
507         }
508         gettimeofday(&t, NULL);
509         entry->entry.generation->time = t.tv_sec;
510         entry->entry.generation->usec = t.tv_usec;
511         entry->entry.generation->gen = 0;
512     } else
513         entry->entry.generation->gen++;
514
515     code = hdb_seal_keys(context, db, &entry->entry);
516     if (code)
517         return code;
518
519     hdb_principal2key(context, entry->entry.principal, &key);
520
521     /* remove aliases */
522     code = hdb_remove_aliases(context, db, &key);
523     if (code) {
524         krb5_data_free(&key);
525         return code;
526     }
527     hdb_entry2value(context, &entry->entry, &value);
528     code = db->hdb__put(context, db, flags & HDB_F_REPLACE, key, value);
529     krb5_data_free(&value);
530     krb5_data_free(&key);
531     if (code)
532         return code;
533
534     code = hdb_add_aliases(context, db, flags, entry);
535
536     return code;
537 }
538
539 krb5_error_code
540 _hdb_remove(krb5_context context, HDB *db,
541             unsigned flags, krb5_const_principal principal)
542 {
543     krb5_data key, value;
544     HDB_EntryOrAlias eoa;
545     int is_alias = -1;
546     int code;
547
548     /*
549      * We only allow deletion of entries by canonical name.  To remove an
550      * alias use kadm5_modify_principal().
551      *
552      * We need to determine if this is an alias.  We decode as a
553      * HDB_EntryOrAlias, which is expensive -- we could decode as a
554      * HDB_entry_alias instead and assume it's an entry if decoding fails...
555      */
556
557     hdb_principal2key(context, principal, &key);
558     code = db->hdb__get(context, db, key, &value);
559     if (code == 0) {
560         code = decode_HDB_EntryOrAlias(value.data, value.length, &eoa, NULL);
561         krb5_data_free(&value);
562     }
563     if (code == 0) {
564         is_alias = eoa.element == choice_HDB_EntryOrAlias_entry ? 0 : 1;
565         free_HDB_EntryOrAlias(&eoa);
566     }
567
568     if ((flags & HDB_F_PRECHECK)) {
569         if (code == 0 && is_alias)
570             krb5_set_error_message(context, code = HDB_ERR_NOENTRY,
571                                    "Cannot delete alias of principal");
572         krb5_data_free(&key);
573         return code;
574     }
575
576     code = hdb_remove_aliases(context, db, &key);
577     if (code == 0)
578         code = db->hdb__del(context, db, key);
579     krb5_data_free(&key);
580     return code;
581 }
582
583 /* PRF+(K_base, pad, keylen(etype)) */
584 static krb5_error_code
585 derive_Key1(krb5_context context,
586             krb5_data *pad,
587             EncryptionKey *base,
588             krb5int32 etype,
589             EncryptionKey *nk)
590 {
591     krb5_error_code ret;
592     krb5_crypto crypto = NULL;
593     krb5_data out;
594     size_t len;
595
596     out.data = 0;
597     out.length = 0;
598
599     ret = krb5_enctype_keysize(context, base->keytype, &len);
600     if (ret == 0)
601         ret = krb5_crypto_init(context, base, 0, &crypto);
602     if (ret == 0)
603         ret = krb5_crypto_prfplus(context, crypto, pad, len, &out);
604     if (crypto)
605         krb5_crypto_destroy(context, crypto);
606     if (ret == 0)
607         ret = krb5_random_to_key(context, etype, out.data, out.length, nk);
608     krb5_data_free(&out);
609     return ret;
610 }
611
612 /* PRF+(PRF+(K_base, princ, keylen(etype)), kvno, keylen(etype)) */
613 /* XXX Make it PRF+(PRF+(K_base, princ, keylen(K_base.etype)), and lift it, kvno, keylen(etype)) */
614 static krb5_error_code
615 derive_Key(krb5_context context,
616            const char *princ,
617            krb5uint32 kvno,
618            EncryptionKey *base,
619            krb5int32 etype,
620            Key *nk)
621 {
622     krb5_error_code ret = 0;
623     EncryptionKey intermediate;
624     krb5_data pad;
625
626     nk->salt = NULL;
627     nk->mkvno = NULL;
628     nk->key.keytype = 0;
629     nk->key.keyvalue.data = 0;
630     nk->key.keyvalue.length = 0;
631
632     intermediate.keytype = 0;
633     intermediate.keyvalue.data = 0;
634     intermediate.keyvalue.length = 0;
635     if (princ) {
636         /* Derive intermediate key for the given principal */
637         /* XXX Lift to optimize? */
638         pad.data = (void *)(uintptr_t)princ;
639         pad.length = strlen(princ);
640         ret = derive_Key1(context, &pad, base, etype, &intermediate);
641         if (ret == 0)
642             base = &intermediate;
643     } /* else `base' is already an intermediate key for the desired princ */
644
645     /* Derive final key for `kvno' from intermediate key */
646     kvno = htonl(kvno);
647     pad.data = &kvno;
648     pad.length = sizeof(kvno);
649     if (ret == 0)
650         ret = derive_Key1(context, &pad, base, etype, &nk->key);
651     free_EncryptionKey(&intermediate);
652     return ret;
653 }
654
655 /*
656  * PRF+(PRF+(K_base, princ, keylen(etype)), kvno, keylen(etype)) for one
657  * enctype.
658  */
659 static krb5_error_code
660 derive_Keys(krb5_context context,
661             const char *princ,
662             krb5uint32 kvno,
663             krb5int32 etype,
664             const Keys *base,
665             Keys *dk)
666
667 {
668     krb5_error_code ret = 0;
669     size_t i;
670     Key nk;
671
672     dk->len = 0;
673     dk->val = 0;
674     
675     /*
676      * The enctypes of the base keys is the list of enctypes to derive keys
677      * for.  Still, we derive all keys from the first base key.
678      */
679     for (i = 0; ret == 0 && i < base->len; i++) {
680         if (etype != KRB5_ENCTYPE_NULL && etype != base->val[i].key.keytype)
681             continue;
682         ret = derive_Key(context, princ, kvno, &base->val[0].key,
683                          base->val[i].key.keytype, &nk);
684         if (ret)
685             break;
686         ret = add_Keys(dk, &nk);
687         free_Key(&nk);
688         /*
689          * FIXME We need to finish kdc/kadm5/kadmin support for the `etypes' so
690          * we can reduce the number of keys in keytabs to just those in current
691          * use and only of *one* enctype.
692          *
693          * What we could do is derive *one* key and for the others output a
694          * one-byte key of the intended enctype (which will never work).
695          *
696          * We'll never need any keys but the first one...
697          */
698     }
699
700     if (ret)
701         free_Keys(dk);
702     return ret;
703 }
704
705 /* Helper for derive_keys_for_kr() */
706 static krb5_error_code
707 derive_keyset(krb5_context context,
708               const Keys *base_keys,
709               const char *princ,
710               krb5int32 etype,
711               krb5uint32 kvno,
712               KerberosTime set_time, /* "now" */
713               hdb_keyset *dks)
714 {
715     dks->kvno = kvno;
716     dks->keys.val = 0;
717     dks->set_time = malloc(sizeof(*dks->set_time));
718     if (dks->set_time == NULL)
719         return krb5_enomem(context);
720     *dks->set_time = set_time;
721     return derive_Keys(context, princ, kvno, etype, base_keys, &dks->keys);
722 }
723
724 /* Possibly derive and install in `h' a keyset identified by `t' */
725 static krb5_error_code
726 derive_keys_for_kr(krb5_context context,
727                    hdb_entry_ex *h,
728                    HDB_Ext_KeySet *base_keys,
729                    int is_current_keyset,
730                    int rotation_period_offset,
731                    const char *princ,
732                    krb5int32 etype,
733                    krb5uint32 kvno_wanted,
734                    KerberosTime t,
735                    struct KeyRotation *krp)
736 {
737     krb5_error_code ret;
738     hdb_keyset dks;
739     KerberosTime set_time, n;
740     krb5uint32 kvno;
741     size_t i;
742
743     if (rotation_period_offset < -1 || rotation_period_offset > 1)
744         return EINVAL; /* wat */
745
746     /*
747      * Compute `kvno' and `set_time' given `t' and `krp'.
748      *
749      * There be signed 32-bit time_t dragons here.
750      *
751      * (t - krp->epoch < 0) is better than (krp->epoch < t), making us more
752      * tolerant of signed 32-bit time_t here near 2038.  Of course, we have
753      * signed 32-bit time_t dragons elsewhere.
754      */
755     if (t - krp->epoch < 0)
756         return 0; /* This KR is not relevant yet */
757     n = (t - krp->epoch) / krp->period;
758     n += rotation_period_offset;
759     set_time = krp->epoch + krp->period * n;
760     kvno = krp->base_kvno + n;
761
762
763     /*
764      * Do not waste cycles computing keys not wanted or needed.
765      * A past kvno is too old if its set_time + rotation period is in the past
766      * by more than half a rotation period, since then no service ticket
767      * encrypted with keys of that kvno can still be extant.
768      *
769      * A future kvno is not coming up soon enough if we're more than a quarter
770      * of the rotation period away from it.
771      *
772      * Recall: the assumption for virtually-keyed principals is that services
773      * fetch their future keys frequently enough that they'll never miss having
774      * the keys they need.
775      */
776     if (!is_current_keyset || rotation_period_offset != 0) {
777         if ((kvno_wanted && kvno != kvno_wanted) ||
778             t - (set_time + krp->period + (krp->period >> 1)) > 0 ||
779             (set_time - t > 0 && (set_time - t) > (krp->period >> 2)))
780             return 0;
781     }
782
783     for (i = 0; i < base_keys->len; i++) {
784         if (base_keys->val[i].kvno == krp->base_key_kvno)
785             break;
786     }
787     if (i == base_keys->len) {
788         /* Base key not found! */
789         if (kvno_wanted || is_current_keyset) {
790             krb5_set_error_message(context, ret = HDB_ERR_KVNO_NOT_FOUND,
791                                    "Base key version %u not found for %s",
792                                    krp->base_key_kvno, princ);
793             return ret;
794         }
795         return 0;
796     }
797
798     ret = derive_keyset(context, &base_keys->val[i].keys, princ, etype, kvno,
799                         set_time, &dks);
800     if (ret == 0)
801         ret = hdb_install_keyset(context, &h->entry, is_current_keyset, &dks);
802
803     free_HDB_keyset(&dks);
804     return ret;
805 }
806
807 /* Derive and install current keys, and possibly preceding or next keys */
808 static krb5_error_code
809 derive_keys_for_current_kr(krb5_context context,
810                            hdb_entry_ex *h, 
811                            HDB_Ext_KeySet *base_keys,
812                            const char *princ,
813                            unsigned int flags,
814                            krb5int32 etype,
815                            krb5uint32 kvno_wanted,
816                            KerberosTime t,
817                            struct KeyRotation *krp,
818                            KerberosTime future_epoch)
819 {
820     krb5_error_code ret;
821
822     /* derive_keys_for_kr() for current kvno and install as the current keys */
823     ret = derive_keys_for_kr(context, h, base_keys, 1, 0, princ, etype,
824                              kvno_wanted, t, krp);
825     if (!(flags & HDB_F_ALL_KVNOS))
826         return ret;
827
828     /* */
829
830
831     /*
832      * derive_keys_for_kr() for prev kvno if still needed -- it can only be
833      * needed if the prev kvno's start time is within this KR's epoch.
834      *
835      * Note that derive_keys_for_kr() can return without doing anything if this
836      * is isn't the current keyset.  So these conditions need not be
837      * sufficiently narrow.
838      */
839     if (ret == 0 && t - krp->epoch >= krp->period)
840         ret = derive_keys_for_kr(context, h, base_keys, 0, -1, princ, etype,
841                                  kvno_wanted, t, krp);
842     /*
843      * derive_keys_for_kr() for next kvno if near enough, but only if it
844      * doesn't start after the next KR's epoch.
845      */
846     if (future_epoch &&
847         t - krp->epoch >= 0 /* We know!  Hint to the compiler */) {
848         KerberosTime next_kvno_start, n;
849
850         n = (t - krp->epoch) / krp->period;
851         next_kvno_start = krp->epoch + krp->period * (n + 1);
852         if (future_epoch - next_kvno_start <= 0)
853             return ret;
854     }
855     if (ret == 0)
856         ret = derive_keys_for_kr(context, h, base_keys, 0, 1, princ, etype,
857                                  kvno_wanted, t, krp);
858     return ret;
859 }
860
861 /*
862  * Derive and install all keysets in `h' that `princ' needs at time `now'.
863  *
864  * This mutates the entry `h' to
865  *
866  * a) not have base keys,
867  * b) have keys derived from the base keys according to
868  * c) the key rotation periods for the base principal (possibly the same
869  *    principal if it's a concrete principal with virtual keys), and the
870  *    requested time, enctype, and kvno (all of which are optional, with zero
871  *    implying some default).
872  *
873  * Arguments:
874  *
875  *  - `flags' is the flags passed to `hdb_fetch_kvno()'
876  *  - `princ' is the name of the principal we'll end up with in `h->entry'
877  *  - `h_is_namespace' indicates whether `h' is for a namespace or a concrete
878  *     principal (that might nonetheless have virtual/derived keys)
879  *  - `t' is the time such that the derived keys are for kvnos needed at `t'
880  *  - `etype' indicates what enctype to derive keys for (0 for all enctypes in
881  *    `h->entry.etypes')
882  *  - `kvno' requests a particular kvno, or all if zero
883  *
884  * The caller doesn't know if the principal needs key derivation -- we make
885  * that determination in this function.
886  *
887  * Note that this function is fully deterministic for any given set of
888  * arguments and HDB contents.
889  *
890  * Definitions:
891  *
892  *  - A keyset is a set of keys for a single kvno.
893  *  - A keyset is relevant IFF:
894  *     - it is the keyset for a time period identified by `t' in a
895  *       corresponding KR
896  *     - it is a keyset for a past time period for which there may be extant,
897  *       not-yet-expired tickets that a service may need to decrypt
898  *     - it is a keyset for an upcoming time period that a service will need to
899  *       fetch before that time period becomes current, that way the service
900  *       can have keytab entries for those keys in time for when the KDC starts
901  *       encrypting service tickets to those keys
902  *
903  * This function derives the keyset(s) for the current KR first.  The idea is
904  * to optimize the order of resulting keytabs so that the most likely keys to
905  * be used come first.
906  *
907  * Invariants:
908  *
909  *  - KR metadata is sane because sanity is checked for when storing HDB
910  *    entries
911  *  - KRs are sorted by epoch in descending order; KR #0's epoch is the most
912  *    recent
913  *  - KR periods are non-zero (we divide by period)
914  *  - kvnos are numerically ordered and correspond to time periods
915  *     - within each KR, the kvnos for larger times are larger than (or equal
916  *       to) the kvnos of earlier times
917  *     - at KR boundaries, the first kvno of the newer boundary is larger than
918  *       the kvno of the last time period of the previous KR
919  *  - the time `t' must fall into exactly one KR period
920  *  - the time `t' must fall into exactly one period within a KR period
921  *  - at most two kvnos will be relevant from the KR that `t' falls into
922  *    (the current kvno for `t', and possibly either the preceding, or the
923  *    next)
924  *  - at most one kvno from non-current KRs will be derived: possibly one for a
925  *    preceding KR, and possibly one from an upcoming KR
926  *
927  * There can be:
928  *
929  *  - no KR extension (not a namespace principal, and no virtual keys)
930  *  - 1, 2, or 3 KRs (see above)
931  *  - the newest KR may have the `deleted' flag, meaning "does not exist after
932  *    this epoch"
933  *
934  * Note that the last time period in any older KR can be partial.
935  *
936  * Timeline diagram:
937  *
938  *   .......|--+--+...+--|---+---+---+...+--|----+...
939  *         T20          T10 T11 RT12    T1n     T01
940  *     ^    ^  ^  ^   ^  ^               ^ T00
941  *     |    |  | T22 T2n |               |  ^
942  *     ^    | T21        |               |  |
943  *   princ  |  |        epoch of         | epoch of
944  *    did   |  |        middle KR        | newest epoch
945  *    not   |  |                         |
946  *   exist! | start of                  Note that T1n
947  *          | second kvno               is shown as shorter
948  *          | in 1st epoch              than preceding periods
949  *          |
950  *          ^
951  *         first KR's
952  *         epoch, and start
953  *         of its first kvno
954  *
955  * Tmn == the start of the Mth KR's Nth time period.
956  *        (higher M -> older KR; lower M -> newer KR)
957  *        (N is the reverse: lower N -> older time period in KR)
958  * T20 == start of oldest KR -- no keys before this time will be derived.
959  * T2n == last time period in oldest KR
960  * T10 == start of middle KR
961  * T1n == last time period in middle KR
962  * T00 == start of newest KR
963  * T0n == current time period in newest KR for wall clock time
964  */
965 static krb5_error_code
966 derive_keys(krb5_context context,
967             unsigned flags,
968             krb5_const_principal princ,
969             int h_is_namespace,
970             krb5_timestamp t,
971             krb5int32 etype,
972             krb5uint32 kvno,
973             hdb_entry_ex *h)
974 {
975     HDB_Ext_KeyRotation kr;
976     HDB_Ext_KeySet base_keys;
977     krb5_error_code ret = 0;
978     size_t current_kr, future_kr, past_kr, i;
979     char *p = NULL;
980     int valid = 1;
981
982     if (!h_is_namespace && !h->entry.flags.virtual_keys)
983         return 0;
984     h->entry.flags.virtual = 1;
985     if (h_is_namespace) {
986         /* Set the entry's principal name */
987         free_Principal(h->entry.principal);
988         ret = copy_Principal(princ, h->entry.principal);
989     }
990
991     kr.len = 0;
992     kr.val = 0;
993     if (ret == 0) {
994         const HDB_Ext_KeyRotation *ckr;
995
996         /* Installing keys invalidates `ckr', so we copy it */
997         ret = hdb_entry_get_key_rotation(context, &h->entry, &ckr);
998         if (!ckr)
999             return ret;
1000         if (ret == 0)
1001             ret = copy_HDB_Ext_KeyRotation(ckr, &kr);
1002     }
1003
1004     /* Get the base keys from the entry, and remove them */
1005     base_keys.val = 0;
1006     base_keys.len = 0;
1007     if (ret == 0)
1008         ret = hdb_remove_base_keys(context, &h->entry, &base_keys);
1009
1010     /* Make sure we have h->entry.etypes */
1011     if (ret == 0 && !h->entry.etypes)
1012         ret = hdb_derive_etypes(context, &h->entry, &base_keys);
1013
1014     /* Keys not desired?  Don't derive them! */
1015     if (ret || !(flags & HDB_F_DECRYPT)) {
1016         free_HDB_Ext_KeyRotation(&kr);
1017         free_HDB_Ext_KeySet(&base_keys);
1018         return ret;
1019     }
1020
1021     /* The principal name will be used in key derivation and error messages */
1022     if (ret == 0 && h_is_namespace)
1023         ret = krb5_unparse_name(context, princ, &p);
1024
1025     /* Sanity check key rotations, determine current & last kr */
1026     if (ret == 0 && kr.len < 1)
1027         krb5_set_error_message(context, ret = HDB_ERR_NOENTRY,
1028                                "no key rotation periods for %s", p);
1029     if (ret == 0)
1030         current_kr = future_kr = past_kr = kr.len;
1031     else
1032         current_kr = future_kr = past_kr = 1;
1033
1034     /*
1035      * Identify a current, next, and previous KRs if there are any.
1036      *
1037      * There can be up to three KRs, ordered by epoch, descending, making up a
1038      * timeline like:
1039      *
1040      *   ...|---------|--------|------>
1041      *   ^  |         |        |
1042      *   |  |         |        |
1043      *   |  |         |        Newest KR (kr.val[0])
1044      *   |  |         Middle KR (kr.val[1])
1045      *   |  Oldest (last) KR (kr.val[2])
1046      *   |
1047      *   Before the begging of time for this namespace
1048      *
1049      * We step through these from future towards past looking for the best
1050      * future, current, and past KRs.  The best current KR is one that has its
1051      * epoch nearest to `t' but in the past of `t'.
1052      *
1053      * We validate KRs before storing HDB entries with the KR extension, so we
1054      * can assume they are valid here.  However, we do some validity checking,
1055      * and if they're not valid, we pick the best current KR and ignore the
1056      * others.
1057      *
1058      * In principle there cannot be two future KRs, but this function is
1059      * deterministic and takes a time value, so it should not enforce this just
1060      * so we can test.  Enforcement of such rules should be done at store time.
1061      */
1062     for (i = 0; ret == 0 && i < kr.len; i++) {
1063         /* Minimal validation: order and period */
1064         if (i && kr.val[i - 1].epoch - kr.val[i].epoch <= 0) {
1065             future_kr = past_kr = kr.len;
1066             valid = 0;
1067         }
1068         if (!kr.val[i].period) {
1069             future_kr = past_kr = kr.len;
1070             valid = 0;
1071             continue;
1072         }
1073         if (t - kr.val[i].epoch >= 0) {
1074             /*
1075              * `t' is in the future of this KR's epoch, so it's a candidate for
1076              * either current or past KR.
1077              */
1078             if (current_kr == kr.len)
1079                 current_kr = i; /* First curr KR candidate; should be best */
1080             else if (kr.val[current_kr].epoch - kr.val[i].epoch < 0)
1081                 current_kr = i; /* Invalid KRs, but better curr KR cand. */
1082             else if (valid && past_kr == kr.len)
1083                 past_kr = i;
1084         } else if (valid) {
1085             /* This KR is in the future of `t', a candidate for next KR */
1086             future_kr = i;
1087         }
1088     }
1089     if (ret == 0 && current_kr == kr.len)
1090         /* No current KR -> too soon */
1091         krb5_set_error_message(context, ret = HDB_ERR_NOENTRY,
1092                                "Too soon for virtual principal to exist");
1093
1094     /* Check that the principal has not been marked deleted */
1095     if (ret == 0 && current_kr < kr.len && kr.val[current_kr].flags.deleted)
1096         krb5_set_error_message(context, ret = HDB_ERR_NOENTRY,
1097                                "virtual principal %s does not exist "
1098                                "because last key rotation period "
1099                                "marks deletion", p);
1100
1101     /*
1102      * Derive and set in `h' its current kvno and current keys.
1103      *
1104      * This will set h->entry.kvno as well.
1105      *
1106      * This may set up to TWO keysets for the current key rotation period:
1107      *  - current keys (h->entry.keys and h->entry.kvno)
1108      *  - possibly one future
1109      *    OR
1110      *    possibly one past keyset in hist_keys for the current_kr
1111      */
1112     if (ret == 0 && current_kr < kr.len)
1113         ret = derive_keys_for_current_kr(context, h, &base_keys, p, flags,
1114                                          etype, kvno, t, &kr.val[current_kr],
1115                                          current_kr ? kr.val[0].epoch : 0);
1116
1117     /*
1118      * Derive and set in `h' its future keys for next KR if it is soon to be
1119      * current.
1120      *
1121      * We want to derive keys for the first kvno of the next (future) KR if
1122      * it's sufficiently close to `t', meaning within 1 period of the current
1123      * KR, but we want these keys to be available sooner, so 1.5 of the current
1124      * period.
1125      */
1126     if (ret == 0 && future_kr < kr.len && (flags & HDB_F_ALL_KVNOS))
1127         ret = derive_keys_for_kr(context, h, &base_keys, 0, 0, p, etype, kvno,
1128                                  kr.val[future_kr].epoch, &kr.val[future_kr]);
1129
1130     /*
1131      * Derive and set in `h' its past keys for the previous KR if its last time
1132      * period could still have extant, unexpired service tickets encrypted in
1133      * its keys.
1134      */
1135     if (ret == 0 && past_kr < kr.len && (flags & HDB_F_ALL_KVNOS))
1136         ret = derive_keys_for_kr(context, h, &base_keys, 0, 0, p, etype, kvno,
1137                                  kr.val[current_kr].epoch - 1, &kr.val[past_kr]);
1138
1139     /*
1140      * Impose a bound on h->entry.max_life so that [when the KDC is the caller]
1141      * the KDC won't issue tickets longer lived than this.
1142      */
1143     if (ret == 0 && !h->entry.max_life &&
1144         (h->entry.max_life = malloc(sizeof(h->entry.max_life[0]))) == NULL)
1145         ret = krb5_enomem(context);
1146     if (ret == 0 && *h->entry.max_life > kr.val[current_kr].period >> 1)
1147         *h->entry.max_life = kr.val[current_kr].period >> 1;
1148
1149     free_HDB_Ext_KeyRotation(&kr);
1150     free_HDB_Ext_KeySet(&base_keys);
1151     free(p);
1152     return ret;
1153 }
1154
1155 /*
1156  * In order for disparate keytab provisioning systems such as OSKT and our own
1157  * kadmin ext_keytab and httpkadmind's get-keys to coexist, we need to be able
1158  * to force keys set by the former to not become current keys until users of
1159  * the latter have had a chance to fetch those keys into their keytabs.  To do
1160  * this we have to search the list of keys in the entry looking for the newest
1161  * keys older than `now - db->new_service_key_delay'.
1162  *
1163  * The context is that OSKT's krb5_keytab is very happy to change keys in a way
1164  * that requires all members of a cluster to rekey together.  If one also
1165  * wishes to have cluster members that opt out of this and just fetch current,
1166  * past, and future keys periodically, then the keys set by OSKT need to not
1167  * come into effect until all the opt-out members have had a chance to fetch
1168  * the new keys.
1169  *
1170  * The assumption is that services will fetch new keys periodically, say, every
1171  * four hours.  Then one can set `[hdb] new_service_key_delay = 8h' in the
1172  * configuration and new keys set by OSKT will not be used until 8h after they
1173  * are set.
1174  *
1175  * Naturally, this applies only to concrete principals with concrete keys.
1176  */
1177 static krb5_error_code
1178 fix_keys(krb5_context context,
1179          HDB *db,
1180          unsigned flags,
1181          krb5_timestamp now,
1182          krb5uint32 kvno,
1183          hdb_entry_ex *h)
1184 {
1185     HDB_extension *ext;
1186     HDB_Ext_KeySet keys;
1187     time_t current = 0;
1188     time_t best;
1189     size_t i;
1190
1191     /*
1192      * If we want a specific kvno, or if the caller doesn't want new keys
1193      * delayed, or if there's no new-key delay configured, or we're not
1194      * fetching for use as a service principal, then we're out.
1195      */
1196     if (!(flags & HDB_F_DELAY_NEW_KEYS) || kvno || h->entry.flags.virtual ||
1197         h->entry.flags.virtual_keys || db->new_service_key_delay <= 0)
1198         return 0;
1199
1200     /* No history -> current keyset is the only one and therefore the best */
1201     ext = hdb_find_extension(&h->entry, choice_HDB_extension_data_hist_keys);
1202     if (!ext)
1203         return 0;
1204
1205     /* Assume the current keyset is the best to start with */
1206     (void) hdb_entry_get_pw_change_time(&h->entry, &current);
1207     if (current == 0 && h->entry.modified_by)
1208         current = h->entry.modified_by->time;
1209     if (current == 0)
1210         current = h->entry.created_by.time;
1211
1212     /* Current keyset starts out as best */
1213     best = current;
1214     kvno = h->entry.kvno;
1215
1216     /* Look for a better keyset in the history */
1217     keys = ext->data.u.hist_keys;
1218     for (i = 0; i < keys.len; i++) {
1219         /* No set_time?  Ignore.  Too new?  Ignore */
1220         if (!keys.val[i].set_time ||
1221             keys.val[i].set_time[0] + db->new_service_key_delay > now)
1222             continue;
1223
1224         /*
1225          * Ignore the keyset with kvno 1 when the entry has better kvnos
1226          * because kadmin's `ank -r' command immediately changes the keys.
1227          */
1228         if (kvno > 1 && keys.val[i].kvno == 1)
1229             continue;
1230
1231         /*
1232          * This keyset's set_time older than the previous best?  Ignore.
1233          * However, if the current best is the entry's current and that one
1234          * is too new, then don't ignore this one.
1235          */
1236         if (keys.val[i].set_time[0] < best &&
1237             (best != current || current + db->new_service_key_delay < now))
1238             continue;
1239
1240         /*
1241          * If two good enough keysets have the same set_time, take the keyset
1242          * with the highest kvno.
1243          */
1244         if (keys.val[i].set_time[0] == best && keys.val[i].kvno <= kvno)
1245             continue;
1246
1247         /*
1248          * This keyset is clearly more current than the previous best keyset
1249          * but still old enough to use for encrypting tickets with.
1250          */
1251         best = keys.val[i].set_time[0];
1252         kvno = keys.val[i].kvno;
1253     }
1254     return hdb_change_kvno(context, kvno, &h->entry);
1255 }
1256
1257 /*
1258  * Make a WELLKNOWN/HOSTBASED-NAMESPACE/${svc}/${hostname} or
1259  * WELLKNOWN/HOSTBASED-NAMESPACE/${svc}/${hostname}/${domainname} principal
1260  * object, with the service and hostname components take from `wanted', but if
1261  * the service name is not in the list `db->virtual_hostbased_princ_svcs[]'
1262  * then use "_" (wildcard) instead.  This way we can have different attributes
1263  * for different services in the same namespaces.
1264  *
1265  * For example, virtual hostbased service names for the "host" service might
1266  * have ok-as-delegate set, but ones for the "HTTP" service might not.
1267  */
1268 static krb5_error_code
1269 make_namespace_princ(krb5_context context,
1270                      HDB *db,
1271                      krb5_const_principal wanted,
1272                      krb5_principal *namespace)
1273 {
1274     krb5_error_code ret = 0;
1275     const char *realm = krb5_principal_get_realm(context, wanted);
1276     const char *comp0 = krb5_principal_get_comp_string(context, wanted, 0);
1277     const char *comp1 = krb5_principal_get_comp_string(context, wanted, 1);
1278     const char *comp2 = krb5_principal_get_comp_string(context, wanted, 2);
1279     char * const *svcs = db->virtual_hostbased_princ_svcs;
1280     size_t i;
1281
1282     *namespace = NULL;
1283     if (comp0 == NULL || comp1 == NULL)
1284         return EINVAL;
1285     if (strcmp(comp0, "krbtgt") == 0)
1286         return 0;
1287
1288     for (i = 0; svcs && svcs[i]; i++) {
1289         if (strcmp(comp0, svcs[i]) == 0) {
1290             comp0 = svcs[i];
1291             break;
1292         }
1293     }
1294     if (!svcs || !svcs[i])
1295         comp0 = "_";
1296
1297     /* First go around, need a namespace princ.  Make it! */
1298     ret = krb5_build_principal(context, namespace, strlen(realm),
1299                                 realm, "WELLKNOWN",
1300                                 HDB_WK_NAMESPACE, comp0, NULL);
1301     if (ret == 0)
1302         ret = krb5_principal_set_comp_string(context, *namespace, 3, comp1);
1303     if (ret == 0 && comp2)
1304         /* Support domain-based names */
1305         ret = krb5_principal_set_comp_string(context, *namespace, 4, comp2);
1306     /* Caller frees `*namespace' on error */
1307     return ret;
1308 }
1309
1310 /* Wrapper around db->hdb_fetch_kvno() that implements virtual princs/keys */
1311 static krb5_error_code
1312 fetch_it(krb5_context context,
1313          HDB *db,
1314          krb5_const_principal princ,
1315          unsigned flags,
1316          krb5_timestamp t,
1317          krb5int32 etype,
1318          krb5uint32 kvno,
1319          hdb_entry_ex *ent)
1320 {
1321     krb5_const_principal tmpprinc = princ;
1322     krb5_principal baseprinc = NULL;
1323     krb5_error_code ret = 0;
1324     const char *comp0 = krb5_principal_get_comp_string(context, princ, 0);
1325     const char *comp1 = krb5_principal_get_comp_string(context, princ, 1);
1326     const char *tmp;
1327     size_t mindots = db->virtual_hostbased_princ_ndots;
1328     size_t maxdots = db->virtual_hostbased_princ_maxdots;
1329     size_t hdots = 0;
1330     char *host = NULL;
1331     int do_search = 0;
1332
1333     if (db->enable_virtual_hostbased_princs && comp1 &&
1334         strcmp("krbtgt", comp0) != 0 && strcmp("WELLKNOWN", comp0) != 0) {
1335         char *htmp;
1336
1337         if ((host = strdup(comp1)) == NULL)
1338             return krb5_enomem(context);
1339
1340         /* Strip out any :port */
1341         htmp = strchr(host, ':');
1342         if (htmp) {
1343             if (strchr(htmp + 1, ':')) {
1344                 /* Extra ':'s?  No virtualization for you! */
1345                 free(host);
1346                 host = NULL;
1347                 htmp = NULL;
1348             } else {
1349                 *htmp = '\0';
1350             }
1351         }
1352         /* Count dots in `host' */
1353         for (hdots = 0, htmp = host; htmp && *htmp; htmp++)
1354             if (*htmp == '.')
1355                 hdots++;
1356
1357         do_search = 1;
1358     }
1359
1360     tmp = host ? host : comp1;
1361     for (ret = HDB_ERR_NOENTRY; ret == HDB_ERR_NOENTRY; tmpprinc = baseprinc) {
1362         krb5_error_code ret2 = 0;
1363
1364         /*
1365          * We break out of this loop with ret == 0 only if we found the HDB
1366          * entry we were looking for or the HDB entry for a matching namespace.
1367          *
1368          * Otherwise we break out with ret != 0, typically HDB_ERR_NOENTRY.
1369          *
1370          * First time through we lookup the principal as given.
1371          *
1372          * Next we lookup a namespace principal, stripping off hostname labels
1373          * from the left until we find one or get tired of looking or run out
1374          * of labels.
1375          */
1376         ret = db->hdb_fetch_kvno(context, db, tmpprinc, flags, kvno, ent);
1377         if (ret != HDB_ERR_NOENTRY || hdots == 0 || hdots < mindots || !tmp ||
1378             !do_search)
1379             break;
1380
1381         /*
1382          * Breadcrumb:
1383          *
1384          *  - if we found a concrete principal, but it's been marked
1385          *    as now-virtual, then we must keep going
1386          *
1387          * But this will be coded in the future.
1388          *
1389          * Maybe we can take attributes from the concrete principal...
1390          */
1391
1392         /*
1393          * The namespace's hostname will not have more labels than maxdots + 1.
1394          * Thus we truncate immediately down to maxdots + 1 if we haven't yet.
1395          *
1396          * Example: with maxdots == 3,
1397          *          foo.bar.baz.app.blah.example -> baz.app.blah.example
1398          */
1399         while (maxdots && hdots > maxdots && tmp) {
1400             tmp = strchr(tmp, '.');
1401             /* tmp != NULL because maxdots > 0 */
1402             tmp++;
1403             hdots--;
1404         }
1405
1406         if (baseprinc == NULL)
1407             /* First go around, need a namespace princ.  Make it! */
1408             ret2 = make_namespace_princ(context, db, tmpprinc, &baseprinc);
1409             /* Update the hostname component */
1410         if (ret2 == 0)
1411             ret2 = krb5_principal_set_comp_string(context, baseprinc, 3, tmp);
1412         if (ret2)
1413             ret = ret2;
1414
1415         if (tmp) {
1416             /* Strip off left-most label for the next go-around */
1417             if ((tmp = strchr(tmp, '.')))
1418                 tmp++;
1419             hdots--;
1420         } /* else we'll break out after the next db->hdb_fetch_kvno() call */
1421     }
1422
1423     /*
1424      * If unencrypted keys were requested, derive them.  There may not be any
1425      * key derivation to do, but that's decided in derive_keys().
1426      */
1427     if (ret == 0) {
1428         ret = derive_keys(context, flags, princ, !!baseprinc, t, etype, kvno,
1429                           ent);
1430         if (ret == 0)
1431             ret = fix_keys(context, db, flags, t, kvno, ent);
1432         if (ret)
1433             hdb_free_entry(context, ent);
1434     }
1435     krb5_free_principal(context, baseprinc);
1436     free(host);
1437     return ret;
1438 }
1439
1440 /**
1441  * Fetch a principal's HDB entry, possibly generating virtual keys from base
1442  * keys according to strict key rotation schedules.  If a time is given, other
1443  * than HDB I/O, this function is pure, thus usable for testing.
1444  *
1445  * HDB writers should use `db->hdb_fetch_kvno()' to avoid materializing virtual
1446  * principals.
1447  *
1448  * HDB readers should use this function rather than `db->hdb_fetch_kvno()'
1449  * unless they only want to see concrete principals and not bother generating
1450  * any virtual keys.
1451  *
1452  * @param context Context
1453  * @param db HDB
1454  * @param principal Principal name
1455  * @param flags Fetch flags
1456  * @param t For virtual keys, use this as the point in time (use zero to mean "now")
1457  * @param etype Key enctype (use KRB5_ENCTYPE_NULL to mean "preferred")
1458  * @param kvno Key version number (use zero to mean "current")
1459  * @param h Output HDB entry
1460  *
1461  * @return Zero on success, an error code otherwise.
1462  */
1463 krb5_error_code
1464 hdb_fetch_kvno(krb5_context context,
1465                HDB *db,
1466                krb5_const_principal principal,
1467                unsigned int flags,
1468                krb5_timestamp t,
1469                krb5int32 etype,
1470                krb5uint32 kvno,
1471                hdb_entry_ex *h)
1472 {
1473     krb5_error_code ret = HDB_ERR_NOENTRY;
1474
1475     flags |= kvno ? HDB_F_KVNO_SPECIFIED : 0; /* XXX is this needed */
1476     if (t == 0)
1477         krb5_timeofday(context, &t);
1478     ret = fetch_it(context, db, principal, flags, t, etype, kvno, h);
1479     if (ret == HDB_ERR_NOENTRY)
1480         krb5_set_error_message(context, ret, "no such entry found in hdb");
1481
1482     /*
1483      * This check is to support aliases in HDB; the force_canonicalize
1484      * check is to allow HDB backends to support realm name canon
1485      * independently of principal aliases (used by Samba).
1486      */
1487     if (ret == 0 && !(flags & HDB_F_ADMIN_DATA) &&
1488         !h->entry.flags.force_canonicalize &&
1489         !krb5_realm_compare(context, principal, h->entry.principal))
1490             ret = HDB_ERR_WRONG_REALM;
1491     return ret;
1492 }
1493
1494 size_t ASN1CALL
1495 length_hdb_keyset(HDB_keyset *data)
1496 {
1497     return length_HDB_keyset(data);
1498 }
1499
1500 size_t ASN1CALL
1501 length_hdb_entry(HDB_entry *data)
1502 {
1503     return length_HDB_entry(data);
1504 }
1505
1506 size_t ASN1CALL
1507 length_hdb_entry_alias(HDB_entry_alias *data)
1508 {
1509     return length_HDB_entry_alias(data);
1510 }
1511
1512 void ASN1CALL
1513 free_hdb_keyset(HDB_keyset *data)
1514 {
1515     free_HDB_keyset(data);
1516 }
1517
1518 void ASN1CALL
1519 free_hdb_entry(HDB_entry *data)
1520 {
1521     free_HDB_entry(data);
1522 }
1523
1524 void ASN1CALL
1525 free_hdb_entry_alias(HDB_entry_alias *data)
1526 {
1527     free_HDB_entry_alias(data);
1528 }
1529
1530 size_t ASN1CALL
1531 copy_hdb_keyset(const HDB_keyset *from, HDB_keyset *to)
1532 {
1533     return copy_HDB_keyset(from, to);
1534 }
1535
1536 size_t ASN1CALL
1537 copy_hdb_entry(const HDB_entry *from, HDB_entry *to)
1538 {
1539     return copy_HDB_entry(from, to);
1540 }
1541
1542 size_t ASN1CALL
1543 copy_hdb_entry_alias(const HDB_entry_alias *from, HDB_entry_alias *to)
1544 {
1545     return copy_HDB_entry_alias(from, to);
1546 }
1547
1548 int ASN1CALL
1549 decode_hdb_keyset(const unsigned char *p,
1550                   size_t len,
1551                   HDB_keyset *data,
1552                   size_t *size)
1553 {
1554     return decode_HDB_keyset(p, len, data, size);
1555 }
1556
1557 int ASN1CALL
1558 decode_hdb_entry(const unsigned char *p,
1559                  size_t len,
1560                  HDB_entry *data,
1561                  size_t *size)
1562 {
1563     return decode_HDB_entry(p, len, data, size);
1564 }
1565
1566 int ASN1CALL
1567 decode_hdb_entry_alias(const unsigned char *p,
1568                        size_t len,
1569                        HDB_entry_alias *data,
1570                        size_t *size)
1571 {
1572     return decode_HDB_entry_alias(p, len, data, size);
1573 }
1574
1575 int ASN1CALL
1576 encode_hdb_keyset(unsigned char *p,
1577                   size_t len,
1578                   const HDB_keyset *data,
1579                   size_t *size)
1580 {
1581     return encode_HDB_keyset(p, len, data, size);
1582 }
1583
1584 int ASN1CALL
1585 encode_hdb_entry(unsigned char *p,
1586                  size_t len,
1587                  const HDB_entry *data,
1588                  size_t *size)
1589 {
1590     return encode_HDB_entry(p, len, data, size);
1591 }
1592
1593 int ASN1CALL
1594 encode_hdb_entry_alias(unsigned char *p,
1595                        size_t len,
1596                        const HDB_entry_alias *data,
1597                        size_t *size)
1598 {
1599     return encode_HDB_entry_alias(p, len, data, size);
1600 }