~ubuntu-branches/ubuntu/maverick/krb5/maverick

« back to all changes in this revision

Viewing changes to src/kdc/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman
  • Date: 2009-05-07 16:16:34 UTC
  • mfrom: (13.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20090507161634-xqyk0s9na0le4flj
Tags: 1.7dfsg~beta1-4
When  decrypting the TGS response fails with the subkey, try with the
session key to work around Heimdal bug, Closes: #527353 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * kdc/main.c
3
3
 *
4
 
 * Copyright 1990,2001 by the Massachusetts Institute of Technology.
 
4
 * Copyright 1990,2001,2008,2009 by the Massachusetts Institute of Technology.
5
5
 *
6
6
 * Export of this software from the United States of America may
7
7
 *   require a specific license from the United States Government.
25
25
 *
26
26
 * Main procedure body for the KDC server process.
27
27
 */
 
28
/*
 
29
 * Copyright (c) 2006-2008, Novell, Inc.
 
30
 * All rights reserved.
 
31
 *
 
32
 * Redistribution and use in source and binary forms, with or without
 
33
 * modification, are permitted provided that the following conditions are met:
 
34
 *
 
35
 *   * Redistributions of source code must retain the above copyright notice,
 
36
 *       this list of conditions and the following disclaimer.
 
37
 *   * Redistributions in binary form must reproduce the above copyright
 
38
 *       notice, this list of conditions and the following disclaimer in the
 
39
 *       documentation and/or other materials provided with the distribution.
 
40
 *   * The copyright holder's name is not used to endorse or promote products
 
41
 *       derived from this software without specific prior written permission.
 
42
 *
 
43
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
44
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
45
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
46
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
47
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
48
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
49
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
50
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
51
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
52
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
53
 * POSSIBILITY OF SUCH DAMAGE.
 
54
 */
28
55
 
29
56
#include <stdio.h>
30
57
#include <syslog.h>
44
71
#include <netinet/in.h>
45
72
#endif
46
73
 
47
 
#ifdef KRB5_KRB4_COMPAT
48
 
#include <des.h>
49
 
#endif
50
 
 
51
74
#if defined(NEED_DAEMON_PROTO)
52
75
extern int daemon(int, int);
53
76
#endif
63
86
 
64
87
void initialize_realms (krb5_context, int, char **);
65
88
 
66
 
void finish_realms (char *);
 
89
void finish_realms (void);
67
90
 
68
91
static int nofork = 0;
69
92
static int rkey_init_done = 0;
74
97
 
75
98
#define KRB5_KDC_MAX_REALMS     32
76
99
 
 
100
static krb5_context kdc_err_context;
 
101
static const char *kdc_progname;
 
102
 
 
103
/*
 
104
 * We use krb5_klog_init to set up a com_err callback to log error
 
105
 * messages.  The callback also pulls the error message out of the
 
106
 * context we pass to krb5_klog_init; however, we use realm-specific
 
107
 * contexts for most of our krb5 library calls, so the error message
 
108
 * isn't present in the global context.  This wrapper ensures that the
 
109
 * error message state from the call context is copied into the
 
110
 * context known by krb5_klog.  call_context can be NULL if the error
 
111
 * code did not come from a krb5 library function.
 
112
 */
 
113
void
 
114
kdc_err(krb5_context call_context, errcode_t code, const char *fmt, ...)
 
115
{
 
116
    va_list ap;
 
117
 
 
118
    if (call_context)
 
119
        krb5_copy_error_message(kdc_err_context, call_context);
 
120
    va_start(ap, fmt);
 
121
    com_err_va(kdc_progname, code, fmt, ap);
 
122
    va_end(ap);
 
123
}
 
124
 
77
125
/*
78
126
 * Find the realm entry for a given realm.
79
127
 */
123
171
        free(rdp->realm_tcp_ports);
124
172
    if (rdp->realm_keytab)
125
173
        krb5_kt_close(rdp->realm_context, rdp->realm_keytab);
 
174
    if (rdp->realm_host_based_services)
 
175
        free(rdp->realm_host_based_services);
 
176
    if (rdp->realm_no_host_referral)
 
177
        free(rdp->realm_no_host_referral);
126
178
    if (rdp->realm_context) {
127
179
        if (rdp->realm_mprinc)
128
180
            krb5_free_principal(rdp->realm_context, rdp->realm_mprinc);
129
181
        if (rdp->realm_mkey.length && rdp->realm_mkey.contents) {
 
182
            /* XXX shouldn't memset be zap for safety? */
130
183
            memset(rdp->realm_mkey.contents, 0, rdp->realm_mkey.length);
131
184
            free(rdp->realm_mkey.contents);
132
185
        }
 
186
        if (rdp->mkey_list)
 
187
            krb5_dbe_free_key_list(rdp->realm_context, rdp->mkey_list);
133
188
        krb5_db_fini(rdp->realm_context);
134
189
        if (rdp->realm_tgsprinc)
135
190
            krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc);
139
194
    free(rdp);
140
195
}
141
196
 
 
197
static krb5_error_code 
 
