diff options
Diffstat (limited to 'src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c')
| -rw-r--r-- | src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c | 1526 |
1 files changed, 1526 insertions, 0 deletions
diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c new file mode 100644 index 000000000000..5a745e21d9ec --- /dev/null +++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c @@ -0,0 +1,1526 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c */ +/* + * Copyright 1990,1991,2001, 2002, 2008 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* Copyright (c) 2004-2005, Novell, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The copyright holder's name is not used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Create / Modify / Destroy / View / List realm(s) + */ + +#include <k5-int.h> +#include <kadm5/admin.h> +#include <adm_proto.h> +#include "kdb5_ldap_util.h" +#include "kdb5_ldap_list.h" +#include <ldap_principal.h> +#include <ldap_krbcontainer.h> +extern time_t get_date(char *); /* kadmin/cli/getdate.o */ + +char *yes = "yes\n"; /* \n to compare against result of fgets */ +krb5_key_salt_tuple def_kslist = {ENCTYPE_DES_CBC_CRC, KRB5_KDB_SALTTYPE_NORMAL}; + +krb5_data tgt_princ_entries[] = { + {0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME}, + {0, 0, 0} }; + +krb5_data db_creator_entries[] = { + {0, sizeof("db_creation")-1, "db_creation"} }; + + +static krb5_principal_data db_create_princ = { + 0, /* magic number */ + {0, 0, 0}, /* krb5_data realm */ + db_creator_entries, /* krb5_data *data */ + 1, /* int length */ + KRB5_NT_SRV_INST /* int type */ +}; + +extern char *mkey_password; +extern char *progname; +extern kadm5_config_params global_params; + +static void print_realm_params(krb5_ldap_realm_params *rparams, int mask); +static int kdb_ldap_create_principal (krb5_context context, krb5_principal + princ, enum ap_op op, + struct realm_info *pblock, + const krb5_keyblock *master_keyblock); + + +static char *strdur(time_t duration); +static int get_ticket_policy(krb5_ldap_realm_params *rparams, int *i, char *argv[],int argc); +static krb5_error_code krb5_dbe_update_mod_princ_data_new (krb5_context context, krb5_db_entry *entry, krb5_timestamp mod_date, krb5_const_principal mod_princ); +static krb5_error_code krb5_dbe_update_tl_data_new ( krb5_context context, krb5_db_entry *entry, krb5_tl_data *new_tl_data); + +#define ADMIN_LIFETIME 60*60*3 /* 3 hours */ +#define CHANGEPW_LIFETIME 60*5 /* 5 minutes */ + +static int +get_ticket_policy(krb5_ldap_realm_params *rparams, int *i, char *argv[], + int argc) +{ + time_t date; + time_t now; + int mask = 0; + krb5_error_code retval = 0; + krb5_boolean no_msg = FALSE; + + krb5_boolean print_usage = FALSE; + char *me = progname; + + time(&now); + if (!strcmp(argv[*i], "-maxtktlife")) { + if (++(*i) > argc-1) + goto err_usage; + date = get_date(argv[*i]); + if (date == (time_t)(-1)) { + retval = EINVAL; + com_err(me, retval, _("while providing time specification")); + goto err_nomsg; + } + rparams->max_life = date-now; + mask |= LDAP_REALM_MAXTICKETLIFE; + } + + + else if (!strcmp(argv[*i], "-maxrenewlife")) { + if (++(*i) > argc-1) + goto err_usage; + + date = get_date(argv[*i]); + if (date == (time_t)(-1)) { + retval = EINVAL; + com_err(me, retval, _("while providing time specification")); + goto err_nomsg; + } + rparams->max_renewable_life = date-now; + mask |= LDAP_REALM_MAXRENEWLIFE; + } else if (!strcmp((argv[*i] + 1), "allow_postdated")) { + if (*(argv[*i]) == '+') + rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED); + else if (*(argv[*i]) == '-') + rparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED; + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "allow_forwardable")) { + if (*(argv[*i]) == '+') + rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE); + + else if (*(argv[*i]) == '-') + rparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE; + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "allow_renewable")) { + if (*(argv[*i]) == '+') + rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE); + else if (*(argv[*i]) == '-') + rparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE; + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "allow_proxiable")) { + if (*(argv[*i]) == '+') + rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE); + else if (*(argv[*i]) == '-') + rparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE; + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "allow_dup_skey")) { + if (*(argv[*i]) == '+') + rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY); + else if (*(argv[*i]) == '-') + rparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY; + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } + + else if (!strcmp((argv[*i] + 1), "requires_preauth")) { + if (*(argv[*i]) == '+') + rparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH; + else if (*(argv[*i]) == '-') + rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH); + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "requires_hwauth")) { + if (*(argv[*i]) == '+') + rparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH; + else if (*(argv[*i]) == '-') + rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH); + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "allow_svr")) { + if (*(argv[*i]) == '+') + rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR); + else if (*(argv[*i]) == '-') + rparams->tktflags |= KRB5_KDB_DISALLOW_SVR; + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "allow_tgs_req")) { + if (*(argv[*i]) == '+') + rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED); + else if (*(argv[*i]) == '-') + rparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED; + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "allow_tix")) { + if (*(argv[*i]) == '+') + rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX); + else if (*(argv[*i]) == '-') + rparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX; + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "needchange")) { + if (*(argv[*i]) == '+') + rparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE; + else if (*(argv[*i]) == '-') + rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE); + else + goto err_usage; + + mask |= LDAP_REALM_KRBTICKETFLAGS; + } else if (!strcmp((argv[*i] + 1), "password_changing_service")) { + if (*(argv[*i]) == '+') + rparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE; + else if (*(argv[*i]) == '-') + rparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE); + else + goto err_usage; + + mask |=LDAP_REALM_KRBTICKETFLAGS; + } +err_usage: + print_usage = TRUE; + +err_nomsg: + no_msg = TRUE; + + return mask; +} + +/* Create a special principal using two specified components. */ +static krb5_error_code +create_fixed_special(krb5_context context, struct realm_info *rinfo, + krb5_keyblock *mkey, const char *comp1, const char *comp2) +{ + krb5_error_code ret; + krb5_principal princ; + const char *realm = global_params.realm; + + ret = krb5_build_principal(context, &princ, strlen(realm), realm, comp1, + comp2, (const char *)NULL); + if (ret) + return ret; + ret = kdb_ldap_create_principal(context, princ, TGT_KEY, rinfo, mkey); + krb5_free_principal(context, princ); + return ret; + +} + +/* Create a special principal using one specified component and the + * canonicalized local hostname. */ +static krb5_error_code +create_hostbased_special(krb5_context context, struct realm_info *rinfo, + krb5_keyblock *mkey, const char *comp1) +{ + krb5_error_code ret; + krb5_principal princ = NULL; + + ret = krb5_sname_to_principal(context, NULL, comp1, KRB5_NT_SRV_HST, + &princ); + if (ret) + goto cleanup; + ret = krb5_set_principal_realm(context, princ, global_params.realm); + if (ret) + goto cleanup; + ret = kdb_ldap_create_principal(context, princ, TGT_KEY, rinfo, mkey); + +cleanup: + krb5_free_principal(context, princ); + return ret; +} + +/* Create all special principals for the realm. */ +static krb5_error_code +create_special_princs(krb5_context context, krb5_principal master_princ, + krb5_keyblock *mkey) +{ + krb5_error_code ret; + struct realm_info rblock; + + rblock.max_life = global_params.max_life; + rblock.max_rlife = global_params.max_rlife; + rblock.expiration = global_params.expiration; + rblock.flags = global_params.flags; + rblock.key = mkey; + rblock.nkslist = global_params.num_keysalts; + rblock.kslist = global_params.keysalts; + + /* Create master principal. */ + rblock.flags |= KRB5_KDB_DISALLOW_ALL_TIX; + ret = kdb_ldap_create_principal(context, master_princ, MASTER_KEY, &rblock, + mkey); + if (ret) + return ret; + + /* Create local krbtgt principal. */ + rblock.flags = 0; + ret = create_fixed_special(context, &rblock, mkey, KRB5_TGS_NAME, + global_params.realm); + if (ret) + return ret; + + /* Create kadmin/admin and kadmin/<hostname>. */ + rblock.max_life = ADMIN_LIFETIME; + rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED; + ret = create_fixed_special(context, &rblock, mkey, "kadmin", "admin"); + if (ret) + return ret; + ret = create_hostbased_special(context, &rblock, mkey, "kadmin"); + if (ret) + return ret; + + /* Create kiprop/<hostname>. */ + rblock.max_life = global_params.max_life; + rblock.flags = 0; + ret = create_hostbased_special(context, &rblock, mkey, "kiprop"); + if (ret) + return ret; + + /* Create kadmin/changepw. */ + rblock.max_life = CHANGEPW_LIFETIME; + rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_PWCHANGE_SERVICE; + ret = create_fixed_special(context, &rblock, mkey, "kadmin", "changepw"); + if (ret) + return ret; + + /* Create kadmin/history. */ + rblock.max_life = global_params.max_life; + rblock.flags = 0; + return create_fixed_special(context, &rblock, mkey, "kadmin", "history"); +} + +/* + * This function will create a realm on the LDAP Server, with + * the specified attributes. + */ +void +kdb5_ldap_create(int argc, char *argv[]) +{ + krb5_error_code retval = 0; + krb5_keyblock master_keyblock; + krb5_ldap_realm_params *rparams = NULL; + krb5_principal master_princ = NULL; + kdb5_dal_handle *dal_handle = NULL; + krb5_ldap_context *ldap_context=NULL; + krb5_boolean realm_obj_created = FALSE; + krb5_boolean create_complete = FALSE; + krb5_boolean print_usage = FALSE; + krb5_boolean no_msg = FALSE; + char *oldcontainerref=NULL; + char pw_str[1024]; + int do_stash = 0; + int i = 0; + int mask = 0, ret_mask = 0; + char **list = NULL; + + memset(&master_keyblock, 0, sizeof(master_keyblock)); + + rparams = (krb5_ldap_realm_params *)malloc( + sizeof(krb5_ldap_realm_params)); + if (rparams == NULL) { + retval = ENOMEM; + goto cleanup; + } + memset(rparams, 0, sizeof(krb5_ldap_realm_params)); + + /* Parse the arguments */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-subtrees")) { + if (++i > argc-1) + goto err_usage; + + if (strncmp(argv[i], "", strlen(argv[i]))!=0) { + list = (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *)); + if (list == NULL) { + retval = ENOMEM; + goto cleanup; + } + if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) { + free(list); + list = NULL; + goto cleanup; + } + + rparams->subtreecount=0; + while (list[rparams->subtreecount]!=NULL) + (rparams->subtreecount)++; + rparams->subtree = list; + } else if (strncmp(argv[i], "", strlen(argv[i]))==0) { + /* dont allow subtree value to be set at the root(NULL, "") of the tree */ + com_err(progname, EINVAL, + _("for subtree while creating realm '%s'"), + global_params.realm); + goto err_nomsg; + } + rparams->subtree[rparams->subtreecount] = NULL; + mask |= LDAP_REALM_SUBTREE; + } else if (!strcmp(argv[i], "-containerref")) { + if (++i > argc-1) + goto err_usage; + if (strncmp(argv[i], "", strlen(argv[i]))==0) { + /* dont allow containerref value to be set at the root(NULL, "") of the tree */ + com_err(progname, EINVAL, + _("for container reference while creating realm '%s'"), + global_params.realm); + goto err_nomsg; + } + free(rparams->containerref); + rparams->containerref = strdup(argv[i]); + if (rparams->containerref == NULL) { + retval = ENOMEM; + goto cleanup; + } + mask |= LDAP_REALM_CONTREF; + } else if (!strcmp(argv[i], "-sscope")) { + if (++i > argc-1) + goto err_usage; + /* Possible values for search scope are + * one (or 1) and sub (or 2) + */ + if (!strcasecmp(argv[i], "one")) { + rparams->search_scope = 1; + } else if (!strcasecmp(argv[i], "sub")) { + rparams->search_scope = 2; + } else { + rparams->search_scope = atoi(argv[i]); + if ((rparams->search_scope != 1) && + (rparams->search_scope != 2)) { + com_err(progname, EINVAL, _("invalid search scope while " + "creating realm '%s'"), + global_params.realm); + goto err_nomsg; + } + } + mask |= LDAP_REALM_SEARCHSCOPE; + } + else if (!strcmp(argv[i], "-s")) { + do_stash = 1; + } else if ((ret_mask= get_ticket_policy(rparams,&i,argv,argc)) !=0) { + mask|=ret_mask; + } + + else { + printf(_("'%s' is an invalid option\n"), argv[i]); + goto err_usage; + } + } + + krb5_princ_set_realm_data(util_context, &db_create_princ, global_params.realm); + krb5_princ_set_realm_length(util_context, &db_create_princ, strlen(global_params.realm)); + + printf(_("Initializing database for realm '%s'\n"), global_params.realm); + + if (!mkey_password) { + unsigned int pw_size; + printf(_("You will be prompted for the database Master Password.\n")); + printf(_("It is important that you NOT FORGET this password.\n")); + fflush(stdout); + + pw_size = sizeof (pw_str); + memset(pw_str, 0, pw_size); + + retval = krb5_read_password(util_context, KRB5_KDC_MKEY_1, KRB5_KDC_MKEY_2, + pw_str, &pw_size); + if (retval) { + com_err(progname, retval, + _("while reading master key from keyboard")); + goto err_nomsg; + } + mkey_password = pw_str; + } + + rparams->realm_name = strdup(global_params.realm); + if (rparams->realm_name == NULL) { + retval = ENOMEM; + com_err(progname, ENOMEM, _("while creating realm '%s'"), + global_params.realm); + goto err_nomsg; + } + + dal_handle = util_context->dal_handle; + ldap_context = (krb5_ldap_context *) dal_handle->db_context; + if (!ldap_context) { + retval = EINVAL; + goto cleanup; + } + + /* read the kerberos container */ + retval = krb5_ldap_read_krbcontainer_dn(util_context, + &ldap_context->container_dn); + if (retval) { + /* Prompt the user for entering the DN of Kerberos container */ + char krb_location[MAX_KRB_CONTAINER_LEN]; + int krb_location_len = 0; + + printf(_("Enter DN of Kerberos container: ")); + if (fgets(krb_location, MAX_KRB_CONTAINER_LEN, stdin) != NULL) { + /* Remove the newline character at the end */ + krb_location_len = strlen(krb_location); + if ((krb_location[krb_location_len - 1] == '\n') || + (krb_location[krb_location_len - 1] == '\r')) { + krb_location[krb_location_len - 1] = '\0'; + krb_location_len--; + } + ldap_context->container_dn = strdup(krb_location); + if (ldap_context->container_dn == NULL) { + retval = ENOMEM; + goto cleanup; + } + } + } + + /* create the kerberos container if it doesn't exist */ + retval = krb5_ldap_create_krbcontainer(util_context, + ldap_context->container_dn); + if (retval) + goto cleanup; + + if ((retval = krb5_ldap_create_realm(util_context, + /* global_params.realm, */ rparams, mask))) { + goto cleanup; + } + + /* We just created the Realm container. Here starts our transaction tracking */ + realm_obj_created = TRUE; + + if ((retval = krb5_ldap_read_realm_params(util_context, + global_params.realm, + &(ldap_context->lrparams), + &mask))) { + com_err(progname, retval, _("while reading information of realm '%s'"), + global_params.realm); + goto err_nomsg; + } + free(ldap_context->lrparams->realm_name); + ldap_context->lrparams->realm_name = strdup(global_params.realm); + if (ldap_context->lrparams->realm_name == NULL) { + retval = ENOMEM; + goto cleanup; + } + + /* assemble & parse the master key name */ + if ((retval = krb5_db_setup_mkey_name(util_context, + global_params.mkey_name, + global_params.realm, + 0, &master_princ))) { + com_err(progname, retval, _("while setting up master key name")); + goto err_nomsg; + } + + /* Obtain master key from master password */ + { + krb5_data master_salt, pwd; + + pwd.data = mkey_password; + pwd.length = strlen(mkey_password); + retval = krb5_principal2salt(util_context, master_princ, &master_salt); + if (retval) { + com_err(progname, retval, _("while calculating master key salt")); + goto err_nomsg; + } + + retval = krb5_c_string_to_key(util_context, global_params.enctype, + &pwd, &master_salt, &master_keyblock); + + if (master_salt.data) + free(master_salt.data); + + if (retval) { + com_err(progname, retval, + _("while transforming master key from password")); + goto err_nomsg; + } + } + + /* Create special principals (not in the container reference). */ + oldcontainerref = ldap_context->lrparams->containerref; + ldap_context->lrparams->containerref = NULL; + retval = create_special_princs(util_context, master_princ, + &master_keyblock); + ldap_context->lrparams->containerref = oldcontainerref; + if (retval) { + com_err(progname, retval, _("while adding entries to the database")); + goto err_nomsg; + } + + /* The Realm creation is completed. Here is the end of transaction */ + create_complete = TRUE; + + /* Stash the master key only if '-s' option is specified */ + if (do_stash || global_params.mask & KADM5_CONFIG_STASH_FILE) { + krb5_kvno mkey_kvno; + /* + * Determine the kvno to use, it must be that used to create the master + * key princ. + */ + if (global_params.mask & KADM5_CONFIG_KVNO) + mkey_kvno = global_params.kvno; /* user specified */ + else + mkey_kvno = 1; /* Default */ + + retval = krb5_db_store_master_key(util_context, + global_params.stash_file, + master_princ, + mkey_kvno, + &master_keyblock, NULL); + if (retval) { + com_err(progname, errno, _("while storing key")); + printf(_("Warning: couldn't stash master key.\n")); + } + } + + goto cleanup; + + +err_usage: + print_usage = TRUE; + +err_nomsg: + no_msg = TRUE; + +cleanup: + /* If the Realm creation is not complete, do the roll-back here */ + if ((realm_obj_created) && (!create_complete)) + krb5_ldap_delete_realm(util_context, global_params.realm); + + if (rparams) + krb5_ldap_free_realm_params(rparams); + + memset (pw_str, 0, sizeof (pw_str)); + + if (print_usage) + db_usage(CREATE_REALM); + + if (retval) { + if (!no_msg) { + com_err(progname, retval, _("while creating realm '%s'"), + global_params.realm); + } + exit_status++; + } + + krb5_free_keyblock_contents(util_context, &master_keyblock); + krb5_free_principal(util_context, master_princ); +} + + +/* + * This function will modify the attributes of a given realm object + */ +void +kdb5_ldap_modify(int argc, char *argv[]) +{ + krb5_error_code retval = 0; + krb5_ldap_realm_params *rparams = NULL; + krb5_boolean print_usage = FALSE; + krb5_boolean no_msg = FALSE; + kdb5_dal_handle *dal_handle = NULL; + krb5_ldap_context *ldap_context=NULL; + int i = 0; + int mask = 0, rmask = 0, ret_mask = 0; + char **slist = {NULL}; + + dal_handle = util_context->dal_handle; + ldap_context = (krb5_ldap_context *) dal_handle->db_context; + if (!(ldap_context)) { + retval = EINVAL; + goto cleanup; + } + + retval = krb5_ldap_read_krbcontainer_dn(util_context, + &ldap_context->container_dn); + if (retval) { + com_err(progname, retval, + _("while reading Kerberos container information")); + goto err_nomsg; + } + + retval = krb5_ldap_read_realm_params(util_context, + global_params.realm, &rparams, &rmask); + if (retval) + goto cleanup; + /* Parse the arguments */ + for (i = 1; i < argc; i++) { + int k = 0; + if (!strcmp(argv[i], "-subtrees")) { + if (++i > argc-1) + goto err_usage; + + if (rmask & LDAP_REALM_SUBTREE) { + if (rparams->subtree) { + for (k=0; k<rparams->subtreecount && rparams->subtree[k]; k++) + free(rparams->subtree[k]); + free(rparams->subtree); + rparams->subtreecount=0; + rparams->subtree = NULL; + } + } + if (strncmp(argv[i] ,"", strlen(argv[i]))!=0) { + slist = (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *)); + if (slist == NULL) { + retval = ENOMEM; + goto cleanup; + } + if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, slist))) { + free(slist); + slist = NULL; + goto cleanup; + } + + rparams->subtreecount=0; + while (slist[rparams->subtreecount]!=NULL) + (rparams->subtreecount)++; + rparams->subtree = slist; + } else if (strncmp(argv[i], "", strlen(argv[i]))==0) { + /* dont allow subtree value to be set at the root(NULL, "") of the tree */ + com_err(progname, EINVAL, + _("for subtree while modifying realm '%s'"), + global_params.realm); + goto err_nomsg; + } + rparams->subtree[rparams->subtreecount] = NULL; + mask |= LDAP_REALM_SUBTREE; + } else if (!strncmp(argv[i], "-containerref", strlen(argv[i]))) { + if (++i > argc-1) + goto err_usage; + if (strncmp(argv[i], "", strlen(argv[i]))==0) { + /* dont allow containerref value to be set at the root(NULL, "") of the tree */ + com_err(progname, EINVAL, _("for container reference while " + "modifying realm '%s'"), + global_params.realm); + goto err_nomsg; + } + free(rparams->containerref); + rparams->containerref = strdup(argv[i]); + if (rparams->containerref == NULL) { + retval = ENOMEM; + goto cleanup; + } + mask |= LDAP_REALM_CONTREF; + } else if (!strcmp(argv[i], "-sscope")) { + if (++i > argc-1) + goto err_usage; + /* Possible values for search scope are + * one (or 1) and sub (or 2) + */ + if (strcasecmp(argv[i], "one") == 0) { + rparams->search_scope = 1; + } else if (strcasecmp(argv[i], "sub") == 0) { + rparams->search_scope = 2; + } else { + rparams->search_scope = atoi(argv[i]); + if ((rparams->search_scope != 1) && + (rparams->search_scope != 2)) { + retval = EINVAL; + com_err(progname, retval, + _("specified for search scope while modifying " + "information of realm '%s'"), + global_params.realm); + goto err_nomsg; + } + } + mask |= LDAP_REALM_SEARCHSCOPE; + } + else if ((ret_mask= get_ticket_policy(rparams,&i,argv,argc)) !=0) { + mask|=ret_mask; + } else { + printf(_("'%s' is an invalid option\n"), argv[i]); + goto err_usage; + } + } + + if ((retval = krb5_ldap_modify_realm(util_context, + /* global_params.realm, */ rparams, mask))) { + goto cleanup; + } + + goto cleanup; + +err_usage: + print_usage = TRUE; + +err_nomsg: + no_msg = TRUE; + +cleanup: + krb5_ldap_free_realm_params(rparams); + + if (print_usage) { + db_usage(MODIFY_REALM); + } + + if (retval) { + if (!no_msg) + com_err(progname, retval, + _("while modifying information of realm '%s'"), + global_params.realm); + exit_status++; + } + + return; +} + + + +/* + * This function displays the attributes of a Realm + */ +void +kdb5_ldap_view(int argc, char *argv[]) +{ + krb5_ldap_realm_params *rparams = NULL; + krb5_error_code retval = 0; + kdb5_dal_handle *dal_handle=NULL; + krb5_ldap_context *ldap_context=NULL; + int mask = 0; + + dal_handle = util_context->dal_handle; + ldap_context = (krb5_ldap_context *) dal_handle->db_context; + if (!(ldap_context)) { + retval = EINVAL; + com_err(progname, retval, _("while initializing database")); + exit_status++; + return; + } + + /* Read the kerberos container information */ + retval = krb5_ldap_read_krbcontainer_dn(util_context, + &ldap_context->container_dn); + if (retval) { + com_err(progname, retval, + _("while reading kerberos container information")); + exit_status++; + return; + } + + if ((retval = krb5_ldap_read_realm_params(util_context, + global_params.realm, &rparams, &mask)) || (!rparams)) { + com_err(progname, retval, _("while reading information of realm '%s'"), + global_params.realm); + exit_status++; + return; + } + print_realm_params(rparams, mask); + krb5_ldap_free_realm_params(rparams); + + return; +} + +static char * +strdur(time_t duration) +{ + static char out[50]; + int neg, days, hours, minutes, seconds; + + if (duration < 0) { + duration *= -1; + neg = 1; + } else + neg = 0; + days = duration / (24 * 3600); + duration %= 24 * 3600; + hours = duration / 3600; + duration %= 3600; + minutes = duration / 60; + duration %= 60; + seconds = duration; + snprintf(out, sizeof(out), "%s%d %s %02d:%02d:%02d", neg ? "-" : "", + days, days == 1 ? "day" : "days", + hours, minutes, seconds); + return out; +} + +/* + * This function prints the attributes of a given realm to the + * standard output. + */ +static void +print_realm_params(krb5_ldap_realm_params *rparams, int mask) +{ + char **slist = NULL; + unsigned int num_entry_printed = 0, i = 0; + + /* Print the Realm Attributes on the standard output */ + printf("%25s: %-50s\n", _("Realm Name"), global_params.realm); + if (mask & LDAP_REALM_SUBTREE) { + for (i=0; rparams->subtree[i]!=NULL; i++) + printf("%25s: %-50s\n", _("Subtree"), rparams->subtree[i]); + } + if (mask & LDAP_REALM_CONTREF) + printf("%25s: %-50s\n", _("Principal Container Reference"), + rparams->containerref); + if (mask & LDAP_REALM_SEARCHSCOPE) { + if ((rparams->search_scope != 1) && + (rparams->search_scope != 2)) { + printf("%25s: %-50s\n", _("SearchScope"), _("Invalid !")); + } else { + printf("%25s: %-50s\n", _("SearchScope"), + (rparams->search_scope == 1) ? "ONE" : "SUB"); + } + } + if (mask & LDAP_REALM_KDCSERVERS) { + printf("%25s:", _("KDC Services")); + if (rparams->kdcservers != NULL) { + num_entry_printed = 0; + for (slist = rparams->kdcservers; *slist != NULL; slist++) { + if (num_entry_printed) + printf(" %25s %-50s\n", " ", *slist); + else + printf(" %-50s\n", *slist); + num_entry_printed++; + } + } + if (num_entry_printed == 0) + printf("\n"); + } + if (mask & LDAP_REALM_ADMINSERVERS) { + printf("%25s:", _("Admin Services")); + if (rparams->adminservers != NULL) { + num_entry_printed = 0; + for (slist = rparams->adminservers; *slist != NULL; slist++) { + if (num_entry_printed) + printf(" %25s %-50s\n", " ", *slist); + else + printf(" %-50s\n", *slist); + num_entry_printed++; + } + } + if (num_entry_printed == 0) + printf("\n"); + } + if (mask & LDAP_REALM_PASSWDSERVERS) { + printf("%25s:", _("Passwd Services")); + if (rparams->passwdservers != NULL) { + num_entry_printed = 0; + for (slist = rparams->passwdservers; *slist != NULL; slist++) { + if (num_entry_printed) + printf(" %25s %-50s\n", " ", *slist); + else + printf(" %-50s\n", *slist); + num_entry_printed++; + } + } + if (num_entry_printed == 0) + printf("\n"); + } + + if (mask & LDAP_REALM_MAXTICKETLIFE) { + printf("%25s:", _("Maximum Ticket Life")); + printf(" %s \n", strdur(rparams->max_life)); + } + + if (mask & LDAP_REALM_MAXRENEWLIFE) { + printf("%25s:", _("Maximum Renewable Life")); + printf(" %s \n", strdur(rparams->max_renewable_life)); + } + + if (mask & LDAP_REALM_KRBTICKETFLAGS) { + int ticketflags = rparams->tktflags; + + printf("%25s: ", _("Ticket flags")); + if (ticketflags & KRB5_KDB_DISALLOW_POSTDATED) + printf("%s ","DISALLOW_POSTDATED"); + + if (ticketflags & KRB5_KDB_DISALLOW_FORWARDABLE) + printf("%s ","DISALLOW_FORWARDABLE"); + + if (ticketflags & KRB5_KDB_DISALLOW_RENEWABLE) + printf("%s ","DISALLOW_RENEWABLE"); + + if (ticketflags & KRB5_KDB_DISALLOW_PROXIABLE) + printf("%s ","DISALLOW_PROXIABLE"); + + if (ticketflags & KRB5_KDB_DISALLOW_DUP_SKEY) + printf("%s ","DISALLOW_DUP_SKEY"); + + if (ticketflags & KRB5_KDB_REQUIRES_PRE_AUTH) + printf("%s ","REQUIRES_PRE_AUTH"); + + if (ticketflags & KRB5_KDB_REQUIRES_HW_AUTH) + printf("%s ","REQUIRES_HW_AUTH"); + + if (ticketflags & KRB5_KDB_DISALLOW_SVR) + printf("%s ","DISALLOW_SVR"); + + if (ticketflags & KRB5_KDB_DISALLOW_TGT_BASED) + printf("%s ","DISALLOW_TGT_BASED"); + + if (ticketflags & KRB5_KDB_DISALLOW_ALL_TIX) + printf("%s ","DISALLOW_ALL_TIX"); + + if (ticketflags & KRB5_KDB_REQUIRES_PWCHANGE) + printf("%s ","REQUIRES_PWCHANGE"); + + if (ticketflags & KRB5_KDB_PWCHANGE_SERVICE) + printf("%s ","PWCHANGE_SERVICE"); + + printf("\n"); + } + + + return; +} + + + +/* + * This function lists the Realm(s) present under the Kerberos container + * on the LDAP Server. + */ +void +kdb5_ldap_list(int argc, char *argv[]) +{ + char **list = NULL; + char **plist = NULL; + krb5_error_code retval = 0; + kdb5_dal_handle *dal_handle=NULL; + krb5_ldap_context *ldap_context=NULL; + + dal_handle = util_context->dal_handle; + ldap_context = (krb5_ldap_context *) dal_handle->db_context; + if (!(ldap_context)) { + retval = EINVAL; + exit_status++; + return; + } + + /* Read the kerberos container information */ + retval = krb5_ldap_read_krbcontainer_dn(util_context, + &ldap_context->container_dn); + if (retval) { + com_err(progname, retval, + _("while reading kerberos container information")); + exit_status++; + return; + } + + retval = krb5_ldap_list_realm(util_context, &list); + if (retval != 0) { + com_err(progname, retval, _("while listing realms")); + exit_status++; + return; + } + /* This is to handle the case of realm not present */ + if (list == NULL) + return; + + for (plist = list; *plist != NULL; plist++) { + printf("%s\n", *plist); + } + krb5_free_list_entries(list); + free(list); + + return; +} + +/* + * Duplicating the following two functions here because + * 'krb5_dbe_update_tl_data' uses backend specific memory allocation. The catch + * here is that the backend is not initialized - kdb5_ldap_util doesn't go + * through DAL. + * 1. krb5_dbe_update_tl_data + * 2. krb5_dbe_update_mod_princ_data + */ + +/* Start duplicate code ... */ + +static krb5_error_code +krb5_dbe_update_tl_data_new(krb5_context context, krb5_db_entry *entry, + krb5_tl_data *new_tl_data) +{ + krb5_tl_data *tl_data = NULL; + krb5_octet *tmp; + + /* copy the new data first, so we can fail cleanly if malloc() + * fails */ + if ((tmp = (krb5_octet *) malloc (new_tl_data->tl_data_length)) == NULL) + return (ENOMEM); + + /* Find an existing entry of the specified type and point at + * it, or NULL if not found */ + + if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) { /* db_args can be multiple */ + for (tl_data = entry->tl_data; tl_data; + tl_data = tl_data->tl_data_next) + if (tl_data->tl_data_type == new_tl_data->tl_data_type) + break; + } + + /* if necessary, chain a new record in the beginning and point at it */ + + if (!tl_data) { + if ((tl_data = (krb5_tl_data *) malloc (sizeof(krb5_tl_data))) == NULL) { + free(tmp); + return (ENOMEM); + } + memset(tl_data, 0, sizeof(krb5_tl_data)); + tl_data->tl_data_next = entry->tl_data; + entry->tl_data = tl_data; + entry->n_tl_data++; + } + + /* fill in the record */ + + free(tl_data->tl_data_contents); + + tl_data->tl_data_type = new_tl_data->tl_data_type; + tl_data->tl_data_length = new_tl_data->tl_data_length; + tl_data->tl_data_contents = tmp; + memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length); + + return (0); +} + +static krb5_error_code +krb5_dbe_update_mod_princ_data_new(krb5_context context, krb5_db_entry *entry, + krb5_timestamp mod_date, + krb5_const_principal mod_princ) +{ + krb5_tl_data tl_data; + + krb5_error_code retval = 0; + krb5_octet * nextloc = 0; + char * unparse_mod_princ = 0; + unsigned int unparse_mod_princ_size; + + if ((retval = krb5_unparse_name(context, mod_princ, + &unparse_mod_princ))) + return(retval); + + unparse_mod_princ_size = strlen(unparse_mod_princ) + 1; + + if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4)) + == NULL) { + free(unparse_mod_princ); + return(ENOMEM); + } + + tl_data.tl_data_type = KRB5_TL_MOD_PRINC; + tl_data.tl_data_length = unparse_mod_princ_size + 4; + tl_data.tl_data_contents = nextloc; + + /* Mod Date */ + krb5_kdb_encode_int32(mod_date, nextloc); + + /* Mod Princ */ + memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size); + + retval = krb5_dbe_update_tl_data_new(context, entry, &tl_data); + + free(unparse_mod_princ); + free(nextloc); + + return(retval); +} + +static krb5_error_code +kdb_ldap_tgt_keysalt_iterate(krb5_key_salt_tuple *ksent, krb5_pointer ptr) +{ + krb5_context context; + krb5_error_code kret; + struct iterate_args *iargs; + krb5_keyblock key; + krb5_int32 ind; + krb5_data pwd; + krb5_db_entry *entry; + + iargs = (struct iterate_args *) ptr; + kret = 0; + + context = iargs->ctx; + entry = iargs->dbentp; + + /* + * Convert the master key password into a key for this particular + * encryption system. + */ + pwd.data = mkey_password; + pwd.length = strlen(mkey_password); + kret = krb5_c_random_seed(context, &pwd); + if (kret) + return kret; + + /*if (!(kret = krb5_dbe_create_key_data(iargs->ctx, iargs->dbentp))) {*/ + if ((entry->key_data = + (krb5_key_data *) realloc(entry->key_data, + (sizeof(krb5_key_data) * + (entry->n_key_data + 1)))) == NULL) + return (ENOMEM); + + memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data)); + ind = entry->n_key_data++; + + if (!(kret = krb5_c_make_random_key(context, ksent->ks_enctype, + &key))) { + kret = krb5_dbe_encrypt_key_data(context, iargs->rblock->key, &key, + NULL, 1, &entry->key_data[ind]); + krb5_free_keyblock_contents(context, &key); + } + /*}*/ + + return(kret); +} +/* End duplicate code */ + +/* + * This function creates service principals when + * creating the realm object. + */ +static int +kdb_ldap_create_principal(krb5_context context, krb5_principal princ, + enum ap_op op, struct realm_info *pblock, + const krb5_keyblock *master_keyblock) +{ + int retval=0, currlen=0, princtype = 2 /* Service Principal */; + unsigned char *curr=NULL; + krb5_tl_data *tl_data=NULL; + krb5_db_entry entry; + long mask = 0; + krb5_keyblock key; + int kvno = 0; + kdb5_dal_handle *dal_handle = NULL; + krb5_ldap_context *ldap_context=NULL; + struct iterate_args iargs; + krb5_data *pdata; + krb5_timestamp now; + krb5_actkvno_node actkvno; + + memset(&entry, 0, sizeof(entry)); + + if ((pblock == NULL) || (context == NULL)) { + retval = EINVAL; + goto cleanup; + } + dal_handle = context->dal_handle; + ldap_context = (krb5_ldap_context *) dal_handle->db_context; + if (!(ldap_context)) { + retval = EINVAL; + goto cleanup; + } + + tl_data = malloc(sizeof(*tl_data)); + if (tl_data == NULL) { + retval = ENOMEM; + goto cleanup; + } + memset(tl_data, 0, sizeof(*tl_data)); + tl_data->tl_data_length = 1 + 2 + 2 + 1 + 2 + 4; + tl_data->tl_data_type = 7; /* KDB_TL_USER_INFO */ + curr = tl_data->tl_data_contents = malloc(tl_data->tl_data_length); + if (tl_data->tl_data_contents == NULL) { + retval = ENOMEM; + goto cleanup; + } + + memset(curr, 1, 1); /* Passing the mask as principal type */ + curr += 1; + currlen = 2; + STORE16_INT(curr, currlen); + curr += currlen; + STORE16_INT(curr, princtype); + curr += currlen; + + mask |= KADM5_PRINCIPAL; + mask |= KADM5_ATTRIBUTES ; + mask |= KADM5_MAX_LIFE ; + mask |= KADM5_MAX_RLIFE ; + mask |= KADM5_PRINC_EXPIRE_TIME ; + mask |= KADM5_KEY_DATA; + + entry.tl_data = tl_data; + entry.n_tl_data += 1; + /* Set the creator's name */ + if ((retval = krb5_timeofday(context, &now))) + goto cleanup; + if ((retval = krb5_dbe_update_mod_princ_data_new(context, &entry, + now, &db_create_princ))) + goto cleanup; + + entry.attributes = pblock->flags; + entry.max_life = pblock->max_life; + entry.max_renewable_life = pblock->max_rlife; + entry.expiration = pblock->expiration; + entry.mask = mask; + if ((retval = krb5_copy_principal(context, princ, &entry.princ))) + goto cleanup; + + + switch (op) { + case TGT_KEY: + if ((pdata = krb5_princ_component(context, princ, 1)) && + pdata->length == strlen("history") && + !memcmp(pdata->data, "history", strlen("history"))) { + + /* Allocate memory for storing the key */ + if ((entry.key_data = (krb5_key_data *) malloc( + sizeof(krb5_key_data))) == NULL) { + retval = ENOMEM; + goto cleanup; + } + + memset(entry.key_data, 0, sizeof(krb5_key_data)); + entry.n_key_data++; + + retval = krb5_c_make_random_key(context, global_params.enctype, &key); + if (retval) { + goto cleanup; + } + kvno = 1; /* New key is getting set */ + retval = krb5_dbe_encrypt_key_data(context, master_keyblock, + &key, NULL, kvno, + &entry.key_data[entry.n_key_data - 1]); + krb5_free_keyblock_contents(context, &key); + if (retval) { + goto cleanup; + } + } else { + /*retval = krb5_c_make_random_key(context, 16, &key) ;*/ + iargs.ctx = context; + iargs.rblock = pblock; + iargs.dbentp = &entry; + + /* + * Iterate through the key/salt list, ignoring salt types. + */ + if ((retval = krb5_keysalt_iterate(pblock->kslist, + pblock->nkslist, + 1, + kdb_ldap_tgt_keysalt_iterate, + (krb5_pointer) &iargs))) + return retval; + } + break; + + case MASTER_KEY: + /* Allocate memory for storing the key */ + if ((entry.key_data = (krb5_key_data *) malloc( + sizeof(krb5_key_data))) == NULL) { + retval = ENOMEM; + goto cleanup; + } + + memset(entry.key_data, 0, sizeof(krb5_key_data)); + entry.n_key_data++; + kvno = 1; /* New key is getting set */ + retval = krb5_dbe_encrypt_key_data(context, pblock->key, + master_keyblock, NULL, kvno, + &entry.key_data[entry.n_key_data - 1]); + if (retval) { + goto cleanup; + } + /* + * There should always be at least one "active" mkey so creating the + * KRB5_TL_ACTKVNO entry now so the initial mkey is active. + */ + actkvno.next = NULL; + actkvno.act_kvno = kvno; + actkvno.act_time = now; + retval = krb5_dbe_update_actkvno(context, &entry, &actkvno); + if (retval) + goto cleanup; + + break; + + case NULL_KEY: + default: + break; + } /* end of switch */ + + retval = krb5_ldap_put_principal(context, &entry, NULL); + if (retval) { + com_err(NULL, retval, _("while adding entries to database")); + goto cleanup; + } + +cleanup: + krb5_dbe_free_contents(context, &entry); + return retval; +} + + +/* + * This function destroys the realm object and the associated principals + */ +void +kdb5_ldap_destroy(int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + int optchar = 0; + char buf[5] = {0}; + krb5_error_code retval = 0; + int force = 0; + int mask = 0; + kdb5_dal_handle *dal_handle = NULL; + krb5_ldap_context *ldap_context = NULL; + + optind = 1; + while ((optchar = getopt(argc, argv, "f")) != -1) { + switch (optchar) { + case 'f': + force++; + break; + case '?': + default: + db_usage(DESTROY_REALM); + return; + /*NOTREACHED*/ + } + } + + if (!force) { + printf(_("Deleting KDC database of '%s', are you sure?\n"), + global_params.realm); + printf(_("(type 'yes' to confirm)? ")); + if (fgets(buf, sizeof(buf), stdin) == NULL) { + exit_status++; + return; + } + if (strcmp(buf, yes)) { + exit_status++; + return; + } + printf(_("OK, deleting database of '%s'...\n"), global_params.realm); + } + + dal_handle = util_context->dal_handle; + ldap_context = (krb5_ldap_context *) dal_handle->db_context; + if (!(ldap_context)) { + com_err(progname, EINVAL, _("while initializing database")); + exit_status++; + return; + } + + /* Read the kerberos container DN */ + retval = krb5_ldap_read_krbcontainer_dn(util_context, + &ldap_context->container_dn); + if (retval) { + com_err(progname, retval, + _("while reading kerberos container information")); + exit_status++; + return; + } + + /* Read the Realm information from the LDAP Server */ + if ((retval = krb5_ldap_read_realm_params(util_context, global_params.realm, + &(ldap_context->lrparams), &mask)) != 0) { + com_err(progname, retval, _("while reading realm information")); + exit_status++; + return; + } + + /* Delete the realm container and all the associated principals */ + retval = krb5_ldap_delete_realm(util_context, global_params.realm); + if (retval) { + com_err(progname, retval, + _("deleting database of '%s'"), global_params.realm); + exit_status++; + return; + } + + printf(_("** Database of '%s' destroyed.\n"), global_params.realm); + + return; +} |
