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_fast
= TRUE
;
105 c
->enable_armored_pa_enc_timestamp
= TRUE
;
106 c
->enable_unarmored_pa_enc_timestamp
= TRUE
;
107 c
->enable_pkinit
= FALSE
;
108 c
->pkinit_princ_in_cert
= TRUE
;
109 c
->pkinit_require_binding
= TRUE
;
110 c
->synthetic_clients
= FALSE
;
111 c
->pkinit_max_life_from_cert_extension
= FALSE
;
112 c
->pkinit_max_life_bound
= 0;
113 c
->synthetic_clients_max_life
= 300;
114 c
->synthetic_clients_max_renew
= 300;
115 c
->pkinit_dh_min_bits
= 1024;
120 c
->num_kdc_processes
=
121 krb5_config_get_int_default(context
, NULL
, c
->num_kdc_processes
,
122 "kdc", "num-kdc-processes", NULL
);
125 krb5_config_get_bool_default(context
, NULL
,
127 "kdc", "require-preauth", NULL
);
130 krb5_config_get_bool_default(context
, NULL
,
132 "kdc", "enable-digest", NULL
);
137 digests
= krb5_config_get_string(context
, NULL
,
139 "digests_allowed", NULL
);
142 c
->digests_allowed
= parse_flags(digests
,_kdc_digestunits
, 0);
143 if (c
->digests_allowed
== -1) {
144 kdc_log(context
, c
, 0,
145 "unparsable digest units (%s), turning off digest",
147 c
->enable_digest
= 0;
148 } else if (c
->digests_allowed
== 0) {
149 kdc_log(context
, c
, 0, "no digest enable, turning digest off");
150 c
->enable_digest
= 0;
157 krb5_config_get_bool_default(context
, NULL
,
159 "kdc", "enable_kx509", NULL
);
162 c
->tgt_use_strongest_session_key
=
163 krb5_config_get_bool_default(context
, NULL
,
164 c
->tgt_use_strongest_session_key
,
166 "tgt-use-strongest-session-key", NULL
);
167 c
->preauth_use_strongest_session_key
=
168 krb5_config_get_bool_default(context
, NULL
,
169 c
->preauth_use_strongest_session_key
,
171 "preauth-use-strongest-session-key", NULL
);
172 c
->svc_use_strongest_session_key
=
173 krb5_config_get_bool_default(context
, NULL
,
174 c
->svc_use_strongest_session_key
,
176 "svc-use-strongest-session-key", NULL
);
177 c
->use_strongest_server_key
=
178 krb5_config_get_bool_default(context
, NULL
,
179 c
->use_strongest_server_key
,
181 "use-strongest-server-key", NULL
);
183 c
->check_ticket_addresses
=
184 krb5_config_get_bool_default(context
, NULL
,
185 c
->check_ticket_addresses
,
187 "check-ticket-addresses", NULL
);
188 c
->warn_ticket_addresses
=
189 krb5_config_get_bool_default(context
, NULL
,
190 c
->warn_ticket_addresses
,
192 "warn_ticket_addresses", NULL
);
193 c
->allow_null_ticket_addresses
=
194 krb5_config_get_bool_default(context
, NULL
,
195 c
->allow_null_ticket_addresses
,
197 "allow-null-ticket-addresses", NULL
);
200 krb5_config_get_bool_default(context
, NULL
,
203 "allow-anonymous", NULL
);
205 c
->historical_anon_realm
=
206 krb5_config_get_bool_default(context
, NULL
,
207 c
->historical_anon_realm
,
209 "historical_anon_realm", NULL
);
211 c
->strict_nametypes
=
212 krb5_config_get_bool_default(context
, NULL
,
215 "strict-nametypes", NULL
);
217 c
->max_datagram_reply_length
=
218 krb5_config_get_int_default(context
,
222 "max-kdc-datagram-reply-length",
226 const char *trpolicy_str
;
229 krb5_config_get_string_default(context
, NULL
, "DEFAULT", "kdc",
230 "transited-policy", NULL
);
231 if(strcasecmp(trpolicy_str
, "always-check") == 0) {
232 c
->trpolicy
= TRPOLICY_ALWAYS_CHECK
;
233 } else if(strcasecmp(trpolicy_str
, "allow-per-principal") == 0) {
234 c
->trpolicy
= TRPOLICY_ALLOW_PER_PRINCIPAL
;
235 } else if(strcasecmp(trpolicy_str
, "always-honour-request") == 0) {
236 c
->trpolicy
= TRPOLICY_ALWAYS_HONOUR_REQUEST
;
237 } else if(strcasecmp(trpolicy_str
, "DEFAULT") == 0) {
240 kdc_log(context
, c
, 0,
241 "unknown transited-policy: %s, "
242 "reverting to default (always-check)",
247 c
->encode_as_rep_as_tgs_rep
=
248 krb5_config_get_bool_default(context
, NULL
,
249 c
->encode_as_rep_as_tgs_rep
,
251 "encode_as_rep_as_tgs_rep", NULL
);
253 c
->kdc_warn_pwexpire
=
254 krb5_config_get_time_default (context
, NULL
,
255 c
->kdc_warn_pwexpire
,
256 "kdc", "kdc_warn_pwexpire", NULL
);
259 krb5_config_get_bool_default(context
,
267 krb5_config_get_bool_default(context
,
274 c
->enable_armored_pa_enc_timestamp
=
275 krb5_config_get_bool_default(context
,
277 c
->enable_armored_pa_enc_timestamp
,
279 "enable_armored_pa_enc_timestamp",
282 c
->enable_unarmored_pa_enc_timestamp
=
283 krb5_config_get_bool_default(context
,
285 c
->enable_unarmored_pa_enc_timestamp
,
287 "enable_unarmored_pa_enc_timestamp",
291 krb5_config_get_bool_default(context
,
299 c
->pkinit_kdc_identity
=
300 krb5_config_get_string(context
, NULL
,
301 "kdc", "pkinit_identity", NULL
);
302 c
->pkinit_kdc_anchors
=
303 krb5_config_get_string(context
, NULL
,
304 "kdc", "pkinit_anchors", NULL
);
305 c
->pkinit_kdc_cert_pool
=
306 krb5_config_get_strings(context
, NULL
,
307 "kdc", "pkinit_pool", NULL
);
308 c
->pkinit_kdc_revoke
=
309 krb5_config_get_strings(context
, NULL
,
310 "kdc", "pkinit_revoke", NULL
);
311 c
->pkinit_kdc_ocsp_file
=
312 krb5_config_get_string(context
, NULL
,
313 "kdc", "pkinit_kdc_ocsp", NULL
);
314 c
->pkinit_kdc_friendly_name
=
315 krb5_config_get_string(context
, NULL
,
316 "kdc", "pkinit_kdc_friendly_name", NULL
);
317 c
->pkinit_princ_in_cert
=
318 krb5_config_get_bool_default(context
, NULL
,
319 c
->pkinit_princ_in_cert
,
321 "pkinit_principal_in_certificate",
323 c
->pkinit_require_binding
=
324 krb5_config_get_bool_default(context
, NULL
,
325 c
->pkinit_require_binding
,
327 "pkinit_win2k_require_binding",
329 c
->pkinit_dh_min_bits
=
330 krb5_config_get_int_default(context
, NULL
,
332 "kdc", "pkinit_dh_min_bits", NULL
);
334 c
->pkinit_max_life_from_cert_extension
=
335 krb5_config_get_bool_default(context
, NULL
,
336 c
->pkinit_max_life_from_cert_extension
,
338 "pkinit_max_life_from_cert_extension",
341 c
->synthetic_clients
=
342 krb5_config_get_bool_default(context
, NULL
,
343 c
->synthetic_clients
,
348 c
->pkinit_max_life_bound
=
349 krb5_config_get_time_default(context
, NULL
, 0, "kdc",
350 "pkinit_max_life_bound",
353 c
->pkinit_max_life_from_cert
=
354 krb5_config_get_time_default(context
, NULL
, 0, "kdc",
355 "pkinit_max_life_from_cert",
358 c
->synthetic_clients_max_life
=
359 krb5_config_get_time_default(context
, NULL
, 300, "kdc",
360 "synthetic_clients_max_life",
363 c
->synthetic_clients_max_renew
=
364 krb5_config_get_time_default(context
, NULL
, 300, "kdc",
365 "synthetic_clients_max_renew",
368 c
->enable_gss_preauth
=
369 krb5_config_get_bool_default(context
, NULL
,
370 c
->enable_gss_preauth
,
372 "enable_gss_preauth", NULL
);
374 c
->enable_gss_auth_data
=
375 krb5_config_get_bool_default(context
, NULL
,
376 c
->enable_gss_auth_data
,
378 "enable_gss_auth_data", NULL
);
380 ret
= _kdc_gss_get_mechanism_config(context
, "kdc",
381 "gss_mechanisms_allowed",
382 &c
->gss_mechanisms_allowed
);
388 ret
= _kdc_gss_get_mechanism_config(context
, "kdc",
389 "gss_cross_realm_mechanisms_allowed",
390 &c
->gss_cross_realm_mechanisms_allowed
);
393 gss_release_oid_set(&minor
, &c
->gss_mechanisms_allowed
);
403 KDC_LIB_FUNCTION krb5_error_code KDC_LIB_CALL
404 krb5_kdc_pkinit_config(krb5_context context
, krb5_kdc_configuration
*config
)
408 config
->enable_pkinit
= 1;
410 if (config
->pkinit_kdc_identity
== NULL
) {
411 if (config
->pkinit_kdc_friendly_name
== NULL
)
412 config
->pkinit_kdc_friendly_name
=
413 strdup("O=System Identity,CN=com.apple.kerberos.kdc");
414 config
->pkinit_kdc_identity
= strdup("KEYCHAIN:");
416 if (config
->pkinit_kdc_anchors
== NULL
)
417 config
->pkinit_kdc_anchors
= strdup("KEYCHAIN:");
419 #endif /* __APPLE__ */
421 if (config
->enable_pkinit
) {
422 if (config
->pkinit_kdc_identity
== NULL
)
423 krb5_errx(context
, 1, "pkinit enabled but no identity");
425 if (config
->pkinit_kdc_anchors
== NULL
)
426 krb5_errx(context
, 1, "pkinit enabled but no X509 anchors");
428 krb5_kdc_pk_initialize(context
, config
,
429 config
->pkinit_kdc_identity
,
430 config
->pkinit_kdc_anchors
,
431 config
->pkinit_kdc_cert_pool
,
432 config
->pkinit_kdc_revoke
);