198
handle_referral_params(krb5_realm_params *rparams, 
 
199
                       char *no_refrls, char *host_based_srvcs, 
 
200
                       kdc_realm_t *rdp )
 
201
{
 
202
    krb5_error_code retval = 0;
 
203
    if (no_refrls && krb5_match_config_pattern(no_refrls, KRB5_CONF_ASTERISK) == TRUE) {
 
204
        rdp->realm_no_host_referral = strdup(KRB5_CONF_ASTERISK);
 
205
        if (!rdp->realm_no_host_referral)
 
206
            retval = ENOMEM;
 
207
    } else {
 
208
        if (rparams && rparams->realm_no_host_referral) {
 
209
            if (krb5_match_config_pattern(rparams->realm_no_host_referral, KRB5_CONF_ASTERISK) == TRUE) {
 
210
                rdp->realm_no_host_referral = strdup(KRB5_CONF_ASTERISK);
 
211
                if (!rdp->realm_no_host_referral)
 
212
                    retval = ENOMEM;
 
213
           } else if  (no_refrls && (asprintf(&(rdp->realm_no_host_referral), "%s%s%s%s%s",
 
214
                        " ", no_refrls," ",rparams->realm_no_host_referral, " ") < 0))
 
215
                retval = ENOMEM; 
 
216
            else if (asprintf(&(rdp->realm_no_host_referral),"%s%s%s", " ", 
 
217
                        rparams->realm_no_host_referral, " ") < 0) 
 
218
                retval = ENOMEM; 
 
219
        } else if( no_refrls != NULL) {
 
220
            if ( asprintf(&(rdp->realm_no_host_referral),"%s%s%s", " ", no_refrls, " ") < 0)
 
221
                retval = ENOMEM; 
 
222
        } else
 
223
            rdp->realm_no_host_referral = NULL;
 
224
    }
 
225
 
 
226
    if (rdp->realm_no_host_referral && krb5_match_config_pattern(rdp->realm_no_host_referral, KRB5_CONF_ASTERISK) == TRUE) {
 
227
        rdp->realm_host_based_services = NULL; 
 
228
        return 0;
 
229
    }
 
230
 
 
231
    if (host_based_srvcs && (krb5_match_config_pattern(host_based_srvcs, KRB5_CONF_ASTERISK) == TRUE)) {
 
232
            rdp->realm_host_based_services = strdup(KRB5_CONF_ASTERISK);
 
233
            if (!rdp->realm_host_based_services)
 
234
                retval = ENOMEM;
 
235
    } else {
 
236
            if (rparams && rparams->realm_host_based_services) {
 
237
                if (krb5_match_config_pattern(rparams->realm_host_based_services, KRB5_CONF_ASTERISK) == TRUE) {
 
238
                    rdp->realm_host_based_services = strdup(KRB5_CONF_ASTERISK);
 
239
                    if (!rdp->realm_host_based_services)
 
240
                        retval = ENOMEM;
 
241
                } else if (host_based_srvcs) {
 
242
                    if (asprintf(&(rdp->realm_host_based_services), "%s%s%s%s%s",
 
243
                           " ", host_based_srvcs," ",rparams->realm_host_based_services, " ") < 0)
 
244
                    retval = ENOMEM; 
 
245
                } else if (asprintf(&(rdp->realm_host_based_services),"%s%s%s", " ", 
 
246
                           rparams->realm_host_based_services, " ") < 0) 
 
247
                    retval = ENOMEM; 
 
248
            } else if (host_based_srvcs) {
 
249
                if (asprintf(&(rdp->realm_host_based_services),"%s%s%s", " ", host_based_srvcs, " ") < 0)
 
250
                    retval = ENOMEM; 
 
251
            } else
 
252
                rdp->realm_host_based_services = NULL;
 
253
    }
 
254
 
 
255
    return retval;
 
256
}
142
257
/*
143
258
 * Initialize a realm control structure from the alternate profile or from
144
259
 * the specified defaults.
147
262
 * realm data and we should be all set to begin operation for that realm.
148
263
 */
