2 * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #include <parse_bytes.h>
40 static const char *sysplugin_dirs
[] = {
44 "$ORIGIN/../lib/plugin/kdc",
53 load_kdc_plugins_once(void *ctx
)
55 krb5_context context
= ctx
;
56 const char * const *dirs
= sysplugin_dirs
;
60 cfdirs
= krb5_config_get_strings(context
, NULL
, "kdc", "plugin_dir", NULL
);
62 dirs
= (const char * const *)cfdirs
;
65 _krb5_load_plugins(context
, "kdc", (const char **)dirs
);
68 krb5_config_free_strings(cfdirs
);
72 KDC_LIB_FUNCTION krb5_error_code KDC_LIB_CALL
73 krb5_kdc_get_config(krb5_context context
, krb5_kdc_configuration
**config
)
75 static heim_base_once_t load_kdc_plugins
= HEIM_BASE_ONCE_INIT
;
76 krb5_kdc_configuration
*c
;
79 heim_base_once_f(&load_kdc_plugins
, context
, load_kdc_plugins_once
);
81 c
= calloc(1, sizeof(*c
));
83 krb5_set_error_message(context
, ENOMEM
, "malloc: out of memory");
88 c
->num_kdc_processes
= -1;
89 c
->require_preauth
= TRUE
;
90 c
->kdc_warn_pwexpire
= 0;
91 c
->encode_as_rep_as_tgs_rep
= FALSE
;
92 c
->tgt_use_strongest_session_key
= FALSE
;
93 c
->preauth_use_strongest_session_key
= FALSE
;
94 c
->svc_use_strongest_session_key
= FALSE
;
95 c
->use_strongest_server_key
= TRUE
;
96 c
->check_ticket_addresses
= TRUE
;
97 c
->warn_ticket_addresses
= FALSE
;
98 c
->allow_null_ticket_addresses
= TRUE
;
99 c
->allow_anonymous
= FALSE
;
100 c
->historical_anon_realm
= FALSE
;
101 c
->strict_nametypes
= FALSE
;
102 c
->trpolicy
= TRPOLICY_ALWAYS_CHECK
;
103 c
->require_pac
= FALSE
;
104 c
->enable_armored_pa_enc_timestamp
= TRUE
;
105 c
->enable_unarmored_pa_enc_timestamp
= TRUE
;
106 c
->enable_pkinit
= FALSE
;
107 c
->pkinit_princ_in_cert
= TRUE
;
108 c
->pkinit_require_binding
= TRUE
;
109 c
->synthetic_clients
= FALSE
;
110 c
->pkinit_max_life_from_cert_extension
= FALSE
;
111 c
->pkinit_max_life_bound
= 0;
112 c
->synthetic_clients_max_life
= 300;
113 c
->synthetic_clients_max_renew
= 300;
114 c
->pkinit_dh_min_bits
= 1024;
119 c
->num_kdc_processes
=
120 krb5_config_get_int_default(context
, NULL
, c
->num_kdc_processes
,
121 "kdc", "num-kdc-processes", NULL
);
124 krb5_config_get_bool_default(context
, NULL
,
126 "kdc", "require-preauth", NULL
);
129 krb5_config_get_bool_default(context
, NULL
,
131 "kdc", "enable-digest", NULL
);
136 digests
= krb5_config_get_string(context
, NULL
,
138 "digests_allowed", NULL
);
141 c
->digests_allowed
= parse_flags(digests
,_kdc_digestunits
, 0);
142 if (c
->digests_allowed
== -1) {
143 kdc_log(context
, c
, 0,
144 "unparsable digest units (%s), turning off digest",
146 c
->enable_digest
= 0;
147 } else if (c
->digests_allowed
== 0) {
148 kdc_log(context
, c
, 0, "no digest enable, turning digest off");
149 c
->enable_digest
= 0;
156 krb5_config_get_bool_default(context
, NULL
,
158 "kdc", "enable_kx509", NULL
);
161 c
->tgt_use_strongest_session_key
=
162 krb5_config_get_bool_default(context
, NULL
,
163 c
->tgt_use_strongest_session_key
,
165 "tgt-use-strongest-session-key", NULL
);
166 c
->preauth_use_strongest_session_key
=
167 krb5_config_get_bool_default(context
, NULL
,
168 c
->preauth_use_strongest_session_key
,
170 "preauth-use-strongest-session-key", NULL
);
171 c
->svc_use_strongest_session_key
=
172 krb5_config_get_bool_default(context
, NULL
,
173 c
->svc_use_strongest_session_key
,
175 "svc-use-strongest-session-key", NULL
);
176 c
->use_strongest_server_key
=
177 krb5_config_get_bool_default(context
, NULL
,
178 c
->use_strongest_server_key
,
180 "use-strongest-server-key", NULL
);
182 c
->check_ticket_addresses
=
183 krb5_config_get_bool_default(context
, NULL
,
184 c
->check_ticket_addresses
,
186 "check-ticket-addresses", NULL
);
187 c
->warn_ticket_addresses
=
188 krb5_config_get_bool_default(context
, NULL
,
189 c
->warn_ticket_addresses
,
191 "warn_ticket_addresses", NULL
);
192 c
->allow_null_ticket_addresses
=
193 krb5_config_get_bool_default(context
, NULL
,
194 c
->allow_null_ticket_addresses
,
196 "allow-null-ticket-addresses", NULL
);
199 krb5_config_get_bool_default(context
, NULL
,
202 "allow-anonymous", NULL
);
204 c
->historical_anon_realm
=
205 krb5_config_get_bool_default(context
, NULL
,
206 c
->historical_anon_realm
,
208 "historical_anon_realm", NULL
);
210 c
->strict_nametypes
=
211 krb5_config_get_bool_default(context
, NULL
,
214 "strict-nametypes", NULL
);
216 c
->max_datagram_reply_length
=
217 krb5_config_get_int_default(context
,
221 "max-kdc-datagram-reply-length",
225 const char *trpolicy_str
;
228 krb5_config_get_string_default(context
, NULL
, "DEFAULT", "kdc",
229 "transited-policy", NULL
);
230 if(strcasecmp(trpolicy_str
, "always-check") == 0) {
231 c
->trpolicy
= TRPOLICY_ALWAYS_CHECK
;
232 } else if(strcasecmp(trpolicy_str
, "allow-per-principal") == 0) {
233 c
->trpolicy
= TRPOLICY_ALLOW_PER_PRINCIPAL
;
234 } else if(strcasecmp(trpolicy_str
, "always-honour-request") == 0) {
235 c
->trpolicy
= TRPOLICY_ALWAYS_HONOUR_REQUEST
;
236 } else if(strcasecmp(trpolicy_str
, "DEFAULT") == 0) {
239 kdc_log(context
, c
, 0,
240 "unknown transited-policy: %s, "
241 "reverting to default (always-check)",
246 c
->encode_as_rep_as_tgs_rep
=
247 krb5_config_get_bool_default(context
, NULL
,
248 c
->encode_as_rep_as_tgs_rep
,
250 "encode_as_rep_as_tgs_rep", NULL
);
252 c
->kdc_warn_pwexpire
=
253 krb5_config_get_time_default (context
, NULL
,
254 c
->kdc_warn_pwexpire
,
255 "kdc", "kdc_warn_pwexpire", NULL
);
258 krb5_config_get_bool_default(context
,
265 c
->enable_armored_pa_enc_timestamp
=
266 krb5_config_get_bool_default(context
,
268 c
->enable_armored_pa_enc_timestamp
,
270 "enable_armored_pa_enc_timestamp",
273 c
->enable_unarmored_pa_enc_timestamp
=
274 krb5_config_get_bool_default(context
,
276 c
->enable_unarmored_pa_enc_timestamp
,
278 "enable_unarmored_pa_enc_timestamp",
282 krb5_config_get_bool_default(context
,
290 c
->pkinit_kdc_identity
=
291 krb5_config_get_string(context
, NULL
,
292 "kdc", "pkinit_identity", NULL
);
293 c
->pkinit_kdc_anchors
=
294 krb5_config_get_string(context
, NULL
,
295 "kdc", "pkinit_anchors", NULL
);
296 c
->pkinit_kdc_cert_pool
=
297 krb5_config_get_strings(context
, NULL
,
298 "kdc", "pkinit_pool", NULL
);
299 c
->pkinit_kdc_revoke
=
300 krb5_config_get_strings(context
, NULL
,
301 "kdc", "pkinit_revoke", NULL
);
302 c
->pkinit_kdc_ocsp_file
=
303 krb5_config_get_string(context
, NULL
,
304 "kdc", "pkinit_kdc_ocsp", NULL
);
305 c
->pkinit_kdc_friendly_name
=
306 krb5_config_get_string(context
, NULL
,
307 "kdc", "pkinit_kdc_friendly_name", NULL
);
308 c
->pkinit_princ_in_cert
=
309 krb5_config_get_bool_default(context
, NULL
,
310 c
->pkinit_princ_in_cert
,
312 "pkinit_principal_in_certificate",
314 c
->pkinit_require_binding
=
315 krb5_config_get_bool_default(context
, NULL
,
316 c
->pkinit_require_binding
,
318 "pkinit_win2k_require_binding",
320 c
->pkinit_dh_min_bits
=
321 krb5_config_get_int_default(context
, NULL
,
323 "kdc", "pkinit_dh_min_bits", NULL
);
325 c
->pkinit_max_life_from_cert_extension
=
326 krb5_config_get_bool_default(context
, NULL
,
327 c
->pkinit_max_life_from_cert_extension
,
329 "pkinit_max_life_from_cert_extension",
332 c
->synthetic_clients
=
333 krb5_config_get_bool_default(context
, NULL
,
334 c
->synthetic_clients
,
339 c
->pkinit_max_life_bound
=
340 krb5_config_get_time_default(context
, NULL
, 0, "kdc",
341 "pkinit_max_life_bound",
344 c
->pkinit_max_life_from_cert
=
345 krb5_config_get_time_default(context
, NULL
, 0, "kdc",
346 "pkinit_max_life_from_cert",
349 c
->synthetic_clients_max_life
=
350 krb5_config_get_time_default(context
, NULL
, 300, "kdc",
351 "synthetic_clients_max_life",
354 c
->synthetic_clients_max_renew
=
355 krb5_config_get_time_default(context
, NULL
, 300, "kdc",
356 "synthetic_clients_max_renew",
359 c
->enable_gss_preauth
=
360 krb5_config_get_bool_default(context
, NULL
,
361 c
->enable_gss_preauth
,
363 "enable_gss_preauth", NULL
);
365 c
->enable_gss_auth_data
=
366 krb5_config_get_bool_default(context
, NULL
,
367 c
->enable_gss_auth_data
,
369 "enable_gss_auth_data", NULL
);
371 ret
= _kdc_gss_get_mechanism_config(context
, "kdc",
372 "gss_mechanisms_allowed",
373 &c
->gss_mechanisms_allowed
);
379 ret
= _kdc_gss_get_mechanism_config(context
, "kdc",
380 "gss_cross_realm_mechanisms_allowed",
381 &c
->gss_cross_realm_mechanisms_allowed
);
384 gss_release_oid_set(&minor
, &c
->gss_mechanisms_allowed
);
394 KDC_LIB_FUNCTION krb5_error_code KDC_LIB_CALL
395 krb5_kdc_pkinit_config(krb5_context context
, krb5_kdc_configuration
*config
)
399 config
->enable_pkinit
= 1;
401 if (config
->pkinit_kdc_identity
== NULL
) {
402 if (config
->pkinit_kdc_friendly_name
== NULL
)
403 config
->pkinit_kdc_friendly_name
=
404 strdup("O=System Identity,CN=com.apple.kerberos.kdc");
405 config
->pkinit_kdc_identity
= strdup("KEYCHAIN:");
407 if (config
->pkinit_kdc_anchors
== NULL
)
408 config
->pkinit_kdc_anchors
= strdup("KEYCHAIN:");
410 #endif /* __APPLE__ */
412 if (config
->enable_pkinit
) {
413 if (config
->pkinit_kdc_identity
== NULL
)
414 krb5_errx(context
, 1, "pkinit enabled but no identity");
416 if (config
->pkinit_kdc_anchors
== NULL
)
417 krb5_errx(context
, 1, "pkinit enabled but no X509 anchors");
419 krb5_kdc_pk_initialize(context
, config
,
420 config
->pkinit_kdc_identity
,
421 config
->pkinit_kdc_anchors
,
422 config
->pkinit_kdc_cert_pool
,
423 config
->pkinit_kdc_revoke
);