Make it more obvious that default ticket lifetimes is not yet
[krb5.git] / src / lib / krb5 / krb / init_ctx.c
1 /*
2  * lib/krb5/krb/init_ctx.c
3  *
4  * Copyright 1994 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  * 
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  M.I.T. makes no representations about the suitability of
20  * this software for any purpose.  It is provided "as is" without express
21  * or implied warranty.
22  *
23  * krb5_init_contex()
24  */
25
26 #include "k5-int.h"
27 #include <ctype.h>
28
29 #if (defined(_MSDOS) || defined(_WIN32))
30 extern void krb5_win_do_init();
31 #endif
32
33 krb5_error_code INTERFACE
34 krb5_init_context(context)
35         krb5_context *context;
36 {
37         krb5_context ctx;
38         krb5_error_code retval;
39         int tmp;
40
41 #if (defined(_MSDOS) || defined(_WIN32))
42         /*
43          * krb5_win_do_init() is defined in win_glue.c, and this is
44          * where we handle the timebomb and version server checks.
45          */
46         krb5_win_do_init();
47 #endif
48
49         *context = 0;
50
51         ctx = malloc(sizeof(struct _krb5_context));
52         if (!ctx)
53                 return ENOMEM;
54         memset(ctx, 0, sizeof(struct _krb5_context));
55         ctx->magic = KV5M_CONTEXT;
56
57         /* Set the default encryption types, possible defined in krb5/conf */
58         if ((retval = krb5_set_default_in_tkt_ktypes(ctx, NULL)))
59                 goto cleanup;
60
61         if ((retval = krb5_set_default_tgs_ktypes(ctx, NULL)))
62                 goto cleanup;
63
64         if ((retval = krb5_os_init_context(ctx)))
65                 goto cleanup;
66
67         ctx->default_realm = 0;
68         profile_get_integer(ctx->profile, "libdefaults", "clockskew",
69                             0, 5 * 60, &tmp);
70         ctx->clockskew = tmp;
71
72 #if 0
73         /* Default ticket lifetime is currently not supported */
74         profile_get_integer(ctx->profile, "libdefaults", "tkt_lifetime",
75                             0, 10 * 60 * 60, &tmp);
76         ctx->tkt_lifetime = tmp;
77 #endif
78
79         /* DCE 1.1 and below only support CKSUMTYPE_RSA_MD4 (2)  */
80         /* DCE add kdc_req_checksum_type = 2 to krb5.conf */
81         profile_get_integer(ctx->profile, "libdefaults",
82                             "kdc_req_checksum_type", 0, CKSUMTYPE_RSA_MD5, 
83                             &tmp);
84         ctx->kdc_req_sumtype = tmp;
85
86         profile_get_integer(ctx->profile, "libdefaults",
87                             "ap_req_checksum_type", 0, CKSUMTYPE_RSA_MD5,
88                             &tmp);
89         ctx->default_ap_req_sumtype = tmp;
90
91         profile_get_integer(ctx->profile, "libdefaults",
92                             "safe_checksum_type", 0,
93                             CKSUMTYPE_RSA_MD5_DES, &tmp);
94         ctx->default_safe_sumtype = tmp;
95
96         profile_get_integer(ctx->profile, "libdefaults",
97                             "kdc_default_options", 0,
98                             KDC_OPT_RENEWABLE_OK, &tmp);
99         ctx->kdc_default_options = KDC_OPT_RENEWABLE_OK;
100 #ifdef _MACINTOSH
101 #define DEFAULT_KDC_TIMESYNC 1
102 #else
103 #define DEFAULT_KDC_TIMESYNC 0
104 #endif
105         profile_get_integer(ctx->profile, "libdefaults",
106                             "kdc_timesync", 0, DEFAULT_KDC_TIMESYNC,
107                             &tmp);
108         ctx->library_options = tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0;
109
110         /*
111          * We use a default file credentials cache of 3.  See
112          * lib/krb5/krb/ccache/file/fcc.h for a description of the
113          * credentials cache types.
114          *
115          * Note: DCE 1.0.3a only supports a cache type of 1
116          *      DCE 1.1 supports a cache type of 2.
117          */
118 #ifdef _MACINTOSH
119 #define DEFAULT_CCACHE_TYPE 4
120 #else
121 #define DEFAULT_CCACHE_TYPE 3
122 #endif
123         profile_get_integer(ctx->profile, "libdefaults", "ccache_type",
124                             0, DEFAULT_CCACHE_TYPE, &tmp);
125         ctx->fcc_default_format = tmp + 0x0500;
126         ctx->scc_default_format = tmp + 0x0500;
127
128         *context = ctx;
129         return 0;
130
131 cleanup:
132         krb5_free_context(ctx);
133         return retval;
134 }
135
136 void
137 krb5_free_context(ctx)
138         krb5_context    ctx;
139 {
140      krb5_os_free_context(ctx);
141
142      if (ctx->in_tkt_ktypes)
143           free(ctx->in_tkt_ktypes);
144
145      if (ctx->tgs_ktypes)
146           free(ctx->tgs_ktypes);
147
148      if (ctx->default_realm)
149           free(ctx->default_realm);
150
151      if (ctx->ser_ctx_count && ctx->ser_ctx)
152          free(ctx->ser_ctx);
153
154      ctx->magic = 0;
155      free(ctx);
156 }
157
158 /*
159  * Set the desired default ktypes, making sure they are valid.
160  */
161 krb5_error_code
162 krb5_set_default_in_tkt_ktypes(context, ktypes)
163         krb5_context context;
164         const krb5_enctype *ktypes;
165 {
166     krb5_enctype * new_ktypes;
167     int i;
168
169     if (ktypes) {
170         for (i = 0; ktypes[i]; i++) {
171             if (!valid_enctype(ktypes[i])) 
172                 return KRB5_PROG_ETYPE_NOSUPP;
173         }
174
175         /* Now copy the default ktypes into the context pointer */
176         if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i)))
177             memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i);
178         else
179             return ENOMEM;
180
181     } else {
182         i = 0;
183         new_ktypes = 0;
184     }
185
186     if (context->in_tkt_ktypes) 
187         free(context->in_tkt_ktypes);
188     context->in_tkt_ktypes = new_ktypes;
189     context->in_tkt_ktype_count = i;
190     return 0;
191 }
192
193 krb5_error_code
194 krb5_get_default_in_tkt_ktypes(context, ktypes)
195     krb5_context context;
196     krb5_enctype **ktypes;
197 {
198     krb5_enctype * old_ktypes;
199
200     if (context->in_tkt_ktype_count) {
201       /* application-set defaults */
202       if ((old_ktypes = 
203            (krb5_enctype *)malloc(sizeof(krb5_enctype) *
204                                   (context->in_tkt_ktype_count + 1)))) {
205         memcpy(old_ktypes, context->in_tkt_ktypes, sizeof(krb5_enctype) * 
206                context->in_tkt_ktype_count);
207         old_ktypes[context->in_tkt_ktype_count] = 0;
208       } else {
209         return ENOMEM;
210       }
211     } else {
212         /* taken directly from krb5_get_tgs_ktypes... */
213         /*
214            XXX - For now, we only support libdefaults
215            Perhaps this should be extended to allow for per-host / per-realm
216            session key types.
217          */
218
219         char *retval;
220         char *sp, *ep;
221         int i, j, count;
222         krb5_error_code code;
223
224         code = profile_get_string(context->profile,
225                                   "libdefaults", "default_tkt_enctypes", NULL,
226                                   "des-cbc-md5 des-cbc-crc",
227                                   &retval);
228         if (code)
229             return code;
230
231         count = 0;
232         sp = retval;
233         while (sp) {
234             for (ep = sp; *ep && (*ep != ',') && !isspace(*ep); ep++)
235                 ;
236             if (*ep) {
237                 *ep++ = '\0';
238                 while (isspace(*ep))
239                     ep++;
240             } else
241                 ep = (char *) NULL;
242
243             count++;
244             sp = ep;
245         }
246         
247         if ((old_ktypes =
248              (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
249             (krb5_enctype *) NULL)
250             return ENOMEM;
251         
252         sp = retval;
253         j = 0;
254         i = 1;
255         while (1) {
256             if (! krb5_string_to_enctype(sp, &old_ktypes[j]))
257                 j++;
258
259             if (i++ >= count)
260                 break;
261
262             /* skip to next token */
263             while (*sp) sp++;
264             while (! *sp) sp++;
265         }
266
267         old_ktypes[j] = (krb5_enctype) 0;
268         free(retval);
269     }
270
271     *ktypes = old_ktypes;
272     return 0;
273 }
274
275 krb5_error_code
276 krb5_set_default_tgs_ktypes(context, ktypes)
277         krb5_context context;
278         const krb5_enctype *ktypes;
279 {
280     krb5_enctype * new_ktypes;
281     int i;
282
283     if (ktypes) {
284         for (i = 0; ktypes[i]; i++) {
285             if (!valid_enctype(ktypes[i])) 
286                 return KRB5_PROG_ETYPE_NOSUPP;
287         }
288
289         /* Now copy the default ktypes into the context pointer */
290         if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i)))
291             memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i);
292         else
293             return ENOMEM;
294
295     } else {
296         i = 0;
297         new_ktypes = (krb5_enctype *)NULL;
298     }
299
300     if (context->tgs_ktypes) 
301         free(context->tgs_ktypes);
302     context->tgs_ktypes = new_ktypes;
303     context->tgs_ktype_count = i;
304     return 0;
305 }
306
307 krb5_error_code
308 krb5_get_tgs_ktypes(context, princ, ktypes)
309     krb5_context context;
310     krb5_const_principal princ;
311     krb5_enctype **ktypes;
312 {
313     krb5_enctype * old_ktypes;
314
315     if (context->tgs_ktype_count) {
316
317         /* Application-set defaults */
318
319         if ((old_ktypes =
320              (krb5_enctype *)malloc(sizeof(krb5_enctype) *
321                                     (context->tgs_ktype_count + 1)))) {
322             memcpy(old_ktypes, context->tgs_ktypes, sizeof(krb5_enctype) * 
323                    context->tgs_ktype_count);
324             old_ktypes[context->tgs_ktype_count] = 0;
325         } else {
326             return ENOMEM;
327         }
328     } else {
329         /*
330            XXX - For now, we only support libdefaults
331            Perhaps this should be extended to allow for per-host / per-realm
332            session key types.
333          */
334
335         char *retval;
336         char *sp, *ep;
337         int i, j, count;
338         krb5_error_code code;
339
340         code = profile_get_string(context->profile,
341                                   "libdefaults", "default_tgs_enctypes", NULL,
342                                   "des-cbc-md5 des-cbc-crc",
343                                   &retval);
344         if (code)
345             return code;
346
347         count = 0;
348         sp = retval;
349         while (sp) {
350             for (ep = sp; *ep && (*ep != ',') && !isspace(*ep); ep++)
351                 ;
352             if (*ep) {
353                 *ep++ = '\0';
354                 while (isspace(*ep))
355                     ep++;
356             } else
357                 ep = (char *) NULL;
358
359             count++;
360             sp = ep;
361         }
362         
363         if ((old_ktypes =
364              (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
365             (krb5_enctype *) NULL)
366             return ENOMEM;
367         
368         sp = retval;
369         j = 0;
370         i = 1;
371         while (1) {
372             if (! krb5_string_to_enctype(sp, &old_ktypes[j]))
373                 j++;
374
375             if (i++ >= count)
376                 break;
377
378             /* skip to next token */
379             while (*sp) sp++;
380             while (! *sp) sp++;
381         }
382
383         old_ktypes[j] = (krb5_enctype) 0;
384         free(retval);
385     }
386
387     *ktypes = old_ktypes;
388     return 0;
389 }