149
264
static krb5_error_code
150
 
init_realm(char *progname, kdc_realm_t *rdp, char *realm, 
151
 
           char *def_mpname, krb5_enctype def_enctype, char *def_udp_ports,
152
 
           char *def_tcp_ports, krb5_boolean def_manual, char **db_args)
 
265
init_realm(kdc_realm_t *rdp, char *realm, char *def_mpname,
 
266
           krb5_enctype def_enctype, char *def_udp_ports, char *def_tcp_ports,
 
267
           krb5_boolean def_manual, char **db_args, char *no_refrls,
 
268
           char *host_based_srvcs)
153
269
{
154
270
    krb5_error_code     kret;
155
271
    krb5_boolean        manual;
156
272
    krb5_realm_params   *rparams;
 
273
    int                 kdb_open_flags;
 
274
    krb5_kvno       mkvno = IGNORE_VNO;
157
275
 
158
276
    memset((char *) rdp, 0, sizeof(kdc_realm_t));
159
277
    if (!realm) {
164
282
    rdp->realm_name = realm;
165
283
    kret = krb5int_init_context_kdc(&rdp->realm_context);
166
284
    if (kret) {
167
 
        com_err(progname, kret, "while getting context for realm %s",
168
 
                realm);
 
285
        kdc_err(NULL, kret, "while getting context for realm %s", realm);
169
286
        goto whoops;
170
287
    }
171
288
 
172
289
    kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name,
173
290
                                  &rparams);
174
291
    if (kret) {
175
 
        com_err(progname, kret, "while reading realm parameters");
 
292
        kdc_err(rdp->realm_context, kret, "while reading realm parameters");
176
293
        goto whoops;
177
294
    }
178
295
    
179
296
    /* Handle profile file name */
180
 
    if (rparams && rparams->realm_profile)
 
297
    if (rparams && rparams->realm_profile) {
181
298
        rdp->realm_profile = strdup(rparams->realm_profile);
 
299
        if (!rdp->realm_profile) {
 
300
            kret = ENOMEM;
 
301
            goto whoops;
 
302
        }
 
303
    }
182
304
 
183
305
    /* Handle master key name */
184
306
    if (rparams && rparams->realm_mkey_name)
186
308
    else
187
309
        rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) :
188
310
            strdup(KRB5_KDB_M_NAME);
 
311
    if (!rdp->realm_mpname) {
 
312
        kret = ENOMEM;
 
313
        goto whoops;
 
314
    }
189
315
 
190
316
    /* Handle KDC ports */
191
317
    if (rparams && rparams->realm_kdc_ports)
192
318
        rdp->realm_ports = strdup(rparams->realm_kdc_ports);
193
319
    else
194
320
        rdp->realm_ports = strdup(def_udp_ports);
 
321
    if (!rdp->realm_ports) {
 
322
        kret = ENOMEM;
 
323
        goto whoops;
 
324
    }
195
325
    if (rparams && rparams->realm_kdc_tcp_ports)
196
326
        rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports);
197
327
    else
