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