2 * kadmin/v5server/keytab.c
4 * Copyright 1995 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
33 is_xrealm_tgt(krb5_context
, krb5_const_principal
);
35 krb5_error_code
krb5_ktkdb_close (krb5_context
, krb5_keytab
);
37 krb5_error_code
krb5_ktkdb_get_entry (krb5_context
, krb5_keytab
, krb5_const_principal
,
38 krb5_kvno
, krb5_enctype
, krb5_keytab_entry
*);
40 static krb5_error_code
41 krb5_ktkdb_get_name(krb5_context context
, krb5_keytab keytab
,
42 char *name
, unsigned int namelen
)
44 if (namelen
< sizeof("KDB:"))
45 return KRB5_KT_NAME_TOOLONG
;
50 krb5_kt_ops krb5_kt_kdb_ops
= {
52 "KDB", /* Prefix -- this string should not appear anywhere else! */
53 krb5_ktkdb_resolve
, /* resolve */
54 krb5_ktkdb_get_name
, /* get_name */
55 krb5_ktkdb_close
, /* close */
56 krb5_ktkdb_get_entry
, /* get */
57 NULL
, /* start_seq_get */
60 NULL
, /* add (extended) */
61 NULL
, /* remove (extended) */
62 NULL
, /* (void *) &krb5_ktfile_ser_entry */
65 typedef struct krb5_ktkdb_data
{
70 krb5_ktkdb_resolve(context
, name
, id
)
75 if ((*id
= (krb5_keytab
) malloc(sizeof(**id
))) == NULL
)
77 (*id
)->ops
= &krb5_kt_kdb_ops
;
78 (*id
)->magic
= KV5M_KEYTAB
;
83 krb5_ktkdb_close(context
, kt
)
88 * This routine is responsible for freeing all memory allocated
89 * for this keytab. There are no system resources that need
90 * to be freed nor are there any open files.
92 * This routine should undo anything done by krb5_ktkdb_resolve().
101 static krb5_context ktkdb_ctx
= NULL
;
104 * Set a different context for use with ktkdb_get_entry(). This is
105 * primarily useful for kadmind, where the gssapi library context,
106 * which will be used for the keytab, will necessarily have a
107 * different context than that used by the kadm5 library to access the
108 * database for its own purposes.
111 krb5_ktkdb_set_context(krb5_context ctx
)
118 krb5_ktkdb_get_entry(in_context
, id
, principal
, kvno
, enctype
, entry
)
119 krb5_context in_context
;
121 krb5_const_principal principal
;
123 krb5_enctype enctype
;
124 krb5_keytab_entry
* entry
;
126 krb5_context context
;
127 krb5_keyblock
* master_key
;
128 krb5_error_code kerror
= 0;
129 krb5_key_data
* key_data
;
130 krb5_db_entry db_entry
;
131 krb5_boolean more
= 0;
134 krb5_boolean similar
;
139 context
= in_context
;
141 xrealm_tgt
= is_xrealm_tgt(context
, principal
);
144 /* krb5_db_init(context); */
145 if ((kerror
= krb5_db_inited(context
)))
149 kerror
= krb5_db_get_principal(context
, principal
, &
150 db_entry
, &n
, &more
);
152 /* krb5_db_close_database(context); */
156 /* krb5_db_close_database(context); */
157 return KRB5_KT_NOTFOUND
;
160 if (db_entry
.attributes
& KRB5_KDB_DISALLOW_SVR
161 || db_entry
.attributes
& KRB5_KDB_DISALLOW_ALL_TIX
) {
162 kerror
= KRB5_KT_NOTFOUND
;
167 kerror
= krb5_db_get_mkey(context
, &master_key
);
171 /* For cross realm tgts, we match whatever enctype is provided;
172 * for other principals, we only match the first enctype that is
173 * found. Since the TGS and AS code do the same thing, then we
174 * will only successfully decrypt tickets we have issued.*/
175 kerror
= krb5_dbe_find_enctype(context
, &db_entry
,
176 xrealm_tgt
?enctype
:-1,
177 -1, kvno
, &key_data
);
182 kerror
= krb5_dbekd_decrypt_key_data(context
, master_key
,
183 key_data
, &entry
->key
, NULL
);
188 kerror
= krb5_c_enctype_compare(context
, enctype
,
189 entry
->key
.enctype
, &similar
);
194 kerror
= KRB5_KDB_NO_PERMITTED_KEY
;
199 * Coerce the enctype of the output keyblock in case we got an
200 * inexact match on the enctype.
202 entry
->key
.enctype
= enctype
;
204 kerror
= krb5_copy_principal(context
, principal
, &entry
->principal
);
210 krb5_db_free_principal(context
, &db_entry
, 1);
211 /* krb5_db_close_database(context); */
216 * is_xrealm_tgt: Returns true if the principal is a cross-realm TGT
217 * principal-- a principal with first component krbtgt and second
218 * component not equal to realm.
221 is_xrealm_tgt(krb5_context context
, krb5_const_principal princ
)
224 if (krb5_princ_size(context
, princ
) != 2)
226 dat
= krb5_princ_component(context
, princ
, 0);
227 if (strncmp("krbtgt", dat
->data
, dat
->length
) != 0)
229 dat
= krb5_princ_component(context
, princ
, 1);
230 if (dat
->length
!= princ
->realm
.length
)
232 if (strncmp(dat
->data
, princ
->realm
.data
, dat
->length
) == 0)