198
328
        rdp->realm_tcp_ports = strdup(def_tcp_ports);
199
 
 
 
329
    if (!rdp->realm_tcp_ports) {
 
330
        kret = ENOMEM;
 
331
        goto whoops;
 
332
    }
200
333
    /* Handle stash file */
201
334
    if (rparams && rparams->realm_stash_file) {
202
335
        rdp->realm_stash = strdup(rparams->realm_stash_file);
 
336
        if (!rdp->realm_stash) {
 
337
            kret = ENOMEM;
 
338
            goto whoops;
 
339
        }
203
340
        manual = FALSE;
204
341
    } else
205
342
        manual = def_manual;
215
352
        rdp->realm_reject_bad_transit = rparams->realm_reject_bad_transit;
216
353
    else
217
354
        rdp->realm_reject_bad_transit = 1;
218
 
 
 
355
 
219
356
    /* Handle ticket maximum life */
220
357
    rdp->realm_maxlife = (rparams && rparams->realm_max_life_valid) ?
221
358
        rparams->realm_max_life : KRB5_KDB_MAX_LIFE;
224
361
    rdp->realm_maxrlife = (rparams && rparams->realm_max_rlife_valid) ?
225
362
        rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE;
226
363
 
 
364
    /* Handle KDC referrals */
 
365
    kret = handle_referral_params(rparams, no_refrls, host_based_srvcs, rdp);
 
366
    if (kret == ENOMEM)
 
367
        goto whoops;
 
368
 
227
369
    if (rparams)
228
370
        krb5_free_realm_params(rdp->realm_context, rparams);
229
371
 
233
375
 
234
376
    /* Set the default realm of this context */
235
377
    if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) {
236
 
        com_err(progname, kret, "while setting default realm to %s",
 
378
        kdc_err(rdp->realm_context, kret, "while setting default realm to %s",
237
379
                realm);
238
380
        goto whoops;
239
381
    }
240
382
 
241
383
    /* first open the database  before doing anything */
242
 
#ifdef KRBCONF_KDC_MODIFIES_KDB    
243
 
    if ((kret = krb5_db_open(rdp->realm_context, db_args, 
244
 
                             KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC))) {
 
384
#ifdef KRBCONF_KDC_MODIFIES_KDB
 
385
    kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC;
245
386
#else
246
 
    if ((kret = krb5_db_open(rdp->realm_context, db_args, 
247
 
                             KRB5_KDB_OPEN_RO | KRB5_KDB_SRV_TYPE_KDC))) {
 
387
    kdb_open_flags = KRB5_KDB_OPEN_RO | KRB5_KDB_SRV_TYPE_KDC;
248
388
#endif
249
 
        com_err(progname, kret,
 
389
    if ((kret = krb5_db_open(rdp->realm_context, db_args, kdb_open_flags))) {
 
390
        kdc_err(rdp->realm_context, kret,
250
391
                "while initializing database for realm %s", realm);
251
392
        goto whoops;
252
393
    }
255
396
    if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname,
256
397
                                        rdp->realm_name, (char **) NULL,
257
398
                                        &rdp->realm_mprinc))) {
258
 
        com_err(progname, kret,
 
399
        kdc_err(rdp->realm_context, kret,
259
400
                "while setting up master key name %s for realm %s",
260
401
                rdp->realm_mpname, realm);
261
402
        goto whoops;
262
403
    }
263
404
 
264
405
    /*
265
 
     * Get the master key.
 
406
     * Get the master key (note, may not be the most current mkey).
266
407
     */
267
408
    if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc,
268
409
                                   rdp->realm_mkey.enctype, manual,
269
410
                                   FALSE, rdp->realm_stash,
270
 
                                   0, &rdp->realm_mkey))) {
271
 
        com_err(progname, kret,
 
411
                                   &mkvno, NULL, &rdp->realm_mkey))) {
 
412
        kdc_err(rdp->realm_context, kret,
272
413
                "while fetching master key %s for realm %s",
273
414
                rdp->realm_mpname, realm);
274
415
        goto whoops;
275
416
    }
276
 
 
 
