2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
11 * Copyright 1995 by the Massachusetts Institute of Technology.
12 * All Rights Reserved.
14 * Export of this software from the United States of America may
15 * require a specific license from the United States Government.
16 * It is the responsibility of any person or organization contemplating
17 * export to obtain such a license before exporting.
19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
20 * distribute this software and its documentation for any purpose and
21 * without fee is hereby granted, provided that the above copyright
22 * notice appear in all copies and that both that copyright notice and
23 * this permission notice appear in supporting documentation, and that
24 * the name of M.I.T. not be used in advertising or publicity pertaining
25 * to distribution of the software without specific, written prior
26 * permission. Furthermore if you modify this software you must label
27 * your software as modified software and not distribute it in such a
28 * fashion that it might be confused with the original M.I.T. software.
29 * M.I.T. makes no representations about the suitability of
30 * this software for any purpose. It is provided "as is" without express
31 * or implied warranty.
44 * Given a particular enctype and optional salttype and kvno, find the
45 * most appropriate krb5_key_data entry of the database entry.
47 * If stype or kvno is negative, it is ignored.
48 * If kvno is 0 get the key which is maxkvno for the princ and matches
49 * the other attributes.
52 krb5_dbe_def_search_enctype(kcontext
, dbentp
, start
, ktype
, stype
, kvno
, kdatap
)
53 krb5_context kcontext
;
54 krb5_db_entry
*dbentp
;
59 krb5_key_data
**kdatap
;
67 if (kvno
== -1 && stype
== -1 && ktype
== -1)
71 /* Get the max key version */
72 for (i
= 0; i
< dbentp
->n_key_data
; i
++) {
73 if (kvno
< dbentp
->key_data
[i
].key_data_kvno
) {
74 kvno
= dbentp
->key_data
[i
].key_data_kvno
;
80 datap
= (krb5_key_data
*) NULL
;
81 for (i
= *start
; i
< dbentp
->n_key_data
; i
++) {
86 if (dbentp
->key_data
[i
].key_data_ver
> 1) {
87 db_stype
= dbentp
->key_data
[i
].key_data_type
[1];
89 db_stype
= KRB5_KDB_SALTTYPE_NORMAL
;
93 * Filter out non-permitted enctypes.
95 if (!krb5_is_permitted_enctype(kcontext
,
96 dbentp
->key_data
[i
].key_data_type
[0])) {
97 ret
= KRB5_KDB_NO_PERMITTED_KEY
;
103 if ((ret
= krb5_c_enctype_compare(kcontext
, (krb5_enctype
) ktype
,
104 dbentp
->key_data
[i
].key_data_type
[0],
110 if (((ktype
<= 0) || similar
) &&
111 ((db_stype
== stype
) || (stype
< 0))) {
113 if (kvno
== dbentp
->key_data
[i
].key_data_kvno
) {
114 datap
= &dbentp
->key_data
[i
];
120 if (dbentp
->key_data
[i
].key_data_kvno
> maxkvno
) {
121 maxkvno
= dbentp
->key_data
[i
].key_data_kvno
;
122 datap
= &dbentp
->key_data
[i
];
129 return ret
? ret
: KRB5_KDB_NO_MATCHING_KEY
;
136 * kdb default functions. Ideally, some other file should have this functions. For now, TBD.
139 #define min(a,b) (((a) < (b)) ? (a) : (b))
143 krb5_def_store_mkey(context
, keyfile
, mname
, key
, master_pwd
)
144 krb5_context context
;
146 krb5_principal mname
;
151 krb5_error_code retval
= 0;
153 char defkeyfile
[MAXPATHLEN
+1];
154 krb5_data
*realm
= krb5_princ_realm(context
, mname
);
160 (void) strcpy(defkeyfile
, DEFAULT_KEYFILE_STUB
);
161 (void) strncat(defkeyfile
, realm
->data
,
162 min(sizeof(defkeyfile
)-sizeof(DEFAULT_KEYFILE_STUB
)-1,
164 defkeyfile
[sizeof(defkeyfile
) - 1] = '\0';
165 keyfile
= defkeyfile
;
172 /* Solaris Kerberos: using F to deal with 256 open file limit */
173 if (!(kf
= fopen(keyfile
, "wbF")))
175 if (!(kf
= fopen(keyfile
, "wF")))
180 (void) umask(oumask
);
182 krb5_set_error_message (context
, e
,
183 gettext("%s accessing file '%s'"),
184 error_message (e
), keyfile
);
187 enctype
= key
->enctype
;
188 if ((fwrite((krb5_pointer
) &enctype
,
190 (fwrite((krb5_pointer
) &key
->length
,
191 sizeof(key
->length
), 1, kf
) != 1) ||
192 (fwrite((krb5_pointer
) key
->contents
,
193 sizeof(key
->contents
[0]), (unsigned) key
->length
,
194 kf
) != key
->length
)) {
198 if (fclose(kf
) == EOF
)
201 (void) umask(oumask
);
208 krb5_db_def_fetch_mkey( krb5_context context
,
209 krb5_principal mname
,
214 krb5_error_code retval
;
216 char defkeyfile
[MAXPATHLEN
+1];
217 krb5_data
*realm
= krb5_princ_realm(context
, mname
);
221 key
->magic
= KV5M_KEYBLOCK
;
222 (void) strcpy(defkeyfile
, DEFAULT_KEYFILE_STUB
);
223 (void) strncat(defkeyfile
, realm
->data
,
224 min(sizeof(defkeyfile
)-sizeof(DEFAULT_KEYFILE_STUB
)-1,
226 defkeyfile
[sizeof(defkeyfile
) - 1] = '\0';
229 /* Solaris Kerberos: using F to deal with 256 open file limit */
230 if (!(kf
= fopen((db_args
) ? db_args
: defkeyfile
, "rbF")))
232 if (!(kf
= fopen((db_args
) ? db_args
: defkeyfile
, "rF")))
234 return KRB5_KDB_CANTREAD_STORED
;
236 if (fread((krb5_pointer
) &enctype
, 2, 1, kf
) != 1) {
237 retval
= KRB5_KDB_CANTREAD_STORED
;
241 if (key
->enctype
== ENCTYPE_UNKNOWN
)
242 key
->enctype
= enctype
;
243 else if (enctype
!= key
->enctype
) {
244 retval
= KRB5_KDB_BADSTORED_MKEY
;
248 if (fread((krb5_pointer
) &key
->length
,
249 sizeof(key
->length
), 1, kf
) != 1) {
250 retval
= KRB5_KDB_CANTREAD_STORED
;
254 if (!key
->length
|| ((int) key
->length
) < 0) {
255 retval
= KRB5_KDB_BADSTORED_MKEY
;
259 if (!(key
->contents
= (krb5_octet
*)malloc(key
->length
))) {
264 if (fread((krb5_pointer
) key
->contents
,
265 sizeof(key
->contents
[0]), key
->length
, kf
)
267 retval
= KRB5_KDB_CANTREAD_STORED
;
268 memset(key
->contents
, 0, key
->length
);
284 krb5_def_verify_master_key(context
, mprinc
, mkey
)
285 krb5_context context
;
286 krb5_principal mprinc
;
289 krb5_error_code retval
;
290 krb5_db_entry master_entry
;
293 krb5_keyblock tempkey
;
296 if ((retval
= krb5_db_get_principal(context
, mprinc
,
297 &master_entry
, &nprinc
, &more
)))
302 krb5_db_free_principal(context
, &master_entry
, nprinc
);
303 return(KRB5_KDB_NOMASTERKEY
);
305 krb5_db_free_principal(context
, &master_entry
, nprinc
);
306 return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE
);
309 if ((retval
= krb5_dbekd_decrypt_key_data(context
, mkey
,
310 &master_entry
.key_data
[0],
312 krb5_db_free_principal(context
, &master_entry
, nprinc
);
316 if (mkey
->length
!= tempkey
.length
||
317 memcmp((char *)mkey
->contents
,
318 (char *)tempkey
.contents
,mkey
->length
)) {
319 retval
= KRB5_KDB_BADMASTERKEY
;
322 memset((char *)tempkey
.contents
, 0, tempkey
.length
);
323 krb5_xfree(tempkey
.contents
);
324 krb5_db_free_principal(context
, &master_entry
, nprinc
);
330 krb5_error_code
kdb_def_set_mkey ( krb5_context kcontext
,
334 /* printf("default set master key\n"); */
338 krb5_error_code
kdb_def_get_mkey ( krb5_context kcontext
,
339 krb5_keyblock
**key
)
341 /* printf("default get master key\n"); */
345 krb5_error_code
krb5_def_promote_db (krb5_context kcontext
,
346 char *s
, char **args
)
348 /* printf("default promote_db\n"); */
349 return KRB5_PLUGIN_OP_NOTSUPP
;