Export krb5_init_creds_* functions
[metze/heimdal/wip.git] / kdc / default_config.c
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 load_kdc_plugins_once(void *ctx)
54 {
55     krb5_context context = ctx;
56     const char * const *dirs = sysplugin_dirs;
57 #ifndef _WIN32
58     char **cfdirs;
59
60     cfdirs = krb5_config_get_strings(context, NULL, "kdc", "plugin_dir", NULL);
61     if (cfdirs)
62         dirs = (const char * const *)cfdirs;
63 #endif
64
65     _krb5_load_plugins(context, "kdc", (const char **)dirs);
66
67 #ifndef _WIN32
68     krb5_config_free_strings(cfdirs);
69 #endif
70 }
71
72 krb5_error_code
73 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
78     heim_base_once_f(&load_kdc_plugins, context, load_kdc_plugins_once);
79
80     c = calloc(1, sizeof(*c));
81     if (c == NULL) {
82         krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
83         return ENOMEM;
84     }
85
86     c->app = "kdc";
87     c->num_kdc_processes = -1;
88     c->require_preauth = TRUE;
89     c->kdc_warn_pwexpire = 0;
90     c->encode_as_rep_as_tgs_rep = FALSE;
91     c->tgt_use_strongest_session_key = FALSE;
92     c->preauth_use_strongest_session_key = FALSE;
93     c->svc_use_strongest_session_key = FALSE;
94     c->use_strongest_server_key = TRUE;
95     c->autodetect_referrals = TRUE;
96     c->check_ticket_addresses = TRUE;
97     c->allow_null_ticket_addresses = TRUE;
98     c->allow_anonymous = FALSE;
99     c->historical_anon_realm = FALSE;
100     c->strict_nametypes = FALSE;
101     c->trpolicy = TRPOLICY_ALWAYS_CHECK;
102     c->enable_pkinit = FALSE;
103     c->pkinit_princ_in_cert = TRUE;
104     c->pkinit_require_binding = TRUE;
105     c->db = NULL;
106     c->num_db = 0;
107     c->logf = NULL;
108     c->enable_derived_keys = FALSE;
109     c->derived_keys_ndots = 2;
110     c->derived_keys_maxdots = -1;
111
112     c->num_kdc_processes =
113         krb5_config_get_int_default(context, NULL, c->num_kdc_processes,
114                                     "kdc", "num-kdc-processes", NULL);
115
116     c->require_preauth =
117         krb5_config_get_bool_default(context, NULL,
118                                      c->require_preauth,
119                                      "kdc", "require-preauth", NULL);
120 #ifdef DIGEST
121     c->enable_digest =
122         krb5_config_get_bool_default(context, NULL,
123                                      FALSE,
124                                      "kdc", "enable-digest", NULL);
125
126     {
127         const char *digests;
128
129         digests = krb5_config_get_string(context, NULL,
130                                          "kdc",
131                                          "digests_allowed", NULL);
132         if (digests == NULL)
133             digests = "ntlm-v2";
134         c->digests_allowed = parse_flags(digests,_kdc_digestunits, 0);
135         if (c->digests_allowed == -1) {
136             kdc_log(context, c, 0,
137                     "unparsable digest units (%s), turning off digest",
138                     digests);
139             c->enable_digest = 0;
140         } else if (c->digests_allowed == 0) {
141             kdc_log(context, c, 0, "no digest enable, turning digest off");
142             c->enable_digest = 0;
143         }
144     }
145 #endif
146
147 #ifdef KX509
148     c->enable_kx509 =
149         krb5_config_get_bool_default(context, NULL,
150                                      FALSE,
151                                      "kdc", "enable_kx509", NULL);
152 #endif
153
154     c->tgt_use_strongest_session_key =
155         krb5_config_get_bool_default(context, NULL,
156                                      c->tgt_use_strongest_session_key,
157                                      "kdc",
158                                      "tgt-use-strongest-session-key", NULL);
159     c->preauth_use_strongest_session_key =
160         krb5_config_get_bool_default(context, NULL,
161                                      c->preauth_use_strongest_session_key,
162                                      "kdc",
163                                      "preauth-use-strongest-session-key", NULL);
164     c->svc_use_strongest_session_key =
165         krb5_config_get_bool_default(context, NULL,
166                                      c->svc_use_strongest_session_key,
167                                      "kdc",
168                                      "svc-use-strongest-session-key", NULL);
169     c->use_strongest_server_key =
170         krb5_config_get_bool_default(context, NULL,
171                                      c->use_strongest_server_key,
172                                      "kdc",
173                                      "use-strongest-server-key", NULL);
174
175     c->check_ticket_addresses =
176         krb5_config_get_bool_default(context, NULL,
177                                      c->check_ticket_addresses,
178                                      "kdc",
179                                      "check-ticket-addresses", NULL);
180     c->allow_null_ticket_addresses =
181         krb5_config_get_bool_default(context, NULL,
182                                      c->allow_null_ticket_addresses,
183                                      "kdc",
184                                      "allow-null-ticket-addresses", NULL);
185
186     c->allow_anonymous =
187         krb5_config_get_bool_default(context, NULL,
188                                      c->allow_anonymous,
189                                      "kdc",
190                                      "allow-anonymous", NULL);
191
192     c->historical_anon_realm =
193         krb5_config_get_bool_default(context, NULL,
194                                      c->historical_anon_realm,
195                                      "kdc",
196                                      "historical_anon_realm", NULL);
197
198     c->strict_nametypes =
199         krb5_config_get_bool_default(context, NULL,
200                                      c->strict_nametypes,
201                                      "kdc",
202                                      "strict-nametypes", NULL);
203
204     c->max_datagram_reply_length =
205         krb5_config_get_int_default(context,
206                                     NULL,
207                                     1400,
208                                     "kdc",
209                                     "max-kdc-datagram-reply-length",
210                                     NULL);
211
212     {
213         const char *trpolicy_str;
214
215         trpolicy_str =
216             krb5_config_get_string_default(context, NULL, "DEFAULT", "kdc",
217                                            "transited-policy", NULL);
218         if(strcasecmp(trpolicy_str, "always-check") == 0) {
219             c->trpolicy = TRPOLICY_ALWAYS_CHECK;
220         } else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0) {
221             c->trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL;
222         } else if(strcasecmp(trpolicy_str, "always-honour-request") == 0) {
223             c->trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST;
224         } else if(strcasecmp(trpolicy_str, "DEFAULT") == 0) {
225             /* default */
226         } else {
227             kdc_log(context, c, 0,
228                     "unknown transited-policy: %s, "
229                     "reverting to default (always-check)",
230                     trpolicy_str);
231         }
232     }
233
234     c->encode_as_rep_as_tgs_rep =
235         krb5_config_get_bool_default(context, NULL,
236                                      c->encode_as_rep_as_tgs_rep,
237                                      "kdc",
238                                      "encode_as_rep_as_tgs_rep", NULL);
239
240     c->kdc_warn_pwexpire =
241         krb5_config_get_time_default (context, NULL,
242                                       c->kdc_warn_pwexpire,
243                                       "kdc", "kdc_warn_pwexpire", NULL);
244
245
246     c->enable_pkinit =
247         krb5_config_get_bool_default(context,
248                                      NULL,
249                                      c->enable_pkinit,
250                                      "kdc",
251                                      "enable-pkinit",
252                                      NULL);
253
254
255     c->pkinit_kdc_identity =
256         krb5_config_get_string(context, NULL,
257                                "kdc", "pkinit_identity", NULL);
258     c->pkinit_kdc_anchors =
259         krb5_config_get_string(context, NULL,
260                                "kdc", "pkinit_anchors", NULL);
261     c->pkinit_kdc_cert_pool =
262         krb5_config_get_strings(context, NULL,
263                                 "kdc", "pkinit_pool", NULL);
264     c->pkinit_kdc_revoke =
265         krb5_config_get_strings(context, NULL,
266                                 "kdc", "pkinit_revoke", NULL);
267     c->pkinit_kdc_ocsp_file =
268         krb5_config_get_string(context, NULL,
269                                "kdc", "pkinit_kdc_ocsp", NULL);
270     c->pkinit_kdc_friendly_name =
271         krb5_config_get_string(context, NULL,
272                                "kdc", "pkinit_kdc_friendly_name", NULL);
273     c->pkinit_princ_in_cert =
274         krb5_config_get_bool_default(context, NULL,
275                                      c->pkinit_princ_in_cert,
276                                      "kdc",
277                                      "pkinit_principal_in_certificate",
278                                      NULL);
279     c->pkinit_require_binding =
280         krb5_config_get_bool_default(context, NULL,
281                                      c->pkinit_require_binding,
282                                      "kdc",
283                                      "pkinit_win2k_require_binding",
284                                      NULL);
285     c->pkinit_dh_min_bits =
286         krb5_config_get_int_default(context, NULL,
287                                     0,
288                                     "kdc", "pkinit_dh_min_bits", NULL);
289
290     c->enable_derived_keys =
291         krb5_config_get_bool_default(context, NULL, c->enable_derived_keys,
292                                      "kdc", "enable_derived_keys", NULL);
293
294     c->derived_keys_ndots =
295         krb5_config_get_int_default(context, NULL, c->derived_keys_ndots,
296                                     "kdc", "derived_keys_ndots", NULL);
297
298     c->derived_keys_maxdots =
299         krb5_config_get_int_default(context, NULL, c->derived_keys_maxdots,
300                                     "kdc", "derived_keys_maxdots", NULL);
301
302     *config = c;
303
304     return 0;
305 }
306
307 krb5_error_code
308 krb5_kdc_pkinit_config(krb5_context context, krb5_kdc_configuration *config)
309 {
310 #ifdef PKINIT
311 #ifdef __APPLE__
312     config->enable_pkinit = 1;
313
314     if (config->pkinit_kdc_identity == NULL) {
315         if (config->pkinit_kdc_friendly_name == NULL)
316             config->pkinit_kdc_friendly_name =
317                 strdup("O=System Identity,CN=com.apple.kerberos.kdc");
318         config->pkinit_kdc_identity = strdup("KEYCHAIN:");
319     }
320     if (config->pkinit_kdc_anchors == NULL)
321         config->pkinit_kdc_anchors = strdup("KEYCHAIN:");
322
323 #endif /* __APPLE__ */
324
325     if (config->enable_pkinit) {
326         if (config->pkinit_kdc_identity == NULL)
327             krb5_errx(context, 1, "pkinit enabled but no identity");
328
329         if (config->pkinit_kdc_anchors == NULL)
330             krb5_errx(context, 1, "pkinit enabled but no X509 anchors");
331
332         krb5_kdc_pk_initialize(context, config,
333                                config->pkinit_kdc_identity,
334                                config->pkinit_kdc_anchors,
335                                config->pkinit_kdc_cert_pool,
336                                config->pkinit_kdc_revoke);
337
338     }
339
340     return 0;
341 #endif /* PKINIT */
342 }