417
#if 0 /************** Begin IFDEF'ed OUT *******************************/
 
418
    /*
 
419
     * Commenting krb5_db_verify_master_key out because it requires the most
 
420
     * current mkey which may not be the case here.  The call to
 
421
     * krb5_db_fetch_mkey_list() will end up verifying that the mkey is viable
 
422
     * anyway.
 
423
     */
277
424
    /* Verify the master key */
278
425
    if ((kret = krb5_db_verify_master_key(rdp->realm_context,
279
426
                                          rdp->realm_mprinc,
 
427
                                          IGNORE_VNO,
280
428
                                          &rdp->realm_mkey))) {
281
 
        com_err(progname, kret,
 
429
        kdc_err(rdp->realm_context, kret,
282
430
                "while verifying master key for realm %s", realm);
283
431
        goto whoops;
284
432
    }
 
433
#endif /**************** END IFDEF'ed OUT *******************************/
 
434
 
 
435
    if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc,
 
436
                                   &rdp->realm_mkey, mkvno, &rdp->mkey_list))) {
 
437
        kdc_err(rdp->realm_context, kret,
 
438
                "while fetching master keys list for realm %s", realm);
 
439
        goto whoops;
 
440
    }
285
441
 
286
442
    if ((kret = krb5_db_set_mkey(rdp->realm_context, &rdp->realm_mkey))) {
287
 
        com_err(progname, kret,
 
443
        kdc_err(rdp->realm_context, kret,
288
444
                "while setting master key for realm %s", realm);
289
445
        goto whoops;
290
446
    }
 
447
    kret = krb5_db_set_mkey_list(rdp->realm_context, rdp->mkey_list);
 
448
    if (kret) {
 
449
        kdc_err(rdp->realm_context, kret,
 
450
                "while setting master key list for realm %s", realm);
 
451
        goto whoops;
 
452
    }
291
453
 
292
454
    /* Set up the keytab */
293
455
    if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL,
294
456
                                   &rdp->realm_keytab))) {
295
 
        com_err(progname, kret,
 
457
        kdc_err(rdp->realm_context, kret,
296
458
                "while resolving kdb keytab for realm %s", realm);
297
459
        goto whoops;
298
460
    }
301
463
    if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc,
302
464
                                     strlen(realm), realm, KRB5_TGS_NAME,
303
465
                                     realm, (char *) NULL))) {
304
 
        com_err(progname, kret,
 
466
        kdc_err(rdp->realm_context, kret,
305
467
                "while building TGS name for realm %s", realm);
306
468
        goto whoops;
307
469
    }
308
470
 
309
471
    if (!rkey_init_done) {
310
472
        krb5_data seed;
311
 
#ifdef KRB5_KRB4_COMPAT
312
 
        krb5_keyblock temp_key;
313
 
#endif
314
473
        /*
315
474
         * If all that worked, then initialize the random key
316
475
         * generators.
317
476
         */
318
477
 
319
478
        seed.length = rdp->realm_mkey.length;
320
 
        seed.data = rdp->realm_mkey.contents;
 
479
        seed.data = (char *)rdp->realm_mkey.contents;
321
480
 
322
481
        if ((kret = krb5_c_random_add_entropy(rdp->realm_context,
323
482
                                             KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
324
483
            goto whoops;
325
484
 
326
 
#ifdef KRB5_KRB4_COMPAT
327
 
        if ((kret = krb5_c_make_random_key(rdp->realm_context,
328
 
                                           ENCTYPE_DES_CBC_CRC, &temp_key))) {
329
 
            com_err(progname, kret,
330
 
                    "while initializing V4 random key generator");
331
 
            goto whoops;
332
 
        }
333
 
 
334
 
        (void) des_init_random_number_generator(temp_key.contents);
335
 
        krb5_free_keyblock_contents(rdp->realm_context, &temp_key);
336
 
#endif
337
485
        rkey_init_done = 1;
338
486
    }
339
487
 whoops:
403
551
void
404
552
usage(char *name)
405
553
{
406
 
    fprintf(stderr, "usage: %s [-x db_args]* [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-4 v4mode] [-X] [-n]\n"
407
 
            "\nwhere,\n\t[-x db_args]* - any number of database specific arguments.\n"
408
 
            "\t\t\tLook at each database documentation for supported arguments\n",
 
554
    fprintf(stderr, "usage: %s [-x db_args]* [-d dbpathname] [-r dbrealmname]\n\t\t[-R replaycachename] [-m] [-k masterenctype] [-M masterkeyname]\n\t\t[-p port] [-n]\n"
 
555
            "\nwhere,\n\t[-x db_args]* - Any number of database specific arguments.  Look at\n"
 
556
            "\t\t\teach database module documentation for supported\n\t\t\targuments\n",
409
557
            name);
410
558
    return;
411
559
}
415
563
{
416
564
    int                 c;
417
565
    char                *db_name = (char *) NULL;
 
566
    char                *lrealm = (char *) NULL;
418
567
    char                *mkey_name = (char *) NULL;
419
568
    char                *rcname = KDCRCACHE;
420
 
    char                *lrealm;
421
569
    krb5_error_code     retval;
422
570
    krb5_enctype        menctype = ENCTYPE_UNKNOWN;
423
 
    kdc_realm_t         *rdatap;
 
571
    kdc_realm_t         *rdatap = NULL;
424
572
    krb5_boolean        manual = FALSE;
425
573
    char                *default_udp_ports = 0;
426
574
    char                *default_tcp_ports = 0;
427
575
    krb5_pointer        aprof;
428
576
    const char          *hierarchy[3];
429
577
    char               **db_args      = NULL;
 
578
    char                *no_refrls = NULL;
 
579
    char                *host_based_srvcs = NULL;
430
580
    int                  db_args_size = 0;
431
581
 
432
 
#ifdef KRB5_KRB4_COMPAT
433
 
    char                *v4mode = 0;
434
 
#endif
435
582
    extern char *optarg;
436
583
 
437
584
    if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) {
438
 
        hierarchy[0] = "kdcdefaults";
439
 
        hierarchy[1] = "kdc_ports";
 
585
        hierarchy[0] = KRB5_CONF_KDCDEFAULTS;
 
586
        hierarchy[1] = KRB5_CONF_KDC_PORTS;
440
587
        hierarchy[2] = (char *) NULL;
441
588
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_udp_ports))
442
589
            default_udp_ports = 0;
443
 
        hierarchy[1] = "kdc_tcp_ports";
 
590
        hierarchy[1] = KRB5_CONF_KDC_TCP_PORTS;
444
591
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports))
445
592
            default_tcp_ports = 0;
446
 
#ifdef KRB5_KRB4_COMPAT
447
 
        hierarchy[1] = "v4_mode";
448
 
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode))
449
 
            v4mode = 0;
