xref: /onnv-gate/usr/src/cmd/krb5/ldap_util/kdb5_ldap_realm.c (revision 8092:19771b16f0a8)
14960Swillf /*
2*8092SMark.Phalan@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
34960Swillf  * Use is subject to license terms.
44960Swillf  */
54960Swillf 
64960Swillf /*
74960Swillf  * kadmin/ldap_util/kdb5_ldap_realm.c
84960Swillf  *
94960Swillf  * Copyright 1990,1991,2001, 2002 by the Massachusetts Institute of Technology.
104960Swillf  * All Rights Reserved.
114960Swillf  *
124960Swillf  * Export of this software from the United States of America may
134960Swillf  *   require a specific license from the United States Government.
144960Swillf  *   It is the responsibility of any person or organization contemplating
154960Swillf  *   export to obtain such a license before exporting.
164960Swillf  *
174960Swillf  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
184960Swillf  * distribute this software and its documentation for any purpose and
194960Swillf  * without fee is hereby granted, provided that the above copyright
204960Swillf  * notice appear in all copies and that both that copyright notice and
214960Swillf  * this permission notice appear in supporting documentation, and that
224960Swillf  * the name of M.I.T. not be used in advertising or publicity pertaining
234960Swillf  * to distribution of the software without specific, written prior
244960Swillf  * permission.  Furthermore if you modify this software you must label
254960Swillf  * your software as modified software and not distribute it in such a
264960Swillf  * fashion that it might be confused with the original M.I.T. software.
274960Swillf  * M.I.T. makes no representations about the suitability of
284960Swillf  * this software for any purpose.  It is provided "as is" without express
294960Swillf  * or implied warranty.
304960Swillf  */
314960Swillf 
324960Swillf /*
334960Swillf  * Copyright (C) 1998 by the FundsXpress, INC.
344960Swillf  *
354960Swillf  * All rights reserved.
364960Swillf  *
374960Swillf  * Export of this software from the United States of America may require
384960Swillf  * a specific license from the United States Government.  It is the
394960Swillf  * responsibility of any person or organization contemplating export to
404960Swillf  * obtain such a license before exporting.
414960Swillf  *
424960Swillf  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
434960Swillf  * distribute this software and its documentation for any purpose and
444960Swillf  * without fee is hereby granted, provided that the above copyright
454960Swillf  * notice appear in all copies and that both that copyright notice and
464960Swillf  * this permission notice appear in supporting documentation, and that
474960Swillf  * the name of FundsXpress. not be used in advertising or publicity pertaining
484960Swillf  * to distribution of the software without specific, written prior
494960Swillf  * permission.  FundsXpress makes no representations about the suitability of
504960Swillf  * this software for any purpose.  It is provided "as is" without express
514960Swillf  * or implied warranty.
524960Swillf  *
534960Swillf  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
544960Swillf  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
554960Swillf  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
564960Swillf  */
574960Swillf 
584960Swillf /* Copyright (c) 2004-2005, Novell, Inc.
594960Swillf  * All rights reserved.
604960Swillf  *
614960Swillf  * Redistribution and use in source and binary forms, with or without
624960Swillf  * modification, are permitted provided that the following conditions are met:
634960Swillf  *
644960Swillf  *   * Redistributions of source code must retain the above copyright notice,
654960Swillf  *       this list of conditions and the following disclaimer.
664960Swillf  *   * Redistributions in binary form must reproduce the above copyright
674960Swillf  *       notice, this list of conditions and the following disclaimer in the
684960Swillf  *       documentation and/or other materials provided with the distribution.
694960Swillf  *   * The copyright holder's name is not used to endorse or promote products
704960Swillf  *       derived from this software without specific prior written permission.
714960Swillf  *
724960Swillf  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
734960Swillf  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
744960Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
754960Swillf  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
764960Swillf  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
774960Swillf  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
784960Swillf  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
794960Swillf  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
804960Swillf  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
814960Swillf  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
824960Swillf  * POSSIBILITY OF SUCH DAMAGE.
834960Swillf  */
844960Swillf 
854960Swillf /*
864960Swillf  * Create / Modify / Destroy / View / List realm(s)
874960Swillf  */
884960Swillf 
894960Swillf /* Needed for getting the definition of KRB5_TL_DB_ARGS */
904960Swillf #define SECURID
914960Swillf 
924960Swillf #include <stdio.h>
934960Swillf #include <k5-int.h>
944960Swillf #include <kadm5/admin.h>
954960Swillf #include <libintl.h>
964960Swillf #include <locale.h>
974960Swillf #include "kdb5_ldap_util.h"
984960Swillf #include "kdb5_ldap_list.h"
994960Swillf #include <ldap_principal.h>
1004960Swillf #include <ldap_krbcontainer.h>
1014960Swillf extern time_t get_date(char *); /* kadmin/cli/getdate.o */
1024960Swillf 
1034960Swillf char *yes = "yes\n"; /* \n to compare against result of fgets */
1044960Swillf krb5_key_salt_tuple def_kslist = {ENCTYPE_DES_CBC_CRC, KRB5_KDB_SALTTYPE_NORMAL};
1054960Swillf 
1064960Swillf struct realm_info rblock = {
1074960Swillf     KRB5_KDB_MAX_LIFE,
1084960Swillf     KRB5_KDB_MAX_RLIFE,
1094960Swillf     KRB5_KDB_EXPIRATION,
1104960Swillf     KRB5_KDB_DEF_FLAGS,
1114960Swillf     (krb5_keyblock *) NULL,
1124960Swillf     1,
1134960Swillf     &def_kslist
1144960Swillf };
1154960Swillf 
1164960Swillf krb5_data tgt_princ_entries[] = {
1174960Swillf     {0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME},
1184960Swillf     {0, 0, 0} };
1194960Swillf 
1204960Swillf krb5_data db_creator_entries[] = {
1214960Swillf     {0, sizeof("db_creation")-1, "db_creation"} };
1224960Swillf 
1234960Swillf 
1244960Swillf static krb5_principal_data db_create_princ = {
1254960Swillf     0,					/* magic number */
1264960Swillf     {0, 0, 0},				/* krb5_data realm */
1274960Swillf     db_creator_entries,			/* krb5_data *data */
1284960Swillf     1,					/* int length */
1294960Swillf     KRB5_NT_SRV_INST			/* int type */
1304960Swillf };
1314960Swillf 
1324960Swillf extern char *mkey_password;
1334960Swillf extern char *progname;
1344960Swillf extern kadm5_config_params global_params;
1354960Swillf 
1364960Swillf static void print_realm_params(krb5_ldap_realm_params *rparams, int mask);
1374960Swillf static int kdb_ldap_create_principal (krb5_context context, krb5_principal
1384960Swillf 				      princ, enum ap_op op, struct realm_info *pblock);
1394960Swillf 
1404960Swillf 
1414960Swillf static char *strdur(time_t duration);
1424960Swillf static int get_ticket_policy(krb5_ldap_realm_params *rparams, int *i, char *argv[],int argc);
1434960Swillf 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);
1444960Swillf static krb5_error_code krb5_dbe_update_tl_data_new ( krb5_context context, krb5_db_entry *entry, krb5_tl_data *new_tl_data);
1454960Swillf 
1464960Swillf #define ADMIN_LIFETIME 60*60*3 /* 3 hours */
1474960Swillf #define CHANGEPW_LIFETIME 60*5 /* 5 minutes */
1484960Swillf 
get_ticket_policy(rparams,i,argv,argc)1494960Swillf static int get_ticket_policy(rparams,i,argv,argc)
1504960Swillf     krb5_ldap_realm_params *rparams;
1514960Swillf     int *i;
1524960Swillf     char *argv[];
1534960Swillf     int argc;
1544960Swillf {
1554960Swillf     time_t date;
1564960Swillf     time_t now;
1574960Swillf     int mask = 0;
1584960Swillf     krb5_error_code retval = 0;
1594960Swillf     krb5_boolean no_msg = FALSE;
1604960Swillf 
1614960Swillf     krb5_boolean print_usage = FALSE;
162*8092SMark.Phalan@Sun.COM     /* Solaris Kerberos */
163*8092SMark.Phalan@Sun.COM     char *me = progname;
1644960Swillf 
1654960Swillf     time(&now);
1664960Swillf     if (!strcmp(argv[*i], "-maxtktlife")) {
1674960Swillf 	if (++(*i) > argc-1)
1684960Swillf 	    goto err_usage;
1694960Swillf 	date = get_date(argv[*i]);
1704960Swillf 	if (date == (time_t)(-1)) {
1714960Swillf 	    retval = EINVAL;
1724960Swillf 	    com_err (me, retval, gettext("while providing time specification"));
1734960Swillf 	    goto err_nomsg;
1744960Swillf 	}
1754960Swillf 	rparams->max_life = date-now;
1764960Swillf 	mask |= LDAP_REALM_MAXTICKETLIFE;
1774960Swillf     }
1784960Swillf 
1794960Swillf 
1804960Swillf     else if (!strcmp(argv[*i], "-maxrenewlife")) {
1814960Swillf 	if (++(*i) > argc-1)
1824960Swillf 	    goto err_usage;
1834960Swillf 
1844960Swillf 	date = get_date(argv[*i]);
1854960Swillf 	if (date == (time_t)(-1)) {
1864960Swillf 	    retval = EINVAL;
1874960Swillf 	    com_err (me, retval, gettext("while providing time specification"));
1884960Swillf 	    goto err_nomsg;
1894960Swillf 	}
1904960Swillf 	rparams->max_renewable_life = date-now;
1914960Swillf 	mask |= LDAP_REALM_MAXRENEWLIFE;
1924960Swillf     } else if (!strcmp((argv[*i] + 1), "allow_postdated")) {
1934960Swillf 	if (*(argv[*i]) == '+')
1944960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED);
1954960Swillf 	else if (*(argv[*i]) == '-')
1964960Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED;
1974960Swillf 	else
1984960Swillf 	    goto err_usage;
1994960Swillf 
2004960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2014960Swillf     } else if (!strcmp((argv[*i] + 1), "allow_forwardable")) {
2024960Swillf 	if (*(argv[*i]) == '+')
2034960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE);
2044960Swillf 
2054960Swillf 	else if (*(argv[*i]) == '-')
2064960Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE;
2074960Swillf 	else
2084960Swillf 	    goto err_usage;
2094960Swillf 
2104960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2114960Swillf     } else if (!strcmp((argv[*i] + 1), "allow_renewable")) {
2124960Swillf 	if (*(argv[*i]) == '+')
2134960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE);
2144960Swillf 	else if (*(argv[*i]) == '-')
2154960Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE;
2164960Swillf 	else
2174960Swillf 	    goto err_usage;
2184960Swillf 
2194960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2204960Swillf     } else if (!strcmp((argv[*i] + 1), "allow_proxiable")) {
2214960Swillf 	if (*(argv[*i]) == '+')
2224960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE);
2234960Swillf 	else if (*(argv[*i]) == '-')
2244960Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE;
2254960Swillf 	else
2264960Swillf 	    goto err_usage;
2274960Swillf 
2284960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2294960Swillf     } else if (!strcmp((argv[*i] + 1), "allow_dup_skey")) {
2304960Swillf 	if (*(argv[*i]) == '+')
2314960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY);
2324960Swillf 	else if (*(argv[*i]) == '-')
2334960Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY;
2344960Swillf 	else
2354960Swillf 	    goto err_usage;
2364960Swillf 
2374960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2384960Swillf     }
2394960Swillf 
2404960Swillf     else if (!strcmp((argv[*i] + 1), "requires_preauth")) {
2414960Swillf 	if (*(argv[*i]) == '+')
2424960Swillf 	    rparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH;
2434960Swillf 	else if (*(argv[*i]) == '-')
2444960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH);
2454960Swillf 	else
2464960Swillf 	    goto err_usage;
2474960Swillf 
2484960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2494960Swillf     } else if (!strcmp((argv[*i] + 1), "requires_hwauth")) {
2504960Swillf 	if (*(argv[*i]) == '+')
2514960Swillf 	    rparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH;
2524960Swillf 	else if (*(argv[*i]) == '-')
2534960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH);
2544960Swillf 	else
2554960Swillf 	    goto err_usage;
2564960Swillf 
2574960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2584960Swillf     } else if (!strcmp((argv[*i] + 1), "allow_svr")) {
2594960Swillf 	if (*(argv[*i]) == '+')
2604960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR);
2614960Swillf 	else if (*(argv[*i]) == '-')
2624960Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_SVR;
2634960Swillf 	else
2644960Swillf 	    goto err_usage;
2654960Swillf 
2664960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2674960Swillf     } else if (!strcmp((argv[*i] + 1), "allow_tgs_req")) {
2684960Swillf 	if (*(argv[*i]) == '+')
2694960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED);
2704960Swillf 	else if (*(argv[*i]) == '-')
2714960Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED;
2724960Swillf 	else
2734960Swillf 	    goto err_usage;
2744960Swillf 
2754960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2764960Swillf     } else if (!strcmp((argv[*i] + 1), "allow_tix")) {
2774960Swillf 	if (*(argv[*i]) == '+')
2784960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX);
2794960Swillf 	else if (*(argv[*i]) == '-')
2804960Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX;
2814960Swillf 	else
2824960Swillf 	    goto err_usage;
2834960Swillf 
2844960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2854960Swillf     } else if (!strcmp((argv[*i] + 1), "needchange")) {
2864960Swillf 	if (*(argv[*i]) == '+')
2874960Swillf 	    rparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE;
2884960Swillf 	else if (*(argv[*i]) == '-')
2894960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE);
2904960Swillf 	else
2914960Swillf 	    goto err_usage;
2924960Swillf 
2934960Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
2944960Swillf     } else if (!strcmp((argv[*i] + 1), "password_changing_service")) {
2954960Swillf 	if (*(argv[*i]) == '+')
2964960Swillf 	    rparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE;
2974960Swillf 	else if (*(argv[*i]) == '-')
2984960Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE);
2994960Swillf 	else
3004960Swillf 	    goto err_usage;
3014960Swillf 
3024960Swillf 	mask |=LDAP_REALM_KRBTICKETFLAGS;
3034960Swillf     }
3044960Swillf err_usage:
3054960Swillf     print_usage = TRUE;
3064960Swillf 
3074960Swillf err_nomsg:
3084960Swillf     no_msg = TRUE;
3094960Swillf 
3104960Swillf     return mask;
3114960Swillf }
3124960Swillf 
3134960Swillf /*
3144960Swillf  * This function will create a realm on the LDAP Server, with
3154960Swillf  * the specified attributes.
3164960Swillf  */
kdb5_ldap_create(argc,argv)3174960Swillf void kdb5_ldap_create(argc, argv)
3184960Swillf     int argc;
3194960Swillf     char *argv[];
3204960Swillf {
3214960Swillf     krb5_error_code retval = 0;
3224960Swillf     krb5_keyblock master_keyblock;
3234960Swillf     krb5_ldap_realm_params *rparams = NULL;
3244960Swillf     krb5_principal master_princ = NULL;
3254960Swillf     kdb5_dal_handle *dal_handle = NULL;
3264960Swillf     krb5_ldap_context *ldap_context=NULL;
3274960Swillf     krb5_boolean realm_obj_created = FALSE;
3284960Swillf     krb5_boolean create_complete = FALSE;
3294960Swillf     krb5_boolean print_usage = FALSE;
3304960Swillf     krb5_boolean no_msg = FALSE;
3314960Swillf     char *oldcontainerref=NULL;
3324960Swillf     char pw_str[1024];
3334960Swillf     int do_stash = 0;
3344960Swillf     int i = 0;
3354960Swillf     int mask = 0, ret_mask = 0;
3364960Swillf     char **list = NULL;
3374960Swillf #ifdef HAVE_EDIRECTORY
3384960Swillf     int rightsmask = 0;
3394960Swillf #endif
3404960Swillf 
3414960Swillf     memset(&master_keyblock, 0, sizeof(master_keyblock));
3424960Swillf 
3434960Swillf     rparams = (krb5_ldap_realm_params *)malloc(
3444960Swillf 	sizeof(krb5_ldap_realm_params));
3454960Swillf     if (rparams == NULL) {
3464960Swillf 	retval = ENOMEM;
3474960Swillf 	goto cleanup;
3484960Swillf     }
3494960Swillf     memset(rparams, 0, sizeof(krb5_ldap_realm_params));
3504960Swillf 
3514960Swillf     /* Parse the arguments */
3524960Swillf     for (i = 1; i < argc; i++) {
3534960Swillf 	if (!strcmp(argv[i], "-subtrees")) {
3544960Swillf 	    if (++i > argc-1)
3554960Swillf 		goto err_usage;
3564960Swillf 
3574960Swillf 	    if(strncmp(argv[i], "", strlen(argv[i]))!=0) {
3584960Swillf 		list = (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *));
3594960Swillf 		if (list == NULL) {
3604960Swillf 		    retval = ENOMEM;
3614960Swillf 		    goto cleanup;
3624960Swillf 		}
3634960Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
3644960Swillf 		    free(list);
3654960Swillf 		    list = NULL;
3664960Swillf 		    goto cleanup;
3674960Swillf 		}
3684960Swillf 
3694960Swillf 		rparams->subtreecount=0;
3704960Swillf 		while(list[rparams->subtreecount]!=NULL)
3714960Swillf 		    (rparams->subtreecount)++;
3724960Swillf 		rparams->subtree = list;
3734960Swillf 	    } else if(strncmp(argv[i], "", strlen(argv[i]))==0) {
3744960Swillf 		 /* dont allow subtree value to be set at the root(NULL, "") of the tree */
375*8092SMark.Phalan@Sun.COM 		 /* Solaris Kerberos */
376*8092SMark.Phalan@Sun.COM 		 com_err(progname, EINVAL,
3774960Swillf 			  gettext("for subtree while creating realm '%s'"),
3784960Swillf 			   global_params.realm);
3794960Swillf 		 goto err_nomsg;
3804960Swillf 	    }
3814960Swillf 	    rparams->subtree[rparams->subtreecount] = NULL;
3824960Swillf 	    mask |= LDAP_REALM_SUBTREE;
3834960Swillf 	} else if (!strcmp(argv[i], "-containerref")) {
3844960Swillf 	    if (++i > argc-1)
3854960Swillf 		goto err_usage;
3864960Swillf 	    if(strncmp(argv[i], "", strlen(argv[i]))==0) {
3874960Swillf 		 /* dont allow containerref value to be set at the root(NULL, "") of the tree */
388*8092SMark.Phalan@Sun.COM 		 /* Solaris Kerberos */
389*8092SMark.Phalan@Sun.COM 		 com_err(progname, EINVAL,
3904960Swillf 			  gettext("for container reference while creating realm '%s'"),
3914960Swillf 			   global_params.realm);
3924960Swillf 		 goto err_nomsg;
3934960Swillf 	    }
3944960Swillf 	    rparams->containerref = strdup(argv[i]);
3954960Swillf 	    if (rparams->containerref == NULL) {
3964960Swillf 		retval = ENOMEM;
3974960Swillf 		goto cleanup;
3984960Swillf 	    }
3994960Swillf 	    mask |= LDAP_REALM_CONTREF;
4004960Swillf 	} else if (!strcmp(argv[i], "-sscope")) {
4014960Swillf 	    if (++i > argc-1)
4024960Swillf 		goto err_usage;
4034960Swillf 	    /* Possible values for search scope are
4044960Swillf 	     * one (or 1) and sub (or 2)
4054960Swillf 	     */
4064960Swillf 	    if (!strcasecmp(argv[i], "one")) {
4074960Swillf 		rparams->search_scope = 1;
4084960Swillf 	    } else if (!strcasecmp(argv[i], "sub")) {
4094960Swillf 		rparams->search_scope = 2;
4104960Swillf 	    } else {
4114960Swillf 		rparams->search_scope = atoi(argv[i]);
4124960Swillf 		if ((rparams->search_scope != 1) &&
4134960Swillf 		    (rparams->search_scope != 2)) {
414*8092SMark.Phalan@Sun.COM 		    /* Solaris Kerberos */
415*8092SMark.Phalan@Sun.COM 		    com_err(progname, EINVAL,
4164960Swillf 			    gettext("invalid search scope while creating realm '%s'"),
4174960Swillf 			    global_params.realm);
4184960Swillf 		    goto err_nomsg;
4194960Swillf 		}
4204960Swillf 	    }
4214960Swillf 	    mask |= LDAP_REALM_SEARCHSCOPE;
4224960Swillf 	}
4234960Swillf #ifdef HAVE_EDIRECTORY
4244960Swillf 	else if (!strcmp(argv[i], "-kdcdn")) {
4254960Swillf 	    if (++i > argc-1)
4264960Swillf 		goto err_usage;
4274960Swillf 	    rparams->kdcservers = (char **)malloc(
4284960Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
4294960Swillf 	    if (rparams->kdcservers == NULL) {
4304960Swillf 		retval = ENOMEM;
4314960Swillf 		goto cleanup;
4324960Swillf 	    }
4334960Swillf 	    memset(rparams->kdcservers, 0, sizeof(char*)*MAX_LIST_ENTRIES);
4344960Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
4354960Swillf 					  rparams->kdcservers))) {
4364960Swillf 		goto cleanup;
4374960Swillf 	    }
4384960Swillf 	    mask |= LDAP_REALM_KDCSERVERS;
4394960Swillf 	} else if (!strcmp(argv[i], "-admindn")) {
4404960Swillf 	    if (++i > argc-1)
4414960Swillf 		goto err_usage;
4424960Swillf 	    rparams->adminservers = (char **)malloc(
4434960Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
4444960Swillf 	    if (rparams->adminservers == NULL) {
4454960Swillf 		retval = ENOMEM;
4464960Swillf 		goto cleanup;
4474960Swillf 	    }
4484960Swillf 	    memset(rparams->adminservers, 0, sizeof(char*)*MAX_LIST_ENTRIES);
4494960Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
4504960Swillf 					  rparams->adminservers))) {
4514960Swillf 		goto cleanup;
4524960Swillf 	    }
4534960Swillf 	    mask |= LDAP_REALM_ADMINSERVERS;
4544960Swillf 	} else if (!strcmp(argv[i], "-pwddn")) {
4554960Swillf 	    if (++i > argc-1)
4564960Swillf 		goto err_usage;
4574960Swillf 	    rparams->passwdservers = (char **)malloc(
4584960Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
4594960Swillf 	    if (rparams->passwdservers == NULL) {
4604960Swillf 		retval = ENOMEM;
4614960Swillf 		goto cleanup;
4624960Swillf 	    }
4634960Swillf 	    memset(rparams->passwdservers, 0, sizeof(char*)*MAX_LIST_ENTRIES);
4644960Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
4654960Swillf 					  rparams->passwdservers))) {
4664960Swillf 		goto cleanup;
4674960Swillf 	    }
4684960Swillf 	    mask |= LDAP_REALM_PASSWDSERVERS;
4694960Swillf 	}
4704960Swillf #endif
4714960Swillf 	else if (!strcmp(argv[i], "-s")) {
4724960Swillf 	    do_stash = 1;
4734960Swillf 	} else if ((ret_mask= get_ticket_policy(rparams,&i,argv,argc)) !=0) {
4744960Swillf 	    mask|=ret_mask;
4754960Swillf 	}
4764960Swillf 
4774960Swillf 	else {
4784960Swillf 	    printf(gettext("'%s' is an invalid option\n"), argv[i]);
4794960Swillf 	    goto err_usage;
4804960Swillf 	}
4814960Swillf     }
4824960Swillf 
4834960Swillf     /* If the default enctype/salttype is not provided, use the
4844960Swillf      * default values and also add to the list of supported
4854960Swillf      * enctypes/salttype
4864960Swillf      */
4874960Swillf 
4884960Swillf     rblock.max_life = global_params.max_life;
4894960Swillf     rblock.max_rlife = global_params.max_rlife;
4904960Swillf     rblock.expiration = global_params.expiration;
4914960Swillf     rblock.flags = global_params.flags;
4924960Swillf     rblock.nkslist = global_params.num_keysalts;
4934960Swillf     rblock.kslist = global_params.keysalts;
4944960Swillf 
4954960Swillf     krb5_princ_set_realm_data(util_context, &db_create_princ, global_params.realm);
4964960Swillf     krb5_princ_set_realm_length(util_context, &db_create_princ, strlen(global_params.realm));
4974960Swillf 
4984960Swillf     printf(gettext("Initializing database for realm '%s'\n"), global_params.realm);
4994960Swillf 
5004960Swillf     if (!mkey_password) {
5014960Swillf 	unsigned int pw_size;
5024960Swillf 	printf(gettext("You will be prompted for the database Master Password.\n"));
5034960Swillf 	printf(gettext("It is important that you NOT FORGET this password.\n"));
5044960Swillf 	fflush(stdout);
5054960Swillf 
5064960Swillf 	pw_size = sizeof (pw_str);
5074960Swillf 	memset(pw_str, 0, pw_size);
5084960Swillf 
5094960Swillf 	retval = krb5_read_password(util_context, KRB5_KDC_MKEY_1, KRB5_KDC_MKEY_2,
5104960Swillf 				    pw_str, &pw_size);
5114960Swillf 	if (retval) {
512*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
513*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while reading master key from keyboard"));
5144960Swillf 	    goto err_nomsg;
5154960Swillf 	}
5164960Swillf 	mkey_password = pw_str;
5174960Swillf     }
5184960Swillf 
5194960Swillf     rparams->mkey.enctype = global_params.enctype;
5204960Swillf     /* We are sure that 'mkey_password' is a regular string ... */
5214960Swillf     rparams->mkey.length = strlen(mkey_password) + 1;
5224960Swillf     rparams->mkey.contents = (krb5_octet *)strdup(mkey_password);
5234960Swillf     if (rparams->mkey.contents == NULL) {
5244960Swillf 	retval = ENOMEM;
5254960Swillf 	goto cleanup;
5264960Swillf     }
5274960Swillf 
5284960Swillf     rparams->realm_name = strdup(global_params.realm);
5294960Swillf     if (rparams->realm_name == NULL) {
5304960Swillf 	retval = ENOMEM;
531*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
532*8092SMark.Phalan@Sun.COM 	com_err(progname, ENOMEM, gettext("while creating realm '%s'"),
5334960Swillf 		global_params.realm);
5344960Swillf 	goto err_nomsg;
5354960Swillf     }
5364960Swillf 
5374960Swillf     dal_handle = (kdb5_dal_handle *) util_context->db_context;
5384960Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
5394960Swillf     if (!ldap_context) {
5404960Swillf 	retval = EINVAL;
5414960Swillf 	goto cleanup;
5424960Swillf     }
5434960Swillf 
5444960Swillf     /* read the kerberos container */
5454960Swillf     if ((retval=krb5_ldap_read_krbcontainer_params (util_context,
5464960Swillf 						    &(ldap_context->krbcontainer))) == KRB5_KDB_NOENTRY) {
5474960Swillf 	/* Prompt the user for entering the DN of Kerberos container */
5484960Swillf 	char krb_location[MAX_KRB_CONTAINER_LEN];
5494960Swillf 	krb5_ldap_krbcontainer_params kparams;
5504960Swillf 	int krb_location_len = 0;
5514960Swillf 	memset(&kparams, 0, sizeof(kparams));
5524960Swillf 
5534960Swillf 	/* Read the kerberos container location from configuration file */
5544960Swillf 	if (ldap_context->conf_section) {
5554960Swillf 	    if ((retval=profile_get_string(util_context->profile,
5564960Swillf 					   KDB_MODULE_SECTION, ldap_context->conf_section,
5574960Swillf 					   "ldap_kerberos_container_dn", NULL,
5584960Swillf 					   &kparams.DN)) != 0) {
5594960Swillf 		goto cleanup;
5604960Swillf 	    }
5614960Swillf 	}
5624960Swillf 	if (kparams.DN == NULL) {
5634960Swillf 	    if ((retval=profile_get_string(util_context->profile,
5644960Swillf 					   KDB_MODULE_DEF_SECTION,
5654960Swillf 					   "ldap_kerberos_container_dn", NULL,
5664960Swillf 					   NULL, &kparams.DN)) != 0) {
5674960Swillf 		goto cleanup;
5684960Swillf 	    }
5694960Swillf 	}
5704960Swillf 
5714960Swillf 	printf(gettext("\nKerberos container is missing. Creating now...\n"));
5724960Swillf 	if (kparams.DN == NULL) {
5734960Swillf #ifdef HAVE_EDIRECTORY
5744960Swillf 	    printf(gettext("Enter DN of Kerberos container [cn=Kerberos,cn=Security]: "));
5754960Swillf #else
5764960Swillf 	    printf(gettext("Enter DN of Kerberos container: "));
5774960Swillf #endif
5784960Swillf 	    if (fgets(krb_location, MAX_KRB_CONTAINER_LEN, stdin) != NULL) {
5794960Swillf 		/* Remove the newline character at the end */
5804960Swillf 		krb_location_len = strlen(krb_location);
5814960Swillf 		if ((krb_location[krb_location_len - 1] == '\n') ||
5824960Swillf 		    (krb_location[krb_location_len - 1] == '\r')) {
5834960Swillf 		    krb_location[krb_location_len - 1] = '\0';
5844960Swillf 		    krb_location_len--;
5854960Swillf 		}
5864960Swillf 		/* If the user has not given any input, take the default location */
5874960Swillf 		else if (krb_location[0] == '\0')
5884960Swillf 		    kparams.DN = NULL;
5894960Swillf 		else
5904960Swillf 		    kparams.DN = krb_location;
5914960Swillf 	    } else
5924960Swillf 		kparams.DN = NULL;
5934960Swillf 	}
5944960Swillf 
5954960Swillf 	/* create the kerberos container */
5964960Swillf 	retval = krb5_ldap_create_krbcontainer(util_context,
5974960Swillf 					       ((kparams.DN != NULL) ? &kparams : NULL));
5984960Swillf 	if (retval)
5994960Swillf 	    goto cleanup;
6004960Swillf 
6014960Swillf 	retval = krb5_ldap_read_krbcontainer_params(util_context,
6024960Swillf 						    &(ldap_context->krbcontainer));
6034960Swillf 	if (retval) {
604*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
605*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while reading kerberos container information"));
6064960Swillf 	    goto cleanup;
6074960Swillf 	}
6084960Swillf     } else if (retval) {
609*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
610*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while reading kerberos container information"));
6114960Swillf 	goto cleanup;
6124960Swillf     }
6134960Swillf 
6144960Swillf     if ((retval = krb5_ldap_create_realm(util_context,
6154960Swillf 					 /* global_params.realm, */ rparams, mask))) {
6164960Swillf 	goto cleanup;
6174960Swillf     }
6184960Swillf 
6194960Swillf     /* We just created the Realm container. Here starts our transaction tracking */
6204960Swillf     realm_obj_created = TRUE;
6214960Swillf 
6224960Swillf     if ((retval = krb5_ldap_read_realm_params(util_context,
6234960Swillf 					      global_params.realm,
6244960Swillf 					      &(ldap_context->lrparams),
6254960Swillf 					      &mask))) {
626*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
627*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while reading information of realm '%s'"),
6284960Swillf 		global_params.realm);
6294960Swillf 	goto err_nomsg;
6304960Swillf     }
6314960Swillf     ldap_context->lrparams->realm_name = strdup(global_params.realm);
6324960Swillf     if (ldap_context->lrparams->realm_name == NULL) {
6334960Swillf 	retval = ENOMEM;
6344960Swillf 	goto cleanup;
6354960Swillf     }
6364960Swillf 
6374960Swillf     /* assemble & parse the master key name */
6384960Swillf     if ((retval = krb5_db_setup_mkey_name(util_context,
6394960Swillf 					  global_params.mkey_name,
6404960Swillf 					  global_params.realm,
6414960Swillf 					  0, &master_princ))) {
642*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
643*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while setting up master key name"));
6444960Swillf 	goto err_nomsg;
6454960Swillf     }
6464960Swillf 
6474960Swillf     /* Obtain master key from master password */
6484960Swillf     {
6494960Swillf 	krb5_data master_salt, pwd;
6504960Swillf 
6514960Swillf 	pwd.data = mkey_password;
6524960Swillf 	pwd.length = strlen(mkey_password);
6534960Swillf 	retval = krb5_principal2salt(util_context, master_princ, &master_salt);
6544960Swillf 	if (retval) {
655*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
656*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while calculating master key salt"));
6574960Swillf 	    goto err_nomsg;
6584960Swillf 	}
6594960Swillf 
6604960Swillf 	retval = krb5_c_string_to_key(util_context, rparams->mkey.enctype,
6614960Swillf 				      &pwd, &master_salt, &master_keyblock);
6624960Swillf 
6634960Swillf 	if (master_salt.data)
6644960Swillf 	    free(master_salt.data);
6654960Swillf 
6664960Swillf 	if (retval) {
667*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
668*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while transforming master key from password"));
6694960Swillf 	    goto err_nomsg;
6704960Swillf 	}
6714960Swillf 
6724960Swillf     }
6734960Swillf 
6744960Swillf     rblock.key = &master_keyblock;
6754960Swillf     ldap_context->lrparams->mkey = master_keyblock;
6764960Swillf     ldap_context->lrparams->mkey.contents = (krb5_octet *) malloc
6774960Swillf 	(master_keyblock.length);
6784960Swillf     if (ldap_context->lrparams->mkey.contents == NULL) {
6794960Swillf 	retval = ENOMEM;
6804960Swillf 	goto cleanup;
6814960Swillf     }
6824960Swillf     memcpy (ldap_context->lrparams->mkey.contents, master_keyblock.contents,
6834960Swillf 	    master_keyblock.length);
6844960Swillf 
6854960Swillf     /* Create special principals inside the realm subtree */
6864960Swillf     {
6874960Swillf 	char princ_name[MAX_PRINC_SIZE];
6884960Swillf 	krb5_principal_data tgt_princ = {
6894960Swillf 	    0,					/* magic number */
6904960Swillf 	    {0, 0, 0},				/* krb5_data realm */
6914960Swillf 	    tgt_princ_entries,			/* krb5_data *data */
6924960Swillf 	    2,					/* int length */
6934960Swillf 	    KRB5_NT_SRV_INST			/* int type */
6944960Swillf 	};
6954960Swillf 	krb5_principal p, temp_p=NULL;
6964960Swillf 
6974960Swillf 	krb5_princ_set_realm_data(util_context, &tgt_princ, global_params.realm);
6984960Swillf 	krb5_princ_set_realm_length(util_context, &tgt_princ, strlen(global_params.realm));
6994960Swillf 	krb5_princ_component(util_context, &tgt_princ,1)->data = global_params.realm;
7004960Swillf 	krb5_princ_component(util_context, &tgt_princ,1)->length = strlen(global_params.realm);
7014960Swillf 	/* The container reference value is set to NULL, to avoid service principals
7024960Swillf 	 * getting created within the container reference at realm creation */
7034960Swillf 	if (ldap_context->lrparams->containerref != NULL) {
7044960Swillf 	    oldcontainerref = ldap_context->lrparams->containerref;
7054960Swillf 	    ldap_context->lrparams->containerref = NULL;
7064960Swillf 	}
7074960Swillf 
7084960Swillf 	/* Create 'K/M' ... */
7094960Swillf 	rblock.flags |= KRB5_KDB_DISALLOW_ALL_TIX;
7104960Swillf 	if ((retval = kdb_ldap_create_principal(util_context, master_princ, MASTER_KEY, &rblock))) {
711*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
712*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
7134960Swillf 	    goto err_nomsg;
7144960Swillf 	}
7154960Swillf 
7164960Swillf 	/* Create 'krbtgt' ... */
7174960Swillf 	rblock.flags = 0; /* reset the flags */
7184960Swillf 	if ((retval = kdb_ldap_create_principal(util_context, &tgt_princ, TGT_KEY, &rblock))) {
719*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
720*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
7214960Swillf 	    goto err_nomsg;
7224960Swillf 	}
7234960Swillf 	/*
7244960Swillf 	 * Solaris Kerberos:
7254960Swillf 	 * The kadmin/admin principal is unused on Solaris. This principal is used
7264960Swillf 	 * in AUTH_GSSAPI but Solaris doesn't support AUTH_GSSAPI. RPCSEC_GSS can only
7274960Swillf 	 * be used with host-based principals.
7284960Swillf 	 *
7294960Swillf 	 */
7304960Swillf #if 0 /* ************ Begin IFDEF'ed OUT ***************************** */
7314960Swillf 	/* Create 'kadmin/admin' ... */
7324960Swillf 	snprintf(princ_name, sizeof(princ_name), "%s@%s", KADM5_ADMIN_SERVICE, global_params.realm);
7334960Swillf 	if ((retval = krb5_parse_name(util_context, princ_name, &p))) {
734*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
735*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
7364960Swillf 	    goto err_nomsg;
7374960Swillf 	}
7384960Swillf 	rblock.max_life = ADMIN_LIFETIME;
7394960Swillf 	rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED;
7404960Swillf 	if ((retval = kdb_ldap_create_principal(util_context, p, TGT_KEY, &rblock))) {
7414960Swillf 	    krb5_free_principal(util_context, p);
742*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
743*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
7444960Swillf 	    goto err_nomsg;
7454960Swillf 	}
7464960Swillf 	krb5_free_principal(util_context, p);
7474960Swillf #endif /* ************** END IFDEF'ed OUT ***************************** */
7484960Swillf 
7494960Swillf 	/* Create 'kadmin/changepw' ... */
7504960Swillf 	snprintf(princ_name, sizeof(princ_name), "%s@%s", KADM5_CHANGEPW_SERVICE, global_params.realm);
7514960Swillf 	if ((retval = krb5_parse_name(util_context, princ_name, &p))) {
752*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
753*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
7544960Swillf 	    goto err_nomsg;
7554960Swillf 	}
7564960Swillf 	rblock.max_life = CHANGEPW_LIFETIME;
7574960Swillf 	rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_PWCHANGE_SERVICE;
7584960Swillf 	if ((retval = kdb_ldap_create_principal(util_context, p, TGT_KEY, &rblock))) {
7594960Swillf 	    krb5_free_principal(util_context, p);
760*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
761*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
7624960Swillf 	    goto err_nomsg;
7634960Swillf 	}
7644960Swillf 	krb5_free_principal(util_context, p);
7654960Swillf 
7664960Swillf 	/* Create 'kadmin/history' ... */
7674960Swillf 	snprintf(princ_name, sizeof(princ_name), "%s@%s", KADM5_HIST_PRINCIPAL, global_params.realm);
7684960Swillf 	if ((retval = krb5_parse_name(util_context, princ_name, &p))) {
769*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
770*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
7714960Swillf 	    goto err_nomsg;
7724960Swillf 	}
7734960Swillf 	rblock.max_life = global_params.max_life;
7744960Swillf 	rblock.flags = 0;
7754960Swillf 	if ((retval = kdb_ldap_create_principal(util_context, p, TGT_KEY, &rblock))) {
7764960Swillf 	    krb5_free_principal(util_context, p);
777*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
778*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
7794960Swillf 	    goto err_nomsg;
7804960Swillf 	}
7814960Swillf 	krb5_free_principal(util_context, p);
7824960Swillf 
7834960Swillf 	/* Create 'kadmin/<hostname>' ... */
7844960Swillf 	if ((retval=krb5_sname_to_principal(util_context, NULL, KADM5_ADMIN_HOST_SERVICE, KRB5_NT_SRV_HST, &p))) {
785*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
786*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("krb5_sname_to_principal, while adding entries to the database"));
7874960Swillf 	    goto err_nomsg;
7884960Swillf 	}
7894960Swillf 
7904960Swillf 	if ((retval=krb5_copy_principal(util_context, p, &temp_p))) {
791*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
792*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("krb5_copy_principal, while adding entries to the database"));
7934960Swillf 	    goto err_nomsg;
7944960Swillf 	}
7954960Swillf 
7964960Swillf 	/* change the realm portion to the default realm */
7974960Swillf 	free(temp_p->realm.data);
7984960Swillf 	temp_p->realm.length = strlen(util_context->default_realm);
7994960Swillf 	temp_p->realm.data = strdup(util_context->default_realm);
8004960Swillf 	if (temp_p->realm.data == NULL) {
801*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
802*8092SMark.Phalan@Sun.COM 	    com_err(progname, ENOMEM, gettext("while adding entries to the database"));
8034960Swillf 	    goto err_nomsg;
8044960Swillf 	}
8054960Swillf 
8064960Swillf 	rblock.max_life = ADMIN_LIFETIME;
8074960Swillf 	rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED;
8084960Swillf 	if ((retval = kdb_ldap_create_principal(util_context, temp_p, TGT_KEY, &rblock))) {
8094960Swillf 	    krb5_free_principal(util_context, p);
810*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
811*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
8124960Swillf 	    goto err_nomsg;
8134960Swillf 	}
8144960Swillf 	krb5_free_principal(util_context, temp_p);
8154960Swillf 	krb5_free_principal(util_context, p);
8164960Swillf 
8174960Swillf 	/* Solaris Kerberos: Create 'changepw/<hostname>' ... */
8184960Swillf 	if ((retval=krb5_sname_to_principal(util_context, NULL, KADM5_CHANGEPW_HOST_SERVICE, KRB5_NT_SRV_HST, &p))) {
819*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
820*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("krb5_sname_to_principal, while adding entries to the database"));
8214960Swillf 	    goto err_nomsg;
8224960Swillf 	}
8234960Swillf 
8244960Swillf 	if ((retval=krb5_copy_principal(util_context, p, &temp_p))) {
825*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
826*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("krb5_copy_principal, while adding entries to the database"));
8274960Swillf 	    goto err_nomsg;
8284960Swillf 	}
8294960Swillf 
8304960Swillf 	/* change the realm portion to the default realm */
8314960Swillf 	free(temp_p->realm.data);
8324960Swillf 	temp_p->realm.length = strlen(util_context->default_realm);
8334960Swillf 	temp_p->realm.data = strdup(util_context->default_realm);
8344960Swillf 	if (temp_p->realm.data == NULL) {
835*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
836*8092SMark.Phalan@Sun.COM 	    com_err(progname, ENOMEM, gettext("while adding entries to the database"));
8374960Swillf 	    goto err_nomsg;
8384960Swillf 	}
8394960Swillf 
8404960Swillf 	rblock.max_life = ADMIN_LIFETIME;
8414960Swillf 	rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_PWCHANGE_SERVICE;
8424960Swillf 	if ((retval = kdb_ldap_create_principal(util_context, temp_p, TGT_KEY, &rblock))) {
8434960Swillf 	    krb5_free_principal(util_context, p);
844*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
845*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while adding entries to the database"));
8464960Swillf 	    goto err_nomsg;
8474960Swillf 	}
8484960Swillf 	krb5_free_principal(util_context, temp_p);
8494960Swillf 	krb5_free_principal(util_context, p);
8504960Swillf 
8514960Swillf 	if (oldcontainerref != NULL) {
8524960Swillf 	    ldap_context->lrparams->containerref = oldcontainerref;
8534960Swillf 	    oldcontainerref=NULL;
8544960Swillf 	}
8554960Swillf     }
8564960Swillf 
8574960Swillf #ifdef HAVE_EDIRECTORY
8584960Swillf     if ((mask & LDAP_REALM_KDCSERVERS) || (mask & LDAP_REALM_ADMINSERVERS) ||
8594960Swillf 	(mask & LDAP_REALM_PASSWDSERVERS)) {
8604960Swillf 
8614960Swillf 	printf(gettext("Changing rights for the service object. Please wait ... "));
8624960Swillf 	fflush(stdout);
8634960Swillf 
8644960Swillf 	rightsmask =0;
8654960Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
8664960Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
8674960Swillf 	if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
8684960Swillf 	    for (i=0; (rparams->kdcservers[i] != NULL); i++) {
8694960Swillf 		if ((retval=krb5_ldap_add_service_rights(util_context,
8704960Swillf 							 LDAP_KDC_SERVICE, rparams->kdcservers[i],
8714960Swillf 							 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
8724960Swillf 		    printf(gettext("failed\n"));
873*8092SMark.Phalan@Sun.COM 		    /* Solaris Kerberos */
874*8092SMark.Phalan@Sun.COM 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
8754960Swillf 			    rparams->realm_name);
8764960Swillf 		    goto err_nomsg;
8774960Swillf 		}
8784960Swillf 	    }
8794960Swillf 	}
8804960Swillf 
8814960Swillf 	rightsmask = 0;
8824960Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
8834960Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
8844960Swillf 	if ((rparams != NULL) && (rparams->adminservers != NULL)) {
8854960Swillf 	    for (i=0; (rparams->adminservers[i] != NULL); i++) {
8864960Swillf 		if ((retval=krb5_ldap_add_service_rights(util_context,
8874960Swillf 							 LDAP_ADMIN_SERVICE, rparams->adminservers[i],
8884960Swillf 							 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
8894960Swillf 		    printf(gettext("failed\n"));
890*8092SMark.Phalan@Sun.COM 		    /* Solaris Kerberos */
891*8092SMark.Phalan@Sun.COM 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
8924960Swillf 			    rparams->realm_name);
8934960Swillf 		    goto err_nomsg;
8944960Swillf 		}
8954960Swillf 	    }
8964960Swillf 	}
8974960Swillf 
8984960Swillf 	rightsmask = 0;
8994960Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
9004960Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
9014960Swillf 	if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
9024960Swillf 	    for (i=0; (rparams->passwdservers[i] != NULL); i++) {
9034960Swillf 		if ((retval=krb5_ldap_add_service_rights(util_context,
9044960Swillf 							 LDAP_PASSWD_SERVICE, rparams->passwdservers[i],
9054960Swillf 							 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
9064960Swillf 		    printf(gettext("failed\n"));
907*8092SMark.Phalan@Sun.COM 		    /* Solaris Kerberos */
908*8092SMark.Phalan@Sun.COM 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
9094960Swillf 			    rparams->realm_name);
9104960Swillf 		    goto err_nomsg;
9114960Swillf 		}
9124960Swillf 	    }
9134960Swillf 	}
9144960Swillf 
9154960Swillf 	printf(gettext("done\n"));
9164960Swillf     }
9174960Swillf #endif
9184960Swillf     /* The Realm creation is completed. Here is the end of transaction */
9194960Swillf     create_complete = TRUE;
9204960Swillf 
9214960Swillf     /* Stash the master key only if '-s' option is specified */
9224960Swillf     if (do_stash || global_params.mask & KADM5_CONFIG_STASH_FILE) {
9234960Swillf 	retval = krb5_def_store_mkey(util_context,
9244960Swillf 				     global_params.stash_file,
9254960Swillf 				     master_princ,
9264960Swillf 				     &master_keyblock, NULL);
9274960Swillf 	if (retval) {
928*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
929*8092SMark.Phalan@Sun.COM 	    com_err(progname, errno, gettext("while storing key"));
9304960Swillf 	    printf(gettext("Warning: couldn't stash master key.\n"));
9314960Swillf 	}
9324960Swillf     }
9334960Swillf 
9344960Swillf     goto cleanup;
9354960Swillf 
9364960Swillf 
9374960Swillf err_usage:
9384960Swillf     print_usage = TRUE;
9394960Swillf 
9404960Swillf err_nomsg:
9414960Swillf     no_msg = TRUE;
9424960Swillf 
9434960Swillf cleanup:
9444960Swillf     /* If the Realm creation is not complete, do the roll-back here */
9454960Swillf     if ((realm_obj_created) && (!create_complete))
9464960Swillf 	krb5_ldap_delete_realm(util_context, global_params.realm);
9474960Swillf 
9484960Swillf     if (rparams)
9494960Swillf 	krb5_ldap_free_realm_params(rparams);
9504960Swillf 
9514960Swillf     memset (pw_str, 0, sizeof (pw_str));
9524960Swillf 
9534960Swillf     if (print_usage)
9544960Swillf 	db_usage(CREATE_REALM);
9554960Swillf 
9564960Swillf     if (retval) {
9574960Swillf 	if (!no_msg) {
958*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
959*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while creating realm '%s'"),
9604960Swillf 		    global_params.realm);
9614960Swillf 	}
9624960Swillf 	exit_status++;
9634960Swillf     }
9644960Swillf 
9654960Swillf     return;
9664960Swillf }
9674960Swillf 
9684960Swillf 
9694960Swillf /*
9704960Swillf  * This function will modify the attributes of a given realm object
9714960Swillf  */
kdb5_ldap_modify(argc,argv)9724960Swillf void kdb5_ldap_modify(argc, argv)
9734960Swillf     int argc;
9744960Swillf     char *argv[];
9754960Swillf {
9764960Swillf     krb5_error_code retval = 0;
9774960Swillf     krb5_ldap_realm_params *rparams = NULL;
9784960Swillf     krb5_boolean print_usage = FALSE;
9794960Swillf     krb5_boolean no_msg = FALSE;
9804960Swillf     kdb5_dal_handle *dal_handle = NULL;
9814960Swillf     krb5_ldap_context *ldap_context=NULL;
9824960Swillf     int i = 0;
9834960Swillf     int mask = 0, rmask = 0, ret_mask = 0;
9844960Swillf     char **slist = {NULL};
9854960Swillf #ifdef HAVE_EDIRECTORY
9864960Swillf     int j = 0;
9874960Swillf     char *list[MAX_LIST_ENTRIES];
9884960Swillf     int existing_entries = 0, list_entries = 0;
9894960Swillf     int newkdcdn = 0, newadmindn = 0, newpwddn = 0;
9904960Swillf     char **tempstr = NULL;
9914960Swillf     char **oldkdcdns = NULL;
9924960Swillf     char **oldadmindns = NULL;
9934960Swillf     char **oldpwddns = NULL;
9944960Swillf     char **newkdcdns = NULL;
9954960Swillf     char **newsubtrees = NULL;
9964960Swillf     char **newadmindns = NULL;
9974960Swillf     char **newpwddns = NULL;
9984960Swillf     char **oldsubtrees = {NULL};
9994960Swillf     int rightsmask = 0;
10004960Swillf     int subtree_changed = 0;
10014960Swillf #endif
10024960Swillf 
10034960Swillf     dal_handle = (kdb5_dal_handle *) util_context->db_context;
10044960Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
10054960Swillf     if (!(ldap_context)) {
10064960Swillf 	retval = EINVAL;
10074960Swillf 	goto cleanup;
10084960Swillf     }
10094960Swillf 
10104960Swillf     if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
10114960Swillf 						     &(ldap_context->krbcontainer)))) {
1012*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1013*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while reading Kerberos container information"));
10144960Swillf 	goto err_nomsg;
10154960Swillf     }
10164960Swillf 
10174960Swillf     retval = krb5_ldap_read_realm_params(util_context,
10184960Swillf 					 global_params.realm, &rparams, &rmask);
10194960Swillf     if (retval)
10204960Swillf 	goto cleanup;
10214960Swillf     /* Parse the arguments */
10224960Swillf     for (i = 1; i < argc; i++) {
10234960Swillf 	int k = 0;
10244960Swillf 	if (!strcmp(argv[i], "-subtrees")) {
10254960Swillf 	    if (++i > argc-1)
10264960Swillf 		goto err_usage;
10274960Swillf 
10284960Swillf 	    if (rmask & LDAP_REALM_SUBTREE) {
10294960Swillf 		if (rparams->subtree) {
10304960Swillf #ifdef HAVE_EDIRECTORY
10314960Swillf 		    oldsubtrees =  (char **) calloc(rparams->subtreecount+1, sizeof(char *));
10324960Swillf 		    if (oldsubtrees == NULL) {
10334960Swillf 			retval = ENOMEM;
10344960Swillf 			goto cleanup;
10354960Swillf 		    }
10364960Swillf 		    for(k=0; rparams->subtree[k]!=NULL && rparams->subtreecount; k++) {
10374960Swillf 			oldsubtrees[k] = strdup(rparams->subtree[k]);
10384960Swillf 			if( oldsubtrees[k] == NULL ) {
10394960Swillf 			    retval = ENOMEM;
10404960Swillf 			    goto cleanup;
10414960Swillf 			}
10424960Swillf 		    }
10434960Swillf #endif
10444960Swillf 		    for(k=0; k<rparams->subtreecount && rparams->subtree[k]; k++)
10454960Swillf 			free(rparams->subtree[k]);
10464960Swillf 		    rparams->subtreecount=0;
10474960Swillf 		}
10484960Swillf 	    }
10494960Swillf 	    if (strncmp(argv[i] ,"", strlen(argv[i]))!=0) {
10504960Swillf 		slist =  (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *));
10514960Swillf 		if (slist == NULL) {
10524960Swillf 		    retval = ENOMEM;
10534960Swillf 		    goto cleanup;
10544960Swillf 		}
10554960Swillf 		if (( retval = krb5_parse_list(argv[i], LIST_DELIMITER, slist))) {
10564960Swillf 		    free(slist);
10574960Swillf 		    slist = NULL;
10584960Swillf 		    goto cleanup;
10594960Swillf 		}
10604960Swillf 
10614960Swillf 		rparams->subtreecount=0;
10624960Swillf 		while(slist[rparams->subtreecount]!=NULL)
10634960Swillf 		    (rparams->subtreecount)++;
10644960Swillf 		rparams->subtree =  slist;
10654960Swillf 	    } else if(strncmp(argv[i], "", strlen(argv[i]))==0) {
10664960Swillf 		 /* dont allow subtree value to be set at the root(NULL, "") of the tree */
1067*8092SMark.Phalan@Sun.COM 		    /* Solaris Kerberos */
1068*8092SMark.Phalan@Sun.COM 		    com_err(progname, EINVAL,
10694960Swillf 			    gettext("for subtree while modifying realm '%s'"),
10704960Swillf 			    global_params.realm);
10714960Swillf 		    goto err_nomsg;
10724960Swillf 	    }
10734960Swillf 	    rparams->subtree[rparams->subtreecount] = NULL;
10744960Swillf 	    mask |= LDAP_REALM_SUBTREE;
10754960Swillf 	} else if (!strncmp(argv[i], "-containerref", strlen(argv[i]))) {
10764960Swillf 	    if (++i > argc-1)
10774960Swillf 		goto err_usage;
10784960Swillf 	    if(strncmp(argv[i], "", strlen(argv[i]))==0) {
10794960Swillf 		 /* dont allow containerref value to be set at the root(NULL, "") of the tree */
1080*8092SMark.Phalan@Sun.COM 		 /* Solaris Kerberos */
1081*8092SMark.Phalan@Sun.COM 		 com_err(progname, EINVAL,
10824960Swillf 			  gettext("for container reference while modifying realm '%s'"),
10834960Swillf 			   global_params.realm);
10844960Swillf 		 goto err_nomsg;
10854960Swillf 	    }
10864960Swillf 	    rparams->containerref = strdup(argv[i]);
10874960Swillf 	    if (rparams->containerref == NULL) {
10884960Swillf 		retval = ENOMEM;
10894960Swillf 		goto cleanup;
10904960Swillf 	    }
10914960Swillf 	    mask |= LDAP_REALM_CONTREF;
10924960Swillf 	} else if (!strcmp(argv[i], "-sscope")) {
10934960Swillf 	    if (++i > argc-1)
10944960Swillf 		goto err_usage;
10954960Swillf 	    /* Possible values for search scope are
10964960Swillf 	     * one (or 1) and sub (or 2)
10974960Swillf 	     */
10984960Swillf 	    if (strcasecmp(argv[i], "one") == 0) {
10994960Swillf 		rparams->search_scope = 1;
11004960Swillf 	    } else if (strcasecmp(argv[i], "sub") == 0) {
11014960Swillf 		rparams->search_scope = 2;
11024960Swillf 	    } else {
11034960Swillf 		rparams->search_scope = atoi(argv[i]);
11044960Swillf 		if ((rparams->search_scope != 1) &&
11054960Swillf 		    (rparams->search_scope != 2)) {
11064960Swillf 		    retval = EINVAL;
1107*8092SMark.Phalan@Sun.COM 		    /* Solaris Kerberos */
1108*8092SMark.Phalan@Sun.COM 		    com_err(progname, retval,
11094960Swillf 			    gettext("specified for search scope while modifying information of realm '%s'"),
11104960Swillf 			    global_params.realm);
11114960Swillf 		    goto err_nomsg;
11124960Swillf 		}
11134960Swillf 	    }
11144960Swillf 	    mask |= LDAP_REALM_SEARCHSCOPE;
11154960Swillf 	}
11164960Swillf #ifdef HAVE_EDIRECTORY
11174960Swillf 	else if (!strcmp(argv[i], "-kdcdn")) {
11184960Swillf 	    if (++i > argc-1)
11194960Swillf 		goto err_usage;
11204960Swillf 
11214960Swillf 	    if ((rmask & LDAP_REALM_KDCSERVERS) && (rparams->kdcservers)) {
11224960Swillf 		if (!oldkdcdns) {
11234960Swillf 		    /* Store the old kdc dns list for removing rights */
11244960Swillf 		    oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
11254960Swillf 		    if (oldkdcdns == NULL) {
11264960Swillf 			retval = ENOMEM;
11274960Swillf 			goto cleanup;
11284960Swillf 		    }
11294960Swillf 
11304960Swillf 		    for (j=0; rparams->kdcservers[j] != NULL; j++) {
11314960Swillf 			oldkdcdns[j] = strdup(rparams->kdcservers[j]);
11324960Swillf 			if (oldkdcdns[j] == NULL) {
11334960Swillf 			    retval = ENOMEM;
11344960Swillf 			    goto cleanup;
11354960Swillf 			}
11364960Swillf 		    }
11374960Swillf 		    oldkdcdns[j] = NULL;
11384960Swillf 		}
11394960Swillf 
11404960Swillf 		krb5_free_list_entries(rparams->kdcservers);
11414960Swillf 		free(rparams->kdcservers);
11424960Swillf 	    }
11434960Swillf 
11444960Swillf 	    rparams->kdcservers = (char **)malloc(
11454960Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
11464960Swillf 	    if (rparams->kdcservers == NULL) {
11474960Swillf 		retval = ENOMEM;
11484960Swillf 		goto cleanup;
11494960Swillf 	    }
11504960Swillf 	    memset(rparams->kdcservers, 0, sizeof(char *)*MAX_LIST_ENTRIES);
11514960Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
11524960Swillf 					  rparams->kdcservers))) {
11534960Swillf 		goto cleanup;
11544960Swillf 	    }
11554960Swillf 	    mask |= LDAP_REALM_KDCSERVERS;
11564960Swillf 	    /* Going to replace the existing value by this new value. Hence
11574960Swillf 	     * setting flag indicating that add or clear options will be ignored
11584960Swillf 	     */
11594960Swillf 	    newkdcdn = 1;
11604960Swillf 	} else if (!strcmp(argv[i], "-clearkdcdn")) {
11614960Swillf 	    if (++i > argc-1)
11624960Swillf 		goto err_usage;
11634960Swillf 	    if ((!newkdcdn) && (rmask & LDAP_REALM_KDCSERVERS) && (rparams->kdcservers)) {
11644960Swillf 		if (!oldkdcdns) {
11654960Swillf 		    /* Store the old kdc dns list for removing rights */
11664960Swillf 		    oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
11674960Swillf 		    if (oldkdcdns == NULL) {
11684960Swillf 			retval = ENOMEM;
11694960Swillf 			goto cleanup;
11704960Swillf 		    }
11714960Swillf 
11724960Swillf 		    for (j=0; rparams->kdcservers[j] != NULL; j++) {
11734960Swillf 			oldkdcdns[j] = strdup(rparams->kdcservers[j]);
11744960Swillf 			if (oldkdcdns[j] == NULL) {
11754960Swillf 			    retval = ENOMEM;
11764960Swillf 			    goto cleanup;
11774960Swillf 			}
11784960Swillf 		    }
11794960Swillf 		    oldkdcdns[j] = NULL;
11804960Swillf 		}
11814960Swillf 
11824960Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
11834960Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
11844960Swillf 		    goto cleanup;
11854960Swillf 		}
11864960Swillf 		list_modify_str_array(&rparams->kdcservers, (const char **)list,
11874960Swillf 				      LIST_MODE_DELETE);
11884960Swillf 		mask |= LDAP_REALM_KDCSERVERS;
11894960Swillf 		krb5_free_list_entries(list);
11904960Swillf 	    }
11914960Swillf 	} else if (!strcmp(argv[i], "-addkdcdn")) {
11924960Swillf 	    if (++i > argc-1)
11934960Swillf 		goto err_usage;
11944960Swillf 	    if (!newkdcdn) {
11954960Swillf 		if ((rmask & LDAP_REALM_KDCSERVERS) && (rparams->kdcservers) && (!oldkdcdns)) {
11964960Swillf 		    /* Store the old kdc dns list for removing rights */
11974960Swillf 		    oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
11984960Swillf 		    if (oldkdcdns == NULL) {
11994960Swillf 			retval = ENOMEM;
12004960Swillf 			goto cleanup;
12014960Swillf 		    }
12024960Swillf 
12034960Swillf 		    for (j = 0; rparams->kdcservers[j] != NULL; j++) {
12044960Swillf 			oldkdcdns[j] = strdup(rparams->kdcservers[j]);
12054960Swillf 			if (oldkdcdns[j] == NULL) {
12064960Swillf 			    retval = ENOMEM;
12074960Swillf 			    goto cleanup;
12084960Swillf 			}
12094960Swillf 		    }
12104960Swillf 		    oldkdcdns[j] = NULL;
12114960Swillf 		}
12124960Swillf 
12134960Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
12144960Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
12154960Swillf 		    goto cleanup;
12164960Swillf 		}
12174960Swillf 		existing_entries = list_count_str_array(rparams->kdcservers);
12184960Swillf 		list_entries = list_count_str_array(list);
12194960Swillf 		if (rmask & LDAP_REALM_KDCSERVERS) {
12204960Swillf 		    tempstr = (char **)realloc(
12214960Swillf 			rparams->kdcservers,
12224960Swillf 			sizeof(char *) * (existing_entries+list_entries+1));
12234960Swillf 		    if (tempstr == NULL) {
12244960Swillf 			retval = ENOMEM;
12254960Swillf 			goto cleanup;
12264960Swillf 		    }
12274960Swillf 		    rparams->kdcservers = tempstr;
12284960Swillf 		} else {
12294960Swillf 		    rparams->kdcservers = (char **)malloc(sizeof(char *) * (list_entries+1));
12304960Swillf 		    if (rparams->kdcservers == NULL) {
12314960Swillf 			retval = ENOMEM;
12324960Swillf 			goto cleanup;
12334960Swillf 		    }
12344960Swillf 		    memset(rparams->kdcservers, 0, sizeof(char *) * (list_entries+1));
12354960Swillf 		}
12364960Swillf 		list_modify_str_array(&rparams->kdcservers, (const char **)list,
12374960Swillf 				      LIST_MODE_ADD);
12384960Swillf 		mask |= LDAP_REALM_KDCSERVERS;
12394960Swillf 	    }
12404960Swillf 	} else if (!strcmp(argv[i], "-admindn")) {
12414960Swillf 	    if (++i > argc-1)
12424960Swillf 		goto err_usage;
12434960Swillf 
12444960Swillf 	    if ((rmask & LDAP_REALM_ADMINSERVERS) && (rparams->adminservers)) {
12454960Swillf 		if (!oldadmindns) {
12464960Swillf 		    /* Store the old admin dns list for removing rights */
12474960Swillf 		    oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
12484960Swillf 		    if (oldadmindns == NULL) {
12494960Swillf 			retval = ENOMEM;
12504960Swillf 			goto cleanup;
12514960Swillf 		    }
12524960Swillf 
12534960Swillf 		    for (j=0; rparams->adminservers[j] != NULL; j++) {
12544960Swillf 			oldadmindns[j] = strdup(rparams->adminservers[j]);
12554960Swillf 			if (oldadmindns[j] == NULL) {
12564960Swillf 			    retval = ENOMEM;
12574960Swillf 			    goto cleanup;
12584960Swillf 			}
12594960Swillf 		    }
12604960Swillf 		    oldadmindns[j] = NULL;
12614960Swillf 		}
12624960Swillf 
12634960Swillf 		krb5_free_list_entries(rparams->adminservers);
12644960Swillf 		free(rparams->adminservers);
12654960Swillf 	    }
12664960Swillf 
12674960Swillf 	    rparams->adminservers = (char **)malloc(
12684960Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
12694960Swillf 	    if (rparams->adminservers == NULL) {
12704960Swillf 		retval = ENOMEM;
12714960Swillf 		goto cleanup;
12724960Swillf 	    }
12734960Swillf 	    memset(rparams->adminservers, 0, sizeof(char *)*MAX_LIST_ENTRIES);
12744960Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
12754960Swillf 					  rparams->adminservers))) {
12764960Swillf 		goto cleanup;
12774960Swillf 	    }
12784960Swillf 	    mask |= LDAP_REALM_ADMINSERVERS;
12794960Swillf 	    /* Going to replace the existing value by this new value. Hence
12804960Swillf 	     * setting flag indicating that add or clear options will be ignored
12814960Swillf 	     */
12824960Swillf 	    newadmindn = 1;
12834960Swillf 	} else if (!strcmp(argv[i], "-clearadmindn")) {
12844960Swillf 	    if (++i > argc-1)
12854960Swillf 		goto err_usage;
12864960Swillf 
12874960Swillf 	    if ((!newadmindn) && (rmask & LDAP_REALM_ADMINSERVERS) && (rparams->adminservers)) {
12884960Swillf 		if (!oldadmindns) {
12894960Swillf 		    /* Store the old admin dns list for removing rights */
12904960Swillf 		    oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
12914960Swillf 		    if (oldadmindns == NULL) {
12924960Swillf 			retval = ENOMEM;
12934960Swillf 			goto cleanup;
12944960Swillf 		    }
12954960Swillf 
12964960Swillf 		    for (j=0; rparams->adminservers[j] != NULL; j++) {
12974960Swillf 			oldadmindns[j] = strdup(rparams->adminservers[j]);
12984960Swillf 			if (oldadmindns[j] == NULL) {
12994960Swillf 			    retval = ENOMEM;
13004960Swillf 			    goto cleanup;
13014960Swillf 			}
13024960Swillf 		    }
13034960Swillf 		    oldadmindns[j] = NULL;
13044960Swillf 		}
13054960Swillf 
13064960Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
13074960Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
13084960Swillf 		    goto cleanup;
13094960Swillf 		}
13104960Swillf 		list_modify_str_array(&rparams->adminservers, (const char **)list,
13114960Swillf 				      LIST_MODE_DELETE);
13124960Swillf 		mask |= LDAP_REALM_ADMINSERVERS;
13134960Swillf 		krb5_free_list_entries(list);
13144960Swillf 	    }
13154960Swillf 	} else if (!strcmp(argv[i], "-addadmindn")) {
13164960Swillf 	    if (++i > argc-1)
13174960Swillf 		goto err_usage;
13184960Swillf 	    if (!newadmindn) {
13194960Swillf 		if ((rmask & LDAP_REALM_ADMINSERVERS) && (rparams->adminservers) && (!oldadmindns)) {
13204960Swillf 		    /* Store the old admin dns list for removing rights */
13214960Swillf 		    oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
13224960Swillf 		    if (oldadmindns == NULL) {
13234960Swillf 			retval = ENOMEM;
13244960Swillf 			goto cleanup;
13254960Swillf 		    }
13264960Swillf 
13274960Swillf 		    for (j=0; rparams->adminservers[j] != NULL; j++) {
13284960Swillf 			oldadmindns[j] = strdup(rparams->adminservers[j]);
13294960Swillf 			if (oldadmindns[j] == NULL) {
13304960Swillf 			    retval = ENOMEM;
13314960Swillf 			    goto cleanup;
13324960Swillf 			}
13334960Swillf 		    }
13344960Swillf 		    oldadmindns[j] = NULL;
13354960Swillf 		}
13364960Swillf 
13374960Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
13384960Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
13394960Swillf 		    goto cleanup;
13404960Swillf 		}
13414960Swillf 		existing_entries = list_count_str_array(rparams->adminservers);
13424960Swillf 		list_entries = list_count_str_array(list);
13434960Swillf 		if (rmask & LDAP_REALM_ADMINSERVERS) {
13444960Swillf 		    tempstr = (char **)realloc(
13454960Swillf 			rparams->adminservers,
13464960Swillf 			sizeof(char *) * (existing_entries+list_entries+1));
13474960Swillf 		    if (tempstr == NULL) {
13484960Swillf 			retval = ENOMEM;
13494960Swillf 			goto cleanup;
13504960Swillf 		    }
13514960Swillf 		    rparams->adminservers = tempstr;
13524960Swillf 		} else {
13534960Swillf 		    rparams->adminservers = (char **)malloc(sizeof(char *) * (list_entries+1));
13544960Swillf 		    if (rparams->adminservers == NULL) {
13554960Swillf 			retval = ENOMEM;
13564960Swillf 			goto cleanup;
13574960Swillf 		    }
13584960Swillf 		    memset(rparams->adminservers, 0, sizeof(char *) * (list_entries+1));
13594960Swillf 		}
13604960Swillf 		list_modify_str_array(&rparams->adminservers, (const char **)list,
13614960Swillf 				      LIST_MODE_ADD);
13624960Swillf 		mask |= LDAP_REALM_ADMINSERVERS;
13634960Swillf 	    }
13644960Swillf 	} else if (!strcmp(argv[i], "-pwddn")) {
13654960Swillf 	    if (++i > argc-1)
13664960Swillf 		goto err_usage;
13674960Swillf 
13684960Swillf 	    if ((rmask & LDAP_REALM_PASSWDSERVERS) && (rparams->passwdservers)) {
13694960Swillf 		if (!oldpwddns) {
13704960Swillf 		    /* Store the old pwd dns list for removing rights */
13714960Swillf 		    oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
13724960Swillf 		    if (oldpwddns == NULL) {
13734960Swillf 			retval = ENOMEM;
13744960Swillf 			goto cleanup;
13754960Swillf 		    }
13764960Swillf 
13774960Swillf 		    for (j=0; rparams->passwdservers[j] != NULL; j++) {
13784960Swillf 			oldpwddns[j] = strdup(rparams->passwdservers[j]);
13794960Swillf 			if (oldpwddns[j] == NULL) {
13804960Swillf 			    retval = ENOMEM;
13814960Swillf 			    goto cleanup;
13824960Swillf 			}
13834960Swillf 		    }
13844960Swillf 		    oldpwddns[j] = NULL;
13854960Swillf 		}
13864960Swillf 
13874960Swillf 		krb5_free_list_entries(rparams->passwdservers);
13884960Swillf 		free(rparams->passwdservers);
13894960Swillf 	    }
13904960Swillf 
13914960Swillf 	    rparams->passwdservers = (char **)malloc(
13924960Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
13934960Swillf 	    if (rparams->passwdservers == NULL) {
13944960Swillf 		retval = ENOMEM;
13954960Swillf 		goto cleanup;
13964960Swillf 	    }
13974960Swillf 	    memset(rparams->passwdservers, 0, sizeof(char *)*MAX_LIST_ENTRIES);
13984960Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
13994960Swillf 					  rparams->passwdservers))) {
14004960Swillf 		goto cleanup;
14014960Swillf 	    }
14024960Swillf 	    mask |= LDAP_REALM_PASSWDSERVERS;
14034960Swillf 	    /* Going to replace the existing value by this new value. Hence
14044960Swillf 	     * setting flag indicating that add or clear options will be ignored
14054960Swillf 	     */
14064960Swillf 	    newpwddn = 1;
14074960Swillf 	} else if (!strcmp(argv[i], "-clearpwddn")) {
14084960Swillf 	    if (++i > argc-1)
14094960Swillf 		goto err_usage;
14104960Swillf 
14114960Swillf 	    if ((!newpwddn) && (rmask & LDAP_REALM_PASSWDSERVERS) && (rparams->passwdservers)) {
14124960Swillf 		if (!oldpwddns) {
14134960Swillf 		    /* Store the old pwd dns list for removing rights */
14144960Swillf 		    oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
14154960Swillf 		    if (oldpwddns == NULL) {
14164960Swillf 			retval = ENOMEM;
14174960Swillf 			goto cleanup;
14184960Swillf 		    }
14194960Swillf 
14204960Swillf 		    for (j=0; rparams->passwdservers[j] != NULL; j++) {
14214960Swillf 			oldpwddns[j] = strdup(rparams->passwdservers[j]);
14224960Swillf 			if (oldpwddns[j] == NULL) {
14234960Swillf 			    retval = ENOMEM;
14244960Swillf 			    goto cleanup;
14254960Swillf 			}
14264960Swillf 		    }
14274960Swillf 		    oldpwddns[j] = NULL;
14284960Swillf 		}
14294960Swillf 
14304960Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
14314960Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
14324960Swillf 		    goto cleanup;
14334960Swillf 		}
14344960Swillf 		list_modify_str_array(&rparams->passwdservers, (const char**)list,
14354960Swillf 				      LIST_MODE_DELETE);
14364960Swillf 		mask |= LDAP_REALM_PASSWDSERVERS;
14374960Swillf 		krb5_free_list_entries(list);
14384960Swillf 	    }
14394960Swillf 	} else if (!strcmp(argv[i], "-addpwddn")) {
14404960Swillf 	    if (++i > argc-1)
14414960Swillf 		goto err_usage;
14424960Swillf 	    if (!newpwddn) {
14434960Swillf 		if ((rmask & LDAP_REALM_PASSWDSERVERS) && (rparams->passwdservers) && (!oldpwddns)) {
14444960Swillf 		    /* Store the old pwd dns list for removing rights */
14454960Swillf 		    oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
14464960Swillf 		    if (oldpwddns == NULL) {
14474960Swillf 			retval = ENOMEM;
14484960Swillf 			goto cleanup;
14494960Swillf 		    }
14504960Swillf 
14514960Swillf 		    for (j=0; rparams->passwdservers[j] != NULL; j++) {
14524960Swillf 			oldpwddns[j] = strdup(rparams->passwdservers[j]);
14534960Swillf 			if (oldpwddns[j] == NULL) {
14544960Swillf 			    retval = ENOMEM;
14554960Swillf 			    goto cleanup;
14564960Swillf 			}
14574960Swillf 		    }
14584960Swillf 		    oldpwddns[j] = NULL;
14594960Swillf 		}
14604960Swillf 
14614960Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
14624960Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
14634960Swillf 		    goto cleanup;
14644960Swillf 		}
14654960Swillf 		existing_entries = list_count_str_array(rparams->passwdservers);
14664960Swillf 		list_entries = list_count_str_array(list);
14674960Swillf 		if (rmask & LDAP_REALM_PASSWDSERVERS) {
14684960Swillf 		    tempstr = (char **)realloc(
14694960Swillf 			rparams->passwdservers,
14704960Swillf 			sizeof(char *) * (existing_entries+list_entries+1));
14714960Swillf 		    if (tempstr == NULL) {
14724960Swillf 			retval = ENOMEM;
14734960Swillf 			goto cleanup;
14744960Swillf 		    }
14754960Swillf 		    rparams->passwdservers = tempstr;
14764960Swillf 		} else {
14774960Swillf 		    rparams->passwdservers = (char **)malloc(sizeof(char *) * (list_entries+1));
14784960Swillf 		    if (rparams->passwdservers == NULL) {
14794960Swillf 			retval = ENOMEM;
14804960Swillf 			goto cleanup;
14814960Swillf 		    }
14824960Swillf 		    memset(rparams->passwdservers, 0, sizeof(char *) * (list_entries+1));
14834960Swillf 		}
14844960Swillf 		list_modify_str_array(&rparams->passwdservers, (const char**)list,
14854960Swillf 				      LIST_MODE_ADD);
14864960Swillf 		mask |= LDAP_REALM_PASSWDSERVERS;
14874960Swillf 	    }
14884960Swillf 	}
14894960Swillf #endif
14904960Swillf 	else if ((ret_mask= get_ticket_policy(rparams,&i,argv,argc)) !=0) {
14914960Swillf 	    mask|=ret_mask;
14924960Swillf 	} else {
14934960Swillf 	    printf(gettext("'%s' is an invalid option\n"), argv[i]);
14944960Swillf 	    goto err_usage;
14954960Swillf 	}
14964960Swillf     }
14974960Swillf 
14984960Swillf     if ((retval = krb5_ldap_modify_realm(util_context,
14994960Swillf 					 /* global_params.realm, */ rparams, mask))) {
15004960Swillf 	goto cleanup;
15014960Swillf     }
15024960Swillf 
15034960Swillf #ifdef HAVE_EDIRECTORY
15044960Swillf     if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_KDCSERVERS) ||
15054960Swillf 	(mask & LDAP_REALM_ADMINSERVERS) || (mask & LDAP_REALM_PASSWDSERVERS)) {
15064960Swillf 
15074960Swillf 	printf(gettext("Changing rights for the service object. Please wait ... "));
15084960Swillf 	fflush(stdout);
15094960Swillf 
15104960Swillf 	if (!(mask & LDAP_REALM_SUBTREE)) {
15114960Swillf 	    if (rparams->subtree != NULL) {
15124960Swillf 		for(i=0; rparams->subtree[i]!=NULL;i++) {
15134960Swillf 		    oldsubtrees[i] = strdup(rparams->subtree[i]);
15144960Swillf 		    if( oldsubtrees[i] == NULL ) {
15154960Swillf 			retval = ENOMEM;
15164960Swillf 			goto cleanup;
15174960Swillf 		    }
15184960Swillf 		}
15194960Swillf 	    }
15204960Swillf 	}
15214960Swillf 
15224960Swillf 	if ((mask & LDAP_REALM_SUBTREE)) {
15234960Swillf 	    int check_subtree = 1;
15244960Swillf 
15254960Swillf 	    newsubtrees = (char**) calloc(rparams->subtreecount, sizeof(char*));
15264960Swillf 
15274960Swillf 	    if (newsubtrees == NULL) {
15284960Swillf 		retval = ENOMEM;
15294960Swillf 		goto cleanup;
15304960Swillf 	    }
15314960Swillf 
15324960Swillf 	    if ( (rparams != NULL) && (rparams->subtree != NULL) ) {
15334960Swillf 		for (j=0; j<rparams->subtreecount && rparams->subtree[j]!= NULL; j++) {
15344960Swillf 		    newsubtrees[j] = strdup(rparams->subtree[j]);
15354960Swillf 		    if (newsubtrees[j] == NULL) {
15364960Swillf 			retval = ENOMEM;
15374960Swillf 			goto cleanup;
15384960Swillf 		    }
15394960Swillf 		}
15404960Swillf 		newsubtrees[j] = NULL;
15414960Swillf 	    }
15424960Swillf 	    for(j=0;oldsubtrees[j]!=NULL;j++) {
15434960Swillf 		check_subtree = 1;
15444960Swillf 		for(i=0; ( (oldsubtrees[j] && !rparams->subtree[i]) ||
15454960Swillf 			(!oldsubtrees[j] && rparams->subtree[i])); i++) {
15464960Swillf 		    if(strcasecmp( oldsubtrees[j], rparams->subtree[i]) == 0) {
15474960Swillf 			check_subtree = 0;
15484960Swillf 			continue;
15494960Swillf 		    }
15504960Swillf 		}
15514960Swillf 		if (check_subtree != 0) {
15524960Swillf 		    subtree_changed=1;
15534960Swillf 		    break;
15544960Swillf 		}
15554960Swillf 	    }
15564960Swillf 	    /* this will return list of the disjoint members */
15574960Swillf 	    disjoint_members( oldsubtrees, newsubtrees);
15584960Swillf 	}
15594960Swillf 
15604960Swillf 	if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_KDCSERVERS)) {
15614960Swillf 
15624960Swillf 	    newkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
15634960Swillf 	    if (newkdcdns == NULL) {
15644960Swillf 		retval = ENOMEM;
15654960Swillf 		goto cleanup;
15664960Swillf 	    }
15674960Swillf 
15684960Swillf 	    if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
15694960Swillf 		for (j=0;  rparams->kdcservers[j]!= NULL; j++) {
15704960Swillf 		    newkdcdns[j] = strdup(rparams->kdcservers[j]);
15714960Swillf 		    if (newkdcdns[j] == NULL) {
15724960Swillf 			retval = ENOMEM;
15734960Swillf 			goto cleanup;
15744960Swillf 		    }
15754960Swillf 		}
15764960Swillf 		newkdcdns[j] = NULL;
15774960Swillf 	    }
15784960Swillf 
15794960Swillf 	    if (!subtree_changed) {
15804960Swillf 		disjoint_members(oldkdcdns, newkdcdns);
15814960Swillf 	    } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
15824960Swillf 		if (!(mask & LDAP_REALM_KDCSERVERS)) {
15834960Swillf 
15844960Swillf 		    oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
15854960Swillf 		    if (oldkdcdns == NULL) {
15864960Swillf 			retval = ENOMEM;
15874960Swillf 			goto cleanup;
15884960Swillf 		    }
15894960Swillf 
15904960Swillf 		    if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
15914960Swillf 			for (j=0;  rparams->kdcservers[j]!= NULL; j++) {
15924960Swillf 			    oldkdcdns[j] = strdup(rparams->kdcservers[j]);
15934960Swillf 			    if (oldkdcdns[j] == NULL) {
15944960Swillf 				retval = ENOMEM;
15954960Swillf 				goto cleanup;
15964960Swillf 			    }
15974960Swillf 			}
15984960Swillf 			oldkdcdns[j] = NULL;
15994960Swillf 		    }
16004960Swillf 		}
16014960Swillf 	    }
16024960Swillf 
16034960Swillf 	    rightsmask =0;
16044960Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
16054960Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
16064960Swillf 	    /* Remove the rights on the old subtrees */
16074960Swillf 	    if (oldkdcdns) {
16084960Swillf 		for (i=0; (oldkdcdns[i] != NULL); i++) {
16094960Swillf 		    if ((retval=krb5_ldap_delete_service_rights(util_context,
16104960Swillf 								LDAP_KDC_SERVICE, oldkdcdns[i],
16114960Swillf 								rparams->realm_name, oldsubtrees, rightsmask)) != 0) {
16124960Swillf 			printf(gettext("failed\n"));
1613*8092SMark.Phalan@Sun.COM 			/* Solaris Kerberos */
1614*8092SMark.Phalan@Sun.COM 			com_err(progname, retval, gettext("while assigning rights '%s'"),
16154960Swillf 				rparams->realm_name);
16164960Swillf 			goto err_nomsg;
16174960Swillf 		    }
16184960Swillf 		}
16194960Swillf 	    }
16204960Swillf 
16214960Swillf 	    rightsmask =0;
16224960Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
16234960Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
16244960Swillf 	    if (newkdcdns) {
16254960Swillf 		for (i=0; (newkdcdns[i] != NULL); i++) {
16264960Swillf 
16274960Swillf 		    if ((retval=krb5_ldap_add_service_rights(util_context,
16284960Swillf 							     LDAP_KDC_SERVICE, newkdcdns[i], rparams->realm_name,
16294960Swillf 							     rparams->subtree, rightsmask)) != 0) {
16304960Swillf 			printf(gettext("failed\n"));
1631*8092SMark.Phalan@Sun.COM 			/* Solaris Kerberos */
1632*8092SMark.Phalan@Sun.COM 			com_err(progname, retval, gettext("while assigning rights to '%s'"),
16334960Swillf 				rparams->realm_name);
16344960Swillf 			goto err_nomsg;
16354960Swillf 		    }
16364960Swillf 		}
16374960Swillf 	    }
16384960Swillf 	}
16394960Swillf 
16404960Swillf 	if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_ADMINSERVERS)) {
16414960Swillf 
16424960Swillf 	    newadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
16434960Swillf 	    if (newadmindns == NULL) {
16444960Swillf 		retval = ENOMEM;
16454960Swillf 		goto cleanup;
16464960Swillf 	    }
16474960Swillf 
16484960Swillf 	    if ((rparams != NULL) && (rparams->adminservers != NULL)) {
16494960Swillf 		for (j=0;  rparams->adminservers[j]!= NULL; j++) {
16504960Swillf 		    newadmindns[j] = strdup(rparams->adminservers[j]);
16514960Swillf 		    if (newadmindns[j] == NULL) {
16524960Swillf 			retval = ENOMEM;
16534960Swillf 			goto cleanup;
16544960Swillf 		    }
16554960Swillf 		}
16564960Swillf 		newadmindns[j] = NULL;
16574960Swillf 	    }
16584960Swillf 
16594960Swillf 	    if (!subtree_changed) {
16604960Swillf 		disjoint_members(oldadmindns, newadmindns);
16614960Swillf 	    } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
16624960Swillf 		if (!(mask & LDAP_REALM_ADMINSERVERS)) {
16634960Swillf 
16644960Swillf 		    oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
16654960Swillf 		    if (oldadmindns == NULL) {
16664960Swillf 			retval = ENOMEM;
16674960Swillf 			goto cleanup;
16684960Swillf 		    }
16694960Swillf 
16704960Swillf 		    if ((rparams != NULL) && (rparams->adminservers != NULL)) {
16714960Swillf 			for (j=0;  rparams->adminservers[j]!= NULL; j++) {
16724960Swillf 			    oldadmindns[j] = strdup(rparams->adminservers[j]);
16734960Swillf 			    if (oldadmindns[j] == NULL) {
16744960Swillf 				retval = ENOMEM;
16754960Swillf 				goto cleanup;
16764960Swillf 			    }
16774960Swillf 			}
16784960Swillf 			oldadmindns[j] = NULL;
16794960Swillf 		    }
16804960Swillf 		}
16814960Swillf 	    }
16824960Swillf 
16834960Swillf 	    rightsmask = 0;
16844960Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
16854960Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
16864960Swillf 	    /* Remove the rights on the old subtrees */
16874960Swillf 	    if (oldadmindns) {
16884960Swillf 		for (i=0; (oldadmindns[i] != NULL); i++) {
16894960Swillf 
16904960Swillf 		    if ((retval=krb5_ldap_delete_service_rights(util_context,
16914960Swillf 								LDAP_ADMIN_SERVICE, oldadmindns[i],
16924960Swillf 								rparams->realm_name, oldsubtrees, rightsmask)) != 0) {
16934960Swillf 			printf(gettext("failed\n"));
1694*8092SMark.Phalan@Sun.COM 			/* Solaris Kerberos */
1695*8092SMark.Phalan@Sun.COM 			com_err(progname, retval, gettext("while assigning rights '%s'"),
16964960Swillf 				rparams->realm_name);
16974960Swillf 			goto err_nomsg;
16984960Swillf 		    }
16994960Swillf 		}
17004960Swillf 	    }
17014960Swillf 
17024960Swillf 	    rightsmask = 0;
17034960Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
17044960Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
17054960Swillf 	    /* Add rights on the new subtree for all the kdc dns */
17064960Swillf 	    if (newadmindns) {
17074960Swillf 		for (i=0; (newadmindns[i] != NULL); i++) {
17084960Swillf 
17094960Swillf 		    if ((retval=krb5_ldap_add_service_rights(util_context,
17104960Swillf 							     LDAP_ADMIN_SERVICE, newadmindns[i],
17114960Swillf 							     rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
17124960Swillf 			printf(gettext("failed\n"));
1713*8092SMark.Phalan@Sun.COM 			/* Solaris Kerberos */
1714*8092SMark.Phalan@Sun.COM 			com_err(progname, retval, gettext("while assigning rights to '%s'"),
17154960Swillf 				rparams->realm_name);
17164960Swillf 			goto err_nomsg;
17174960Swillf 		    }
17184960Swillf 		}
17194960Swillf 	    }
17204960Swillf 	}
17214960Swillf 
17224960Swillf 
17234960Swillf 	if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_PASSWDSERVERS)) {
17244960Swillf 
17254960Swillf 	    newpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
17264960Swillf 	    if (newpwddns == NULL) {
17274960Swillf 		retval = ENOMEM;
17284960Swillf 		goto cleanup;
17294960Swillf 	    }
17304960Swillf 
17314960Swillf 	    if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
17324960Swillf 		for (j=0;  rparams->passwdservers[j]!= NULL; j++) {
17334960Swillf 		    newpwddns[j] = strdup(rparams->passwdservers[j]);
17344960Swillf 		    if (newpwddns[j] == NULL) {
17354960Swillf 			retval = ENOMEM;
17364960Swillf 			goto cleanup;
17374960Swillf 		    }
17384960Swillf 		}
17394960Swillf 		newpwddns[j] = NULL;
17404960Swillf 	    }
17414960Swillf 
17424960Swillf 	    if (!subtree_changed) {
17434960Swillf 		disjoint_members(oldpwddns, newpwddns);
17444960Swillf 	    } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
17454960Swillf 		if (!(mask & LDAP_REALM_ADMINSERVERS)) {
17464960Swillf 
17474960Swillf 		    oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
17484960Swillf 		    if (oldpwddns == NULL) {
17494960Swillf 			retval = ENOMEM;
17504960Swillf 			goto cleanup;
17514960Swillf 		    }
17524960Swillf 
17534960Swillf 		    if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
17544960Swillf 			for (j=0;  rparams->passwdservers[j]!= NULL; j++) {
17554960Swillf 			    oldpwddns[j] = strdup(rparams->passwdservers[j]);
17564960Swillf 			    if (oldpwddns[j] == NULL) {
17574960Swillf 				retval = ENOMEM;
17584960Swillf 				goto cleanup;
17594960Swillf 			    }
17604960Swillf 			}
17614960Swillf 			oldpwddns[j] = NULL;
17624960Swillf 		    }
17634960Swillf 		}
17644960Swillf 	    }
17654960Swillf 
17664960Swillf 	    rightsmask =0;
17674960Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
17684960Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
17694960Swillf 	    /* Remove the rights on the old subtrees */
17704960Swillf 	    if (oldpwddns) {
17714960Swillf 		for (i=0; (oldpwddns[i] != NULL); i++) {
17724960Swillf 		    if ((retval = krb5_ldap_delete_service_rights(util_context,
17734960Swillf 								  LDAP_PASSWD_SERVICE, oldpwddns[i],
17744960Swillf 								  rparams->realm_name, oldsubtrees, rightsmask))) {
17754960Swillf 			printf(gettext("failed\n"));
1776*8092SMark.Phalan@Sun.COM 			/* Solaris Kerberos */
1777*8092SMark.Phalan@Sun.COM 			com_err(progname, retval, gettext("while assigning rights '%s'"),
17784960Swillf 				rparams->realm_name);
17794960Swillf 			goto err_nomsg;
17804960Swillf 		    }
17814960Swillf 		}
17824960Swillf 	    }
17834960Swillf 
17844960Swillf 	    rightsmask =0;
17854960Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
17864960Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
17874960Swillf 	    /* Add rights on the new subtree for all the kdc dns */
17884960Swillf 	    if (newpwddns) {
17894960Swillf 		for (i=0; (newpwddns[i] != NULL); i++) {
17904960Swillf 		    if ((retval = krb5_ldap_add_service_rights(util_context,
17914960Swillf 							       LDAP_PASSWD_SERVICE, newpwddns[i],
17924960Swillf 							       rparams->realm_name, rparams->subtree, rightsmask))) {
17934960Swillf 			printf(gettext("failed\n"));
1794*8092SMark.Phalan@Sun.COM 			/* Solaris Kerberos */
1795*8092SMark.Phalan@Sun.COM 			com_err(progname, retval, gettext("while assigning rights to '%s'"),
17964960Swillf 				rparams->realm_name);
17974960Swillf 			goto err_nomsg;
17984960Swillf 		    }
17994960Swillf 		}
18004960Swillf 	    }
18014960Swillf 	}
18024960Swillf 
18034960Swillf 	printf(gettext("done\n"));
18044960Swillf     }
18054960Swillf #endif
18064960Swillf 
18074960Swillf     goto cleanup;
18084960Swillf 
18094960Swillf err_usage:
18104960Swillf     print_usage = TRUE;
18114960Swillf 
18124960Swillf err_nomsg:
18134960Swillf     no_msg = TRUE;
18144960Swillf 
18154960Swillf cleanup:
18164960Swillf     krb5_ldap_free_realm_params(rparams);
18174960Swillf 
18184960Swillf 
18194960Swillf #ifdef HAVE_EDIRECTORY
18204960Swillf     if (oldkdcdns) {
18214960Swillf 	for (i=0; oldkdcdns[i] != NULL; i++)
18224960Swillf 	    free(oldkdcdns[i]);
18234960Swillf 	free(oldkdcdns);
18244960Swillf     }
18254960Swillf     if (oldpwddns) {
18264960Swillf 	for (i=0; oldpwddns[i] != NULL; i++)
18274960Swillf 	    free(oldpwddns[i]);
18284960Swillf 	free(oldpwddns);
18294960Swillf     }
18304960Swillf     if (oldadmindns) {
18314960Swillf 	for (i=0; oldadmindns[i] != NULL; i++)
18324960Swillf 	    free(oldadmindns[i]);
18334960Swillf 	free(oldadmindns);
18344960Swillf     }
18354960Swillf     if (newkdcdns) {
18364960Swillf 	for (i=0; newkdcdns[i] != NULL; i++)
18374960Swillf 	    free(newkdcdns[i]);
18384960Swillf 	free(newkdcdns);
18394960Swillf     }
18404960Swillf     if (newpwddns) {
18414960Swillf 	for (i=0; newpwddns[i] != NULL; i++)
18424960Swillf 	    free(newpwddns[i]);
18434960Swillf 	free(newpwddns);
18444960Swillf     }
18454960Swillf     if (newadmindns) {
18464960Swillf 	for (i=0; newadmindns[i] != NULL; i++)
18474960Swillf 	    free(newadmindns[i]);
18484960Swillf 	free(newadmindns);
18494960Swillf     }
18504960Swillf     if (oldsubtrees) {
18514960Swillf 	for (i=0;oldsubtrees[i]!=NULL; i++)
18524960Swillf 	    free(oldsubtrees[i]);
18534960Swillf 	free(oldsubtrees);
18544960Swillf     }
18554960Swillf     if (newsubtrees) {
18564960Swillf 	for (i=0;newsubtrees[i]!=NULL; i++)
18574960Swillf 	    free(newsubtrees[i]);
18584960Swillf 	free(oldsubtrees);
18594960Swillf     }
18604960Swillf #endif
18614960Swillf     if (print_usage) {
18624960Swillf 	db_usage(MODIFY_REALM);
18634960Swillf     }
18644960Swillf 
18654960Swillf     if (retval) {
1866*8092SMark.Phalan@Sun.COM 	if (!no_msg) {
1867*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
1868*8092SMark.Phalan@Sun.COM 	    com_err(progname, retval, gettext("while modifying information of realm '%s'"),
18694960Swillf 		    global_params.realm);
1870*8092SMark.Phalan@Sun.COM 	}
18714960Swillf 	exit_status++;
18724960Swillf     }
18734960Swillf 
18744960Swillf     return;
18754960Swillf }
18764960Swillf 
18774960Swillf 
18784960Swillf 
18794960Swillf /*
18804960Swillf  * This function displays the attributes of a Realm
18814960Swillf  */
kdb5_ldap_view(argc,argv)18824960Swillf void kdb5_ldap_view(argc, argv)
18834960Swillf     int argc;
18844960Swillf     char *argv[];
18854960Swillf {
18864960Swillf     krb5_ldap_realm_params *rparams = NULL;
18874960Swillf     krb5_error_code retval = 0;
18884960Swillf     kdb5_dal_handle *dal_handle=NULL;
18894960Swillf     krb5_ldap_context *ldap_context=NULL;
18904960Swillf     int mask = 0;
18914960Swillf 
18924960Swillf     dal_handle = (kdb5_dal_handle *) util_context->db_context;
18934960Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
18944960Swillf     if (!(ldap_context)) {
18954960Swillf 	retval = EINVAL;
1896*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1897*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while initializing database"));
18984960Swillf 	exit_status++;
18994960Swillf 	return;
19004960Swillf     }
19014960Swillf 
19024960Swillf     /* Read the kerberos container information */
19034960Swillf     if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
19044960Swillf 						     &(ldap_context->krbcontainer))) != 0) {
1905*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1906*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while reading kerberos container information"));
19074960Swillf 	exit_status++;
19084960Swillf 	return;
19094960Swillf     }
19104960Swillf 
19114960Swillf     if ((retval = krb5_ldap_read_realm_params(util_context,
19124960Swillf 					      global_params.realm, &rparams, &mask)) || (!rparams)) {
1913*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
1914*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while reading information of realm '%s'"),
19154960Swillf 		global_params.realm);
19164960Swillf 	exit_status++;
19174960Swillf 	return;
19184960Swillf     }
19194960Swillf     print_realm_params(rparams, mask);
19204960Swillf     krb5_ldap_free_realm_params(rparams);
19214960Swillf 
19224960Swillf     return;
19234960Swillf }
19244960Swillf 
strdur(duration)19254960Swillf static char *strdur(duration)
19264960Swillf     time_t duration;
19274960Swillf {
19284960Swillf     static char out[50];
19294960Swillf     int neg, days, hours, minutes, seconds;
19304960Swillf 
19314960Swillf     if (duration < 0) {
19324960Swillf 	duration *= -1;
19334960Swillf 	neg = 1;
19344960Swillf     } else
19354960Swillf 	neg = 0;
19364960Swillf     days = duration / (24 * 3600);
19374960Swillf     duration %= 24 * 3600;
19384960Swillf     hours = duration / 3600;
19394960Swillf     duration %= 3600;
19404960Swillf     minutes = duration / 60;
19414960Swillf     duration %= 60;
19424960Swillf     seconds = duration;
19434960Swillf     snprintf(out, sizeof(out), "%s%d %s %02d:%02d:%02d", neg ? "-" : "",
19444960Swillf 	    days, days == 1 ? gettext("day") : gettext("days"),
19454960Swillf 	    hours, minutes, seconds);
19464960Swillf     return out;
19474960Swillf }
19484960Swillf 
19494960Swillf /*
19504960Swillf  * This function prints the attributes of a given realm to the
19514960Swillf  * standard output.
19524960Swillf  */
print_realm_params(krb5_ldap_realm_params * rparams,int mask)19534960Swillf static void print_realm_params(krb5_ldap_realm_params *rparams, int mask)
19544960Swillf {
19554960Swillf     char **slist = NULL;
19564960Swillf     int num_entry_printed = 0, i = 0;
19574960Swillf 
19584960Swillf     /* Print the Realm Attributes on the standard output */
19594960Swillf     printf("%25s: %-50s\n", gettext("Realm Name"), global_params.realm);
19604960Swillf     if (mask & LDAP_REALM_SUBTREE) {
19614960Swillf 	for (i=0; rparams->subtree[i]!=NULL; i++)
19624960Swillf 	    printf("%25s: %-50s\n", gettext("Subtree"), rparams->subtree[i]);
19634960Swillf     }
19644960Swillf     if (mask & LDAP_REALM_CONTREF)
19654960Swillf 	printf("%25s: %-50s\n", gettext("Principal Container Reference"), rparams->containerref);
19664960Swillf     if (mask & LDAP_REALM_SEARCHSCOPE) {
19674960Swillf 	if ((rparams->search_scope != 1) &&
19684960Swillf 	    (rparams->search_scope != 2)) {
19694960Swillf 	    printf("%25s: %-50s\n", gettext("SearchScope"), gettext("Invalid !"));
19704960Swillf 	} else {
19714960Swillf 	    printf("%25s: %-50s\n", gettext("SearchScope"),
19724960Swillf 		   (rparams->search_scope == 1) ? gettext("ONE") : gettext("SUB"));
19734960Swillf 	}
19744960Swillf     }
19754960Swillf     if (mask & LDAP_REALM_KDCSERVERS) {
19764960Swillf 	printf("%25s:", gettext("KDC Services"));
19774960Swillf 	if (rparams->kdcservers != NULL) {
19784960Swillf 	    num_entry_printed = 0;
19794960Swillf 	    for (slist = rparams->kdcservers; *slist != NULL; slist++) {
19804960Swillf 		if (num_entry_printed)
19814960Swillf 		    printf(" %25s %-50s\n", " ", *slist);
19824960Swillf 		else
19834960Swillf 		    printf(" %-50s\n", *slist);
19844960Swillf 		num_entry_printed++;
19854960Swillf 	    }
19864960Swillf 	}
19874960Swillf 	if (num_entry_printed == 0)
19884960Swillf 	    printf("\n");
19894960Swillf     }
19904960Swillf     if (mask & LDAP_REALM_ADMINSERVERS) {
19914960Swillf 	printf("%25s:", gettext("Admin Services"));
19924960Swillf 	if (rparams->adminservers != NULL) {
19934960Swillf 	    num_entry_printed = 0;
19944960Swillf 	    for (slist = rparams->adminservers; *slist != NULL; slist++) {
19954960Swillf 		if (num_entry_printed)
19964960Swillf 		    printf(" %25s %-50s\n", " ", *slist);
19974960Swillf 		else
19984960Swillf 		    printf(" %-50s\n", *slist);
19994960Swillf 		num_entry_printed++;
20004960Swillf 	    }
20014960Swillf 	}
20024960Swillf 	if (num_entry_printed == 0)
20034960Swillf 	    printf("\n");
20044960Swillf     }
20054960Swillf     if (mask & LDAP_REALM_PASSWDSERVERS) {
20064960Swillf 	printf("%25s:", gettext("Passwd Services"));
20074960Swillf 	if (rparams->passwdservers != NULL) {
20084960Swillf 	    num_entry_printed = 0;
20094960Swillf 	    for (slist = rparams->passwdservers; *slist != NULL; slist++) {
20104960Swillf 		if (num_entry_printed)
20114960Swillf 		    printf(" %25s %-50s\n", " ", *slist);
20124960Swillf 		else
20134960Swillf 		    printf(" %-50s\n", *slist);
20144960Swillf 		num_entry_printed++;
20154960Swillf 	    }
20164960Swillf 	}
20174960Swillf 	if (num_entry_printed == 0)
20184960Swillf 	    printf("\n");
20194960Swillf     }
20204960Swillf     if (mask & LDAP_REALM_MAXTICKETLIFE) {
20214960Swillf 	printf("%25s:", gettext("Maximum Ticket Life"));
20224960Swillf 	printf(" %s \n", strdur(rparams->max_life));
20234960Swillf     }
20244960Swillf 
20254960Swillf     if (mask & LDAP_REALM_MAXRENEWLIFE) {
20264960Swillf 	printf("%25s:", gettext("Maximum Renewable Life"));
20274960Swillf 	printf(" %s \n", strdur(rparams->max_renewable_life));
20284960Swillf     }
20294960Swillf 
20304960Swillf     if (mask & LDAP_REALM_KRBTICKETFLAGS) {
20314960Swillf 	int ticketflags = rparams->tktflags;
20324960Swillf 
20334960Swillf 	printf("%25s: ", gettext("Ticket flags"));
20344960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_POSTDATED)
20354960Swillf 	    printf("%s ","DISALLOW_POSTDATED");
20364960Swillf 
20374960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_FORWARDABLE)
20384960Swillf 	    printf("%s ","DISALLOW_FORWARDABLE");
20394960Swillf 
20404960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_RENEWABLE)
20414960Swillf 	    printf("%s ","DISALLOW_RENEWABLE");
20424960Swillf 
20434960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_PROXIABLE)
20444960Swillf 	    printf("%s ","DISALLOW_PROXIABLE");
20454960Swillf 
20464960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_DUP_SKEY)
20474960Swillf 	    printf("%s ","DISALLOW_DUP_SKEY");
20484960Swillf 
20494960Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_PRE_AUTH)
20504960Swillf 	    printf("%s ","REQUIRES_PRE_AUTH");
20514960Swillf 
20524960Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_HW_AUTH)
20534960Swillf 	    printf("%s ","REQUIRES_HW_AUTH");
20544960Swillf 
20554960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_SVR)
20564960Swillf 	    printf("%s ","DISALLOW_SVR");
20574960Swillf 
20584960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_TGT_BASED)
20594960Swillf 	    printf("%s ","DISALLOW_TGT_BASED");
20604960Swillf 
20614960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_ALL_TIX)
20624960Swillf 	    printf("%s ","DISALLOW_ALL_TIX");
20634960Swillf 
20644960Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_PWCHANGE)
20654960Swillf 	    printf("%s ","REQUIRES_PWCHANGE");
20664960Swillf 
20674960Swillf 	if (ticketflags & KRB5_KDB_PWCHANGE_SERVICE)
20684960Swillf 	    printf("%s ","PWCHANGE_SERVICE");
20694960Swillf 
20704960Swillf 	printf("\n");
20714960Swillf     }
20724960Swillf 
20734960Swillf 
20744960Swillf     return;
20754960Swillf }
20764960Swillf 
20774960Swillf 
20784960Swillf 
20794960Swillf /*
20804960Swillf  * This function lists the Realm(s) present under the Kerberos container
20814960Swillf  * on the LDAP Server.
20824960Swillf  */
kdb5_ldap_list(argc,argv)20834960Swillf void kdb5_ldap_list(argc, argv)
20844960Swillf     int argc;
20854960Swillf     char *argv[];
20864960Swillf {
20874960Swillf     char **list = NULL;
20884960Swillf     char **plist = NULL;
20894960Swillf     krb5_error_code retval = 0;
20904960Swillf     kdb5_dal_handle *dal_handle=NULL;
20914960Swillf     krb5_ldap_context *ldap_context=NULL;
20924960Swillf 
20934960Swillf     dal_handle = (kdb5_dal_handle *)util_context->db_context;
20944960Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
20954960Swillf     if (!(ldap_context)) {
20964960Swillf 	retval = EINVAL;
20974960Swillf 	exit_status++;
20984960Swillf 	return;
20994960Swillf     }
21004960Swillf 
21014960Swillf     /* Read the kerberos container information */
21024960Swillf     if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
21034960Swillf 						     &(ldap_context->krbcontainer))) != 0) {
2104*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2105*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while reading kerberos container information"));
21064960Swillf 	exit_status++;
21074960Swillf 	return;
21084960Swillf     }
21094960Swillf 
21104960Swillf     retval = krb5_ldap_list_realm(util_context, &list);
21114960Swillf     if (retval != 0) {
21124960Swillf 	krb5_ldap_free_krbcontainer_params(ldap_context->krbcontainer);
21134960Swillf 	ldap_context->krbcontainer = NULL;
2114*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2115*8092SMark.Phalan@Sun.COM 	com_err (progname, retval, gettext("while listing realms"));
21164960Swillf 	exit_status++;
21174960Swillf 	return;
21184960Swillf     }
21194960Swillf     /* This is to handle the case of realm not present */
21204960Swillf     if (list == NULL) {
21214960Swillf 	krb5_ldap_free_krbcontainer_params(ldap_context->krbcontainer);
21224960Swillf 	ldap_context->krbcontainer = NULL;
21234960Swillf 	return;
21244960Swillf     }
21254960Swillf 
21264960Swillf     for (plist = list; *plist != NULL; plist++) {
21274960Swillf 	printf("%s\n", *plist);
21284960Swillf     }
21294960Swillf     krb5_ldap_free_krbcontainer_params(ldap_context->krbcontainer);
21304960Swillf     ldap_context->krbcontainer = NULL;
21314960Swillf     krb5_free_list_entries(list);
21324960Swillf     free(list);
21334960Swillf 
21344960Swillf     return;
21354960Swillf }
21364960Swillf 
21374960Swillf /*
21384960Swillf  * Duplicating the following two functions here because
21394960Swillf  * 'krb5_dbe_update_tl_data' uses backend specific memory allocation. The catch
21404960Swillf  * here is that the backend is not initialized - kdb5_ldap_util doesn't go
21414960Swillf  * through DAL.
21424960Swillf  * 1. krb5_dbe_update_tl_data
21434960Swillf  * 2. krb5_dbe_update_mod_princ_data
21444960Swillf  */
21454960Swillf 
21464960Swillf /* Start duplicate code ... */
21474960Swillf 
21484960Swillf static krb5_error_code
krb5_dbe_update_tl_data_new(context,entry,new_tl_data)21494960Swillf krb5_dbe_update_tl_data_new(context, entry, new_tl_data)
21504960Swillf     krb5_context context;
21514960Swillf     krb5_db_entry *entry;
21524960Swillf     krb5_tl_data *new_tl_data;
21534960Swillf {
21544960Swillf     krb5_tl_data *tl_data = NULL;
21554960Swillf     krb5_octet *tmp;
21564960Swillf 
21574960Swillf     /* copy the new data first, so we can fail cleanly if malloc()
21584960Swillf      * fails */
21594960Swillf /*
21604960Swillf     if ((tmp =
21614960Swillf 	 (krb5_octet *) krb5_db_alloc(context, NULL,
21624960Swillf 				      new_tl_data->tl_data_length)) == NULL)
21634960Swillf */
21644960Swillf     if ((tmp = (krb5_octet *) malloc (new_tl_data->tl_data_length)) == NULL)
21654960Swillf 	return (ENOMEM);
21664960Swillf 
21674960Swillf     /* Find an existing entry of the specified type and point at
21684960Swillf      * it, or NULL if not found */
21694960Swillf 
21704960Swillf     if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) {	/* db_args can be multiple */
21714960Swillf 	for (tl_data = entry->tl_data; tl_data;
21724960Swillf 	     tl_data = tl_data->tl_data_next)
21734960Swillf 	    if (tl_data->tl_data_type == new_tl_data->tl_data_type)
21744960Swillf 		break;
21754960Swillf     }
21764960Swillf 
21774960Swillf     /* if necessary, chain a new record in the beginning and point at it */
21784960Swillf 
21794960Swillf     if (!tl_data) {
21804960Swillf /*
21814960Swillf 	if ((tl_data =
21824960Swillf 	     (krb5_tl_data *) krb5_db_alloc(context, NULL,
21834960Swillf 					    sizeof(krb5_tl_data)))
21844960Swillf 	    == NULL) {
21854960Swillf */
21864960Swillf 	if ((tl_data = (krb5_tl_data *) malloc (sizeof(krb5_tl_data))) == NULL) {
21874960Swillf 	    free(tmp);
21884960Swillf 	    return (ENOMEM);
21894960Swillf 	}
21904960Swillf 	memset(tl_data, 0, sizeof(krb5_tl_data));
21914960Swillf 	tl_data->tl_data_next = entry->tl_data;
21924960Swillf 	entry->tl_data = tl_data;
21934960Swillf 	entry->n_tl_data++;
21944960Swillf     }
21954960Swillf 
21964960Swillf     /* fill in the record */
21974960Swillf 
21984960Swillf     if (tl_data->tl_data_contents)
21994960Swillf 	krb5_db_free(context, tl_data->tl_data_contents);
22004960Swillf 
22014960Swillf     tl_data->tl_data_type = new_tl_data->tl_data_type;
22024960Swillf     tl_data->tl_data_length = new_tl_data->tl_data_length;
22034960Swillf     tl_data->tl_data_contents = tmp;
22044960Swillf     memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
22054960Swillf 
22064960Swillf     return (0);
22074960Swillf }
22084960Swillf 
22094960Swillf static krb5_error_code
krb5_dbe_update_mod_princ_data_new(context,entry,mod_date,mod_princ)22104960Swillf krb5_dbe_update_mod_princ_data_new(context, entry, mod_date, mod_princ)
22114960Swillf     krb5_context	  context;
22124960Swillf     krb5_db_entry	* entry;
22134960Swillf     krb5_timestamp	  mod_date;
22144960Swillf     krb5_const_principal  mod_princ;
22154960Swillf {
22164960Swillf     krb5_tl_data          tl_data;
22174960Swillf 
22184960Swillf     krb5_error_code 	  retval = 0;
22194960Swillf     krb5_octet		* nextloc = 0;
22204960Swillf     char		* unparse_mod_princ = 0;
22214960Swillf     unsigned int	unparse_mod_princ_size;
22224960Swillf 
22234960Swillf     if ((retval = krb5_unparse_name(context, mod_princ,
22244960Swillf 				    &unparse_mod_princ)))
22254960Swillf 	return(retval);
22264960Swillf 
22274960Swillf     unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
22284960Swillf 
22294960Swillf     if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
22304960Swillf 	== NULL) {
22314960Swillf 	free(unparse_mod_princ);
22324960Swillf 	return(ENOMEM);
22334960Swillf     }
22344960Swillf 
22354960Swillf     tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
22364960Swillf     tl_data.tl_data_length = unparse_mod_princ_size + 4;
22374960Swillf     tl_data.tl_data_contents = nextloc;
22384960Swillf 
22394960Swillf     /* Mod Date */
22404960Swillf     krb5_kdb_encode_int32(mod_date, nextloc);
22414960Swillf 
22424960Swillf     /* Mod Princ */
22434960Swillf     memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size);
22444960Swillf 
22454960Swillf     retval = krb5_dbe_update_tl_data_new(context, entry, &tl_data);
22464960Swillf 
22474960Swillf     free(unparse_mod_princ);
22484960Swillf     free(nextloc);
22494960Swillf 
22504960Swillf     return(retval);
22514960Swillf }
22524960Swillf 
22534960Swillf static krb5_error_code
kdb_ldap_tgt_keysalt_iterate(ksent,ptr)22544960Swillf kdb_ldap_tgt_keysalt_iterate(ksent, ptr)
22554960Swillf     krb5_key_salt_tuple *ksent;
22564960Swillf     krb5_pointer        ptr;
22574960Swillf {
22584960Swillf     krb5_context        context;
22594960Swillf     krb5_error_code     kret;
22604960Swillf     struct iterate_args *iargs;
22614960Swillf     krb5_keyblock       key;
22624960Swillf     krb5_int32          ind;
22634960Swillf     krb5_data   pwd;
22644960Swillf     krb5_db_entry       *entry;
22654960Swillf 
22664960Swillf     iargs = (struct iterate_args *) ptr;
22674960Swillf     kret = 0;
22684960Swillf 
22694960Swillf     context = iargs->ctx;
22704960Swillf     entry = iargs->dbentp;
22714960Swillf 
22724960Swillf     /*
22734960Swillf      * Convert the master key password into a key for this particular
22744960Swillf      * encryption system.
22754960Swillf      */
22764960Swillf     pwd.data = mkey_password;
22774960Swillf     pwd.length = strlen(mkey_password);
22784960Swillf     kret = krb5_c_random_seed(context, &pwd);
22794960Swillf     if (kret)
22804960Swillf 	return kret;
22814960Swillf 
22824960Swillf     /*if (!(kret = krb5_dbe_create_key_data(iargs->ctx, iargs->dbentp))) {*/
22834960Swillf     if ((entry->key_data =
22844960Swillf 	     (krb5_key_data *) realloc(entry->key_data,
22854960Swillf 					    (sizeof(krb5_key_data) *
22864960Swillf 					    (entry->n_key_data + 1)))) == NULL)
22874960Swillf 	return (ENOMEM);
22884960Swillf 
22894960Swillf     memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data));
22904960Swillf     ind = entry->n_key_data++;
22914960Swillf 
22924960Swillf     if (!(kret = krb5_c_make_random_key(context, ksent->ks_enctype,
22934960Swillf 					&key))) {
22944960Swillf 	kret = krb5_dbekd_encrypt_key_data(context,
22954960Swillf 					   iargs->rblock->key,
22964960Swillf 					   &key,
22974960Swillf 					   NULL,
22984960Swillf 					   1,
22994960Swillf 					   &entry->key_data[ind]);
23004960Swillf 	krb5_free_keyblock_contents(context, &key);
23014960Swillf     }
23024960Swillf     /*}*/
23034960Swillf 
23044960Swillf     return(kret);
23054960Swillf }
23064960Swillf /* End duplicate code */
23074960Swillf 
23084960Swillf /*
23094960Swillf  * This function creates service principals when
23104960Swillf  * creating the realm object.
23114960Swillf  */
23124960Swillf static int
kdb_ldap_create_principal(context,princ,op,pblock)23134960Swillf kdb_ldap_create_principal (context, princ, op, pblock)
23144960Swillf     krb5_context context;
23154960Swillf     krb5_principal princ;
23164960Swillf     enum ap_op op;
23174960Swillf     struct realm_info *pblock;
23184960Swillf {
23194960Swillf     int              retval=0, currlen=0, princtype = 2 /* Service Principal */;
23204960Swillf     unsigned char    *curr=NULL;
23214960Swillf     krb5_tl_data     *tl_data=NULL;
23224960Swillf     krb5_db_entry    entry;
23234960Swillf     int              nentry=1;
23244960Swillf     long             mask = 0;
23254960Swillf     krb5_keyblock    key;
23264960Swillf     int              kvno = 0;
23274960Swillf     kdb5_dal_handle *dal_handle = NULL;
23284960Swillf     krb5_ldap_context *ldap_context=NULL;
23294960Swillf     struct iterate_args   iargs;
23304960Swillf     krb5_data       *pdata;
23314960Swillf 
23324960Swillf     if ((pblock == NULL) || (context == NULL)) {
23334960Swillf 	retval = EINVAL;
23344960Swillf 	goto cleanup;
23354960Swillf     }
23364960Swillf     dal_handle = (kdb5_dal_handle *) context->db_context;
23374960Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
23384960Swillf     if (!(ldap_context)) {
23394960Swillf 	retval = EINVAL;
23404960Swillf 	goto cleanup;
23414960Swillf     }
23424960Swillf 
23434960Swillf     memset(&entry, 0, sizeof(entry));
23444960Swillf 
23454960Swillf     tl_data = malloc(sizeof(*tl_data));
23464960Swillf     if (tl_data == NULL) {
23474960Swillf 	retval = ENOMEM;
23484960Swillf 	goto cleanup;
23494960Swillf     }
23504960Swillf     memset(tl_data, 0, sizeof(*tl_data));
23514960Swillf     tl_data->tl_data_length = 1 + 2 + 2 + 1 + 2 + 4;
23524960Swillf     tl_data->tl_data_type = 7; /* KDB_TL_USER_INFO */
23534960Swillf     curr = tl_data->tl_data_contents = malloc(tl_data->tl_data_length);
23544960Swillf     if (tl_data->tl_data_contents == NULL) {
23554960Swillf 	retval = ENOMEM;
23564960Swillf 	goto cleanup;
23574960Swillf     }
23584960Swillf 
23594960Swillf     memset(curr, 1, 1); /* Passing the mask as principal type */
23604960Swillf     curr += 1;
23614960Swillf     currlen = 2;
23624960Swillf     STORE16_INT(curr, currlen);
23634960Swillf     curr += currlen;
23644960Swillf     STORE16_INT(curr, princtype);
23654960Swillf     curr += currlen;
23664960Swillf 
23674960Swillf     mask |= KADM5_PRINCIPAL;
23684960Swillf     mask |= KADM5_ATTRIBUTES ;
23694960Swillf     mask |= KADM5_MAX_LIFE ;
23704960Swillf     mask |= KADM5_MAX_RLIFE ;
23714960Swillf     mask |= KADM5_PRINC_EXPIRE_TIME ;
23724960Swillf     mask |= KADM5_KEY_DATA;
23734960Swillf 
23744960Swillf     entry.tl_data = tl_data;
23754960Swillf     entry.n_tl_data += 1;
23764960Swillf     /* Set the creator's name */
23774960Swillf     {
23784960Swillf 	krb5_timestamp now;
23794960Swillf 	if ((retval = krb5_timeofday(context, &now)))
23804960Swillf 	    goto cleanup;
23814960Swillf 	if ((retval = krb5_dbe_update_mod_princ_data_new(context, &entry,
23824960Swillf 			now, &db_create_princ)))
23834960Swillf 	    goto cleanup;
23844960Swillf     }
23854960Swillf     entry.attributes = pblock->flags;
23864960Swillf     entry.max_life = pblock->max_life;
23874960Swillf     entry.max_renewable_life = pblock->max_rlife;
23884960Swillf     entry.expiration = pblock->expiration;
23894960Swillf     entry.mask = mask;
23904960Swillf     if ((retval = krb5_copy_principal(context, princ, &entry.princ)))
23914960Swillf 	goto cleanup;
23924960Swillf 
23934960Swillf 
23944960Swillf     switch (op) {
23954960Swillf     case TGT_KEY:
23964960Swillf 	if ((pdata = krb5_princ_component(context, princ, 1)) &&
23974960Swillf 	    pdata->length == strlen("history") &&
23984960Swillf 	    !memcmp(pdata->data, "history", strlen("history"))) {
23994960Swillf 
24004960Swillf 	    /* Allocate memory for storing the key */
24014960Swillf 	    if ((entry.key_data = (krb5_key_data *) malloc(
24024960Swillf 					      sizeof(krb5_key_data))) == NULL) {
24034960Swillf 		retval = ENOMEM;
24044960Swillf 		goto cleanup;
24054960Swillf 	    }
24064960Swillf 
24074960Swillf 	    memset(entry.key_data, 0, sizeof(krb5_key_data));
24084960Swillf 	    entry.n_key_data++;
24094960Swillf 
24104960Swillf 	    retval = krb5_c_make_random_key(context, global_params.enctype, &key);
24114960Swillf 	    if (retval) {
24124960Swillf 		goto cleanup;
24134960Swillf 	    }
24144960Swillf 	    kvno = 1; /* New key is getting set */
24154960Swillf 	    retval = krb5_dbekd_encrypt_key_data(context,
24164960Swillf 					&ldap_context->lrparams->mkey,
24174960Swillf 					&key, NULL, kvno,
24184960Swillf 					&entry.key_data[entry.n_key_data - 1]);
24194960Swillf 	    krb5_free_keyblock_contents(context, &key);
24204960Swillf 	    if (retval) {
24214960Swillf 		goto cleanup;
24224960Swillf 	    }
24234960Swillf 	} else {
24244960Swillf 	    /*retval = krb5_c_make_random_key(context, 16, &key) ;*/
24254960Swillf 	    iargs.ctx = context;
24264960Swillf 	    iargs.rblock = pblock;
24274960Swillf 	    iargs.dbentp = &entry;
24284960Swillf 
24294960Swillf 	    /*
24304960Swillf 	     * create a set of random keys by iterating through the key/salt
24314960Swillf 	     * list, ignoring salt types.
24324960Swillf 	     */
24334960Swillf 	    if ((retval = krb5_keysalt_iterate(pblock->kslist,
24344960Swillf 					       pblock->nkslist,
24354960Swillf 					       1,
24364960Swillf 					       kdb_ldap_tgt_keysalt_iterate,
24374960Swillf 					       (krb5_pointer) &iargs)))
24384960Swillf 		return retval;
24394960Swillf 	}
24404960Swillf 	break;
24414960Swillf 
24424960Swillf     case MASTER_KEY:
24434960Swillf 	/* Allocate memory for storing the key */
24444960Swillf 	if ((entry.key_data = (krb5_key_data *) malloc(
24454960Swillf 					      sizeof(krb5_key_data))) == NULL) {
24464960Swillf 	    retval = ENOMEM;
24474960Swillf 	    goto cleanup;
24484960Swillf 	}
24494960Swillf 
24504960Swillf 	memset(entry.key_data, 0, sizeof(krb5_key_data));
24514960Swillf 	entry.n_key_data++;
24524960Swillf 	kvno = 1; /* New key is getting set */
24534960Swillf 	retval = krb5_dbekd_encrypt_key_data(context, pblock->key,
24544960Swillf 					 &ldap_context->lrparams->mkey,
24554960Swillf 					 NULL, kvno,
24564960Swillf 					 &entry.key_data[entry.n_key_data - 1]);
24574960Swillf 	if (retval) {
24584960Swillf 	    goto cleanup;
24594960Swillf 	}
24604960Swillf 	break;
24614960Swillf 
24624960Swillf     case NULL_KEY:
24634960Swillf     default:
24644960Swillf 	break;
24654960Swillf     } /* end of switch */
24664960Swillf 
24674960Swillf     retval = krb5_ldap_put_principal(context, &entry, &nentry, NULL);
24684960Swillf     if (retval) {
24694960Swillf 	com_err(NULL, retval, gettext("while adding entries to database"));
24704960Swillf 	goto cleanup;
24714960Swillf     }
24724960Swillf 
24734960Swillf cleanup:
24744960Swillf     krb5_dbe_free_contents(context, &entry);
24754960Swillf     return retval;
24764960Swillf }
24774960Swillf 
24784960Swillf 
24794960Swillf /*
24804960Swillf  * This function destroys the realm object and the associated principals
24814960Swillf  */
24824960Swillf void
kdb5_ldap_destroy(argc,argv)24834960Swillf kdb5_ldap_destroy(argc, argv)
24844960Swillf     int argc;
24854960Swillf     char *argv[];
24864960Swillf {
24874960Swillf     extern char *optarg;
24884960Swillf     extern int optind;
24894960Swillf     int optchar = 0;
24904960Swillf     char buf[5] = {0};
24914960Swillf     krb5_error_code retval = 0;
24924960Swillf     int force = 0;
24934960Swillf     int mask = 0;
24944960Swillf     kdb5_dal_handle *dal_handle = NULL;
24954960Swillf     krb5_ldap_context *ldap_context = NULL;
24964960Swillf #ifdef HAVE_EDIRECTORY
24974960Swillf     int i = 0, rightsmask = 0;
24984960Swillf     krb5_ldap_realm_params *rparams = NULL;
24994960Swillf #endif
25004960Swillf     /* Solaris Kerberos: to remove stash file */
25014960Swillf     char *stash_file = NULL;
25024960Swillf     struct stat stb;
25034960Swillf 
25044960Swillf     optind = 1;
25054960Swillf     while ((optchar = getopt(argc, argv, "f")) != -1) {
25064960Swillf 	switch (optchar) {
25074960Swillf 	case 'f':
25084960Swillf 	    force++;
25094960Swillf 	    break;
25104960Swillf 	case '?':
25114960Swillf 	default:
25124960Swillf 	    db_usage(DESTROY_REALM);
25134960Swillf 	    return;
25144960Swillf 	    /*NOTREACHED*/
25154960Swillf 	}
25164960Swillf     }
25174960Swillf 
25184960Swillf     if (!force) {
25194960Swillf 	printf(gettext("Deleting KDC database of '%s', are you sure?\n"), global_params.realm);
25204960Swillf 	printf(gettext("(type 'yes' to confirm)? "));
25214960Swillf 	if (fgets(buf, sizeof(buf), stdin) == NULL) {
25224960Swillf 	    exit_status++;
25234960Swillf 	    return;
25244960Swillf 	}
25254960Swillf 	if (strcmp(buf, yes)) {
25264960Swillf 	    exit_status++;
25274960Swillf 	    return;
25284960Swillf 	}
25294960Swillf 	printf(gettext("OK, deleting database of '%s'...\n"), global_params.realm);
25304960Swillf     }
25314960Swillf 
25324960Swillf     dal_handle = (kdb5_dal_handle *)util_context->db_context;
25334960Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
25344960Swillf     if (!(ldap_context)) {
2535*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2536*8092SMark.Phalan@Sun.COM 	com_err(progname, EINVAL, gettext("while initializing database"));
25374960Swillf 	exit_status++;
25384960Swillf 	return;
25394960Swillf     }
25404960Swillf 
25414960Swillf     /* Read the kerberos container from the LDAP Server */
25424960Swillf     if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
25434960Swillf 						     &(ldap_context->krbcontainer))) != 0) {
2544*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2545*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while reading kerberos container information"));
25464960Swillf 	exit_status++;
25474960Swillf 	return;
25484960Swillf     }
25494960Swillf 
25504960Swillf     /* Read the Realm information from the LDAP Server */
25514960Swillf     if ((retval = krb5_ldap_read_realm_params(util_context, global_params.realm,
25524960Swillf 					      &(ldap_context->lrparams), &mask)) != 0) {
2553*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2554*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("while reading realm information"));
25554960Swillf 	exit_status++;
25564960Swillf 	return;
25574960Swillf     }
25584960Swillf 
25594960Swillf #ifdef HAVE_EDIRECTORY
25604960Swillf     if ((mask & LDAP_REALM_KDCSERVERS) || (mask & LDAP_REALM_ADMINSERVERS) ||
25614960Swillf 	(mask & LDAP_REALM_PASSWDSERVERS)) {
25624960Swillf 
25634960Swillf 	printf(gettext("Changing rights for the service object. Please wait ... "));
25644960Swillf 	fflush(stdout);
25654960Swillf 
25664960Swillf 	rparams = ldap_context->lrparams;
25674960Swillf 	rightsmask = 0;
25684960Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
25694960Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
25704960Swillf 	if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
25714960Swillf 	    for (i=0; (rparams->kdcservers[i] != NULL); i++) {
25724960Swillf 		if ((retval = krb5_ldap_delete_service_rights(util_context,
25734960Swillf 							      LDAP_KDC_SERVICE, rparams->kdcservers[i],
25744960Swillf 							      rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
25754960Swillf 		    printf(gettext("failed\n"));
2576*8092SMark.Phalan@Sun.COM 		    /* Solaris Kerberos */
2577*8092SMark.Phalan@Sun.COM 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
25784960Swillf 			    rparams->realm_name);
25794960Swillf 		    return;
25804960Swillf 		}
25814960Swillf 	    }
25824960Swillf 	}
25834960Swillf 	rightsmask = 0;
25844960Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
25854960Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
25864960Swillf 	if ((rparams != NULL) && (rparams->adminservers != NULL)) {
25874960Swillf 	    for (i=0; (rparams->adminservers[i] != NULL); i++) {
25884960Swillf 		if ((retval = krb5_ldap_delete_service_rights(util_context,
25894960Swillf 							      LDAP_ADMIN_SERVICE, rparams->adminservers[i],
25904960Swillf 							      rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
25914960Swillf 		    printf(gettext("failed\n"));
2592*8092SMark.Phalan@Sun.COM 		    /* Solaris Kerberos */
2593*8092SMark.Phalan@Sun.COM 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
25944960Swillf 			    rparams->realm_name);
25954960Swillf 		    return;
25964960Swillf 		}
25974960Swillf 	    }
25984960Swillf 	}
25994960Swillf 	rightsmask = 0;
26004960Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
26014960Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
26024960Swillf 	if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
26034960Swillf 	    for (i=0; (rparams->passwdservers[i] != NULL); i++) {
26044960Swillf 		if ((retval = krb5_ldap_delete_service_rights(util_context,
26054960Swillf 							      LDAP_PASSWD_SERVICE, rparams->passwdservers[i],
26064960Swillf 							      rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
26074960Swillf 		    printf(gettext("failed\n"));
2608*8092SMark.Phalan@Sun.COM 		    /* Solaris Kerberos */
2609*8092SMark.Phalan@Sun.COM 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
26104960Swillf 			    rparams->realm_name);
26114960Swillf 		    return;
26124960Swillf 		}
26134960Swillf 	    }
26144960Swillf 	}
26154960Swillf 	printf(gettext("done\n"));
26164960Swillf     }
26174960Swillf #endif
26184960Swillf     /* Delete the realm container and all the associated principals */
26194960Swillf     retval = krb5_ldap_delete_realm(util_context, global_params.realm);
26204960Swillf     if (retval) {
2621*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2622*8092SMark.Phalan@Sun.COM 	com_err(progname, retval, gettext("deleting database of '%s'"), global_params.realm);
26234960Swillf 	exit_status++;
26244960Swillf 	return;
26254960Swillf     }
26264960Swillf 
26274960Swillf     /*
26284960Swillf      * Solaris Kerberos: check for a stash file and delete it if necessary
26294960Swillf      * This behavior exists in the Solaris version of kdb5_util destroy.
26304960Swillf      */
26314960Swillf     if (global_params.stash_file == NULL) {
26324960Swillf 	char stashbuf[MAXPATHLEN+1];
26334960Swillf 	int realm_len = strlen(global_params.realm);
26344960Swillf 
26354960Swillf 	(void) strlcpy(stashbuf, DEFAULT_KEYFILE_STUB, sizeof (stashbuf));
26364960Swillf 
26374960Swillf 	if (realm_len <= (MAXPATHLEN-strlen(stashbuf))) {
26384960Swillf 	    (void) strncat(stashbuf, global_params.realm,
26394960Swillf 		(MAXPATHLEN-strlen(stashbuf)));
26404960Swillf 	} else {
2641*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
2642*8092SMark.Phalan@Sun.COM 	    com_err(progname, EINVAL,
26434960Swillf 		gettext("can not determine stash file name for '%s'"),
26444960Swillf 		global_params.realm);
26454960Swillf 	    exit_status++;
26464960Swillf 	    return;
26474960Swillf 	}
26484960Swillf 	stash_file = stashbuf;
26494960Swillf     } else {
26504960Swillf 	stash_file = global_params.stash_file;
26514960Swillf     }
26524960Swillf     /* Make sure stash_file is a regular file before unlinking */
26534960Swillf     if (stat(stash_file, &stb) == 0) {
26544960Swillf 	if ((stb.st_mode & S_IFMT) == S_IFREG) {
26554960Swillf 	    (void)unlink(stash_file);
26564960Swillf 	} else {
2657*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
2658*8092SMark.Phalan@Sun.COM 	    com_err(progname, EINVAL,
26594960Swillf 		gettext("stash file '%s' not a regular file, can not delete"),
26604960Swillf 		stash_file);
26614960Swillf 	    exit_status++;
26624960Swillf 	    return;
26634960Swillf 	}
26644960Swillf     } else if (errno != ENOENT) {
26654960Swillf 	/*
26664960Swillf 	 * If the error is something other than the file doesn't exist set an
26674960Swillf 	 * error.
26684960Swillf 	 */
2669*8092SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2670*8092SMark.Phalan@Sun.COM 	com_err(progname, EINVAL,
26714960Swillf 	    gettext("could not stat stash file '%s', could not delete"),
26724960Swillf 	    stash_file);
26734960Swillf 	exit_status++;
26744960Swillf 	return;
26754960Swillf     }
26764960Swillf 
26774960Swillf     printf(gettext("** Database of '%s' destroyed.\n"), global_params.realm);
26784960Swillf 
26794960Swillf     return;
26804960Swillf }
2681