Line data Source code
1 : /*
2 : * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7 : *
8 : * Redistribution and use in source and binary forms, with or without
9 : * modification, are permitted provided that the following conditions
10 : * are met:
11 : *
12 : * 1. Redistributions of source code must retain the above copyright
13 : * notice, this list of conditions and the following disclaimer.
14 : *
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.
18 : *
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.
22 : *
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
33 : * SUCH DAMAGE.
34 : */
35 :
36 : #include "kdc_locl.h"
37 : #include <getarg.h>
38 : #include <parse_bytes.h>
39 :
40 : static const char *sysplugin_dirs[] = {
41 : #ifdef _WIN32
42 : "$ORIGIN",
43 : #else
44 : "$ORIGIN/../lib/plugin/kdc",
45 : #endif
46 : #ifdef __APPLE__
47 : LIBDIR "/plugin/kdc",
48 : #endif
49 : NULL
50 : };
51 :
52 : static void
53 93 : load_kdc_plugins_once(void *ctx)
54 : {
55 93 : krb5_context context = ctx;
56 93 : const char * const *dirs = sysplugin_dirs;
57 : #ifndef _WIN32
58 8 : char **cfdirs;
59 :
60 93 : cfdirs = krb5_config_get_strings(context, NULL, "kdc", "plugin_dir", NULL);
61 93 : if (cfdirs)
62 0 : dirs = (const char * const *)cfdirs;
63 : #endif
64 :
65 93 : _krb5_load_plugins(context, "kdc", (const char **)dirs);
66 :
67 : #ifndef _WIN32
68 93 : krb5_config_free_strings(cfdirs);
69 : #endif
70 93 : }
71 :
72 : KDC_LIB_FUNCTION krb5_error_code KDC_LIB_CALL
73 93 : krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
74 : {
75 8 : static heim_base_once_t load_kdc_plugins = HEIM_BASE_ONCE_INIT;
76 8 : krb5_kdc_configuration *c;
77 8 : krb5_error_code ret;
78 :
79 93 : heim_base_once_f(&load_kdc_plugins, context, load_kdc_plugins_once);
80 :
81 93 : c = calloc(1, sizeof(*c));
82 93 : if (c == NULL) {
83 0 : krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
84 0 : return ENOMEM;
85 : }
86 :
87 93 : c->app = "kdc";
88 93 : c->num_kdc_processes = -1;
89 93 : c->require_preauth = TRUE;
90 93 : c->kdc_warn_pwexpire = 0;
91 93 : c->encode_as_rep_as_tgs_rep = FALSE;
92 93 : c->tgt_use_strongest_session_key = FALSE;
93 93 : c->preauth_use_strongest_session_key = FALSE;
94 93 : c->svc_use_strongest_session_key = FALSE;
95 93 : c->use_strongest_server_key = TRUE;
96 93 : c->check_ticket_addresses = TRUE;
97 93 : c->warn_ticket_addresses = FALSE;
98 93 : c->allow_null_ticket_addresses = TRUE;
99 93 : c->allow_anonymous = FALSE;
100 93 : c->historical_anon_realm = FALSE;
101 93 : c->strict_nametypes = FALSE;
102 93 : c->trpolicy = TRPOLICY_ALWAYS_CHECK;
103 93 : c->require_pac = FALSE;
104 93 : c->disable_pac = FALSE;
105 93 : c->enable_fast = TRUE;
106 93 : c->enable_fast_cookie = TRUE;
107 93 : c->enable_armored_pa_enc_timestamp = TRUE;
108 93 : c->enable_unarmored_pa_enc_timestamp = TRUE;
109 93 : c->enable_pkinit = FALSE;
110 93 : c->require_pkinit_freshness = FALSE;
111 93 : c->pkinit_princ_in_cert = TRUE;
112 93 : c->pkinit_require_binding = TRUE;
113 93 : c->synthetic_clients = FALSE;
114 93 : c->pkinit_max_life_from_cert_extension = FALSE;
115 93 : c->pkinit_max_life_bound = 0;
116 93 : c->synthetic_clients_max_life = 300;
117 93 : c->synthetic_clients_max_renew = 300;
118 93 : c->pkinit_dh_min_bits = 1024;
119 93 : c->db = NULL;
120 93 : c->num_db = 0;
121 93 : c->logf = NULL;
122 :
123 101 : c->num_kdc_processes =
124 93 : krb5_config_get_int_default(context, NULL, c->num_kdc_processes,
125 : "kdc", "num-kdc-processes", NULL);
126 :
127 101 : c->require_preauth =
128 186 : krb5_config_get_bool_default(context, NULL,
129 93 : c->require_preauth,
130 : "kdc", "require-preauth", NULL);
131 : #ifdef DIGEST
132 : c->enable_digest =
133 : krb5_config_get_bool_default(context, NULL,
134 : FALSE,
135 : "kdc", "enable-digest", NULL);
136 :
137 : {
138 : const char *digests;
139 :
140 : digests = krb5_config_get_string(context, NULL,
141 : "kdc",
142 : "digests_allowed", NULL);
143 : if (digests == NULL)
144 : digests = "ntlm-v2";
145 : c->digests_allowed = parse_flags(digests,_kdc_digestunits, 0);
146 : if (c->digests_allowed == -1) {
147 : kdc_log(context, c, 0,
148 : "unparsable digest units (%s), turning off digest",
149 : digests);
150 : c->enable_digest = 0;
151 : } else if (c->digests_allowed == 0) {
152 : kdc_log(context, c, 0, "no digest enable, turning digest off");
153 : c->enable_digest = 0;
154 : }
155 : }
156 : #endif
157 :
158 : #ifdef KX509
159 : c->enable_kx509 =
160 : krb5_config_get_bool_default(context, NULL,
161 : FALSE,
162 : "kdc", "enable_kx509", NULL);
163 : #endif
164 :
165 101 : c->tgt_use_strongest_session_key =
166 186 : krb5_config_get_bool_default(context, NULL,
167 93 : c->tgt_use_strongest_session_key,
168 : "kdc",
169 : "tgt-use-strongest-session-key", NULL);
170 101 : c->preauth_use_strongest_session_key =
171 186 : krb5_config_get_bool_default(context, NULL,
172 93 : c->preauth_use_strongest_session_key,
173 : "kdc",
174 : "preauth-use-strongest-session-key", NULL);
175 101 : c->svc_use_strongest_session_key =
176 186 : krb5_config_get_bool_default(context, NULL,
177 93 : c->svc_use_strongest_session_key,
178 : "kdc",
179 : "svc-use-strongest-session-key", NULL);
180 101 : c->use_strongest_server_key =
181 186 : krb5_config_get_bool_default(context, NULL,
182 93 : c->use_strongest_server_key,
183 : "kdc",
184 : "use-strongest-server-key", NULL);
185 :
186 101 : c->check_ticket_addresses =
187 186 : krb5_config_get_bool_default(context, NULL,
188 93 : c->check_ticket_addresses,
189 : "kdc",
190 : "check-ticket-addresses", NULL);
191 101 : c->warn_ticket_addresses =
192 186 : krb5_config_get_bool_default(context, NULL,
193 93 : c->warn_ticket_addresses,
194 : "kdc",
195 : "warn_ticket_addresses", NULL);
196 101 : c->allow_null_ticket_addresses =
197 186 : krb5_config_get_bool_default(context, NULL,
198 93 : c->allow_null_ticket_addresses,
199 : "kdc",
200 : "allow-null-ticket-addresses", NULL);
201 :
202 101 : c->allow_anonymous =
203 186 : krb5_config_get_bool_default(context, NULL,
204 93 : c->allow_anonymous,
205 : "kdc",
206 : "allow-anonymous", NULL);
207 :
208 101 : c->historical_anon_realm =
209 186 : krb5_config_get_bool_default(context, NULL,
210 93 : c->historical_anon_realm,
211 : "kdc",
212 : "historical_anon_realm", NULL);
213 :
214 101 : c->strict_nametypes =
215 186 : krb5_config_get_bool_default(context, NULL,
216 93 : c->strict_nametypes,
217 : "kdc",
218 : "strict-nametypes", NULL);
219 :
220 101 : c->max_datagram_reply_length =
221 93 : krb5_config_get_int_default(context,
222 : NULL,
223 : 1400,
224 : "kdc",
225 : "max-kdc-datagram-reply-length",
226 : NULL);
227 :
228 : {
229 8 : const char *trpolicy_str;
230 :
231 8 : trpolicy_str =
232 93 : krb5_config_get_string_default(context, NULL, "DEFAULT", "kdc",
233 : "transited-policy", NULL);
234 93 : if(strcasecmp(trpolicy_str, "always-check") == 0) {
235 0 : c->trpolicy = TRPOLICY_ALWAYS_CHECK;
236 93 : } else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0) {
237 0 : c->trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL;
238 93 : } else if(strcasecmp(trpolicy_str, "always-honour-request") == 0) {
239 0 : c->trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST;
240 93 : } else if(strcasecmp(trpolicy_str, "DEFAULT") == 0) {
241 : /* default */
242 : } else {
243 0 : kdc_log(context, c, 0,
244 : "unknown transited-policy: %s, "
245 : "reverting to default (always-check)",
246 : trpolicy_str);
247 : }
248 : }
249 :
250 101 : c->encode_as_rep_as_tgs_rep =
251 186 : krb5_config_get_bool_default(context, NULL,
252 93 : c->encode_as_rep_as_tgs_rep,
253 : "kdc",
254 : "encode_as_rep_as_tgs_rep", NULL);
255 :
256 101 : c->kdc_warn_pwexpire =
257 186 : krb5_config_get_time_default (context, NULL,
258 93 : c->kdc_warn_pwexpire,
259 : "kdc", "kdc_warn_pwexpire", NULL);
260 :
261 101 : c->require_pac =
262 186 : krb5_config_get_bool_default(context,
263 : NULL,
264 93 : c->require_pac,
265 : "kdc",
266 : "require_pac",
267 : NULL);
268 :
269 101 : c->disable_pac =
270 186 : krb5_config_get_bool_default(context,
271 : NULL,
272 93 : c->disable_pac,
273 : "kdc",
274 : "disable_pac",
275 : NULL);
276 :
277 101 : c->enable_fast =
278 186 : krb5_config_get_bool_default(context,
279 : NULL,
280 93 : c->enable_fast,
281 : "kdc",
282 : "enable_fast",
283 : NULL);
284 :
285 101 : c->enable_fast_cookie =
286 186 : krb5_config_get_bool_default(context,
287 : NULL,
288 93 : c->enable_fast_cookie,
289 : "kdc",
290 : "enable_fast_cookie",
291 : NULL);
292 :
293 101 : c->enable_armored_pa_enc_timestamp =
294 186 : krb5_config_get_bool_default(context,
295 : NULL,
296 93 : c->enable_armored_pa_enc_timestamp,
297 : "kdc",
298 : "enable_armored_pa_enc_timestamp",
299 : NULL);
300 :
301 101 : c->enable_unarmored_pa_enc_timestamp =
302 186 : krb5_config_get_bool_default(context,
303 : NULL,
304 93 : c->enable_unarmored_pa_enc_timestamp,
305 : "kdc",
306 : "enable_unarmored_pa_enc_timestamp",
307 : NULL);
308 :
309 101 : c->enable_pkinit =
310 186 : krb5_config_get_bool_default(context,
311 : NULL,
312 93 : c->enable_pkinit,
313 : "kdc",
314 : "enable-pkinit",
315 : NULL);
316 :
317 101 : c->require_pkinit_freshness =
318 186 : krb5_config_get_bool_default(context,
319 : NULL,
320 93 : c->require_pkinit_freshness,
321 : "kdc",
322 : "require-pkinit-freshness",
323 : NULL);
324 :
325 101 : c->pkinit_kdc_identity =
326 93 : krb5_config_get_string(context, NULL,
327 : "kdc", "pkinit_identity", NULL);
328 101 : c->pkinit_kdc_anchors =
329 93 : krb5_config_get_string(context, NULL,
330 : "kdc", "pkinit_anchors", NULL);
331 101 : c->pkinit_kdc_cert_pool =
332 93 : krb5_config_get_strings(context, NULL,
333 : "kdc", "pkinit_pool", NULL);
334 101 : c->pkinit_kdc_revoke =
335 93 : krb5_config_get_strings(context, NULL,
336 : "kdc", "pkinit_revoke", NULL);
337 101 : c->pkinit_kdc_ocsp_file =
338 93 : krb5_config_get_string(context, NULL,
339 : "kdc", "pkinit_kdc_ocsp", NULL);
340 101 : c->pkinit_kdc_friendly_name =
341 93 : krb5_config_get_string(context, NULL,
342 : "kdc", "pkinit_kdc_friendly_name", NULL);
343 101 : c->pkinit_princ_in_cert =
344 186 : krb5_config_get_bool_default(context, NULL,
345 93 : c->pkinit_princ_in_cert,
346 : "kdc",
347 : "pkinit_principal_in_certificate",
348 : NULL);
349 101 : c->pkinit_require_binding =
350 186 : krb5_config_get_bool_default(context, NULL,
351 93 : c->pkinit_require_binding,
352 : "kdc",
353 : "pkinit_win2k_require_binding",
354 : NULL);
355 101 : c->pkinit_dh_min_bits =
356 93 : krb5_config_get_int_default(context, NULL,
357 : 0,
358 : "kdc", "pkinit_dh_min_bits", NULL);
359 :
360 101 : c->pkinit_max_life_from_cert_extension =
361 186 : krb5_config_get_bool_default(context, NULL,
362 93 : c->pkinit_max_life_from_cert_extension,
363 : "kdc",
364 : "pkinit_max_life_from_cert_extension",
365 : NULL);
366 :
367 101 : c->synthetic_clients =
368 186 : krb5_config_get_bool_default(context, NULL,
369 93 : c->synthetic_clients,
370 : "kdc",
371 : "synthetic_clients",
372 : NULL);
373 :
374 101 : c->pkinit_max_life_bound =
375 93 : krb5_config_get_time_default(context, NULL, 0, "kdc",
376 : "pkinit_max_life_bound",
377 : NULL);
378 :
379 101 : c->pkinit_max_life_from_cert =
380 93 : krb5_config_get_time_default(context, NULL, 0, "kdc",
381 : "pkinit_max_life_from_cert",
382 : NULL);
383 :
384 101 : c->synthetic_clients_max_life =
385 93 : krb5_config_get_time_default(context, NULL, 300, "kdc",
386 : "synthetic_clients_max_life",
387 : NULL);
388 :
389 101 : c->synthetic_clients_max_renew =
390 93 : krb5_config_get_time_default(context, NULL, 300, "kdc",
391 : "synthetic_clients_max_renew",
392 : NULL);
393 :
394 101 : c->enable_gss_preauth =
395 186 : krb5_config_get_bool_default(context, NULL,
396 93 : c->enable_gss_preauth,
397 : "kdc",
398 : "enable_gss_preauth", NULL);
399 :
400 101 : c->enable_gss_auth_data =
401 186 : krb5_config_get_bool_default(context, NULL,
402 93 : c->enable_gss_auth_data,
403 : "kdc",
404 : "enable_gss_auth_data", NULL);
405 :
406 93 : ret = _kdc_gss_get_mechanism_config(context, "kdc",
407 : "gss_mechanisms_allowed",
408 : &c->gss_mechanisms_allowed);
409 93 : if (ret) {
410 0 : free(c);
411 0 : return ret;
412 : }
413 :
414 93 : ret = _kdc_gss_get_mechanism_config(context, "kdc",
415 : "gss_cross_realm_mechanisms_allowed",
416 : &c->gss_cross_realm_mechanisms_allowed);
417 93 : if (ret) {
418 0 : OM_uint32 minor;
419 0 : gss_release_oid_set(&minor, &c->gss_mechanisms_allowed);
420 0 : free(c);
421 0 : return ret;
422 : }
423 :
424 93 : *config = c;
425 :
426 93 : return 0;
427 : }
428 :
429 : KDC_LIB_FUNCTION krb5_error_code KDC_LIB_CALL
430 93 : krb5_kdc_pkinit_config(krb5_context context, krb5_kdc_configuration *config)
431 : {
432 : #ifdef PKINIT
433 : #ifdef __APPLE__
434 : config->enable_pkinit = 1;
435 :
436 : if (config->pkinit_kdc_identity == NULL) {
437 : if (config->pkinit_kdc_friendly_name == NULL)
438 : config->pkinit_kdc_friendly_name =
439 : strdup("O=System Identity,CN=com.apple.kerberos.kdc");
440 : config->pkinit_kdc_identity = strdup("KEYCHAIN:");
441 : }
442 : if (config->pkinit_kdc_anchors == NULL)
443 : config->pkinit_kdc_anchors = strdup("KEYCHAIN:");
444 :
445 : #endif /* __APPLE__ */
446 :
447 93 : if (config->enable_pkinit) {
448 93 : if (config->pkinit_kdc_identity == NULL)
449 0 : krb5_errx(context, 1, "pkinit enabled but no identity");
450 :
451 93 : if (config->pkinit_kdc_anchors == NULL)
452 0 : krb5_errx(context, 1, "pkinit enabled but no X509 anchors");
453 :
454 93 : krb5_kdc_pk_initialize(context, config,
455 : config->pkinit_kdc_identity,
456 : config->pkinit_kdc_anchors,
457 : config->pkinit_kdc_cert_pool,
458 : config->pkinit_kdc_revoke);
459 :
460 : }
461 :
462 93 : return 0;
463 : #endif /* PKINIT */
464 : }
|