450
 
#endif
 
593
        hierarchy[1] = KRB5_CONF_MAX_DGRAM_REPLY_SIZE;
 
594
        if (krb5_aprof_get_int32(aprof, hierarchy, TRUE, &max_dgram_reply_size))
 
595
            max_dgram_reply_size = MAX_DGRAM_SIZE;
 
596
        hierarchy[1] = KRB5_CONF_NO_HOST_REFERRAL;
 
597
        if (krb5_aprof_get_string_all(aprof, hierarchy, &no_refrls)) 
 
598
            no_refrls = 0;
 
599
        if (!no_refrls || krb5_match_config_pattern(no_refrls, KRB5_CONF_ASTERISK) == FALSE) {
 
600
            hierarchy[1] = KRB5_CONF_HOST_BASED_SERVICES;
 
601
            if (krb5_aprof_get_string_all(aprof, hierarchy, &host_based_srvcs))
 
602
                host_based_srvcs = 0;
 
603
        }
 
604
 
451
605
        /* aprof_init can return 0 with aprof == NULL */
452
606
        if (aprof)
453
607
             krb5_aprof_finish(aprof);
454
608
    }
455
 
    if (default_udp_ports == 0)
 
609
  
 
610
    if (default_udp_ports == 0) {
456
611
        default_udp_ports = strdup(DEFAULT_KDC_UDP_PORTLIST);
457
 
    if (default_tcp_ports == 0)
458
 
        default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST);
 
