Home | History | Annotate | Download | only in ldap_util
      1 /*
      2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 
      6 /*
      7  * kadmin/ldap_util/kdb5_ldap_util.c
      8  *
      9  * (C) Copyright 1990,1991, 1996 by the Massachusetts Institute of Technology.
     10  * All Rights Reserved.
     11  *
     12  * Export of this software from the United States of America may
     13  *   require a specific license from the United States Government.
     14  *   It is the responsibility of any person or organization contemplating
     15  *   export to obtain such a license before exporting.
     16  *
     17  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
     18  * distribute this software and its documentation for any purpose and
     19  * without fee is hereby granted, provided that the above copyright
     20  * notice appear in all copies and that both that copyright notice and
     21  * this permission notice appear in supporting documentation, and that
     22  * the name of M.I.T. not be used in advertising or publicity pertaining
     23  * to distribution of the software without specific, written prior
     24  * permission.  Furthermore if you modify this software you must label
     25  * your software as modified software and not distribute it in such a
     26  * fashion that it might be confused with the original M.I.T. software.
     27  * M.I.T. makes no representations about the suitability of
     28  * this software for any purpose.  It is provided "as is" without express
     29  * or implied warranty.
     30  *
     31  *
     32  * Edit a KDC database.
     33  */
     34 
     35 /*
     36  * Copyright (C) 1998 by the FundsXpress, INC.
     37  *
     38  * All rights reserved.
     39  *
     40  * Export of this software from the United States of America may require
     41  * a specific license from the United States Government.  It is the
     42  * responsibility of any person or organization contemplating export to
     43  * obtain such a license before exporting.
     44  *
     45  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
     46  * distribute this software and its documentation for any purpose and
     47  * without fee is hereby granted, provided that the above copyright
     48  * notice appear in all copies and that both that copyright notice and
     49  * this permission notice appear in supporting documentation, and that
     50  * the name of FundsXpress. not be used in advertising or publicity pertaining
     51  * to distribution of the software without specific, written prior
     52  * permission.  FundsXpress makes no representations about the suitability of
     53  * this software for any purpose.  It is provided "as is" without express
     54  * or implied warranty.
     55  *
     56  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
     57  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
     58  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     59  */
     60 
     61 /* Copyright (c) 2004-2005, Novell, Inc.
     62  * All rights reserved.
     63  *
     64  * Redistribution and use in source and binary forms, with or without
     65  * modification, are permitted provided that the following conditions are met:
     66  *
     67  *   * Redistributions of source code must retain the above copyright notice,
     68  *       this list of conditions and the following disclaimer.
     69  *   * Redistributions in binary form must reproduce the above copyright
     70  *       notice, this list of conditions and the following disclaimer in the
     71  *       documentation and/or other materials provided with the distribution.
     72  *   * The copyright holder's name is not used to endorse or promote products
     73  *       derived from this software without specific prior written permission.
     74  *
     75  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     76  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     77  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     78  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     79  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     80  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     81  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     82  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     83  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     84  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     85  * POSSIBILITY OF SUCH DAMAGE.
     86  */
     87 
     88 #include <stdio.h>
     89 #include <time.h>
     90 
     91 #include <k5-int.h>
     92 #include <kadm5/admin.h>
     93 #include <adm_proto.h>
     94 #include <libintl.h>
     95 #include <locale.h>
     96 #include "kdb5_ldap_util.h"
     97 
     98 typedef void (*cmd_func)(int, char **);
     99 int cmd_index(char *name);
    100 
    101 char *mkey_password = 0;
    102 int exit_status = 0;
    103 krb5_context util_context;
    104 kadm5_config_params global_params;
    105 krb5_boolean db_inited = FALSE;
    106 
    107 char *progname;
    108 krb5_boolean manual_mkey = FALSE;
    109 
    110 /*
    111  * This function prints the usage of kdb5_ldap_util, which is
    112  * the LDAP configuration utility.
    113  */
    114 void usage()
    115 {
    116     fprintf(stderr, "%s: "
    117 "kdb5_ldap_util [-D user_dn [-w passwd]] [-H ldapuri]\n"
    118 "\tcmd [cmd_options]\n"
    119 
    120 /* Create realm */
    121 "create          [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn]\n"
    122 #ifdef HAVE_EDIRECTORY
    123 "\t\t[-kdcdn kdc_service_list] [-admindn admin_service_list]\n"
    124 "\t\t[-pwddn passwd_service_list]\n"
    125 #endif
    126 "\t\t[-m|-P password|-sf stashfilename] [-k mkeytype] [-s]\n"
    127 "\t\t[-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life]\n"
    128 "\t\t[ticket_flags] [-r realm]\n"
    129 
    130 /* modify realm */
    131 "modify          [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn]\n"
    132 #ifdef HAVE_EDIRECTORY
    133 "\t\t[-kdcdn kdc_service_list |\n"
    134 "\t\t[-clearkdcdn kdc_service_list] [-addkdcdn kdc_service_list]]\n"
    135 "\t\t[-admindn admin_service_list | [-clearadmindn admin_service_list]\n"
    136 "\t\t[-addadmindn admin_service_list]] [-pwddn passwd_service_list |\n"
    137 "\t\t[-clearpwddn passwd_service_list] [-addpwddn passwd_service_list]]\n"
    138 #endif
    139 "\t\t[-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life]\n"
    140 "\t\t[ticket_flags] [-r realm]\n"
    141 /* View realm */
    142 "view            [-r realm]\n"
    143 
    144 /* Destroy realm */
    145 "destroy	        [-f] [-r realm]\n"
    146 
    147 /* List realms */
    148 "list\n"
    149 
    150 #ifdef HAVE_EDIRECTORY
    151 /* Create Service */
    152 "create_service  {-kdc|-admin|-pwd} [-servicehost service_host_list]\n"
    153 "\t\t[-realm realm_list] \n"
    154 "\t\t[-randpw|-fileonly] [-f filename] service_dn\n"
    155 
    156 /* Modify service */
    157 "modify_service  [-servicehost service_host_list |\n"
    158 "\t\t[-clearservicehost service_host_list]\n"
    159 "\t\t[-addservicehost service_host_list]]\n"
    160 "\t\t[-realm realm_list | [-clearrealm realm_list]\n"
    161 "\t\t[-addrealm realm_list]] service_dn\n"
    162 
    163 /* View Service */
    164 "view_service    service_dn\n"
    165 
    166 /* Destroy Service */
    167 "destroy_service [-force] [-f stashfilename] service_dn\n"
    168 
    169 /* List services */
    170 "list_service    [-basedn base_dn]\n"
    171 
    172 /* Set Service password */
    173 "setsrvpw        [-randpw|-fileonly] [-f filename] service_dn\n"
    174 
    175 #else
    176 
    177 /* Stash the service password */
    178 "stashsrvpw      [-f filename] service_dn\n"
    179 
    180 #endif
    181 
    182 /* Create policy */
    183 "create_policy   [-r realm] [-maxtktlife max_ticket_life]\n"
    184 "\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n"
    185 
    186 /* Modify policy */
    187 "modify_policy   [-r realm] [-maxtktlife max_ticket_life]\n"
    188 "\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n"
    189 
    190 /* View policy */
    191 "view_policy     [-r realm] policy\n"
    192 
    193 /* Destroy policy */
    194 "destroy_policy  [-r realm] [-force] policy\n"
    195 
    196 /* List policies */
    197 "list_policy     [-r realm]\n",
    198     gettext("Usage"));
    199 }
    200 
    201 void db_usage (int type) {
    202     /*
    203      * This should print usage of 'type' command. For now, we will print usage
    204      * of all commands.
    205      */
    206     usage ();
    207 }
    208 
    209 /* The help messages for all sub-commands should be in the
    210  * same order as listed in this table.
    211  */
    212 static struct _cmd_table {
    213     char *name;
    214     cmd_func func;
    215     int opendb;
    216 } cmd_table[] = {
    217     {"create", kdb5_ldap_create, 1},
    218     {"modify", kdb5_ldap_modify, 1},
    219     {"view", kdb5_ldap_view, 1},
    220     {"destroy", kdb5_ldap_destroy, 1},
    221     {"list", kdb5_ldap_list, 1},
    222 #ifdef HAVE_EDIRECTORY
    223     {"create_service", kdb5_ldap_create_service, 1},
    224     {"modify_service", kdb5_ldap_modify_service, 1},
    225     {"view_service", kdb5_ldap_view_service, 1},
    226     {"destroy_service", kdb5_ldap_destroy_service, 1},
    227     {"list_service",kdb5_ldap_list_services,1},
    228     {"setsrvpw", kdb5_ldap_set_service_password, 0},
    229 #else
    230     {"stashsrvpw", kdb5_ldap_stash_service_password, 0},
    231 #endif
    232     {"create_policy", kdb5_ldap_create_policy, 1},
    233     {"modify_policy", kdb5_ldap_modify_policy, 1},
    234     {"view_policy", kdb5_ldap_view_policy, 1},
    235     {"destroy_policy", kdb5_ldap_destroy_policy, 1},
    236     {"list_policy", kdb5_ldap_list_policies, 1},
    237     {NULL, NULL, 0},
    238 };
    239 
    240 
    241 /*
    242  * The function cmd_lookup returns the structure matching the
    243  * command name and returns NULL if nothing matches.
    244  */
    245 static struct _cmd_table *cmd_lookup(name)
    246     char *name;
    247 {
    248     int i;
    249 
    250     for (i = 0; cmd_table[i].name != NULL; i++)
    251 	if (strcmp(cmd_table[i].name, name) == 0)
    252 	    return &cmd_table[i];
    253 
    254     return NULL;
    255 }
    256 
    257 
    258 /*
    259  * The function cmd_index provides the offset of the command
    260  * in the command table, which can be used to get the corresponding
    261  * help from the help message table.
    262  */
    263 int cmd_index(name)
    264     char *name;
    265 {
    266     int i;
    267 
    268     if (name == NULL)
    269 	return -1;
    270 
    271     for (i = 0; cmd_table[i].name != NULL; i++)
    272 	if (strcmp(cmd_table[i].name, name) == 0)
    273 	    return i;
    274 
    275     return -1;
    276 }
    277 
    278 static void extended_com_err_fn (const char *myprog, errcode_t code,
    279 				 const char *fmt, va_list args)
    280 {
    281     const char *emsg;
    282     /* Solaris Kerberos: code should be like that in kdb5_util.c */
    283     if (code) {
    284 	emsg = krb5_get_error_message (util_context, code);
    285 	fprintf (stderr, "%s: %s ", myprog, emsg);
    286 	krb5_free_error_message (util_context, emsg);
    287     } else {
    288 	fprintf (stderr, "%s: ", myprog);
    289     }
    290     vfprintf (stderr, fmt, args);
    291     fprintf (stderr, "\n");
    292 }
    293 
    294 int main(argc, argv)
    295     int argc;
    296     char *argv[];
    297 {
    298     struct _cmd_table *cmd = NULL;
    299     char *koptarg = NULL, **cmd_argv = NULL;
    300     int cmd_argc = 0;
    301     krb5_error_code retval;
    302     int usage_print = 0;
    303     int gp_is_static = 1;
    304     krb5_error_code db_retval = 1;
    305     char *bind_dn = NULL;
    306     char *passwd = NULL;
    307     char *ldap_server = NULL;
    308     unsigned int ldapmask = 0;
    309     unsigned int passwd_len = 0;
    310     char *prompt = NULL;
    311     kdb5_dal_handle *dal_handle = NULL;
    312     krb5_ldap_context *ldap_context=NULL;
    313     char *value = NULL, *conf_section = NULL;
    314     krb5_boolean realm_name_required = TRUE;
    315     krb5_boolean print_help_message = FALSE;
    316 
    317     /*
    318      * Solaris Kerberos:
    319      * Ensure that "progname" is set before calling com_err.
    320      */
    321     progname = (strrchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
    322 
    323     retval = krb5_init_context(&util_context);
    324     set_com_err_hook(extended_com_err_fn);
    325     if (retval) {
    326 	com_err (progname, retval, gettext("while initializing Kerberos code"));
    327 	exit_status++;
    328 	goto cleanup;
    329     }
    330 
    331     cmd_argv = (char **) malloc(sizeof(char *)*argc);
    332     if (cmd_argv == NULL) {
    333 	com_err(progname, ENOMEM, gettext("while creating sub-command arguments"));
    334 	exit_status++;
    335 	goto cleanup;
    336     }
    337     memset(cmd_argv, 0, sizeof(char *)*argc);
    338     cmd_argc = 1;
    339 
    340     memset(&global_params, 0, sizeof(kadm5_config_params));
    341 
    342     argv++; argc--;
    343     while (*argv) {
    344 	if (strcmp(*argv, "--help") == 0) {
    345 	    print_help_message = TRUE;
    346 	}
    347 	if (strcmp(*argv, "-P") == 0 && ARG_VAL) {
    348 	    mkey_password = koptarg;
    349 	    manual_mkey = TRUE;
    350 	} else if (strcmp(*argv, "-r") == 0 && ARG_VAL) {
    351 	    global_params.realm = koptarg;
    352 	    global_params.mask |= KADM5_CONFIG_REALM;
    353 	    /* not sure this is really necessary */
    354 	    if ((retval = krb5_set_default_realm(util_context,
    355 						 global_params.realm))) {
    356 		com_err(progname, retval, gettext("while setting default realm name"));
    357 		exit_status++;
    358 		goto cleanup;
    359 	    }
    360 	} else if (strcmp(*argv, "-k") == 0 && ARG_VAL) {
    361 	    if (krb5_string_to_enctype(koptarg, &global_params.enctype)) {
    362 		/* Solaris Kerberos */
    363 		com_err(progname, 0, gettext("%s is an invalid enctype"), koptarg);
    364 	    }
    365 	    else
    366 		global_params.mask |= KADM5_CONFIG_ENCTYPE;
    367 	} else if (strcmp(*argv, "-M") == 0 && ARG_VAL) {
    368 	    global_params.mkey_name = koptarg;
    369 	    global_params.mask |= KADM5_CONFIG_MKEY_NAME;
    370 	} else if (strcmp(*argv, "-sf") == 0 && ARG_VAL) {
    371 	    global_params.stash_file = koptarg;
    372 	    global_params.mask |= KADM5_CONFIG_STASH_FILE;
    373 	} else if (strcmp(*argv, "-m") == 0) {
    374 	    manual_mkey = TRUE;
    375 	    global_params.mkey_from_kbd = 1;
    376 	    global_params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
    377 	} else if (strcmp(*argv, "-D") == 0 && ARG_VAL) {
    378 	    bind_dn = koptarg;
    379 	    if (bind_dn == NULL) {
    380 		com_err(progname, ENOMEM, gettext("while reading ldap parameters"));
    381 		exit_status++;
    382 		goto cleanup;
    383 	    }
    384 	    ldapmask |= CMD_LDAP_D;
    385 	} else if (strcmp(*argv, "-w") == 0 && ARG_VAL) {
    386 	    passwd = strdup(koptarg);
    387 	    if (passwd == NULL) {
    388 		com_err(progname, ENOMEM, gettext("while reading ldap parameters"));
    389 		exit_status++;
    390 		goto cleanup;
    391 	    }
    392 	    ldapmask |= CMD_LDAP_W;
    393 	} else if (strcmp(*argv, "-H") == 0 && ARG_VAL) {
    394 	    ldap_server = koptarg;
    395 	    if (ldap_server == NULL) {
    396 		com_err(progname, ENOMEM, gettext("while reading ldap parameters"));
    397 		exit_status++;
    398 		goto cleanup;
    399 	    }
    400 	    ldapmask |= CMD_LDAP_H;
    401 	} else if (cmd_lookup(*argv) != NULL) {
    402 	    if (cmd_argv[0] == NULL)
    403 		cmd_argv[0] = *argv;
    404 	    else {
    405 		free(cmd_argv);
    406 		cmd_argv = NULL;
    407 		usage();
    408 		goto cleanup;
    409 	    }
    410 	} else {
    411 	    cmd_argv[cmd_argc++] = *argv;
    412 	}
    413 	argv++; argc--;
    414     }
    415 
    416     if (cmd_argv[0] == NULL) {
    417 	free(cmd_argv);
    418 	cmd_argv = NULL;
    419 	usage();
    420 	goto cleanup;
    421     }
    422 
    423     /* if we need to print the help message (because of --help option)
    424      * we will print the help corresponding to the sub-command.
    425      */
    426     if (print_help_message) {
    427 	char *cmd_name = cmd_argv[0];
    428 	free(cmd_argv);
    429 	cmd_argv = NULL;
    430 	usage();
    431 	goto cleanup;
    432     }
    433 
    434     /* We need to check for the presence of default realm name only in
    435      * the case of realm related operations like create, destroy etc.
    436      */
    437     if ((strcmp(cmd_argv[0], "list") == 0) ||
    438         (strcmp(cmd_argv[0], "stashsrvpw") == 0)) {
    439         realm_name_required = FALSE;
    440     }
    441 
    442     if (!util_context->default_realm) {
    443 	char *temp = NULL;
    444 	retval = krb5_get_default_realm(util_context, &temp);
    445 	if (retval) {
    446 	    if (realm_name_required) {
    447 		com_err (progname, retval, gettext("while getting default realm"));
    448 		exit_status++;
    449 		goto cleanup;
    450 	    }
    451 	} else
    452 	    util_context->default_realm = temp;
    453     }
    454     /* If we have the realm name, we can safely say that
    455      * realm_name is required so that we don't neglect any information.
    456      */
    457     else
    458 	realm_name_required = TRUE;
    459 
    460     retval = profile_get_string(util_context->profile, KDB_REALM_SECTION,
    461 				util_context->default_realm, KDB_MODULE_POINTER,
    462 				NULL,
    463 				&value);
    464 
    465     if (!(value)) {
    466 	retval = profile_get_string(util_context->profile, KDB_MODULE_DEF_SECTION,
    467 				    KDB_MODULE_POINTER, NULL,
    468 				    NULL,
    469 				    &value);
    470 	if (!(value)) {
    471 	    if (util_context->default_realm)
    472 		conf_section = strdup(util_context->default_realm);
    473 	} else {
    474 	    conf_section = strdup(value);
    475 	    free(value);
    476 	}
    477     } else {
    478 	conf_section = strdup(value);
    479 	free(value);
    480     }
    481 
    482     if (realm_name_required) {
    483 	retval = kadm5_get_config_params(util_context, 1,
    484 					 &global_params, &global_params);
    485 	if (retval) {
    486 	    /* Solaris Kerberos */
    487 	    com_err(progname, retval, gettext("while retreiving configuration parameters"));
    488 	    exit_status++;
    489 	    goto cleanup;
    490 	}
    491 	gp_is_static = 0;
    492     }
    493 
    494     if ((retval = krb5_ldap_lib_init()) != 0) {
    495 	/* Solaris Kerberos */
    496 	com_err(progname, retval, gettext("while initializing error handling"));
    497 	exit_status++;
    498 	goto cleanup;
    499     }
    500 
    501     /* Initialize the ldap context */
    502     ldap_context = calloc(sizeof(krb5_ldap_context), 1);
    503     if (ldap_context == NULL) {
    504 	/* Solaris Kerberos */
    505 	com_err(progname, ENOMEM, gettext("while initializing ldap handle"));
    506 	exit_status++;
    507 	goto cleanup;
    508     }
    509 
    510     ldap_context->kcontext = util_context;
    511 
    512     /* If LDAP parameters are specified, replace them with the values from config */
    513     if (ldapmask & CMD_LDAP_D) {
    514 	/* If password is not specified, prompt for it */
    515 	if (passwd == NULL) {
    516 	    passwd = (char *)malloc(MAX_PASSWD_LEN);
    517 	    if (passwd == NULL) {
    518 		/* Solaris Kerberos */
    519 		com_err(progname, ENOMEM, gettext("while retrieving ldap configuration"));
    520 		exit_status++;
    521 		goto cleanup;
    522 	    }
    523 	    prompt = (char *)malloc(MAX_PASSWD_PROMPT_LEN);
    524 	    if (prompt == NULL) {
    525 		free(passwd);
    526 		passwd = NULL;
    527 		/* Solaris Kerberos */
    528 		com_err(progname, ENOMEM, gettext("while retrieving ldap configuration"));
    529 		exit_status++;
    530 		goto cleanup;
    531 	    }
    532 	    memset(passwd, 0, sizeof(passwd));
    533 	    passwd_len = MAX_PASSWD_LEN - 1;
    534 	    snprintf(prompt, MAX_PASSWD_PROMPT_LEN, gettext("Password for \"%s\""), bind_dn);
    535 
    536 	    db_retval = krb5_read_password(util_context, prompt, NULL, passwd, &passwd_len);
    537 
    538 	    if ((db_retval) || (passwd_len == 0)) {
    539 		/* Solaris Kerberos */
    540 		com_err(progname, db_retval, gettext("while retrieving ldap configuration"));
    541 		free(passwd);
    542 		passwd = NULL;
    543 		exit_status++;
    544 		goto cleanup;
    545 	    }
    546 	}
    547 
    548 	ldap_context->bind_pwd = passwd;
    549     }
    550 
    551     /* If ldaphost is specified, release entry filled by configuration & use this */
    552     if (ldapmask & CMD_LDAP_H) {
    553 
    554 	ldap_context->server_info_list = (krb5_ldap_server_info **) calloc (2, sizeof (krb5_ldap_server_info *)) ;
    555 	if (ldap_context->server_info_list == NULL) {
    556 	    /* Solaris Kerberos */
    557 	    com_err(progname, ENOMEM, gettext("while initializing server list"));
    558 	    exit_status++;
    559 	    goto cleanup;
    560 	}
    561 
    562 	ldap_context->server_info_list[0] = (krb5_ldap_server_info *) calloc (1, sizeof (krb5_ldap_server_info));
    563 	if (ldap_context->server_info_list[0] == NULL) {
    564 	    /* Solaris Kerberos */
    565 	    com_err(progname, ENOMEM, gettext("while initializing server list"));
    566 	    exit_status++;
    567 	    goto cleanup;
    568 	}
    569 
    570 	ldap_context->server_info_list[0]->server_status = NOTSET;
    571 
    572 	ldap_context->server_info_list[0]->server_name = strdup(ldap_server);
    573 	if (ldap_context->server_info_list[0]->server_name == NULL) {
    574 	    /* Solaris Kerberos */
    575 	    com_err(progname, ENOMEM, gettext("while initializing server list"));
    576 	    exit_status++;
    577 	    goto cleanup;
    578 	}
    579     }
    580     if (bind_dn) {
    581 	ldap_context->bind_dn = strdup(bind_dn);
    582 	if (ldap_context->bind_dn == NULL) {
    583 	    /* Solaris Kerberos */
    584 	    com_err(progname, ENOMEM, gettext("while retrieving ldap configuration"));
    585 	    exit_status++;
    586 	    goto cleanup;
    587 	}
    588     } else
    589 	ldap_context->bind_dn = NULL;
    590 
    591     ldap_context->service_type = SERVICE_DN_TYPE_CLIENT;
    592 
    593     if (realm_name_required) {
    594 	if ((global_params.enctype != ENCTYPE_UNKNOWN) &&
    595 	    (!krb5_c_valid_enctype(global_params.enctype))) {
    596 	    /* Solaris Kerberos */
    597 	    com_err(progname, KRB5_PROG_KEYTYPE_NOSUPP,
    598 		    gettext("while setting up enctype %d"), global_params.enctype);
    599 	}
    600     }
    601 
    602     cmd = cmd_lookup(cmd_argv[0]);
    603 
    604     /* Setup DAL handle to access the database */
    605     dal_handle = calloc((size_t)1, sizeof(kdb5_dal_handle));
    606     if (dal_handle == NULL) {
    607 	goto cleanup;
    608     }
    609     dal_handle->db_context = ldap_context;
    610     util_context->db_context = (void *) dal_handle;
    611 
    612     db_retval = krb5_ldap_read_server_params(util_context, conf_section, KRB5_KDB_SRV_TYPE_OTHER);
    613     if (db_retval) {
    614 	/* Solaris Kerberos */
    615 	com_err(progname, db_retval, gettext("while reading ldap configuration"));
    616 	exit_status++;
    617 	goto cleanup;
    618     }
    619 
    620     if (cmd->opendb) {
    621 	db_retval = krb5_ldap_db_init(util_context, ldap_context);
    622 	if (db_retval) {
    623 	    com_err(progname, db_retval, gettext("while initializing database"));
    624 	    exit_status++;
    625 	    goto cleanup;
    626 	}
    627 	db_inited = TRUE;
    628     }
    629     (*cmd->func)(cmd_argc, cmd_argv);
    630 
    631     goto cleanup;
    632 
    633 cleanup:
    634     if (passwd)
    635 	memset(passwd, 0, sizeof(passwd));
    636     if (ldap_context && ldap_context->bind_pwd)
    637 	memset(ldap_context->bind_pwd, 0, sizeof(ldap_context->bind_pwd));
    638 
    639     if (util_context) {
    640 	if (gp_is_static == 0)
    641 	    kadm5_free_config_params(util_context, &global_params);
    642 	krb5_ldap_close(util_context);
    643 	krb5_free_context(util_context);
    644     }
    645 
    646     if (cmd_argv)
    647 	free(cmd_argv);
    648     if (prompt)
    649 	free(prompt);
    650     if (conf_section)
    651 	free(conf_section);
    652     if (dal_handle)
    653 	free(dal_handle);
    654 
    655     if (usage_print) {
    656 	usage();
    657     }
    658 
    659     return exit_status;
    660 }
    661