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 71 : load_kdc_plugins_once(void *ctx)
54 : {
55 71 : krb5_context context = ctx;
56 71 : const char * const *dirs = sysplugin_dirs;
57 : #ifndef _WIN32
58 : char **cfdirs;
59 :
60 71 : cfdirs = krb5_config_get_strings(context, NULL, "kdc", "plugin_dir", NULL);
61 71 : if (cfdirs)
62 0 : dirs = (const char * const *)cfdirs;
63 : #endif
64 :
65 71 : _krb5_load_plugins(context, "kdc", (const char **)dirs);
66 :
67 : #ifndef _WIN32
68 71 : krb5_config_free_strings(cfdirs);
69 : #endif
70 71 : }
71 :
72 : KDC_LIB_FUNCTION krb5_error_code KDC_LIB_CALL
73 71 : krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
74 : {
75 : static heim_base_once_t load_kdc_plugins = HEIM_BASE_ONCE_INIT;
76 : krb5_kdc_configuration *c;
77 : krb5_error_code ret;
78 :
79 71 : heim_base_once_f(&load_kdc_plugins, context, load_kdc_plugins_once);
80 :
81 71 : c = calloc(1, sizeof(*c));
82 71 : if (c == NULL) {
83 0 : krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
84 0 : return ENOMEM;
85 : }
86 :
87 71 : c->app = "kdc";
88 71 : c->num_kdc_processes = -1;
89 71 : c->require_preauth = TRUE;
90 71 : c->kdc_warn_pwexpire = 0;
91 71 : c->encode_as_rep_as_tgs_rep = FALSE;
92 71 : c->tgt_use_strongest_session_key = FALSE;
93 71 : c->preauth_use_strongest_session_key = FALSE;
94 71 : c->svc_use_strongest_session_key = FALSE;
95 71 : c->use_strongest_server_key = TRUE;
96 71 : c->check_ticket_addresses = TRUE;
97 71 : c->warn_ticket_addresses = FALSE;
98 71 : c->allow_null_ticket_addresses = TRUE;
99 71 : c->allow_anonymous = FALSE;
100 71 : c->historical_anon_realm = FALSE;
101 71 : c->strict_nametypes = FALSE;
102 71 : c->trpolicy = TRPOLICY_ALWAYS_CHECK;
103 71 : c->require_pac = FALSE;
104 71 : c->enable_fast = TRUE;
105 71 : c->enable_armored_pa_enc_timestamp = TRUE;
106 71 : c->enable_unarmored_pa_enc_timestamp = TRUE;
107 71 : c->enable_pkinit = FALSE;
108 71 : c->pkinit_princ_in_cert = TRUE;
109 71 : c->pkinit_require_binding = TRUE;
110 71 : c->synthetic_clients = FALSE;
111 71 : c->pkinit_max_life_from_cert_extension = FALSE;
112 71 : c->pkinit_max_life_bound = 0;
113 71 : c->synthetic_clients_max_life = 300;
114 71 : c->synthetic_clients_max_renew = 300;
115 71 : c->pkinit_dh_min_bits = 1024;
116 71 : c->db = NULL;
117 71 : c->num_db = 0;
118 71 : c->logf = NULL;
119 :
120 71 : c->num_kdc_processes =
121 71 : krb5_config_get_int_default(context, NULL, c->num_kdc_processes,
122 : "kdc", "num-kdc-processes", NULL);
123 :
124 71 : c->require_preauth =
125 71 : krb5_config_get_bool_default(context, NULL,
126 71 : c->require_preauth,
127 : "kdc", "require-preauth", NULL);
128 : #ifdef DIGEST
129 : c->enable_digest =
130 : krb5_config_get_bool_default(context, NULL,
131 : FALSE,
132 : "kdc", "enable-digest", NULL);
133 :
134 : {
135 : const char *digests;
136 :
137 : digests = krb5_config_get_string(context, NULL,
138 : "kdc",
139 : "digests_allowed", NULL);
140 : if (digests == NULL)
141 : digests = "ntlm-v2";
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",
146 : digests);
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;
151 : }
152 : }
153 : #endif
154 :
155 : #ifdef KX509
156 : c->enable_kx509 =
157 : krb5_config_get_bool_default(context, NULL,
158 : FALSE,
159 : "kdc", "enable_kx509", NULL);
160 : #endif
161 :
162 71 : c->tgt_use_strongest_session_key =
163 71 : krb5_config_get_bool_default(context, NULL,
164 71 : c->tgt_use_strongest_session_key,
165 : "kdc",
166 : "tgt-use-strongest-session-key", NULL);
167 71 : c->preauth_use_strongest_session_key =
168 71 : krb5_config_get_bool_default(context, NULL,
169 71 : c->preauth_use_strongest_session_key,
170 : "kdc",
171 : "preauth-use-strongest-session-key", NULL);
172 71 : c->svc_use_strongest_session_key =
173 71 : krb5_config_get_bool_default(context, NULL,
174 71 : c->svc_use_strongest_session_key,
175 : "kdc",
176 : "svc-use-strongest-session-key", NULL);
177 71 : c->use_strongest_server_key =
178 71 : krb5_config_get_bool_default(context, NULL,
179 71 : c->use_strongest_server_key,
180 : "kdc",
181 : "use-strongest-server-key", NULL);
182 :
183 71 : c->check_ticket_addresses =
184 71 : krb5_config_get_bool_default(context, NULL,
185 71 : c->check_ticket_addresses,
186 : "kdc",
187 : "check-ticket-addresses", NULL);
188 71 : c->warn_ticket_addresses =
189 71 : krb5_config_get_bool_default(context, NULL,
190 71 : c->warn_ticket_addresses,
191 : "kdc",
192 : "warn_ticket_addresses", NULL);
193 71 : c->allow_null_ticket_addresses =
194 71 : krb5_config_get_bool_default(context, NULL,
195 71 : c->allow_null_ticket_addresses,
196 : "kdc",
197 : "allow-null-ticket-addresses", NULL);
198 :
199 71 : c->allow_anonymous =
200 71 : krb5_config_get_bool_default(context, NULL,
201 71 : c->allow_anonymous,
202 : "kdc",
203 : "allow-anonymous", NULL);
204 :
205 71 : c->historical_anon_realm =
206 71 : krb5_config_get_bool_default(context, NULL,
207 71 : c->historical_anon_realm,
208 : "kdc",
209 : "historical_anon_realm", NULL);
210 :
211 71 : c->strict_nametypes =
212 71 : krb5_config_get_bool_default(context, NULL,
213 71 : c->strict_nametypes,
214 : "kdc",
215 : "strict-nametypes", NULL);
216 :
217 71 : c->max_datagram_reply_length =
218 71 : krb5_config_get_int_default(context,
219 : NULL,
220 : 1400,
221 : "kdc",
222 : "max-kdc-datagram-reply-length",
223 : NULL);
224 :
225 : {
226 : const char *trpolicy_str;
227 :
228 71 : trpolicy_str =
229 : krb5_config_get_string_default(context, NULL, "DEFAULT", "kdc",
230 : "transited-policy", NULL);
231 71 : if(strcasecmp(trpolicy_str, "always-check") == 0) {
232 0 : c->trpolicy = TRPOLICY_ALWAYS_CHECK;
233 71 : } else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0) {
234 0 : c->trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL;
235 71 : } else if(strcasecmp(trpolicy_str, "always-honour-request") == 0) {
236 0 : c->trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST;
237 71 : } else if(strcasecmp(trpolicy_str, "DEFAULT") == 0) {
238 : /* default */
239 : } else {
240 0 : kdc_log(context, c, 0,
241 : "unknown transited-policy: %s, "
242 : "reverting to default (always-check)",
243 : trpolicy_str);
244 : }
245 : }
246 :
247 71 : c->encode_as_rep_as_tgs_rep =
248 71 : krb5_config_get_bool_default(context, NULL,
249 71 : c->encode_as_rep_as_tgs_rep,
250 : "kdc",
251 : "encode_as_rep_as_tgs_rep", NULL);
252 :
253 71 : c->kdc_warn_pwexpire =
254 71 : krb5_config_get_time_default (context, NULL,
255 71 : c->kdc_warn_pwexpire,
256 : "kdc", "kdc_warn_pwexpire", NULL);
257 :
258 71 : c->require_pac =
259 71 : krb5_config_get_bool_default(context,
260 : NULL,
261 71 : c->require_pac,
262 : "kdc",
263 : "require_pac",
264 : NULL);
265 :
266 71 : c->enable_fast =
267 71 : krb5_config_get_bool_default(context,
268 : NULL,
269 71 : c->enable_fast,
270 : "kdc",
271 : "enable_fast",
272 : NULL);
273 :
274 71 : c->enable_armored_pa_enc_timestamp =
275 71 : krb5_config_get_bool_default(context,
276 : NULL,
277 71 : c->enable_armored_pa_enc_timestamp,
278 : "kdc",
279 : "enable_armored_pa_enc_timestamp",
280 : NULL);
281 :
282 71 : c->enable_unarmored_pa_enc_timestamp =
283 71 : krb5_config_get_bool_default(context,
284 : NULL,
285 71 : c->enable_unarmored_pa_enc_timestamp,
286 : "kdc",
287 : "enable_unarmored_pa_enc_timestamp",
288 : NULL);
289 :
290 71 : c->enable_pkinit =
291 71 : krb5_config_get_bool_default(context,
292 : NULL,
293 71 : c->enable_pkinit,
294 : "kdc",
295 : "enable-pkinit",
296 : NULL);
297 :
298 :
299 71 : c->pkinit_kdc_identity =
300 71 : krb5_config_get_string(context, NULL,
301 : "kdc", "pkinit_identity", NULL);
302 71 : c->pkinit_kdc_anchors =
303 71 : krb5_config_get_string(context, NULL,
304 : "kdc", "pkinit_anchors", NULL);
305 71 : c->pkinit_kdc_cert_pool =
306 71 : krb5_config_get_strings(context, NULL,
307 : "kdc", "pkinit_pool", NULL);
308 71 : c->pkinit_kdc_revoke =
309 71 : krb5_config_get_strings(context, NULL,
310 : "kdc", "pkinit_revoke", NULL);
311 71 : c->pkinit_kdc_ocsp_file =
312 71 : krb5_config_get_string(context, NULL,
313 : "kdc", "pkinit_kdc_ocsp", NULL);
314 71 : c->pkinit_kdc_friendly_name =
315 71 : krb5_config_get_string(context, NULL,
316 : "kdc", "pkinit_kdc_friendly_name", NULL);
317 71 : c->pkinit_princ_in_cert =
318 71 : krb5_config_get_bool_default(context, NULL,
319 71 : c->pkinit_princ_in_cert,
320 : "kdc",
321 : "pkinit_principal_in_certificate",
322 : NULL);
323 71 : c->pkinit_require_binding =
324 71 : krb5_config_get_bool_default(context, NULL,
325 71 : c->pkinit_require_binding,
326 : "kdc",
327 : "pkinit_win2k_require_binding",
328 : NULL);
329 71 : c->pkinit_dh_min_bits =
330 71 : krb5_config_get_int_default(context, NULL,
331 : 0,
332 : "kdc", "pkinit_dh_min_bits", NULL);
333 :
334 71 : c->pkinit_max_life_from_cert_extension =
335 71 : krb5_config_get_bool_default(context, NULL,
336 71 : c->pkinit_max_life_from_cert_extension,
337 : "kdc",
338 : "pkinit_max_life_from_cert_extension",
339 : NULL);
340 :
341 71 : c->synthetic_clients =
342 71 : krb5_config_get_bool_default(context, NULL,
343 71 : c->synthetic_clients,
344 : "kdc",
345 : "synthetic_clients",
346 : NULL);
347 :
348 71 : c->pkinit_max_life_bound =
349 71 : krb5_config_get_time_default(context, NULL, 0, "kdc",
350 : "pkinit_max_life_bound",
351 : NULL);
352 :
353 71 : c->pkinit_max_life_from_cert =
354 71 : krb5_config_get_time_default(context, NULL, 0, "kdc",
355 : "pkinit_max_life_from_cert",
356 : NULL);
357 :
358 71 : c->synthetic_clients_max_life =
359 71 : krb5_config_get_time_default(context, NULL, 300, "kdc",
360 : "synthetic_clients_max_life",
361 : NULL);
362 :
363 71 : c->synthetic_clients_max_renew =
364 71 : krb5_config_get_time_default(context, NULL, 300, "kdc",
365 : "synthetic_clients_max_renew",
366 : NULL);
367 :
368 71 : c->enable_gss_preauth =
369 71 : krb5_config_get_bool_default(context, NULL,
370 71 : c->enable_gss_preauth,
371 : "kdc",
372 : "enable_gss_preauth", NULL);
373 :
374 71 : c->enable_gss_auth_data =
375 71 : krb5_config_get_bool_default(context, NULL,
376 71 : c->enable_gss_auth_data,
377 : "kdc",
378 : "enable_gss_auth_data", NULL);
379 :
380 71 : ret = _kdc_gss_get_mechanism_config(context, "kdc",
381 : "gss_mechanisms_allowed",
382 : &c->gss_mechanisms_allowed);
383 71 : if (ret) {
384 0 : free(c);
385 0 : return ret;
386 : }
387 :
388 71 : ret = _kdc_gss_get_mechanism_config(context, "kdc",
389 : "gss_cross_realm_mechanisms_allowed",
390 : &c->gss_cross_realm_mechanisms_allowed);
391 71 : if (ret) {
392 : OM_uint32 minor;
393 0 : gss_release_oid_set(&minor, &c->gss_mechanisms_allowed);
394 0 : free(c);
395 0 : return ret;
396 : }
397 :
398 71 : *config = c;
399 :
400 71 : return 0;
401 : }
402 :
403 : KDC_LIB_FUNCTION krb5_error_code KDC_LIB_CALL
404 71 : krb5_kdc_pkinit_config(krb5_context context, krb5_kdc_configuration *config)
405 : {
406 : #ifdef PKINIT
407 : #ifdef __APPLE__
408 : config->enable_pkinit = 1;
409 :
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:");
415 : }
416 : if (config->pkinit_kdc_anchors == NULL)
417 : config->pkinit_kdc_anchors = strdup("KEYCHAIN:");
418 :
419 : #endif /* __APPLE__ */
420 :
421 71 : if (config->enable_pkinit) {
422 71 : if (config->pkinit_kdc_identity == NULL)
423 0 : krb5_errx(context, 1, "pkinit enabled but no identity");
424 :
425 71 : if (config->pkinit_kdc_anchors == NULL)
426 0 : krb5_errx(context, 1, "pkinit enabled but no X509 anchors");
427 :
428 71 : 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);
433 :
434 : }
435 :
436 71 : return 0;
437 : #endif /* PKINIT */
438 : }
|