612
        if (default_udp_ports == 0) {
 
613
            fprintf(stderr," KDC cannot initialize. Not enough memory\n");
 
614
            exit(1);
 
615
        }
 
616
    }
 
617
    if (default_tcp_ports == 0) {
 
618
        default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST);
 
619
        if (default_tcp_ports == 0) {
 
620
            fprintf(stderr," KDC cannot initialize. Not enough memory\n");
 
621
            exit(1);
 
622
        }
 
623
    }
 
624
 
459
625
    /*
460
626
     * Loop through the option list.  Each time we encounter a realm name,
461
627
     * use the previously scanned options to fill in for defaults.
482
648
        case 'r':                       /* realm name for db */
483
649
            if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
484
650
                if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
485
 
                    if ((retval = init_realm(argv[0], rdatap, optarg, 
486
 
                                             mkey_name, menctype,
487
 
                                             default_udp_ports,
488
 
                                             default_tcp_ports, manual, db_args))) {
 
651
                    if ((retval = init_realm(rdatap, optarg, mkey_name,
 
652
                                             menctype, default_udp_ports,
 
653
                                             default_tcp_ports, manual, db_args,
 
654
                                             no_refrls, host_based_srvcs))) {
489
655
                        fprintf(stderr,"%s: cannot initialize realm %s - see log file for details\n",
490
656
                                argv[0], optarg);
491
657
                        exit(1);
504
670
            break;
505
671
        case 'd':                       /* pathname for db */
506
672
            /* now db_name is not a seperate argument. It has to be passed as part of the db_args */
507
 
            if( db_name == NULL )
508
 
            {
509
 
                db_name = malloc(sizeof("dbname=") + strlen(optarg));
510
 
                if( db_name == NULL )
511
 
                {
512
 
                        fprintf(stderr,"%s: KDC cannot initialize. Not enough memory\n",
513
 
                                argv[0] );
514
 
                        exit(1);
 
673
            if( db_name == NULL ) {
 
674
                if (asprintf(&db_name, "dbname=%s", optarg) < 0) {
 
675
                    fprintf(stderr,
 
676
                            "%s: KDC cannot initialize. Not enough memory\n",
 
677
                            argv[0]);
 
678
                    exit(1);
515
679
                }
516
 
 
517
 
                sprintf( db_name, "dbname=%s", optarg);
518
680
            }
519
681
 
520
682
            db_args_size++;
554
716
            if (default_udp_ports)
555
717
                free(default_udp_ports);
556
718
            default_udp_ports = strdup(optarg);
 
719
            if (!default_udp_ports) {
 
720
                fprintf(stderr," KDC cannot initialize. Not enough memory\n");
 
721
                exit(1);
 
722
            }
557
723
#if 0 /* not yet */
558
724
            if (default_tcp_ports)
559
725
                free(default_tcp_ports);
561
727
#endif
562
728
            break;
563
729
        case '4':
564
 
#ifdef KRB5_KRB4_COMPAT
565
 
            if (v4mode)
566
 
                free(v4mode);
567
 
            v4mode = strdup(optarg);
568
 
#endif
569
730
            break;
570
731
        case 'X':
571
 
#ifdef KRB5_KRB4_COMPAT
572
 
                enable_v4_crossrealm(argv[0]);
573
 
#endif
574
 
                break;
 
732
            break;
575
733
        case '?':
576
734
        default:
577
735
            usage(argv[0]);
579
737
        }
580
738
    }
581
739
 
582
 
#ifdef KRB5_KRB4_COMPAT
583
 
    /*
584
 
     * Setup the v4 mode 
585
 
     */
586
 
    process_v4_mode(argv[0], v4mode);
587
 
    free(v4mode);
588
 
#endif
589
 
 
590
740
    /*
591
741
     * Check to see if we processed any realms.
592
742
     */
600
750
            exit(1);
601
751
        }
602
752
        if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
603
 
            if ((retval = init_realm(argv[0], rdatap, lrealm, 
604
 
                                     mkey_name, menctype, default_udp_ports,
605
 
                                     default_tcp_ports, manual, db_args))) {
 
753
            if ((retval = init_realm(rdatap, lrealm, mkey_name, menctype,
 
754
                                     default_udp_ports, default_tcp_ports,
 
755
                                     manual, db_args, no_refrls,
 
756
                                     host_based_srvcs))) {
606
757
                fprintf(stderr,"%s: cannot initialize realm %s - see log file for details\n",
607
758
                        argv[0], lrealm);
608
759
                exit(1);
633
784
        free(db_args);
634
785
    if (db_name)
635
786
        free(db_name);
 
787
    if (host_based_srvcs)
 
788
        free(host_based_srvcs);
 
789
    if (no_refrls)
 
790
        free(no_refrls);
636
791
 
637
792
    return;
638
793
}
639
794
 
640
795
void
641
 
finish_realms(char *prog)
 
796
finish_realms()
642
797
{
643
798
    int i;
644
799
 
703
858
            exit(1);
704
859
    }
705
860
    krb5_klog_init(kcontext, "kdc", argv[0], 1);
 
861
    kdc_err_context = kcontext;
 
862
    kdc_progname = argv[0];
706
863
    /* N.B.: After this point, com_err sends output to the KDC log
707
 
       file, and not to stderr.  */
 
864
       file, and not to stderr.  We use the kdc_err wrapper around
 
865
       com_err to ensure that the error state exists in the context
 
866
       known to the krb5_klog callback. */
708
867
 
709
868
    initialize_kdc5_error_table();
710
869
 
716
875
    setup_signal_handlers();
717
876
 
718
877
    load_preauth_plugins(kcontext);
 
878
    load_authdata_plugins(kcontext);
719
879
 
720
880
    retval = setup_sam();
721
881
    if (retval) {
722
 
        com_err(argv[0], retval, "while initializing SAM");
723
 
        finish_realms(argv[0]);
 
882
        kdc_err(kcontext, retval, "while initializing SAM");
 
883
        finish_realms();
724
884
        return 1;
725
885
    }
726
886
 
727
 
    if ((retval = setup_network(argv[0]))) {
728
 
        com_err(argv[0], retval, "while initializing network");
729
 
        finish_realms(argv[0]);
 
887
    if ((retval = setup_network())) {
 
888
        kdc_err(kcontext, retval, "while initializing network");
 
889
        finish_realms();
730
890
        return 1;
731
891
    }
732
892
    if (!nofork && daemon(0, 0)) {
733
 
        com_err(argv[0], errno, "while detaching from tty");
734
 
        finish_realms(argv[0]);
 
893
        kdc_err(kcontext, errno, "while detaching from tty");
 
894
        finish_realms();
735
895
        return 1;
736
896
    }
737
897
    krb5_klog_syslog(LOG_INFO, "commencing operation");
738
 
    if ((retval = listen_and_process(argv[0]))) {
739
 
        com_err(argv[0], retval, "while processing network requests");
 
898
    if ((retval = listen_and_process())) {
 
899
        kdc_err(kcontext, retval, "while processing network requests");
740
900
        errout++;
741
901
    }
742
 
    if ((retval = closedown_network(argv[0]))) {
743
 
        com_err(argv[0], retval, "while shutting down network");
 
902
    if ((retval = closedown_network())) {
 
903
        kdc_err(kcontext, retval, "while shutting down network");
744
904
        errout++;
745
905
    }
746
906
    krb5_klog_syslog(LOG_INFO, "shutting down");
747
907
    unload_preauth_plugins(kcontext);
 
908
    unload_authdata_plugins(kcontext);
748
909
    krb5_klog_close(kdc_context);
749
 
    finish_realms(argv[0]);
 
910
    finish_realms();
750
911
    if (kdc_realmlist) 
751
912
      free(kdc_realmlist);
752
913
#ifdef USE_RCACHE
760
921
}
761
922
 
762
923
 
763
 
 
764