154925bf6Swillf /*
2*d7c57852SGary Mills  * Copyright 2017 Gary Mills
3dd9ccd46S  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
454925bf6Swillf  * Use is subject to license terms.
554925bf6Swillf  */
654925bf6Swillf 
754925bf6Swillf /*
854925bf6Swillf  * kadmin/ldap_util/kdb5_ldap_realm.c
954925bf6Swillf  *
1054925bf6Swillf  * Copyright 1990,1991,2001, 2002 by the Massachusetts Institute of Technology.
1154925bf6Swillf  * All Rights Reserved.
1254925bf6Swillf  *
1354925bf6Swillf  * Export of this software from the United States of America may
1454925bf6Swillf  *   require a specific license from the United States Government.
1554925bf6Swillf  *   It is the responsibility of any person or organization contemplating
1654925bf6Swillf  *   export to obtain such a license before exporting.
1754925bf6Swillf  *
1854925bf6Swillf  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
1954925bf6Swillf  * distribute this software and its documentation for any purpose and
2054925bf6Swillf  * without fee is hereby granted, provided that the above copyright
2154925bf6Swillf  * notice appear in all copies and that both that copyright notice and
2254925bf6Swillf  * this permission notice appear in supporting documentation, and that
2354925bf6Swillf  * the name of M.I.T. not be used in advertising or publicity pertaining
2454925bf6Swillf  * to distribution of the software without specific, written prior
2554925bf6Swillf  * permission.  Furthermore if you modify this software you must label
2654925bf6Swillf  * your software as modified software and not distribute it in such a
2754925bf6Swillf  * fashion that it might be confused with the original M.I.T. software.
2854925bf6Swillf  * M.I.T. makes no representations about the suitability of
2954925bf6Swillf  * this software for any purpose.  It is provided "as is" without express
3054925bf6Swillf  * or implied warranty.
3154925bf6Swillf  */
3254925bf6Swillf 
3354925bf6Swillf /*
3454925bf6Swillf  * Copyright (C) 1998 by the FundsXpress, INC.
3554925bf6Swillf  *
3654925bf6Swillf  * All rights reserved.
3754925bf6Swillf  *
3854925bf6Swillf  * Export of this software from the United States of America may require
3954925bf6Swillf  * a specific license from the United States Government.  It is the
4054925bf6Swillf  * responsibility of any person or organization contemplating export to
4154925bf6Swillf  * obtain such a license before exporting.
4254925bf6Swillf  *
4354925bf6Swillf  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
4454925bf6Swillf  * distribute this software and its documentation for any purpose and
4554925bf6Swillf  * without fee is hereby granted, provided that the above copyright
4654925bf6Swillf  * notice appear in all copies and that both that copyright notice and
4754925bf6Swillf  * this permission notice appear in supporting documentation, and that
4854925bf6Swillf  * the name of FundsXpress. not be used in advertising or publicity pertaining
4954925bf6Swillf  * to distribution of the software without specific, written prior
5054925bf6Swillf  * permission.  FundsXpress makes no representations about the suitability of
5154925bf6Swillf  * this software for any purpose.  It is provided "as is" without express
5254925bf6Swillf  * or implied warranty.
5354925bf6Swillf  *
5454925bf6Swillf  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
5554925bf6Swillf  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
5654925bf6Swillf  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
5754925bf6Swillf  */
5854925bf6Swillf 
5954925bf6Swillf /* Copyright (c) 2004-2005, Novell, Inc.
6054925bf6Swillf  * All rights reserved.
6154925bf6Swillf  *
6254925bf6Swillf  * Redistribution and use in source and binary forms, with or without
6354925bf6Swillf  * modification, are permitted provided that the following conditions are met:
6454925bf6Swillf  *
6554925bf6Swillf  *   * Redistributions of source code must retain the above copyright notice,
6654925bf6Swillf  *       this list of conditions and the following disclaimer.
6754925bf6Swillf  *   * Redistributions in binary form must reproduce the above copyright
6854925bf6Swillf  *       notice, this list of conditions and the following disclaimer in the
6954925bf6Swillf  *       documentation and/or other materials provided with the distribution.
7054925bf6Swillf  *   * The copyright holder's name is not used to endorse or promote products
7154925bf6Swillf  *       derived from this software without specific prior written permission.
7254925bf6Swillf  *
7354925bf6Swillf  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
7454925bf6Swillf  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7554925bf6Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7654925bf6Swillf  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
7754925bf6Swillf  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
7854925bf6Swillf  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
7954925bf6Swillf  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8054925bf6Swillf  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
8154925bf6Swillf  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
8254925bf6Swillf  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8354925bf6Swillf  * POSSIBILITY OF SUCH DAMAGE.
8454925bf6Swillf  */
8554925bf6Swillf 
8654925bf6Swillf /*
8754925bf6Swillf  * Create / Modify / Destroy / View / List realm(s)
8854925bf6Swillf  */
8954925bf6Swillf 
9054925bf6Swillf /* Needed for getting the definition of KRB5_TL_DB_ARGS */
9154925bf6Swillf #define SECURID
9254925bf6Swillf 
9354925bf6Swillf #include <stdio.h>
9454925bf6Swillf #include <k5-int.h>
9554925bf6Swillf #include <kadm5/admin.h>
9654925bf6Swillf #include <libintl.h>
9754925bf6Swillf #include <locale.h>
9854925bf6Swillf #include "kdb5_ldap_util.h"
9954925bf6Swillf #include "kdb5_ldap_list.h"
10054925bf6Swillf #include <ldap_principal.h>
10154925bf6Swillf #include <ldap_krbcontainer.h>
10254925bf6Swillf extern time_t get_date(char *); /* kadmin/cli/getdate.o */
10354925bf6Swillf 
10454925bf6Swillf char *yes = "yes\n"; /* \n to compare against result of fgets */
10554925bf6Swillf krb5_key_salt_tuple def_kslist = {ENCTYPE_DES_CBC_CRC, KRB5_KDB_SALTTYPE_NORMAL};
10654925bf6Swillf 
10754925bf6Swillf struct realm_info rblock = {
10854925bf6Swillf     KRB5_KDB_MAX_LIFE,
10954925bf6Swillf     KRB5_KDB_MAX_RLIFE,
11054925bf6Swillf     KRB5_KDB_EXPIRATION,
11154925bf6Swillf     KRB5_KDB_DEF_FLAGS,
11254925bf6Swillf     (krb5_keyblock *) NULL,
11354925bf6Swillf     1,
11454925bf6Swillf     &def_kslist
11554925bf6Swillf };
11654925bf6Swillf 
11754925bf6Swillf krb5_data tgt_princ_entries[] = {
11854925bf6Swillf     {0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME},
11954925bf6Swillf     {0, 0, 0} };
12054925bf6Swillf 
12154925bf6Swillf krb5_data db_creator_entries[] = {
12254925bf6Swillf     {0, sizeof("db_creation")-1, "db_creation"} };
12354925bf6Swillf 
12454925bf6Swillf 
12554925bf6Swillf static krb5_principal_data db_create_princ = {
12654925bf6Swillf     0,					/* magic number */
12754925bf6Swillf     {0, 0, 0},				/* krb5_data realm */
12854925bf6Swillf     db_creator_entries,			/* krb5_data *data */
12954925bf6Swillf     1,					/* int length */
13054925bf6Swillf     KRB5_NT_SRV_INST			/* int type */
13154925bf6Swillf };
13254925bf6Swillf 
13354925bf6Swillf extern char *mkey_password;
13454925bf6Swillf extern char *progname;
13554925bf6Swillf extern kadm5_config_params global_params;
13654925bf6Swillf 
13754925bf6Swillf static void print_realm_params(krb5_ldap_realm_params *rparams, int mask);
13854925bf6Swillf static int kdb_ldap_create_principal (krb5_context context, krb5_principal
13954925bf6Swillf 				      princ, enum ap_op op, struct realm_info *pblock);
14054925bf6Swillf 
14154925bf6Swillf 
14254925bf6Swillf static char *strdur(time_t duration);
14354925bf6Swillf static int get_ticket_policy(krb5_ldap_realm_params *rparams, int *i, char *argv[],int argc);
14454925bf6Swillf 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);
14554925bf6Swillf static krb5_error_code krb5_dbe_update_tl_data_new ( krb5_context context, krb5_db_entry *entry, krb5_tl_data *new_tl_data);
14654925bf6Swillf 
14754925bf6Swillf #define ADMIN_LIFETIME 60*60*3 /* 3 hours */
14854925bf6Swillf #define CHANGEPW_LIFETIME 60*5 /* 5 minutes */
14954925bf6Swillf 
15054925bf6Swillf static int get_ticket_policy(rparams,i,argv,argc)
15154925bf6Swillf     krb5_ldap_realm_params *rparams;
15254925bf6Swillf     int *i;
15354925bf6Swillf     char *argv[];
15454925bf6Swillf     int argc;
15554925bf6Swillf {
15654925bf6Swillf     time_t date;
15754925bf6Swillf     time_t now;
15854925bf6Swillf     int mask = 0;
15954925bf6Swillf     krb5_error_code retval = 0;
16054925bf6Swillf 
161dd9ccd46S     /* Solaris Kerberos */
162dd9ccd46S     char *me = progname;
16354925bf6Swillf 
16454925bf6Swillf     time(&now);
16554925bf6Swillf     if (!strcmp(argv[*i], "-maxtktlife")) {
16654925bf6Swillf 	if (++(*i) > argc-1)
167*d7c57852SGary Mills 	    goto err;
16854925bf6Swillf 	date = get_date(argv[*i]);
16954925bf6Swillf 	if (date == (time_t)(-1)) {
17054925bf6Swillf 	    retval = EINVAL;
17154925bf6Swillf 	    com_err (me, retval, gettext("while providing time specification"));
172*d7c57852SGary Mills 	    goto err;
17354925bf6Swillf 	}
17454925bf6Swillf 	rparams->max_life = date-now;
17554925bf6Swillf 	mask |= LDAP_REALM_MAXTICKETLIFE;
17654925bf6Swillf     }
17754925bf6Swillf 
17854925bf6Swillf 
17954925bf6Swillf     else if (!strcmp(argv[*i], "-maxrenewlife")) {
18054925bf6Swillf 	if (++(*i) > argc-1)
181*d7c57852SGary Mills 	    goto err;
18254925bf6Swillf 
18354925bf6Swillf 	date = get_date(argv[*i]);
18454925bf6Swillf 	if (date == (time_t)(-1)) {
18554925bf6Swillf 	    retval = EINVAL;
18654925bf6Swillf 	    com_err (me, retval, gettext("while providing time specification"));
187*d7c57852SGary Mills 	    goto err;
18854925bf6Swillf 	}
18954925bf6Swillf 	rparams->max_renewable_life = date-now;
19054925bf6Swillf 	mask |= LDAP_REALM_MAXRENEWLIFE;
19154925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "allow_postdated")) {
19254925bf6Swillf 	if (*(argv[*i]) == '+')
19354925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED);
19454925bf6Swillf 	else if (*(argv[*i]) == '-')
19554925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED;
19654925bf6Swillf 	else
197*d7c57852SGary Mills 	    goto err;
19854925bf6Swillf 
19954925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
20054925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "allow_forwardable")) {
20154925bf6Swillf 	if (*(argv[*i]) == '+')
20254925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE);
20354925bf6Swillf 
20454925bf6Swillf 	else if (*(argv[*i]) == '-')
20554925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE;
20654925bf6Swillf 	else
207*d7c57852SGary Mills 	    goto err;
20854925bf6Swillf 
20954925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
21054925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "allow_renewable")) {
21154925bf6Swillf 	if (*(argv[*i]) == '+')
21254925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE);
21354925bf6Swillf 	else if (*(argv[*i]) == '-')
21454925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE;
21554925bf6Swillf 	else
216*d7c57852SGary Mills 	    goto err;
21754925bf6Swillf 
21854925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
21954925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "allow_proxiable")) {
22054925bf6Swillf 	if (*(argv[*i]) == '+')
22154925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE);
22254925bf6Swillf 	else if (*(argv[*i]) == '-')
22354925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE;
22454925bf6Swillf 	else
225*d7c57852SGary Mills 	    goto err;
22654925bf6Swillf 
22754925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
22854925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "allow_dup_skey")) {
22954925bf6Swillf 	if (*(argv[*i]) == '+')
23054925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY);
23154925bf6Swillf 	else if (*(argv[*i]) == '-')
23254925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY;
23354925bf6Swillf 	else
234*d7c57852SGary Mills 	    goto err;
23554925bf6Swillf 
23654925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
23754925bf6Swillf     }
23854925bf6Swillf 
23954925bf6Swillf     else if (!strcmp((argv[*i] + 1), "requires_preauth")) {
24054925bf6Swillf 	if (*(argv[*i]) == '+')
24154925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH;
24254925bf6Swillf 	else if (*(argv[*i]) == '-')
24354925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH);
24454925bf6Swillf 	else
245*d7c57852SGary Mills 	    goto err;
24654925bf6Swillf 
24754925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
24854925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "requires_hwauth")) {
24954925bf6Swillf 	if (*(argv[*i]) == '+')
25054925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH;
25154925bf6Swillf 	else if (*(argv[*i]) == '-')
25254925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH);
25354925bf6Swillf 	else
254*d7c57852SGary Mills 	    goto err;
25554925bf6Swillf 
25654925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
25754925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "allow_svr")) {
25854925bf6Swillf 	if (*(argv[*i]) == '+')
25954925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR);
26054925bf6Swillf 	else if (*(argv[*i]) == '-')
26154925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_SVR;
26254925bf6Swillf 	else
263*d7c57852SGary Mills 	    goto err;
26454925bf6Swillf 
26554925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
26654925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "allow_tgs_req")) {
26754925bf6Swillf 	if (*(argv[*i]) == '+')
26854925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED);
26954925bf6Swillf 	else if (*(argv[*i]) == '-')
27054925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED;
27154925bf6Swillf 	else
272*d7c57852SGary Mills 	    goto err;
27354925bf6Swillf 
27454925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
27554925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "allow_tix")) {
27654925bf6Swillf 	if (*(argv[*i]) == '+')
27754925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX);
27854925bf6Swillf 	else if (*(argv[*i]) == '-')
27954925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX;
28054925bf6Swillf 	else
281*d7c57852SGary Mills 	    goto err;
28254925bf6Swillf 
28354925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
28454925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "needchange")) {
28554925bf6Swillf 	if (*(argv[*i]) == '+')
28654925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE;
28754925bf6Swillf 	else if (*(argv[*i]) == '-')
28854925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE);
28954925bf6Swillf 	else
290*d7c57852SGary Mills 	    goto err;
29154925bf6Swillf 
29254925bf6Swillf 	mask |= LDAP_REALM_KRBTICKETFLAGS;
29354925bf6Swillf     } else if (!strcmp((argv[*i] + 1), "password_changing_service")) {
29454925bf6Swillf 	if (*(argv[*i]) == '+')
29554925bf6Swillf 	    rparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE;
29654925bf6Swillf 	else if (*(argv[*i]) == '-')
29754925bf6Swillf 	    rparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE);
29854925bf6Swillf 	else
299*d7c57852SGary Mills 	    goto err;
30054925bf6Swillf 
30154925bf6Swillf 	mask |=LDAP_REALM_KRBTICKETFLAGS;
30254925bf6Swillf     }
30354925bf6Swillf 
304*d7c57852SGary Mills err:
30554925bf6Swillf 
30654925bf6Swillf     return mask;
30754925bf6Swillf }
30854925bf6Swillf 
30954925bf6Swillf /*
31054925bf6Swillf  * This function will create a realm on the LDAP Server, with
31154925bf6Swillf  * the specified attributes.
31254925bf6Swillf  */
31354925bf6Swillf void kdb5_ldap_create(argc, argv)
31454925bf6Swillf     int argc;
31554925bf6Swillf     char *argv[];
31654925bf6Swillf {
31754925bf6Swillf     krb5_error_code retval = 0;
31854925bf6Swillf     krb5_keyblock master_keyblock;
31954925bf6Swillf     krb5_ldap_realm_params *rparams = NULL;
32054925bf6Swillf     krb5_principal master_princ = NULL;
32154925bf6Swillf     kdb5_dal_handle *dal_handle = NULL;
32254925bf6Swillf     krb5_ldap_context *ldap_context=NULL;
32354925bf6Swillf     krb5_boolean realm_obj_created = FALSE;
32454925bf6Swillf     krb5_boolean create_complete = FALSE;
32554925bf6Swillf     krb5_boolean print_usage = FALSE;
32654925bf6Swillf     krb5_boolean no_msg = FALSE;
32754925bf6Swillf     char *oldcontainerref=NULL;
32854925bf6Swillf     char pw_str[1024];
32954925bf6Swillf     int do_stash = 0;
33054925bf6Swillf     int i = 0;
33154925bf6Swillf     int mask = 0, ret_mask = 0;
33254925bf6Swillf     char **list = NULL;
33354925bf6Swillf #ifdef HAVE_EDIRECTORY
33454925bf6Swillf     int rightsmask = 0;
33554925bf6Swillf #endif
33654925bf6Swillf 
33754925bf6Swillf     memset(&master_keyblock, 0, sizeof(master_keyblock));
33854925bf6Swillf 
33954925bf6Swillf     rparams = (krb5_ldap_realm_params *)malloc(
34054925bf6Swillf 	sizeof(krb5_ldap_realm_params));
34154925bf6Swillf     if (rparams == NULL) {
34254925bf6Swillf 	retval = ENOMEM;
34354925bf6Swillf 	goto cleanup;
34454925bf6Swillf     }
34554925bf6Swillf     memset(rparams, 0, sizeof(krb5_ldap_realm_params));
34654925bf6Swillf 
34754925bf6Swillf     /* Parse the arguments */
34854925bf6Swillf     for (i = 1; i < argc; i++) {
34954925bf6Swillf 	if (!strcmp(argv[i], "-subtrees")) {
35054925bf6Swillf 	    if (++i > argc-1)
35154925bf6Swillf 		goto err_usage;
35254925bf6Swillf 
35354925bf6Swillf 	    if(strncmp(argv[i], "", strlen(argv[i]))!=0) {
35454925bf6Swillf 		list = (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *));
35554925bf6Swillf 		if (list == NULL) {
35654925bf6Swillf 		    retval = ENOMEM;
35754925bf6Swillf 		    goto cleanup;
35854925bf6Swillf 		}
35954925bf6Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
36054925bf6Swillf 		    free(list);
36154925bf6Swillf 		    list = NULL;
36254925bf6Swillf 		    goto cleanup;
36354925bf6Swillf 		}
36454925bf6Swillf 
36554925bf6Swillf 		rparams->subtreecount=0;
36654925bf6Swillf 		while(list[rparams->subtreecount]!=NULL)
36754925bf6Swillf 		    (rparams->subtreecount)++;
36854925bf6Swillf 		rparams->subtree = list;
36954925bf6Swillf 	    } else if(strncmp(argv[i], "", strlen(argv[i]))==0) {
37054925bf6Swillf 		 /* dont allow subtree value to be set at the root(NULL, "") of the tree */
371dd9ccd46S 		 /* Solaris Kerberos */
372dd9ccd46S 		 com_err(progname, EINVAL,
37354925bf6Swillf 			  gettext("for subtree while creating realm '%s'"),
37454925bf6Swillf 			   global_params.realm);
37554925bf6Swillf 		 goto err_nomsg;
37654925bf6Swillf 	    }
37754925bf6Swillf 	    rparams->subtree[rparams->subtreecount] = NULL;
37854925bf6Swillf 	    mask |= LDAP_REALM_SUBTREE;
37954925bf6Swillf 	} else if (!strcmp(argv[i], "-containerref")) {
38054925bf6Swillf 	    if (++i > argc-1)
38154925bf6Swillf 		goto err_usage;
38254925bf6Swillf 	    if(strncmp(argv[i], "", strlen(argv[i]))==0) {
38354925bf6Swillf 		 /* dont allow containerref value to be set at the root(NULL, "") of the tree */
384dd9ccd46S 		 /* Solaris Kerberos */
385dd9ccd46S 		 com_err(progname, EINVAL,
38654925bf6Swillf 			  gettext("for container reference while creating realm '%s'"),
38754925bf6Swillf 			   global_params.realm);
38854925bf6Swillf 		 goto err_nomsg;
38954925bf6Swillf 	    }
39054925bf6Swillf 	    rparams->containerref = strdup(argv[i]);
39154925bf6Swillf 	    if (rparams->containerref == NULL) {
39254925bf6Swillf 		retval = ENOMEM;
39354925bf6Swillf 		goto cleanup;
39454925bf6Swillf 	    }
39554925bf6Swillf 	    mask |= LDAP_REALM_CONTREF;
39654925bf6Swillf 	} else if (!strcmp(argv[i], "-sscope")) {
39754925bf6Swillf 	    if (++i > argc-1)
39854925bf6Swillf 		goto err_usage;
39954925bf6Swillf 	    /* Possible values for search scope are
40054925bf6Swillf 	     * one (or 1) and sub (or 2)
40154925bf6Swillf 	     */
40254925bf6Swillf 	    if (!strcasecmp(argv[i], "one")) {
40354925bf6Swillf 		rparams->search_scope = 1;
40454925bf6Swillf 	    } else if (!strcasecmp(argv[i], "sub")) {
40554925bf6Swillf 		rparams->search_scope = 2;
40654925bf6Swillf 	    } else {
40754925bf6Swillf 		rparams->search_scope = atoi(argv[i]);
40854925bf6Swillf 		if ((rparams->search_scope != 1) &&
40954925bf6Swillf 		    (rparams->search_scope != 2)) {
410dd9ccd46S 		    /* Solaris Kerberos */
411dd9ccd46S 		    com_err(progname, EINVAL,
41254925bf6Swillf 			    gettext("invalid search scope while creating realm '%s'"),
41354925bf6Swillf 			    global_params.realm);
41454925bf6Swillf 		    goto err_nomsg;
41554925bf6Swillf 		}
41654925bf6Swillf 	    }
41754925bf6Swillf 	    mask |= LDAP_REALM_SEARCHSCOPE;
41854925bf6Swillf 	}
41954925bf6Swillf #ifdef HAVE_EDIRECTORY
42054925bf6Swillf 	else if (!strcmp(argv[i], "-kdcdn")) {
42154925bf6Swillf 	    if (++i > argc-1)
42254925bf6Swillf 		goto err_usage;
42354925bf6Swillf 	    rparams->kdcservers = (char **)malloc(
42454925bf6Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
42554925bf6Swillf 	    if (rparams->kdcservers == NULL) {
42654925bf6Swillf 		retval = ENOMEM;
42754925bf6Swillf 		goto cleanup;
42854925bf6Swillf 	    }
42954925bf6Swillf 	    memset(rparams->kdcservers, 0, sizeof(char*)*MAX_LIST_ENTRIES);
43054925bf6Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
43154925bf6Swillf 					  rparams->kdcservers))) {
43254925bf6Swillf 		goto cleanup;
43354925bf6Swillf 	    }
43454925bf6Swillf 	    mask |= LDAP_REALM_KDCSERVERS;
43554925bf6Swillf 	} else if (!strcmp(argv[i], "-admindn")) {
43654925bf6Swillf 	    if (++i > argc-1)
43754925bf6Swillf 		goto err_usage;
43854925bf6Swillf 	    rparams->adminservers = (char **)malloc(
43954925bf6Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
44054925bf6Swillf 	    if (rparams->adminservers == NULL) {
44154925bf6Swillf 		retval = ENOMEM;
44254925bf6Swillf 		goto cleanup;
44354925bf6Swillf 	    }
44454925bf6Swillf 	    memset(rparams->adminservers, 0, sizeof(char*)*MAX_LIST_ENTRIES);
44554925bf6Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
44654925bf6Swillf 					  rparams->adminservers))) {
44754925bf6Swillf 		goto cleanup;
44854925bf6Swillf 	    }
44954925bf6Swillf 	    mask |= LDAP_REALM_ADMINSERVERS;
45054925bf6Swillf 	} else if (!strcmp(argv[i], "-pwddn")) {
45154925bf6Swillf 	    if (++i > argc-1)
45254925bf6Swillf 		goto err_usage;
45354925bf6Swillf 	    rparams->passwdservers = (char **)malloc(
45454925bf6Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
45554925bf6Swillf 	    if (rparams->passwdservers == NULL) {
45654925bf6Swillf 		retval = ENOMEM;
45754925bf6Swillf 		goto cleanup;
45854925bf6Swillf 	    }
45954925bf6Swillf 	    memset(rparams->passwdservers, 0, sizeof(char*)*MAX_LIST_ENTRIES);
46054925bf6Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
46154925bf6Swillf 					  rparams->passwdservers))) {
46254925bf6Swillf 		goto cleanup;
46354925bf6Swillf 	    }
46454925bf6Swillf 	    mask |= LDAP_REALM_PASSWDSERVERS;
46554925bf6Swillf 	}
46654925bf6Swillf #endif
46754925bf6Swillf 	else if (!strcmp(argv[i], "-s")) {
46854925bf6Swillf 	    do_stash = 1;
46954925bf6Swillf 	} else if ((ret_mask= get_ticket_policy(rparams,&i,argv,argc)) !=0) {
47054925bf6Swillf 	    mask|=ret_mask;
47154925bf6Swillf 	}
47254925bf6Swillf 
47354925bf6Swillf 	else {
47454925bf6Swillf 	    printf(gettext("'%s' is an invalid option\n"), argv[i]);
47554925bf6Swillf 	    goto err_usage;
47654925bf6Swillf 	}
47754925bf6Swillf     }
47854925bf6Swillf 
47954925bf6Swillf     /* If the default enctype/salttype is not provided, use the
48054925bf6Swillf      * default values and also add to the list of supported
48154925bf6Swillf      * enctypes/salttype
48254925bf6Swillf      */
48354925bf6Swillf 
48454925bf6Swillf     rblock.max_life = global_params.max_life;
48554925bf6Swillf     rblock.max_rlife = global_params.max_rlife;
48654925bf6Swillf     rblock.expiration = global_params.expiration;
48754925bf6Swillf     rblock.flags = global_params.flags;
48854925bf6Swillf     rblock.nkslist = global_params.num_keysalts;
48954925bf6Swillf     rblock.kslist = global_params.keysalts;
49054925bf6Swillf 
49154925bf6Swillf     krb5_princ_set_realm_data(util_context, &db_create_princ, global_params.realm);
49254925bf6Swillf     krb5_princ_set_realm_length(util_context, &db_create_princ, strlen(global_params.realm));
49354925bf6Swillf 
49454925bf6Swillf     printf(gettext("Initializing database for realm '%s'\n"), global_params.realm);
49554925bf6Swillf 
49654925bf6Swillf     if (!mkey_password) {
49754925bf6Swillf 	unsigned int pw_size;
49854925bf6Swillf 	printf(gettext("You will be prompted for the database Master Password.\n"));
49954925bf6Swillf 	printf(gettext("It is important that you NOT FORGET this password.\n"));
50054925bf6Swillf 	fflush(stdout);
50154925bf6Swillf 
50254925bf6Swillf 	pw_size = sizeof (pw_str);
50354925bf6Swillf 	memset(pw_str, 0, pw_size);
50454925bf6Swillf 
50554925bf6Swillf 	retval = krb5_read_password(util_context, KRB5_KDC_MKEY_1, KRB5_KDC_MKEY_2,
50654925bf6Swillf 				    pw_str, &pw_size);
50754925bf6Swillf 	if (retval) {
508dd9ccd46S 	    /* Solaris Kerberos */
509dd9ccd46S 	    com_err(progname, retval, gettext("while reading master key from keyboard"));
51054925bf6Swillf 	    goto err_nomsg;
51154925bf6Swillf 	}
51254925bf6Swillf 	mkey_password = pw_str;
51354925bf6Swillf     }
51454925bf6Swillf 
51554925bf6Swillf     rparams->mkey.enctype = global_params.enctype;
51654925bf6Swillf     /* We are sure that 'mkey_password' is a regular string ... */
51754925bf6Swillf     rparams->mkey.length = strlen(mkey_password) + 1;
51854925bf6Swillf     rparams->mkey.contents = (krb5_octet *)strdup(mkey_password);
51954925bf6Swillf     if (rparams->mkey.contents == NULL) {
52054925bf6Swillf 	retval = ENOMEM;
52154925bf6Swillf 	goto cleanup;
52254925bf6Swillf     }
52354925bf6Swillf 
52454925bf6Swillf     rparams->realm_name = strdup(global_params.realm);
52554925bf6Swillf     if (rparams->realm_name == NULL) {
52654925bf6Swillf 	retval = ENOMEM;
527dd9ccd46S 	/* Solaris Kerberos */
528dd9ccd46S 	com_err(progname, ENOMEM, gettext("while creating realm '%s'"),
52954925bf6Swillf 		global_params.realm);
53054925bf6Swillf 	goto err_nomsg;
53154925bf6Swillf     }
53254925bf6Swillf 
53354925bf6Swillf     dal_handle = (kdb5_dal_handle *) util_context->db_context;
53454925bf6Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
53554925bf6Swillf     if (!ldap_context) {
53654925bf6Swillf 	retval = EINVAL;
53754925bf6Swillf 	goto cleanup;
53854925bf6Swillf     }
53954925bf6Swillf 
54054925bf6Swillf     /* read the kerberos container */
54154925bf6Swillf     if ((retval=krb5_ldap_read_krbcontainer_params (util_context,
54254925bf6Swillf 						    &(ldap_context->krbcontainer))) == KRB5_KDB_NOENTRY) {
54354925bf6Swillf 	/* Prompt the user for entering the DN of Kerberos container */
54454925bf6Swillf 	char krb_location[MAX_KRB_CONTAINER_LEN];
54554925bf6Swillf 	krb5_ldap_krbcontainer_params kparams;
54654925bf6Swillf 	int krb_location_len = 0;
54754925bf6Swillf 	memset(&kparams, 0, sizeof(kparams));
54854925bf6Swillf 
54954925bf6Swillf 	/* Read the kerberos container location from configuration file */
55054925bf6Swillf 	if (ldap_context->conf_section) {
55154925bf6Swillf 	    if ((retval=profile_get_string(util_context->profile,
55254925bf6Swillf 					   KDB_MODULE_SECTION, ldap_context->conf_section,
55354925bf6Swillf 					   "ldap_kerberos_container_dn", NULL,
55454925bf6Swillf 					   &kparams.DN)) != 0) {
55554925bf6Swillf 		goto cleanup;
55654925bf6Swillf 	    }
55754925bf6Swillf 	}
55854925bf6Swillf 	if (kparams.DN == NULL) {
55954925bf6Swillf 	    if ((retval=profile_get_string(util_context->profile,
56054925bf6Swillf 					   KDB_MODULE_DEF_SECTION,
56154925bf6Swillf 					   "ldap_kerberos_container_dn", NULL,
56254925bf6Swillf 					   NULL, &kparams.DN)) != 0) {
56354925bf6Swillf 		goto cleanup;
56454925bf6Swillf 	    }
56554925bf6Swillf 	}
56654925bf6Swillf 
56754925bf6Swillf 	printf(gettext("\nKerberos container is missing. Creating now...\n"));
56854925bf6Swillf 	if (kparams.DN == NULL) {
56954925bf6Swillf #ifdef HAVE_EDIRECTORY
57054925bf6Swillf 	    printf(gettext("Enter DN of Kerberos container [cn=Kerberos,cn=Security]: "));
57154925bf6Swillf #else
57254925bf6Swillf 	    printf(gettext("Enter DN of Kerberos container: "));
57354925bf6Swillf #endif
57454925bf6Swillf 	    if (fgets(krb_location, MAX_KRB_CONTAINER_LEN, stdin) != NULL) {
57554925bf6Swillf 		/* Remove the newline character at the end */
57654925bf6Swillf 		krb_location_len = strlen(krb_location);
57754925bf6Swillf 		if ((krb_location[krb_location_len - 1] == '\n') ||
57854925bf6Swillf 		    (krb_location[krb_location_len - 1] == '\r')) {
57954925bf6Swillf 		    krb_location[krb_location_len - 1] = '\0';
58054925bf6Swillf 		    krb_location_len--;
58154925bf6Swillf 		}
58254925bf6Swillf 		/* If the user has not given any input, take the default location */
58354925bf6Swillf 		else if (krb_location[0] == '\0')
58454925bf6Swillf 		    kparams.DN = NULL;
58554925bf6Swillf 		else
58654925bf6Swillf 		    kparams.DN = krb_location;
58754925bf6Swillf 	    } else
58854925bf6Swillf 		kparams.DN = NULL;
58954925bf6Swillf 	}
59054925bf6Swillf 
59154925bf6Swillf 	/* create the kerberos container */
59254925bf6Swillf 	retval = krb5_ldap_create_krbcontainer(util_context,
59354925bf6Swillf 					       ((kparams.DN != NULL) ? &kparams : NULL));
59454925bf6Swillf 	if (retval)
59554925bf6Swillf 	    goto cleanup;
59654925bf6Swillf 
59754925bf6Swillf 	retval = krb5_ldap_read_krbcontainer_params(util_context,
59854925bf6Swillf 						    &(ldap_context->krbcontainer));
59954925bf6Swillf 	if (retval) {
600dd9ccd46S 	    /* Solaris Kerberos */
601dd9ccd46S 	    com_err(progname, retval, gettext("while reading kerberos container information"));
60254925bf6Swillf 	    goto cleanup;
60354925bf6Swillf 	}
60454925bf6Swillf     } else if (retval) {
605dd9ccd46S 	/* Solaris Kerberos */
606dd9ccd46S 	com_err(progname, retval, gettext("while reading kerberos container information"));
60754925bf6Swillf 	goto cleanup;
60854925bf6Swillf     }
60954925bf6Swillf 
61054925bf6Swillf     if ((retval = krb5_ldap_create_realm(util_context,
61154925bf6Swillf 					 /* global_params.realm, */ rparams, mask))) {
61254925bf6Swillf 	goto cleanup;
61354925bf6Swillf     }
61454925bf6Swillf 
61554925bf6Swillf     /* We just created the Realm container. Here starts our transaction tracking */
61654925bf6Swillf     realm_obj_created = TRUE;
61754925bf6Swillf 
61854925bf6Swillf     if ((retval = krb5_ldap_read_realm_params(util_context,
61954925bf6Swillf 					      global_params.realm,
62054925bf6Swillf 					      &(ldap_context->lrparams),
62154925bf6Swillf 					      &mask))) {
622dd9ccd46S 	/* Solaris Kerberos */
623dd9ccd46S 	com_err(progname, retval, gettext("while reading information of realm '%s'"),
62454925bf6Swillf 		global_params.realm);
62554925bf6Swillf 	goto err_nomsg;
62654925bf6Swillf     }
62754925bf6Swillf     ldap_context->lrparams->realm_name = strdup(global_params.realm);
62854925bf6Swillf     if (ldap_context->lrparams->realm_name == NULL) {
62954925bf6Swillf 	retval = ENOMEM;
63054925bf6Swillf 	goto cleanup;
63154925bf6Swillf     }
63254925bf6Swillf 
63354925bf6Swillf     /* assemble & parse the master key name */
63454925bf6Swillf     if ((retval = krb5_db_setup_mkey_name(util_context,
63554925bf6Swillf 					  global_params.mkey_name,
63654925bf6Swillf 					  global_params.realm,
63754925bf6Swillf 					  0, &master_princ))) {
638dd9ccd46S 	/* Solaris Kerberos */
639dd9ccd46S 	com_err(progname, retval, gettext("while setting up master key name"));
64054925bf6Swillf 	goto err_nomsg;
64154925bf6Swillf     }
64254925bf6Swillf 
64354925bf6Swillf     /* Obtain master key from master password */
64454925bf6Swillf     {
64554925bf6Swillf 	krb5_data master_salt, pwd;
64654925bf6Swillf 
64754925bf6Swillf 	pwd.data = mkey_password;
64854925bf6Swillf 	pwd.length = strlen(mkey_password);
64954925bf6Swillf 	retval = krb5_principal2salt(util_context, master_princ, &master_salt);
65054925bf6Swillf 	if (retval) {
651dd9ccd46S 	    /* Solaris Kerberos */
652dd9ccd46S 	    com_err(progname, retval, gettext("while calculating master key salt"));
65354925bf6Swillf 	    goto err_nomsg;
65454925bf6Swillf 	}
65554925bf6Swillf 
65654925bf6Swillf 	retval = krb5_c_string_to_key(util_context, rparams->mkey.enctype,
65754925bf6Swillf 				      &pwd, &master_salt, &master_keyblock);
65854925bf6Swillf 
65954925bf6Swillf 	if (master_salt.data)
66054925bf6Swillf 	    free(master_salt.data);
66154925bf6Swillf 
66254925bf6Swillf 	if (retval) {
663dd9ccd46S 	    /* Solaris Kerberos */
664dd9ccd46S 	    com_err(progname, retval, gettext("while transforming master key from password"));
66554925bf6Swillf 	    goto err_nomsg;
66654925bf6Swillf 	}
66754925bf6Swillf 
66854925bf6Swillf     }
66954925bf6Swillf 
67054925bf6Swillf     rblock.key = &master_keyblock;
67154925bf6Swillf     ldap_context->lrparams->mkey = master_keyblock;
67254925bf6Swillf     ldap_context->lrparams->mkey.contents = (krb5_octet *) malloc
67354925bf6Swillf 	(master_keyblock.length);
67454925bf6Swillf     if (ldap_context->lrparams->mkey.contents == NULL) {
67554925bf6Swillf 	retval = ENOMEM;
67654925bf6Swillf 	goto cleanup;
67754925bf6Swillf     }
67854925bf6Swillf     memcpy (ldap_context->lrparams->mkey.contents, master_keyblock.contents,
67954925bf6Swillf 	    master_keyblock.length);
68054925bf6Swillf 
68154925bf6Swillf     /* Create special principals inside the realm subtree */
68254925bf6Swillf     {
68354925bf6Swillf 	char princ_name[MAX_PRINC_SIZE];
68454925bf6Swillf 	krb5_principal_data tgt_princ = {
68554925bf6Swillf 	    0,					/* magic number */
68654925bf6Swillf 	    {0, 0, 0},				/* krb5_data realm */
68754925bf6Swillf 	    tgt_princ_entries,			/* krb5_data *data */
68854925bf6Swillf 	    2,					/* int length */
68954925bf6Swillf 	    KRB5_NT_SRV_INST			/* int type */
69054925bf6Swillf 	};
69154925bf6Swillf 	krb5_principal p, temp_p=NULL;
69254925bf6Swillf 
69354925bf6Swillf 	krb5_princ_set_realm_data(util_context, &tgt_princ, global_params.realm);
69454925bf6Swillf 	krb5_princ_set_realm_length(util_context, &tgt_princ, strlen(global_params.realm));
69554925bf6Swillf 	krb5_princ_component(util_context, &tgt_princ,1)->data = global_params.realm;
69654925bf6Swillf 	krb5_princ_component(util_context, &tgt_princ,1)->length = strlen(global_params.realm);
69754925bf6Swillf 	/* The container reference value is set to NULL, to avoid service principals
69854925bf6Swillf 	 * getting created within the container reference at realm creation */
69954925bf6Swillf 	if (ldap_context->lrparams->containerref != NULL) {
70054925bf6Swillf 	    oldcontainerref = ldap_context->lrparams->containerref;
70154925bf6Swillf 	    ldap_context->lrparams->containerref = NULL;
70254925bf6Swillf 	}
70354925bf6Swillf 
70454925bf6Swillf 	/* Create 'K/M' ... */
70554925bf6Swillf 	rblock.flags |= KRB5_KDB_DISALLOW_ALL_TIX;
70654925bf6Swillf 	if ((retval = kdb_ldap_create_principal(util_context, master_princ, MASTER_KEY, &rblock))) {
707dd9ccd46S 	    /* Solaris Kerberos */
708dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
70954925bf6Swillf 	    goto err_nomsg;
71054925bf6Swillf 	}
71154925bf6Swillf 
71254925bf6Swillf 	/* Create 'krbtgt' ... */
71354925bf6Swillf 	rblock.flags = 0; /* reset the flags */
71454925bf6Swillf 	if ((retval = kdb_ldap_create_principal(util_context, &tgt_princ, TGT_KEY, &rblock))) {
715dd9ccd46S 	    /* Solaris Kerberos */
716dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
71754925bf6Swillf 	    goto err_nomsg;
71854925bf6Swillf 	}
71954925bf6Swillf 	/*
72054925bf6Swillf 	 * Solaris Kerberos:
72154925bf6Swillf 	 * The kadmin/admin principal is unused on Solaris. This principal is used
72254925bf6Swillf 	 * in AUTH_GSSAPI but Solaris doesn't support AUTH_GSSAPI. RPCSEC_GSS can only
72354925bf6Swillf 	 * be used with host-based principals.
72454925bf6Swillf 	 *
72554925bf6Swillf 	 */
72654925bf6Swillf #if 0 /* ************ Begin IFDEF'ed OUT ***************************** */
72754925bf6Swillf 	/* Create 'kadmin/admin' ... */
72854925bf6Swillf 	snprintf(princ_name, sizeof(princ_name), "%s@%s", KADM5_ADMIN_SERVICE, global_params.realm);
72954925bf6Swillf 	if ((retval = krb5_parse_name(util_context, princ_name, &p))) {
730dd9ccd46S 	    /* Solaris Kerberos */
731dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
73254925bf6Swillf 	    goto err_nomsg;
73354925bf6Swillf 	}
73454925bf6Swillf 	rblock.max_life = ADMIN_LIFETIME;
73554925bf6Swillf 	rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED;
73654925bf6Swillf 	if ((retval = kdb_ldap_create_principal(util_context, p, TGT_KEY, &rblock))) {
73754925bf6Swillf 	    krb5_free_principal(util_context, p);
738dd9ccd46S 	    /* Solaris Kerberos */
739dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
74054925bf6Swillf 	    goto err_nomsg;
74154925bf6Swillf 	}
74254925bf6Swillf 	krb5_free_principal(util_context, p);
74354925bf6Swillf #endif /* ************** END IFDEF'ed OUT ***************************** */
74454925bf6Swillf 
74554925bf6Swillf 	/* Create 'kadmin/changepw' ... */
74654925bf6Swillf 	snprintf(princ_name, sizeof(princ_name), "%s@%s", KADM5_CHANGEPW_SERVICE, global_params.realm);
74754925bf6Swillf 	if ((retval = krb5_parse_name(util_context, princ_name, &p))) {
748dd9ccd46S 	    /* Solaris Kerberos */
749dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
75054925bf6Swillf 	    goto err_nomsg;
75154925bf6Swillf 	}
75254925bf6Swillf 	rblock.max_life = CHANGEPW_LIFETIME;
75354925bf6Swillf 	rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_PWCHANGE_SERVICE;
75454925bf6Swillf 	if ((retval = kdb_ldap_create_principal(util_context, p, TGT_KEY, &rblock))) {
75554925bf6Swillf 	    krb5_free_principal(util_context, p);
756dd9ccd46S 	    /* Solaris Kerberos */
757dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
75854925bf6Swillf 	    goto err_nomsg;
75954925bf6Swillf 	}
76054925bf6Swillf 	krb5_free_principal(util_context, p);
76154925bf6Swillf 
76254925bf6Swillf 	/* Create 'kadmin/history' ... */
76354925bf6Swillf 	snprintf(princ_name, sizeof(princ_name), "%s@%s", KADM5_HIST_PRINCIPAL, global_params.realm);
76454925bf6Swillf 	if ((retval = krb5_parse_name(util_context, princ_name, &p))) {
765dd9ccd46S 	    /* Solaris Kerberos */
766dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
76754925bf6Swillf 	    goto err_nomsg;
76854925bf6Swillf 	}
76954925bf6Swillf 	rblock.max_life = global_params.max_life;
77054925bf6Swillf 	rblock.flags = 0;
77154925bf6Swillf 	if ((retval = kdb_ldap_create_principal(util_context, p, TGT_KEY, &rblock))) {
77254925bf6Swillf 	    krb5_free_principal(util_context, p);
773dd9ccd46S 	    /* Solaris Kerberos */
774dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
77554925bf6Swillf 	    goto err_nomsg;
77654925bf6Swillf 	}
77754925bf6Swillf 	krb5_free_principal(util_context, p);
77854925bf6Swillf 
77954925bf6Swillf 	/* Create 'kadmin/<hostname>' ... */
78054925bf6Swillf 	if ((retval=krb5_sname_to_principal(util_context, NULL, KADM5_ADMIN_HOST_SERVICE, KRB5_NT_SRV_HST, &p))) {
781dd9ccd46S 	    /* Solaris Kerberos */
782dd9ccd46S 	    com_err(progname, retval, gettext("krb5_sname_to_principal, while adding entries to the database"));
78354925bf6Swillf 	    goto err_nomsg;
78454925bf6Swillf 	}
78554925bf6Swillf 
78654925bf6Swillf 	if ((retval=krb5_copy_principal(util_context, p, &temp_p))) {
787dd9ccd46S 	    /* Solaris Kerberos */
788dd9ccd46S 	    com_err(progname, retval, gettext("krb5_copy_principal, while adding entries to the database"));
78954925bf6Swillf 	    goto err_nomsg;
79054925bf6Swillf 	}
79154925bf6Swillf 
79254925bf6Swillf 	/* change the realm portion to the default realm */
79354925bf6Swillf 	free(temp_p->realm.data);
79454925bf6Swillf 	temp_p->realm.length = strlen(util_context->default_realm);
79554925bf6Swillf 	temp_p->realm.data = strdup(util_context->default_realm);
79654925bf6Swillf 	if (temp_p->realm.data == NULL) {
797dd9ccd46S 	    /* Solaris Kerberos */
798dd9ccd46S 	    com_err(progname, ENOMEM, gettext("while adding entries to the database"));
79954925bf6Swillf 	    goto err_nomsg;
80054925bf6Swillf 	}
80154925bf6Swillf 
80254925bf6Swillf 	rblock.max_life = ADMIN_LIFETIME;
80354925bf6Swillf 	rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED;
80454925bf6Swillf 	if ((retval = kdb_ldap_create_principal(util_context, temp_p, TGT_KEY, &rblock))) {
80554925bf6Swillf 	    krb5_free_principal(util_context, p);
806dd9ccd46S 	    /* Solaris Kerberos */
807dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
80854925bf6Swillf 	    goto err_nomsg;
80954925bf6Swillf 	}
81054925bf6Swillf 	krb5_free_principal(util_context, temp_p);
81154925bf6Swillf 	krb5_free_principal(util_context, p);
81254925bf6Swillf 
81354925bf6Swillf 	/* Solaris Kerberos: Create 'changepw/<hostname>' ... */
81454925bf6Swillf 	if ((retval=krb5_sname_to_principal(util_context, NULL, KADM5_CHANGEPW_HOST_SERVICE, KRB5_NT_SRV_HST, &p))) {
815dd9ccd46S 	    /* Solaris Kerberos */
816dd9ccd46S 	    com_err(progname, retval, gettext("krb5_sname_to_principal, while adding entries to the database"));
81754925bf6Swillf 	    goto err_nomsg;
81854925bf6Swillf 	}
81954925bf6Swillf 
82054925bf6Swillf 	if ((retval=krb5_copy_principal(util_context, p, &temp_p))) {
821dd9ccd46S 	    /* Solaris Kerberos */
822dd9ccd46S 	    com_err(progname, retval, gettext("krb5_copy_principal, while adding entries to the database"));
82354925bf6Swillf 	    goto err_nomsg;
82454925bf6Swillf 	}
82554925bf6Swillf 
82654925bf6Swillf 	/* change the realm portion to the default realm */
82754925bf6Swillf 	free(temp_p->realm.data);
82854925bf6Swillf 	temp_p->realm.length = strlen(util_context->default_realm);
82954925bf6Swillf 	temp_p->realm.data = strdup(util_context->default_realm);
83054925bf6Swillf 	if (temp_p->realm.data == NULL) {
831dd9ccd46S 	    /* Solaris Kerberos */
832dd9ccd46S 	    com_err(progname, ENOMEM, gettext("while adding entries to the database"));
83354925bf6Swillf 	    goto err_nomsg;
83454925bf6Swillf 	}
83554925bf6Swillf 
83654925bf6Swillf 	rblock.max_life = ADMIN_LIFETIME;
83754925bf6Swillf 	rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_PWCHANGE_SERVICE;
83854925bf6Swillf 	if ((retval = kdb_ldap_create_principal(util_context, temp_p, TGT_KEY, &rblock))) {
83954925bf6Swillf 	    krb5_free_principal(util_context, p);
840dd9ccd46S 	    /* Solaris Kerberos */
841dd9ccd46S 	    com_err(progname, retval, gettext("while adding entries to the database"));
84254925bf6Swillf 	    goto err_nomsg;
84354925bf6Swillf 	}
84454925bf6Swillf 	krb5_free_principal(util_context, temp_p);
84554925bf6Swillf 	krb5_free_principal(util_context, p);
84654925bf6Swillf 
84754925bf6Swillf 	if (oldcontainerref != NULL) {
84854925bf6Swillf 	    ldap_context->lrparams->containerref = oldcontainerref;
84954925bf6Swillf 	    oldcontainerref=NULL;
85054925bf6Swillf 	}
85154925bf6Swillf     }
85254925bf6Swillf 
85354925bf6Swillf #ifdef HAVE_EDIRECTORY
85454925bf6Swillf     if ((mask & LDAP_REALM_KDCSERVERS) || (mask & LDAP_REALM_ADMINSERVERS) ||
85554925bf6Swillf 	(mask & LDAP_REALM_PASSWDSERVERS)) {
85654925bf6Swillf 
85754925bf6Swillf 	printf(gettext("Changing rights for the service object. Please wait ... "));
85854925bf6Swillf 	fflush(stdout);
85954925bf6Swillf 
86054925bf6Swillf 	rightsmask =0;
86154925bf6Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
86254925bf6Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
86354925bf6Swillf 	if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
86454925bf6Swillf 	    for (i=0; (rparams->kdcservers[i] != NULL); i++) {
86554925bf6Swillf 		if ((retval=krb5_ldap_add_service_rights(util_context,
86654925bf6Swillf 							 LDAP_KDC_SERVICE, rparams->kdcservers[i],
86754925bf6Swillf 							 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
86854925bf6Swillf 		    printf(gettext("failed\n"));
869dd9ccd46S 		    /* Solaris Kerberos */
870dd9ccd46S 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
87154925bf6Swillf 			    rparams->realm_name);
87254925bf6Swillf 		    goto err_nomsg;
87354925bf6Swillf 		}
87454925bf6Swillf 	    }
87554925bf6Swillf 	}
87654925bf6Swillf 
87754925bf6Swillf 	rightsmask = 0;
87854925bf6Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
87954925bf6Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
88054925bf6Swillf 	if ((rparams != NULL) && (rparams->adminservers != NULL)) {
88154925bf6Swillf 	    for (i=0; (rparams->adminservers[i] != NULL); i++) {
88254925bf6Swillf 		if ((retval=krb5_ldap_add_service_rights(util_context,
88354925bf6Swillf 							 LDAP_ADMIN_SERVICE, rparams->adminservers[i],
88454925bf6Swillf 							 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
88554925bf6Swillf 		    printf(gettext("failed\n"));
886dd9ccd46S 		    /* Solaris Kerberos */
887dd9ccd46S 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
88854925bf6Swillf 			    rparams->realm_name);
88954925bf6Swillf 		    goto err_nomsg;
89054925bf6Swillf 		}
89154925bf6Swillf 	    }
89254925bf6Swillf 	}
89354925bf6Swillf 
89454925bf6Swillf 	rightsmask = 0;
89554925bf6Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
89654925bf6Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
89754925bf6Swillf 	if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
89854925bf6Swillf 	    for (i=0; (rparams->passwdservers[i] != NULL); i++) {
89954925bf6Swillf 		if ((retval=krb5_ldap_add_service_rights(util_context,
90054925bf6Swillf 							 LDAP_PASSWD_SERVICE, rparams->passwdservers[i],
90154925bf6Swillf 							 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
90254925bf6Swillf 		    printf(gettext("failed\n"));
903dd9ccd46S 		    /* Solaris Kerberos */
904dd9ccd46S 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
90554925bf6Swillf 			    rparams->realm_name);
90654925bf6Swillf 		    goto err_nomsg;
90754925bf6Swillf 		}
90854925bf6Swillf 	    }
90954925bf6Swillf 	}
91054925bf6Swillf 
91154925bf6Swillf 	printf(gettext("done\n"));
91254925bf6Swillf     }
91354925bf6Swillf #endif
91454925bf6Swillf     /* The Realm creation is completed. Here is the end of transaction */
91554925bf6Swillf     create_complete = TRUE;
91654925bf6Swillf 
91754925bf6Swillf     /* Stash the master key only if '-s' option is specified */
91854925bf6Swillf     if (do_stash || global_params.mask & KADM5_CONFIG_STASH_FILE) {
91954925bf6Swillf 	retval = krb5_def_store_mkey(util_context,
92054925bf6Swillf 				     global_params.stash_file,
92154925bf6Swillf 				     master_princ,
92254925bf6Swillf 				     &master_keyblock, NULL);
92354925bf6Swillf 	if (retval) {
924dd9ccd46S 	    /* Solaris Kerberos */
925dd9ccd46S 	    com_err(progname, errno, gettext("while storing key"));
92654925bf6Swillf 	    printf(gettext("Warning: couldn't stash master key.\n"));
92754925bf6Swillf 	}
92854925bf6Swillf     }
92954925bf6Swillf 
93054925bf6Swillf     goto cleanup;
93154925bf6Swillf 
93254925bf6Swillf 
93354925bf6Swillf err_usage:
93454925bf6Swillf     print_usage = TRUE;
93554925bf6Swillf 
93654925bf6Swillf err_nomsg:
93754925bf6Swillf     no_msg = TRUE;
93854925bf6Swillf 
93954925bf6Swillf cleanup:
94054925bf6Swillf     /* If the Realm creation is not complete, do the roll-back here */
94154925bf6Swillf     if ((realm_obj_created) && (!create_complete))
94254925bf6Swillf 	krb5_ldap_delete_realm(util_context, global_params.realm);
94354925bf6Swillf 
94454925bf6Swillf     if (rparams)
94554925bf6Swillf 	krb5_ldap_free_realm_params(rparams);
94654925bf6Swillf 
94754925bf6Swillf     memset (pw_str, 0, sizeof (pw_str));
94854925bf6Swillf 
94954925bf6Swillf     if (print_usage)
95054925bf6Swillf 	db_usage(CREATE_REALM);
95154925bf6Swillf 
95254925bf6Swillf     if (retval) {
95354925bf6Swillf 	if (!no_msg) {
954dd9ccd46S 	    /* Solaris Kerberos */
955dd9ccd46S 	    com_err(progname, retval, gettext("while creating realm '%s'"),
95654925bf6Swillf 		    global_params.realm);
95754925bf6Swillf 	}
95854925bf6Swillf 	exit_status++;
95954925bf6Swillf     }
96054925bf6Swillf 
96154925bf6Swillf     return;
96254925bf6Swillf }
96354925bf6Swillf 
96454925bf6Swillf 
96554925bf6Swillf /*
96654925bf6Swillf  * This function will modify the attributes of a given realm object
96754925bf6Swillf  */
96854925bf6Swillf void kdb5_ldap_modify(argc, argv)
96954925bf6Swillf     int argc;
97054925bf6Swillf     char *argv[];
97154925bf6Swillf {
97254925bf6Swillf     krb5_error_code retval = 0;
97354925bf6Swillf     krb5_ldap_realm_params *rparams = NULL;
97454925bf6Swillf     krb5_boolean print_usage = FALSE;
97554925bf6Swillf     krb5_boolean no_msg = FALSE;
97654925bf6Swillf     kdb5_dal_handle *dal_handle = NULL;
97754925bf6Swillf     krb5_ldap_context *ldap_context=NULL;
97854925bf6Swillf     int i = 0;
97954925bf6Swillf     int mask = 0, rmask = 0, ret_mask = 0;
98054925bf6Swillf     char **slist = {NULL};
98154925bf6Swillf #ifdef HAVE_EDIRECTORY
98254925bf6Swillf     int j = 0;
98354925bf6Swillf     char *list[MAX_LIST_ENTRIES];
98454925bf6Swillf     int existing_entries = 0, list_entries = 0;
98554925bf6Swillf     int newkdcdn = 0, newadmindn = 0, newpwddn = 0;
98654925bf6Swillf     char **tempstr = NULL;
98754925bf6Swillf     char **oldkdcdns = NULL;
98854925bf6Swillf     char **oldadmindns = NULL;
98954925bf6Swillf     char **oldpwddns = NULL;
99054925bf6Swillf     char **newkdcdns = NULL;
99154925bf6Swillf     char **newsubtrees = NULL;
99254925bf6Swillf     char **newadmindns = NULL;
99354925bf6Swillf     char **newpwddns = NULL;
99454925bf6Swillf     char **oldsubtrees = {NULL};
99554925bf6Swillf     int rightsmask = 0;
99654925bf6Swillf     int subtree_changed = 0;
99754925bf6Swillf #endif
99854925bf6Swillf 
99954925bf6Swillf     dal_handle = (kdb5_dal_handle *) util_context->db_context;
100054925bf6Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
100154925bf6Swillf     if (!(ldap_context)) {
100254925bf6Swillf 	retval = EINVAL;
100354925bf6Swillf 	goto cleanup;
100454925bf6Swillf     }
100554925bf6Swillf 
100654925bf6Swillf     if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
100754925bf6Swillf 						     &(ldap_context->krbcontainer)))) {
1008dd9ccd46S 	/* Solaris Kerberos */
1009dd9ccd46S 	com_err(progname, retval, gettext("while reading Kerberos container information"));
101054925bf6Swillf 	goto err_nomsg;
101154925bf6Swillf     }
101254925bf6Swillf 
101354925bf6Swillf     retval = krb5_ldap_read_realm_params(util_context,
101454925bf6Swillf 					 global_params.realm, &rparams, &rmask);
101554925bf6Swillf     if (retval)
101654925bf6Swillf 	goto cleanup;
101754925bf6Swillf     /* Parse the arguments */
101854925bf6Swillf     for (i = 1; i < argc; i++) {
101954925bf6Swillf 	int k = 0;
102054925bf6Swillf 	if (!strcmp(argv[i], "-subtrees")) {
102154925bf6Swillf 	    if (++i > argc-1)
102254925bf6Swillf 		goto err_usage;
102354925bf6Swillf 
102454925bf6Swillf 	    if (rmask & LDAP_REALM_SUBTREE) {
102554925bf6Swillf 		if (rparams->subtree) {
102654925bf6Swillf #ifdef HAVE_EDIRECTORY
102754925bf6Swillf 		    oldsubtrees =  (char **) calloc(rparams->subtreecount+1, sizeof(char *));
102854925bf6Swillf 		    if (oldsubtrees == NULL) {
102954925bf6Swillf 			retval = ENOMEM;
103054925bf6Swillf 			goto cleanup;
103154925bf6Swillf 		    }
103254925bf6Swillf 		    for(k=0; rparams->subtree[k]!=NULL && rparams->subtreecount; k++) {
103354925bf6Swillf 			oldsubtrees[k] = strdup(rparams->subtree[k]);
103454925bf6Swillf 			if( oldsubtrees[k] == NULL ) {
103554925bf6Swillf 			    retval = ENOMEM;
103654925bf6Swillf 			    goto cleanup;
103754925bf6Swillf 			}
103854925bf6Swillf 		    }
103954925bf6Swillf #endif
104054925bf6Swillf 		    for(k=0; k<rparams->subtreecount && rparams->subtree[k]; k++)
104154925bf6Swillf 			free(rparams->subtree[k]);
104254925bf6Swillf 		    rparams->subtreecount=0;
104354925bf6Swillf 		}
104454925bf6Swillf 	    }
104554925bf6Swillf 	    if (strncmp(argv[i] ,"", strlen(argv[i]))!=0) {
104654925bf6Swillf 		slist =  (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *));
104754925bf6Swillf 		if (slist == NULL) {
104854925bf6Swillf 		    retval = ENOMEM;
104954925bf6Swillf 		    goto cleanup;
105054925bf6Swillf 		}
105154925bf6Swillf 		if (( retval = krb5_parse_list(argv[i], LIST_DELIMITER, slist))) {
105254925bf6Swillf 		    free(slist);
105354925bf6Swillf 		    slist = NULL;
105454925bf6Swillf 		    goto cleanup;
105554925bf6Swillf 		}
105654925bf6Swillf 
105754925bf6Swillf 		rparams->subtreecount=0;
105854925bf6Swillf 		while(slist[rparams->subtreecount]!=NULL)
105954925bf6Swillf 		    (rparams->subtreecount)++;
106054925bf6Swillf 		rparams->subtree =  slist;
106154925bf6Swillf 	    } else if(strncmp(argv[i], "", strlen(argv[i]))==0) {
106254925bf6Swillf 		 /* dont allow subtree value to be set at the root(NULL, "") of the tree */
1063dd9ccd46S 		    /* Solaris Kerberos */
1064dd9ccd46S 		    com_err(progname, EINVAL,
106554925bf6Swillf 			    gettext("for subtree while modifying realm '%s'"),
106654925bf6Swillf 			    global_params.realm);
106754925bf6Swillf 		    goto err_nomsg;
106854925bf6Swillf 	    }
106954925bf6Swillf 	    rparams->subtree[rparams->subtreecount] = NULL;
107054925bf6Swillf 	    mask |= LDAP_REALM_SUBTREE;
107154925bf6Swillf 	} else if (!strncmp(argv[i], "-containerref", strlen(argv[i]))) {
107254925bf6Swillf 	    if (++i > argc-1)
107354925bf6Swillf 		goto err_usage;
107454925bf6Swillf 	    if(strncmp(argv[i], "", strlen(argv[i]))==0) {
107554925bf6Swillf 		 /* dont allow containerref value to be set at the root(NULL, "") of the tree */
1076dd9ccd46S 		 /* Solaris Kerberos */
1077dd9ccd46S 		 com_err(progname, EINVAL,
107854925bf6Swillf 			  gettext("for container reference while modifying realm '%s'"),
107954925bf6Swillf 			   global_params.realm);
108054925bf6Swillf 		 goto err_nomsg;
108154925bf6Swillf 	    }
108254925bf6Swillf 	    rparams->containerref = strdup(argv[i]);
108354925bf6Swillf 	    if (rparams->containerref == NULL) {
108454925bf6Swillf 		retval = ENOMEM;
108554925bf6Swillf 		goto cleanup;
108654925bf6Swillf 	    }
108754925bf6Swillf 	    mask |= LDAP_REALM_CONTREF;
108854925bf6Swillf 	} else if (!strcmp(argv[i], "-sscope")) {
108954925bf6Swillf 	    if (++i > argc-1)
109054925bf6Swillf 		goto err_usage;
109154925bf6Swillf 	    /* Possible values for search scope are
109254925bf6Swillf 	     * one (or 1) and sub (or 2)
109354925bf6Swillf 	     */
109454925bf6Swillf 	    if (strcasecmp(argv[i], "one") == 0) {
109554925bf6Swillf 		rparams->search_scope = 1;
109654925bf6Swillf 	    } else if (strcasecmp(argv[i], "sub") == 0) {
109754925bf6Swillf 		rparams->search_scope = 2;
109854925bf6Swillf 	    } else {
109954925bf6Swillf 		rparams->search_scope = atoi(argv[i]);
110054925bf6Swillf 		if ((rparams->search_scope != 1) &&
110154925bf6Swillf 		    (rparams->search_scope != 2)) {
110254925bf6Swillf 		    retval = EINVAL;
1103dd9ccd46S 		    /* Solaris Kerberos */
1104dd9ccd46S 		    com_err(progname, retval,
110554925bf6Swillf 			    gettext("specified for search scope while modifying information of realm '%s'"),
110654925bf6Swillf 			    global_params.realm);
110754925bf6Swillf 		    goto err_nomsg;
110854925bf6Swillf 		}
110954925bf6Swillf 	    }
111054925bf6Swillf 	    mask |= LDAP_REALM_SEARCHSCOPE;
111154925bf6Swillf 	}
111254925bf6Swillf #ifdef HAVE_EDIRECTORY
111354925bf6Swillf 	else if (!strcmp(argv[i], "-kdcdn")) {
111454925bf6Swillf 	    if (++i > argc-1)
111554925bf6Swillf 		goto err_usage;
111654925bf6Swillf 
111754925bf6Swillf 	    if ((rmask & LDAP_REALM_KDCSERVERS) && (rparams->kdcservers)) {
111854925bf6Swillf 		if (!oldkdcdns) {
111954925bf6Swillf 		    /* Store the old kdc dns list for removing rights */
112054925bf6Swillf 		    oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
112154925bf6Swillf 		    if (oldkdcdns == NULL) {
112254925bf6Swillf 			retval = ENOMEM;
112354925bf6Swillf 			goto cleanup;
112454925bf6Swillf 		    }
112554925bf6Swillf 
112654925bf6Swillf 		    for (j=0; rparams->kdcservers[j] != NULL; j++) {
112754925bf6Swillf 			oldkdcdns[j] = strdup(rparams->kdcservers[j]);
112854925bf6Swillf 			if (oldkdcdns[j] == NULL) {
112954925bf6Swillf 			    retval = ENOMEM;
113054925bf6Swillf 			    goto cleanup;
113154925bf6Swillf 			}
113254925bf6Swillf 		    }
113354925bf6Swillf 		    oldkdcdns[j] = NULL;
113454925bf6Swillf 		}
113554925bf6Swillf 
113654925bf6Swillf 		krb5_free_list_entries(rparams->kdcservers);
113754925bf6Swillf 		free(rparams->kdcservers);
113854925bf6Swillf 	    }
113954925bf6Swillf 
114054925bf6Swillf 	    rparams->kdcservers = (char **)malloc(
114154925bf6Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
114254925bf6Swillf 	    if (rparams->kdcservers == NULL) {
114354925bf6Swillf 		retval = ENOMEM;
114454925bf6Swillf 		goto cleanup;
114554925bf6Swillf 	    }
114654925bf6Swillf 	    memset(rparams->kdcservers, 0, sizeof(char *)*MAX_LIST_ENTRIES);
114754925bf6Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
114854925bf6Swillf 					  rparams->kdcservers))) {
114954925bf6Swillf 		goto cleanup;
115054925bf6Swillf 	    }
115154925bf6Swillf 	    mask |= LDAP_REALM_KDCSERVERS;
115254925bf6Swillf 	    /* Going to replace the existing value by this new value. Hence
115354925bf6Swillf 	     * setting flag indicating that add or clear options will be ignored
115454925bf6Swillf 	     */
115554925bf6Swillf 	    newkdcdn = 1;
115654925bf6Swillf 	} else if (!strcmp(argv[i], "-clearkdcdn")) {
115754925bf6Swillf 	    if (++i > argc-1)
115854925bf6Swillf 		goto err_usage;
115954925bf6Swillf 	    if ((!newkdcdn) && (rmask & LDAP_REALM_KDCSERVERS) && (rparams->kdcservers)) {
116054925bf6Swillf 		if (!oldkdcdns) {
116154925bf6Swillf 		    /* Store the old kdc dns list for removing rights */
116254925bf6Swillf 		    oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
116354925bf6Swillf 		    if (oldkdcdns == NULL) {
116454925bf6Swillf 			retval = ENOMEM;
116554925bf6Swillf 			goto cleanup;
116654925bf6Swillf 		    }
116754925bf6Swillf 
116854925bf6Swillf 		    for (j=0; rparams->kdcservers[j] != NULL; j++) {
116954925bf6Swillf 			oldkdcdns[j] = strdup(rparams->kdcservers[j]);
117054925bf6Swillf 			if (oldkdcdns[j] == NULL) {
117154925bf6Swillf 			    retval = ENOMEM;
117254925bf6Swillf 			    goto cleanup;
117354925bf6Swillf 			}
117454925bf6Swillf 		    }
117554925bf6Swillf 		    oldkdcdns[j] = NULL;
117654925bf6Swillf 		}
117754925bf6Swillf 
117854925bf6Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
117954925bf6Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
118054925bf6Swillf 		    goto cleanup;
118154925bf6Swillf 		}
118254925bf6Swillf 		list_modify_str_array(&rparams->kdcservers, (const char **)list,
118354925bf6Swillf 				      LIST_MODE_DELETE);
118454925bf6Swillf 		mask |= LDAP_REALM_KDCSERVERS;
118554925bf6Swillf 		krb5_free_list_entries(list);
118654925bf6Swillf 	    }
118754925bf6Swillf 	} else if (!strcmp(argv[i], "-addkdcdn")) {
118854925bf6Swillf 	    if (++i > argc-1)
118954925bf6Swillf 		goto err_usage;
119054925bf6Swillf 	    if (!newkdcdn) {
119154925bf6Swillf 		if ((rmask & LDAP_REALM_KDCSERVERS) && (rparams->kdcservers) && (!oldkdcdns)) {
119254925bf6Swillf 		    /* Store the old kdc dns list for removing rights */
119354925bf6Swillf 		    oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
119454925bf6Swillf 		    if (oldkdcdns == NULL) {
119554925bf6Swillf 			retval = ENOMEM;
119654925bf6Swillf 			goto cleanup;
119754925bf6Swillf 		    }
119854925bf6Swillf 
119954925bf6Swillf 		    for (j = 0; rparams->kdcservers[j] != NULL; j++) {
120054925bf6Swillf 			oldkdcdns[j] = strdup(rparams->kdcservers[j]);
120154925bf6Swillf 			if (oldkdcdns[j] == NULL) {
120254925bf6Swillf 			    retval = ENOMEM;
120354925bf6Swillf 			    goto cleanup;
120454925bf6Swillf 			}
120554925bf6Swillf 		    }
120654925bf6Swillf 		    oldkdcdns[j] = NULL;
120754925bf6Swillf 		}
120854925bf6Swillf 
120954925bf6Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
121054925bf6Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
121154925bf6Swillf 		    goto cleanup;
121254925bf6Swillf 		}
121354925bf6Swillf 		existing_entries = list_count_str_array(rparams->kdcservers);
121454925bf6Swillf 		list_entries = list_count_str_array(list);
121554925bf6Swillf 		if (rmask & LDAP_REALM_KDCSERVERS) {
121654925bf6Swillf 		    tempstr = (char **)realloc(
121754925bf6Swillf 			rparams->kdcservers,
121854925bf6Swillf 			sizeof(char *) * (existing_entries+list_entries+1));
121954925bf6Swillf 		    if (tempstr == NULL) {
122054925bf6Swillf 			retval = ENOMEM;
122154925bf6Swillf 			goto cleanup;
122254925bf6Swillf 		    }
122354925bf6Swillf 		    rparams->kdcservers = tempstr;
122454925bf6Swillf 		} else {
122554925bf6Swillf 		    rparams->kdcservers = (char **)malloc(sizeof(char *) * (list_entries+1));
122654925bf6Swillf 		    if (rparams->kdcservers == NULL) {
122754925bf6Swillf 			retval = ENOMEM;
122854925bf6Swillf 			goto cleanup;
122954925bf6Swillf 		    }
123054925bf6Swillf 		    memset(rparams->kdcservers, 0, sizeof(char *) * (list_entries+1));
123154925bf6Swillf 		}
123254925bf6Swillf 		list_modify_str_array(&rparams->kdcservers, (const char **)list,
123354925bf6Swillf 				      LIST_MODE_ADD);
123454925bf6Swillf 		mask |= LDAP_REALM_KDCSERVERS;
123554925bf6Swillf 	    }
123654925bf6Swillf 	} else if (!strcmp(argv[i], "-admindn")) {
123754925bf6Swillf 	    if (++i > argc-1)
123854925bf6Swillf 		goto err_usage;
123954925bf6Swillf 
124054925bf6Swillf 	    if ((rmask & LDAP_REALM_ADMINSERVERS) && (rparams->adminservers)) {
124154925bf6Swillf 		if (!oldadmindns) {
124254925bf6Swillf 		    /* Store the old admin dns list for removing rights */
124354925bf6Swillf 		    oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
124454925bf6Swillf 		    if (oldadmindns == NULL) {
124554925bf6Swillf 			retval = ENOMEM;
124654925bf6Swillf 			goto cleanup;
124754925bf6Swillf 		    }
124854925bf6Swillf 
124954925bf6Swillf 		    for (j=0; rparams->adminservers[j] != NULL; j++) {
125054925bf6Swillf 			oldadmindns[j] = strdup(rparams->adminservers[j]);
125154925bf6Swillf 			if (oldadmindns[j] == NULL) {
125254925bf6Swillf 			    retval = ENOMEM;
125354925bf6Swillf 			    goto cleanup;
125454925bf6Swillf 			}
125554925bf6Swillf 		    }
125654925bf6Swillf 		    oldadmindns[j] = NULL;
125754925bf6Swillf 		}
125854925bf6Swillf 
125954925bf6Swillf 		krb5_free_list_entries(rparams->adminservers);
126054925bf6Swillf 		free(rparams->adminservers);
126154925bf6Swillf 	    }
126254925bf6Swillf 
126354925bf6Swillf 	    rparams->adminservers = (char **)malloc(
126454925bf6Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
126554925bf6Swillf 	    if (rparams->adminservers == NULL) {
126654925bf6Swillf 		retval = ENOMEM;
126754925bf6Swillf 		goto cleanup;
126854925bf6Swillf 	    }
126954925bf6Swillf 	    memset(rparams->adminservers, 0, sizeof(char *)*MAX_LIST_ENTRIES);
127054925bf6Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
127154925bf6Swillf 					  rparams->adminservers))) {
127254925bf6Swillf 		goto cleanup;
127354925bf6Swillf 	    }
127454925bf6Swillf 	    mask |= LDAP_REALM_ADMINSERVERS;
127554925bf6Swillf 	    /* Going to replace the existing value by this new value. Hence
127654925bf6Swillf 	     * setting flag indicating that add or clear options will be ignored
127754925bf6Swillf 	     */
127854925bf6Swillf 	    newadmindn = 1;
127954925bf6Swillf 	} else if (!strcmp(argv[i], "-clearadmindn")) {
128054925bf6Swillf 	    if (++i > argc-1)
128154925bf6Swillf 		goto err_usage;
128254925bf6Swillf 
128354925bf6Swillf 	    if ((!newadmindn) && (rmask & LDAP_REALM_ADMINSERVERS) && (rparams->adminservers)) {
128454925bf6Swillf 		if (!oldadmindns) {
128554925bf6Swillf 		    /* Store the old admin dns list for removing rights */
128654925bf6Swillf 		    oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
128754925bf6Swillf 		    if (oldadmindns == NULL) {
128854925bf6Swillf 			retval = ENOMEM;
128954925bf6Swillf 			goto cleanup;
129054925bf6Swillf 		    }
129154925bf6Swillf 
129254925bf6Swillf 		    for (j=0; rparams->adminservers[j] != NULL; j++) {
129354925bf6Swillf 			oldadmindns[j] = strdup(rparams->adminservers[j]);
129454925bf6Swillf 			if (oldadmindns[j] == NULL) {
129554925bf6Swillf 			    retval = ENOMEM;
129654925bf6Swillf 			    goto cleanup;
129754925bf6Swillf 			}
129854925bf6Swillf 		    }
129954925bf6Swillf 		    oldadmindns[j] = NULL;
130054925bf6Swillf 		}
130154925bf6Swillf 
130254925bf6Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
130354925bf6Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
130454925bf6Swillf 		    goto cleanup;
130554925bf6Swillf 		}
130654925bf6Swillf 		list_modify_str_array(&rparams->adminservers, (const char **)list,
130754925bf6Swillf 				      LIST_MODE_DELETE);
130854925bf6Swillf 		mask |= LDAP_REALM_ADMINSERVERS;
130954925bf6Swillf 		krb5_free_list_entries(list);
131054925bf6Swillf 	    }
131154925bf6Swillf 	} else if (!strcmp(argv[i], "-addadmindn")) {
131254925bf6Swillf 	    if (++i > argc-1)
131354925bf6Swillf 		goto err_usage;
131454925bf6Swillf 	    if (!newadmindn) {
131554925bf6Swillf 		if ((rmask & LDAP_REALM_ADMINSERVERS) && (rparams->adminservers) && (!oldadmindns)) {
131654925bf6Swillf 		    /* Store the old admin dns list for removing rights */
131754925bf6Swillf 		    oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
131854925bf6Swillf 		    if (oldadmindns == NULL) {
131954925bf6Swillf 			retval = ENOMEM;
132054925bf6Swillf 			goto cleanup;
132154925bf6Swillf 		    }
132254925bf6Swillf 
132354925bf6Swillf 		    for (j=0; rparams->adminservers[j] != NULL; j++) {
132454925bf6Swillf 			oldadmindns[j] = strdup(rparams->adminservers[j]);
132554925bf6Swillf 			if (oldadmindns[j] == NULL) {
132654925bf6Swillf 			    retval = ENOMEM;
132754925bf6Swillf 			    goto cleanup;
132854925bf6Swillf 			}
132954925bf6Swillf 		    }
133054925bf6Swillf 		    oldadmindns[j] = NULL;
133154925bf6Swillf 		}
133254925bf6Swillf 
133354925bf6Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
133454925bf6Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
133554925bf6Swillf 		    goto cleanup;
133654925bf6Swillf 		}
133754925bf6Swillf 		existing_entries = list_count_str_array(rparams->adminservers);
133854925bf6Swillf 		list_entries = list_count_str_array(list);
133954925bf6Swillf 		if (rmask & LDAP_REALM_ADMINSERVERS) {
134054925bf6Swillf 		    tempstr = (char **)realloc(
134154925bf6Swillf 			rparams->adminservers,
134254925bf6Swillf 			sizeof(char *) * (existing_entries+list_entries+1));
134354925bf6Swillf 		    if (tempstr == NULL) {
134454925bf6Swillf 			retval = ENOMEM;
134554925bf6Swillf 			goto cleanup;
134654925bf6Swillf 		    }
134754925bf6Swillf 		    rparams->adminservers = tempstr;
134854925bf6Swillf 		} else {
134954925bf6Swillf 		    rparams->adminservers = (char **)malloc(sizeof(char *) * (list_entries+1));
135054925bf6Swillf 		    if (rparams->adminservers == NULL) {
135154925bf6Swillf 			retval = ENOMEM;
135254925bf6Swillf 			goto cleanup;
135354925bf6Swillf 		    }
135454925bf6Swillf 		    memset(rparams->adminservers, 0, sizeof(char *) * (list_entries+1));
135554925bf6Swillf 		}
135654925bf6Swillf 		list_modify_str_array(&rparams->adminservers, (const char **)list,
135754925bf6Swillf 				      LIST_MODE_ADD);
135854925bf6Swillf 		mask |= LDAP_REALM_ADMINSERVERS;
135954925bf6Swillf 	    }
136054925bf6Swillf 	} else if (!strcmp(argv[i], "-pwddn")) {
136154925bf6Swillf 	    if (++i > argc-1)
136254925bf6Swillf 		goto err_usage;
136354925bf6Swillf 
136454925bf6Swillf 	    if ((rmask & LDAP_REALM_PASSWDSERVERS) && (rparams->passwdservers)) {
136554925bf6Swillf 		if (!oldpwddns) {
136654925bf6Swillf 		    /* Store the old pwd dns list for removing rights */
136754925bf6Swillf 		    oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
136854925bf6Swillf 		    if (oldpwddns == NULL) {
136954925bf6Swillf 			retval = ENOMEM;
137054925bf6Swillf 			goto cleanup;
137154925bf6Swillf 		    }
137254925bf6Swillf 
137354925bf6Swillf 		    for (j=0; rparams->passwdservers[j] != NULL; j++) {
137454925bf6Swillf 			oldpwddns[j] = strdup(rparams->passwdservers[j]);
137554925bf6Swillf 			if (oldpwddns[j] == NULL) {
137654925bf6Swillf 			    retval = ENOMEM;
137754925bf6Swillf 			    goto cleanup;
137854925bf6Swillf 			}
137954925bf6Swillf 		    }
138054925bf6Swillf 		    oldpwddns[j] = NULL;
138154925bf6Swillf 		}
138254925bf6Swillf 
138354925bf6Swillf 		krb5_free_list_entries(rparams->passwdservers);
138454925bf6Swillf 		free(rparams->passwdservers);
138554925bf6Swillf 	    }
138654925bf6Swillf 
138754925bf6Swillf 	    rparams->passwdservers = (char **)malloc(
138854925bf6Swillf 		sizeof(char *) * MAX_LIST_ENTRIES);
138954925bf6Swillf 	    if (rparams->passwdservers == NULL) {
139054925bf6Swillf 		retval = ENOMEM;
139154925bf6Swillf 		goto cleanup;
139254925bf6Swillf 	    }
139354925bf6Swillf 	    memset(rparams->passwdservers, 0, sizeof(char *)*MAX_LIST_ENTRIES);
139454925bf6Swillf 	    if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
139554925bf6Swillf 					  rparams->passwdservers))) {
139654925bf6Swillf 		goto cleanup;
139754925bf6Swillf 	    }
139854925bf6Swillf 	    mask |= LDAP_REALM_PASSWDSERVERS;
139954925bf6Swillf 	    /* Going to replace the existing value by this new value. Hence
140054925bf6Swillf 	     * setting flag indicating that add or clear options will be ignored
140154925bf6Swillf 	     */
140254925bf6Swillf 	    newpwddn = 1;
140354925bf6Swillf 	} else if (!strcmp(argv[i], "-clearpwddn")) {
140454925bf6Swillf 	    if (++i > argc-1)
140554925bf6Swillf 		goto err_usage;
140654925bf6Swillf 
140754925bf6Swillf 	    if ((!newpwddn) && (rmask & LDAP_REALM_PASSWDSERVERS) && (rparams->passwdservers)) {
140854925bf6Swillf 		if (!oldpwddns) {
140954925bf6Swillf 		    /* Store the old pwd dns list for removing rights */
141054925bf6Swillf 		    oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
141154925bf6Swillf 		    if (oldpwddns == NULL) {
141254925bf6Swillf 			retval = ENOMEM;
141354925bf6Swillf 			goto cleanup;
141454925bf6Swillf 		    }
141554925bf6Swillf 
141654925bf6Swillf 		    for (j=0; rparams->passwdservers[j] != NULL; j++) {
141754925bf6Swillf 			oldpwddns[j] = strdup(rparams->passwdservers[j]);
141854925bf6Swillf 			if (oldpwddns[j] == NULL) {
141954925bf6Swillf 			    retval = ENOMEM;
142054925bf6Swillf 			    goto cleanup;
142154925bf6Swillf 			}
142254925bf6Swillf 		    }
142354925bf6Swillf 		    oldpwddns[j] = NULL;
142454925bf6Swillf 		}
142554925bf6Swillf 
142654925bf6Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
142754925bf6Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
142854925bf6Swillf 		    goto cleanup;
142954925bf6Swillf 		}
143054925bf6Swillf 		list_modify_str_array(&rparams->passwdservers, (const char**)list,
143154925bf6Swillf 				      LIST_MODE_DELETE);
143254925bf6Swillf 		mask |= LDAP_REALM_PASSWDSERVERS;
143354925bf6Swillf 		krb5_free_list_entries(list);
143454925bf6Swillf 	    }
143554925bf6Swillf 	} else if (!strcmp(argv[i], "-addpwddn")) {
143654925bf6Swillf 	    if (++i > argc-1)
143754925bf6Swillf 		goto err_usage;
143854925bf6Swillf 	    if (!newpwddn) {
143954925bf6Swillf 		if ((rmask & LDAP_REALM_PASSWDSERVERS) && (rparams->passwdservers) && (!oldpwddns)) {
144054925bf6Swillf 		    /* Store the old pwd dns list for removing rights */
144154925bf6Swillf 		    oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
144254925bf6Swillf 		    if (oldpwddns == NULL) {
144354925bf6Swillf 			retval = ENOMEM;
144454925bf6Swillf 			goto cleanup;
144554925bf6Swillf 		    }
144654925bf6Swillf 
144754925bf6Swillf 		    for (j=0; rparams->passwdservers[j] != NULL; j++) {
144854925bf6Swillf 			oldpwddns[j] = strdup(rparams->passwdservers[j]);
144954925bf6Swillf 			if (oldpwddns[j] == NULL) {
145054925bf6Swillf 			    retval = ENOMEM;
145154925bf6Swillf 			    goto cleanup;
145254925bf6Swillf 			}
145354925bf6Swillf 		    }
145454925bf6Swillf 		    oldpwddns[j] = NULL;
145554925bf6Swillf 		}
145654925bf6Swillf 
145754925bf6Swillf 		memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
145854925bf6Swillf 		if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
145954925bf6Swillf 		    goto cleanup;
146054925bf6Swillf 		}
146154925bf6Swillf 		existing_entries = list_count_str_array(rparams->passwdservers);
146254925bf6Swillf 		list_entries = list_count_str_array(list);
146354925bf6Swillf 		if (rmask & LDAP_REALM_PASSWDSERVERS) {
146454925bf6Swillf 		    tempstr = (char **)realloc(
146554925bf6Swillf 			rparams->passwdservers,
146654925bf6Swillf 			sizeof(char *) * (existing_entries+list_entries+1));
146754925bf6Swillf 		    if (tempstr == NULL) {
146854925bf6Swillf 			retval = ENOMEM;
146954925bf6Swillf 			goto cleanup;
147054925bf6Swillf 		    }
147154925bf6Swillf 		    rparams->passwdservers = tempstr;
147254925bf6Swillf 		} else {
147354925bf6Swillf 		    rparams->passwdservers = (char **)malloc(sizeof(char *) * (list_entries+1));
147454925bf6Swillf 		    if (rparams->passwdservers == NULL) {
147554925bf6Swillf 			retval = ENOMEM;
147654925bf6Swillf 			goto cleanup;
147754925bf6Swillf 		    }
147854925bf6Swillf 		    memset(rparams->passwdservers, 0, sizeof(char *) * (list_entries+1));
147954925bf6Swillf 		}
148054925bf6Swillf 		list_modify_str_array(&rparams->passwdservers, (const char**)list,
148154925bf6Swillf 				      LIST_MODE_ADD);
148254925bf6Swillf 		mask |= LDAP_REALM_PASSWDSERVERS;
148354925bf6Swillf 	    }
148454925bf6Swillf 	}
148554925bf6Swillf #endif
148654925bf6Swillf 	else if ((ret_mask= get_ticket_policy(rparams,&i,argv,argc)) !=0) {
148754925bf6Swillf 	    mask|=ret_mask;
148854925bf6Swillf 	} else {
148954925bf6Swillf 	    printf(gettext("'%s' is an invalid option\n"), argv[i]);
149054925bf6Swillf 	    goto err_usage;
149154925bf6Swillf 	}
149254925bf6Swillf     }
149354925bf6Swillf 
149454925bf6Swillf     if ((retval = krb5_ldap_modify_realm(util_context,
149554925bf6Swillf 					 /* global_params.realm, */ rparams, mask))) {
149654925bf6Swillf 	goto cleanup;
149754925bf6Swillf     }
149854925bf6Swillf 
149954925bf6Swillf #ifdef HAVE_EDIRECTORY
150054925bf6Swillf     if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_KDCSERVERS) ||
150154925bf6Swillf 	(mask & LDAP_REALM_ADMINSERVERS) || (mask & LDAP_REALM_PASSWDSERVERS)) {
150254925bf6Swillf 
150354925bf6Swillf 	printf(gettext("Changing rights for the service object. Please wait ... "));
150454925bf6Swillf 	fflush(stdout);
150554925bf6Swillf 
150654925bf6Swillf 	if (!(mask & LDAP_REALM_SUBTREE)) {
150754925bf6Swillf 	    if (rparams->subtree != NULL) {
150854925bf6Swillf 		for(i=0; rparams->subtree[i]!=NULL;i++) {
150954925bf6Swillf 		    oldsubtrees[i] = strdup(rparams->subtree[i]);
151054925bf6Swillf 		    if( oldsubtrees[i] == NULL ) {
151154925bf6Swillf 			retval = ENOMEM;
151254925bf6Swillf 			goto cleanup;
151354925bf6Swillf 		    }
151454925bf6Swillf 		}
151554925bf6Swillf 	    }
151654925bf6Swillf 	}
151754925bf6Swillf 
151854925bf6Swillf 	if ((mask & LDAP_REALM_SUBTREE)) {
151954925bf6Swillf 	    int check_subtree = 1;
152054925bf6Swillf 
152154925bf6Swillf 	    newsubtrees = (char**) calloc(rparams->subtreecount, sizeof(char*));
152254925bf6Swillf 
152354925bf6Swillf 	    if (newsubtrees == NULL) {
152454925bf6Swillf 		retval = ENOMEM;
152554925bf6Swillf 		goto cleanup;
152654925bf6Swillf 	    }
152754925bf6Swillf 
152854925bf6Swillf 	    if ( (rparams != NULL) && (rparams->subtree != NULL) ) {
152954925bf6Swillf 		for (j=0; j<rparams->subtreecount && rparams->subtree[j]!= NULL; j++) {
153054925bf6Swillf 		    newsubtrees[j] = strdup(rparams->subtree[j]);
153154925bf6Swillf 		    if (newsubtrees[j] == NULL) {
153254925bf6Swillf 			retval = ENOMEM;
153354925bf6Swillf 			goto cleanup;
153454925bf6Swillf 		    }
153554925bf6Swillf 		}
153654925bf6Swillf 		newsubtrees[j] = NULL;
153754925bf6Swillf 	    }
153854925bf6Swillf 	    for(j=0;oldsubtrees[j]!=NULL;j++) {
153954925bf6Swillf 		check_subtree = 1;
154054925bf6Swillf 		for(i=0; ( (oldsubtrees[j] && !rparams->subtree[i]) ||
154154925bf6Swillf 			(!oldsubtrees[j] && rparams->subtree[i])); i++) {
154254925bf6Swillf 		    if(strcasecmp( oldsubtrees[j], rparams->subtree[i]) == 0) {
154354925bf6Swillf 			check_subtree = 0;
154454925bf6Swillf 			continue;
154554925bf6Swillf 		    }
154654925bf6Swillf 		}
154754925bf6Swillf 		if (check_subtree != 0) {
154854925bf6Swillf 		    subtree_changed=1;
154954925bf6Swillf 		    break;
155054925bf6Swillf 		}
155154925bf6Swillf 	    }
155254925bf6Swillf 	    /* this will return list of the disjoint members */
155354925bf6Swillf 	    disjoint_members( oldsubtrees, newsubtrees);
155454925bf6Swillf 	}
155554925bf6Swillf 
155654925bf6Swillf 	if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_KDCSERVERS)) {
155754925bf6Swillf 
155854925bf6Swillf 	    newkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
155954925bf6Swillf 	    if (newkdcdns == NULL) {
156054925bf6Swillf 		retval = ENOMEM;
156154925bf6Swillf 		goto cleanup;
156254925bf6Swillf 	    }
156354925bf6Swillf 
156454925bf6Swillf 	    if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
156554925bf6Swillf 		for (j=0;  rparams->kdcservers[j]!= NULL; j++) {
156654925bf6Swillf 		    newkdcdns[j] = strdup(rparams->kdcservers[j]);
156754925bf6Swillf 		    if (newkdcdns[j] == NULL) {
156854925bf6Swillf 			retval = ENOMEM;
156954925bf6Swillf 			goto cleanup;
157054925bf6Swillf 		    }
157154925bf6Swillf 		}
157254925bf6Swillf 		newkdcdns[j] = NULL;
157354925bf6Swillf 	    }
157454925bf6Swillf 
157554925bf6Swillf 	    if (!subtree_changed) {
157654925bf6Swillf 		disjoint_members(oldkdcdns, newkdcdns);
157754925bf6Swillf 	    } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
157854925bf6Swillf 		if (!(mask & LDAP_REALM_KDCSERVERS)) {
157954925bf6Swillf 
158054925bf6Swillf 		    oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
158154925bf6Swillf 		    if (oldkdcdns == NULL) {
158254925bf6Swillf 			retval = ENOMEM;
158354925bf6Swillf 			goto cleanup;
158454925bf6Swillf 		    }
158554925bf6Swillf 
158654925bf6Swillf 		    if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
158754925bf6Swillf 			for (j=0;  rparams->kdcservers[j]!= NULL; j++) {
158854925bf6Swillf 			    oldkdcdns[j] = strdup(rparams->kdcservers[j]);
158954925bf6Swillf 			    if (oldkdcdns[j] == NULL) {
159054925bf6Swillf 				retval = ENOMEM;
159154925bf6Swillf 				goto cleanup;
159254925bf6Swillf 			    }
159354925bf6Swillf 			}
159454925bf6Swillf 			oldkdcdns[j] = NULL;
159554925bf6Swillf 		    }
159654925bf6Swillf 		}
159754925bf6Swillf 	    }
159854925bf6Swillf 
159954925bf6Swillf 	    rightsmask =0;
160054925bf6Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
160154925bf6Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
160254925bf6Swillf 	    /* Remove the rights on the old subtrees */
160354925bf6Swillf 	    if (oldkdcdns) {
160454925bf6Swillf 		for (i=0; (oldkdcdns[i] != NULL); i++) {
160554925bf6Swillf 		    if ((retval=krb5_ldap_delete_service_rights(util_context,
160654925bf6Swillf 								LDAP_KDC_SERVICE, oldkdcdns[i],
160754925bf6Swillf 								rparams->realm_name, oldsubtrees, rightsmask)) != 0) {
160854925bf6Swillf 			printf(gettext("failed\n"));
1609dd9ccd46S 			/* Solaris Kerberos */
1610dd9ccd46S 			com_err(progname, retval, gettext("while assigning rights '%s'"),
161154925bf6Swillf 				rparams->realm_name);
161254925bf6Swillf 			goto err_nomsg;
161354925bf6Swillf 		    }
161454925bf6Swillf 		}
161554925bf6Swillf 	    }
161654925bf6Swillf 
161754925bf6Swillf 	    rightsmask =0;
161854925bf6Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
161954925bf6Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
162054925bf6Swillf 	    if (newkdcdns) {
162154925bf6Swillf 		for (i=0; (newkdcdns[i] != NULL); i++) {
162254925bf6Swillf 
162354925bf6Swillf 		    if ((retval=krb5_ldap_add_service_rights(util_context,
162454925bf6Swillf 							     LDAP_KDC_SERVICE, newkdcdns[i], rparams->realm_name,
162554925bf6Swillf 							     rparams->subtree, rightsmask)) != 0) {
162654925bf6Swillf 			printf(gettext("failed\n"));
1627dd9ccd46S 			/* Solaris Kerberos */
1628dd9ccd46S 			com_err(progname, retval, gettext("while assigning rights to '%s'"),
162954925bf6Swillf 				rparams->realm_name);
163054925bf6Swillf 			goto err_nomsg;
163154925bf6Swillf 		    }
163254925bf6Swillf 		}
163354925bf6Swillf 	    }
163454925bf6Swillf 	}
163554925bf6Swillf 
163654925bf6Swillf 	if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_ADMINSERVERS)) {
163754925bf6Swillf 
163854925bf6Swillf 	    newadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
163954925bf6Swillf 	    if (newadmindns == NULL) {
164054925bf6Swillf 		retval = ENOMEM;
164154925bf6Swillf 		goto cleanup;
164254925bf6Swillf 	    }
164354925bf6Swillf 
164454925bf6Swillf 	    if ((rparams != NULL) && (rparams->adminservers != NULL)) {
164554925bf6Swillf 		for (j=0;  rparams->adminservers[j]!= NULL; j++) {
164654925bf6Swillf 		    newadmindns[j] = strdup(rparams->adminservers[j]);
164754925bf6Swillf 		    if (newadmindns[j] == NULL) {
164854925bf6Swillf 			retval = ENOMEM;
164954925bf6Swillf 			goto cleanup;
165054925bf6Swillf 		    }
165154925bf6Swillf 		}
165254925bf6Swillf 		newadmindns[j] = NULL;
165354925bf6Swillf 	    }
165454925bf6Swillf 
165554925bf6Swillf 	    if (!subtree_changed) {
165654925bf6Swillf 		disjoint_members(oldadmindns, newadmindns);
165754925bf6Swillf 	    } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
165854925bf6Swillf 		if (!(mask & LDAP_REALM_ADMINSERVERS)) {
165954925bf6Swillf 
166054925bf6Swillf 		    oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
166154925bf6Swillf 		    if (oldadmindns == NULL) {
166254925bf6Swillf 			retval = ENOMEM;
166354925bf6Swillf 			goto cleanup;
166454925bf6Swillf 		    }
166554925bf6Swillf 
166654925bf6Swillf 		    if ((rparams != NULL) && (rparams->adminservers != NULL)) {
166754925bf6Swillf 			for (j=0;  rparams->adminservers[j]!= NULL; j++) {
166854925bf6Swillf 			    oldadmindns[j] = strdup(rparams->adminservers[j]);
166954925bf6Swillf 			    if (oldadmindns[j] == NULL) {
167054925bf6Swillf 				retval = ENOMEM;
167154925bf6Swillf 				goto cleanup;
167254925bf6Swillf 			    }
167354925bf6Swillf 			}
167454925bf6Swillf 			oldadmindns[j] = NULL;
167554925bf6Swillf 		    }
167654925bf6Swillf 		}
167754925bf6Swillf 	    }
167854925bf6Swillf 
167954925bf6Swillf 	    rightsmask = 0;
168054925bf6Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
168154925bf6Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
168254925bf6Swillf 	    /* Remove the rights on the old subtrees */
168354925bf6Swillf 	    if (oldadmindns) {
168454925bf6Swillf 		for (i=0; (oldadmindns[i] != NULL); i++) {
168554925bf6Swillf 
168654925bf6Swillf 		    if ((retval=krb5_ldap_delete_service_rights(util_context,
168754925bf6Swillf 								LDAP_ADMIN_SERVICE, oldadmindns[i],
168854925bf6Swillf 								rparams->realm_name, oldsubtrees, rightsmask)) != 0) {
168954925bf6Swillf 			printf(gettext("failed\n"));
1690dd9ccd46S 			/* Solaris Kerberos */
1691dd9ccd46S 			com_err(progname, retval, gettext("while assigning rights '%s'"),
169254925bf6Swillf 				rparams->realm_name);
169354925bf6Swillf 			goto err_nomsg;
169454925bf6Swillf 		    }
169554925bf6Swillf 		}
169654925bf6Swillf 	    }
169754925bf6Swillf 
169854925bf6Swillf 	    rightsmask = 0;
169954925bf6Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
170054925bf6Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
170154925bf6Swillf 	    /* Add rights on the new subtree for all the kdc dns */
170254925bf6Swillf 	    if (newadmindns) {
170354925bf6Swillf 		for (i=0; (newadmindns[i] != NULL); i++) {
170454925bf6Swillf 
170554925bf6Swillf 		    if ((retval=krb5_ldap_add_service_rights(util_context,
170654925bf6Swillf 							     LDAP_ADMIN_SERVICE, newadmindns[i],
170754925bf6Swillf 							     rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
170854925bf6Swillf 			printf(gettext("failed\n"));
1709dd9ccd46S 			/* Solaris Kerberos */
1710dd9ccd46S 			com_err(progname, retval, gettext("while assigning rights to '%s'"),
171154925bf6Swillf 				rparams->realm_name);
171254925bf6Swillf 			goto err_nomsg;
171354925bf6Swillf 		    }
171454925bf6Swillf 		}
171554925bf6Swillf 	    }
171654925bf6Swillf 	}
171754925bf6Swillf 
171854925bf6Swillf 
171954925bf6Swillf 	if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_PASSWDSERVERS)) {
172054925bf6Swillf 
172154925bf6Swillf 	    newpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
172254925bf6Swillf 	    if (newpwddns == NULL) {
172354925bf6Swillf 		retval = ENOMEM;
172454925bf6Swillf 		goto cleanup;
172554925bf6Swillf 	    }
172654925bf6Swillf 
172754925bf6Swillf 	    if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
172854925bf6Swillf 		for (j=0;  rparams->passwdservers[j]!= NULL; j++) {
172954925bf6Swillf 		    newpwddns[j] = strdup(rparams->passwdservers[j]);
173054925bf6Swillf 		    if (newpwddns[j] == NULL) {
173154925bf6Swillf 			retval = ENOMEM;
173254925bf6Swillf 			goto cleanup;
173354925bf6Swillf 		    }
173454925bf6Swillf 		}
173554925bf6Swillf 		newpwddns[j] = NULL;
173654925bf6Swillf 	    }
173754925bf6Swillf 
173854925bf6Swillf 	    if (!subtree_changed) {
173954925bf6Swillf 		disjoint_members(oldpwddns, newpwddns);
174054925bf6Swillf 	    } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
174154925bf6Swillf 		if (!(mask & LDAP_REALM_ADMINSERVERS)) {
174254925bf6Swillf 
174354925bf6Swillf 		    oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
174454925bf6Swillf 		    if (oldpwddns == NULL) {
174554925bf6Swillf 			retval = ENOMEM;
174654925bf6Swillf 			goto cleanup;
174754925bf6Swillf 		    }
174854925bf6Swillf 
174954925bf6Swillf 		    if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
175054925bf6Swillf 			for (j=0;  rparams->passwdservers[j]!= NULL; j++) {
175154925bf6Swillf 			    oldpwddns[j] = strdup(rparams->passwdservers[j]);
175254925bf6Swillf 			    if (oldpwddns[j] == NULL) {
175354925bf6Swillf 				retval = ENOMEM;
175454925bf6Swillf 				goto cleanup;
175554925bf6Swillf 			    }
175654925bf6Swillf 			}
175754925bf6Swillf 			oldpwddns[j] = NULL;
175854925bf6Swillf 		    }
175954925bf6Swillf 		}
176054925bf6Swillf 	    }
176154925bf6Swillf 
176254925bf6Swillf 	    rightsmask =0;
176354925bf6Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
176454925bf6Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
176554925bf6Swillf 	    /* Remove the rights on the old subtrees */
176654925bf6Swillf 	    if (oldpwddns) {
176754925bf6Swillf 		for (i=0; (oldpwddns[i] != NULL); i++) {
176854925bf6Swillf 		    if ((retval = krb5_ldap_delete_service_rights(util_context,
176954925bf6Swillf 								  LDAP_PASSWD_SERVICE, oldpwddns[i],
177054925bf6Swillf 								  rparams->realm_name, oldsubtrees, rightsmask))) {
177154925bf6Swillf 			printf(gettext("failed\n"));
1772dd9ccd46S 			/* Solaris Kerberos */
1773dd9ccd46S 			com_err(progname, retval, gettext("while assigning rights '%s'"),
177454925bf6Swillf 				rparams->realm_name);
177554925bf6Swillf 			goto err_nomsg;
177654925bf6Swillf 		    }
177754925bf6Swillf 		}
177854925bf6Swillf 	    }
177954925bf6Swillf 
178054925bf6Swillf 	    rightsmask =0;
178154925bf6Swillf 	    rightsmask |= LDAP_REALM_RIGHTS;
178254925bf6Swillf 	    rightsmask |= LDAP_SUBTREE_RIGHTS;
178354925bf6Swillf 	    /* Add rights on the new subtree for all the kdc dns */
178454925bf6Swillf 	    if (newpwddns) {
178554925bf6Swillf 		for (i=0; (newpwddns[i] != NULL); i++) {
178654925bf6Swillf 		    if ((retval = krb5_ldap_add_service_rights(util_context,
178754925bf6Swillf 							       LDAP_PASSWD_SERVICE, newpwddns[i],
178854925bf6Swillf 							       rparams->realm_name, rparams->subtree, rightsmask))) {
178954925bf6Swillf 			printf(gettext("failed\n"));
1790dd9ccd46S 			/* Solaris Kerberos */
1791dd9ccd46S 			com_err(progname, retval, gettext("while assigning rights to '%s'"),
179254925bf6Swillf 				rparams->realm_name);
179354925bf6Swillf 			goto err_nomsg;
179454925bf6Swillf 		    }
179554925bf6Swillf 		}
179654925bf6Swillf 	    }
179754925bf6Swillf 	}
179854925bf6Swillf 
179954925bf6Swillf 	printf(gettext("done\n"));
180054925bf6Swillf     }
180154925bf6Swillf #endif
180254925bf6Swillf 
180354925bf6Swillf     goto cleanup;
180454925bf6Swillf 
180554925bf6Swillf err_usage:
180654925bf6Swillf     print_usage = TRUE;
180754925bf6Swillf 
180854925bf6Swillf err_nomsg:
180954925bf6Swillf     no_msg = TRUE;
181054925bf6Swillf 
181154925bf6Swillf cleanup:
181254925bf6Swillf     krb5_ldap_free_realm_params(rparams);
181354925bf6Swillf 
181454925bf6Swillf 
181554925bf6Swillf #ifdef HAVE_EDIRECTORY
181654925bf6Swillf     if (oldkdcdns) {
181754925bf6Swillf 	for (i=0; oldkdcdns[i] != NULL; i++)
181854925bf6Swillf 	    free(oldkdcdns[i]);
181954925bf6Swillf 	free(oldkdcdns);
182054925bf6Swillf     }
182154925bf6Swillf     if (oldpwddns) {
182254925bf6Swillf 	for (i=0; oldpwddns[i] != NULL; i++)
182354925bf6Swillf 	    free(oldpwddns[i]);
182454925bf6Swillf 	free(oldpwddns);
182554925bf6Swillf     }
182654925bf6Swillf     if (oldadmindns) {
182754925bf6Swillf 	for (i=0; oldadmindns[i] != NULL; i++)
182854925bf6Swillf 	    free(oldadmindns[i]);
182954925bf6Swillf 	free(oldadmindns);
183054925bf6Swillf     }
183154925bf6Swillf     if (newkdcdns) {
183254925bf6Swillf 	for (i=0; newkdcdns[i] != NULL; i++)
183354925bf6Swillf 	    free(newkdcdns[i]);
183454925bf6Swillf 	free(newkdcdns);
183554925bf6Swillf     }
183654925bf6Swillf     if (newpwddns) {
183754925bf6Swillf 	for (i=0; newpwddns[i] != NULL; i++)
183854925bf6Swillf 	    free(newpwddns[i]);
183954925bf6Swillf 	free(newpwddns);
184054925bf6Swillf     }
184154925bf6Swillf     if (newadmindns) {
184254925bf6Swillf 	for (i=0; newadmindns[i] != NULL; i++)
184354925bf6Swillf 	    free(newadmindns[i]);
184454925bf6Swillf 	free(newadmindns);
184554925bf6Swillf     }
184654925bf6Swillf     if (oldsubtrees) {
184754925bf6Swillf 	for (i=0;oldsubtrees[i]!=NULL; i++)
184854925bf6Swillf 	    free(oldsubtrees[i]);
184954925bf6Swillf 	free(oldsubtrees);
185054925bf6Swillf     }
185154925bf6Swillf     if (newsubtrees) {
185254925bf6Swillf 	for (i=0;newsubtrees[i]!=NULL; i++)
185354925bf6Swillf 	    free(newsubtrees[i]);
185454925bf6Swillf 	free(oldsubtrees);
185554925bf6Swillf     }
185654925bf6Swillf #endif
185754925bf6Swillf     if (print_usage) {
185854925bf6Swillf 	db_usage(MODIFY_REALM);
185954925bf6Swillf     }
186054925bf6Swillf 
186154925bf6Swillf     if (retval) {
1862dd9ccd46S 	if (!no_msg) {
1863dd9ccd46S 	    /* Solaris Kerberos */
1864dd9ccd46S 	    com_err(progname, retval, gettext("while modifying information of realm '%s'"),
186554925bf6Swillf 		    global_params.realm);
1866dd9ccd46S 	}
186754925bf6Swillf 	exit_status++;
186854925bf6Swillf     }
186954925bf6Swillf 
187054925bf6Swillf     return;
187154925bf6Swillf }
187254925bf6Swillf 
187354925bf6Swillf 
187454925bf6Swillf 
187554925bf6Swillf /*
187654925bf6Swillf  * This function displays the attributes of a Realm
187754925bf6Swillf  */
187854925bf6Swillf void kdb5_ldap_view(argc, argv)
187954925bf6Swillf     int argc;
188054925bf6Swillf     char *argv[];
188154925bf6Swillf {
188254925bf6Swillf     krb5_ldap_realm_params *rparams = NULL;
188354925bf6Swillf     krb5_error_code retval = 0;
188454925bf6Swillf     kdb5_dal_handle *dal_handle=NULL;
188554925bf6Swillf     krb5_ldap_context *ldap_context=NULL;
188654925bf6Swillf     int mask = 0;
188754925bf6Swillf 
188854925bf6Swillf     dal_handle = (kdb5_dal_handle *) util_context->db_context;
188954925bf6Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
189054925bf6Swillf     if (!(ldap_context)) {
189154925bf6Swillf 	retval = EINVAL;
1892dd9ccd46S 	/* Solaris Kerberos */
1893dd9ccd46S 	com_err(progname, retval, gettext("while initializing database"));
189454925bf6Swillf 	exit_status++;
189554925bf6Swillf 	return;
189654925bf6Swillf     }
189754925bf6Swillf 
189854925bf6Swillf     /* Read the kerberos container information */
189954925bf6Swillf     if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
190054925bf6Swillf 						     &(ldap_context->krbcontainer))) != 0) {
1901dd9ccd46S 	/* Solaris Kerberos */
1902dd9ccd46S 	com_err(progname, retval, gettext("while reading kerberos container information"));
190354925bf6Swillf 	exit_status++;
190454925bf6Swillf 	return;
190554925bf6Swillf     }
190654925bf6Swillf 
190754925bf6Swillf     if ((retval = krb5_ldap_read_realm_params(util_context,
190854925bf6Swillf 					      global_params.realm, &rparams, &mask)) || (!rparams)) {
1909dd9ccd46S 	/* Solaris Kerberos */
1910dd9ccd46S 	com_err(progname, retval, gettext("while reading information of realm '%s'"),
191154925bf6Swillf 		global_params.realm);
191254925bf6Swillf 	exit_status++;
191354925bf6Swillf 	return;
191454925bf6Swillf     }
191554925bf6Swillf     print_realm_params(rparams, mask);
191654925bf6Swillf     krb5_ldap_free_realm_params(rparams);
191754925bf6Swillf 
191854925bf6Swillf     return;
191954925bf6Swillf }
192054925bf6Swillf 
192154925bf6Swillf static char *strdur(duration)
192254925bf6Swillf     time_t duration;
192354925bf6Swillf {
192454925bf6Swillf     static char out[50];
192554925bf6Swillf     int neg, days, hours, minutes, seconds;
192654925bf6Swillf 
192754925bf6Swillf     if (duration < 0) {
192854925bf6Swillf 	duration *= -1;
192954925bf6Swillf 	neg = 1;
193054925bf6Swillf     } else
193154925bf6Swillf 	neg = 0;
193254925bf6Swillf     days = duration / (24 * 3600);
193354925bf6Swillf     duration %= 24 * 3600;
193454925bf6Swillf     hours = duration / 3600;
193554925bf6Swillf     duration %= 3600;
193654925bf6Swillf     minutes = duration / 60;
193754925bf6Swillf     duration %= 60;
193854925bf6Swillf     seconds = duration;
193954925bf6Swillf     snprintf(out, sizeof(out), "%s%d %s %02d:%02d:%02d", neg ? "-" : "",
194054925bf6Swillf 	    days, days == 1 ? gettext("day") : gettext("days"),
194154925bf6Swillf 	    hours, minutes, seconds);
194254925bf6Swillf     return out;
194354925bf6Swillf }
194454925bf6Swillf 
194554925bf6Swillf /*
194654925bf6Swillf  * This function prints the attributes of a given realm to the
194754925bf6Swillf  * standard output.
194854925bf6Swillf  */
194954925bf6Swillf static void print_realm_params(krb5_ldap_realm_params *rparams, int mask)
195054925bf6Swillf {
195154925bf6Swillf     char **slist = NULL;
195254925bf6Swillf     int num_entry_printed = 0, i = 0;
195354925bf6Swillf 
195454925bf6Swillf     /* Print the Realm Attributes on the standard output */
195554925bf6Swillf     printf("%25s: %-50s\n", gettext("Realm Name"), global_params.realm);
195654925bf6Swillf     if (mask & LDAP_REALM_SUBTREE) {
195754925bf6Swillf 	for (i=0; rparams->subtree[i]!=NULL; i++)
195854925bf6Swillf 	    printf("%25s: %-50s\n", gettext("Subtree"), rparams->subtree[i]);
195954925bf6Swillf     }
196054925bf6Swillf     if (mask & LDAP_REALM_CONTREF)
196154925bf6Swillf 	printf("%25s: %-50s\n", gettext("Principal Container Reference"), rparams->containerref);
196254925bf6Swillf     if (mask & LDAP_REALM_SEARCHSCOPE) {
196354925bf6Swillf 	if ((rparams->search_scope != 1) &&
196454925bf6Swillf 	    (rparams->search_scope != 2)) {
196554925bf6Swillf 	    printf("%25s: %-50s\n", gettext("SearchScope"), gettext("Invalid !"));
196654925bf6Swillf 	} else {
196754925bf6Swillf 	    printf("%25s: %-50s\n", gettext("SearchScope"),
196854925bf6Swillf 		   (rparams->search_scope == 1) ? gettext("ONE") : gettext("SUB"));
196954925bf6Swillf 	}
197054925bf6Swillf     }
197154925bf6Swillf     if (mask & LDAP_REALM_KDCSERVERS) {
197254925bf6Swillf 	printf("%25s:", gettext("KDC Services"));
197354925bf6Swillf 	if (rparams->kdcservers != NULL) {
197454925bf6Swillf 	    num_entry_printed = 0;
197554925bf6Swillf 	    for (slist = rparams->kdcservers; *slist != NULL; slist++) {
197654925bf6Swillf 		if (num_entry_printed)
197754925bf6Swillf 		    printf(" %25s %-50s\n", " ", *slist);
197854925bf6Swillf 		else
197954925bf6Swillf 		    printf(" %-50s\n", *slist);
198054925bf6Swillf 		num_entry_printed++;
198154925bf6Swillf 	    }
198254925bf6Swillf 	}
198354925bf6Swillf 	if (num_entry_printed == 0)
198454925bf6Swillf 	    printf("\n");
198554925bf6Swillf     }
198654925bf6Swillf     if (mask & LDAP_REALM_ADMINSERVERS) {
198754925bf6Swillf 	printf("%25s:", gettext("Admin Services"));
198854925bf6Swillf 	if (rparams->adminservers != NULL) {
198954925bf6Swillf 	    num_entry_printed = 0;
199054925bf6Swillf 	    for (slist = rparams->adminservers; *slist != NULL; slist++) {
199154925bf6Swillf 		if (num_entry_printed)
199254925bf6Swillf 		    printf(" %25s %-50s\n", " ", *slist);
199354925bf6Swillf 		else
199454925bf6Swillf 		    printf(" %-50s\n", *slist);
199554925bf6Swillf 		num_entry_printed++;
199654925bf6Swillf 	    }
199754925bf6Swillf 	}
199854925bf6Swillf 	if (num_entry_printed == 0)
199954925bf6Swillf 	    printf("\n");
200054925bf6Swillf     }
200154925bf6Swillf     if (mask & LDAP_REALM_PASSWDSERVERS) {
200254925bf6Swillf 	printf("%25s:", gettext("Passwd Services"));
200354925bf6Swillf 	if (rparams->passwdservers != NULL) {
200454925bf6Swillf 	    num_entry_printed = 0;
200554925bf6Swillf 	    for (slist = rparams->passwdservers; *slist != NULL; slist++) {
200654925bf6Swillf 		if (num_entry_printed)
200754925bf6Swillf 		    printf(" %25s %-50s\n", " ", *slist);
200854925bf6Swillf 		else
200954925bf6Swillf 		    printf(" %-50s\n", *slist);
201054925bf6Swillf 		num_entry_printed++;
201154925bf6Swillf 	    }
201254925bf6Swillf 	}
201354925bf6Swillf 	if (num_entry_printed == 0)
201454925bf6Swillf 	    printf("\n");
201554925bf6Swillf     }
201654925bf6Swillf     if (mask & LDAP_REALM_MAXTICKETLIFE) {
201754925bf6Swillf 	printf("%25s:", gettext("Maximum Ticket Life"));
201854925bf6Swillf 	printf(" %s \n", strdur(rparams->max_life));
201954925bf6Swillf     }
202054925bf6Swillf 
202154925bf6Swillf     if (mask & LDAP_REALM_MAXRENEWLIFE) {
202254925bf6Swillf 	printf("%25s:", gettext("Maximum Renewable Life"));
202354925bf6Swillf 	printf(" %s \n", strdur(rparams->max_renewable_life));
202454925bf6Swillf     }
202554925bf6Swillf 
202654925bf6Swillf     if (mask & LDAP_REALM_KRBTICKETFLAGS) {
202754925bf6Swillf 	int ticketflags = rparams->tktflags;
202854925bf6Swillf 
202954925bf6Swillf 	printf("%25s: ", gettext("Ticket flags"));
203054925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_POSTDATED)
203154925bf6Swillf 	    printf("%s ","DISALLOW_POSTDATED");
203254925bf6Swillf 
203354925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_FORWARDABLE)
203454925bf6Swillf 	    printf("%s ","DISALLOW_FORWARDABLE");
203554925bf6Swillf 
203654925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_RENEWABLE)
203754925bf6Swillf 	    printf("%s ","DISALLOW_RENEWABLE");
203854925bf6Swillf 
203954925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_PROXIABLE)
204054925bf6Swillf 	    printf("%s ","DISALLOW_PROXIABLE");
204154925bf6Swillf 
204254925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_DUP_SKEY)
204354925bf6Swillf 	    printf("%s ","DISALLOW_DUP_SKEY");
204454925bf6Swillf 
204554925bf6Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_PRE_AUTH)
204654925bf6Swillf 	    printf("%s ","REQUIRES_PRE_AUTH");
204754925bf6Swillf 
204854925bf6Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_HW_AUTH)
204954925bf6Swillf 	    printf("%s ","REQUIRES_HW_AUTH");
205054925bf6Swillf 
205154925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_SVR)
205254925bf6Swillf 	    printf("%s ","DISALLOW_SVR");
205354925bf6Swillf 
205454925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_TGT_BASED)
205554925bf6Swillf 	    printf("%s ","DISALLOW_TGT_BASED");
205654925bf6Swillf 
205754925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_ALL_TIX)
205854925bf6Swillf 	    printf("%s ","DISALLOW_ALL_TIX");
205954925bf6Swillf 
206054925bf6Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_PWCHANGE)
206154925bf6Swillf 	    printf("%s ","REQUIRES_PWCHANGE");
206254925bf6Swillf 
206354925bf6Swillf 	if (ticketflags & KRB5_KDB_PWCHANGE_SERVICE)
206454925bf6Swillf 	    printf("%s ","PWCHANGE_SERVICE");
206554925bf6Swillf 
206654925bf6Swillf 	printf("\n");
206754925bf6Swillf     }
206854925bf6Swillf 
206954925bf6Swillf 
207054925bf6Swillf     return;
207154925bf6Swillf }
207254925bf6Swillf 
207354925bf6Swillf 
207454925bf6Swillf 
207554925bf6Swillf /*
207654925bf6Swillf  * This function lists the Realm(s) present under the Kerberos container
207754925bf6Swillf  * on the LDAP Server.
207854925bf6Swillf  */
207954925bf6Swillf void kdb5_ldap_list(argc, argv)
208054925bf6Swillf     int argc;
208154925bf6Swillf     char *argv[];
208254925bf6Swillf {
208354925bf6Swillf     char **list = NULL;
208454925bf6Swillf     char **plist = NULL;
208554925bf6Swillf     krb5_error_code retval = 0;
208654925bf6Swillf     kdb5_dal_handle *dal_handle=NULL;
208754925bf6Swillf     krb5_ldap_context *ldap_context=NULL;
208854925bf6Swillf 
208954925bf6Swillf     dal_handle = (kdb5_dal_handle *)util_context->db_context;
209054925bf6Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
209154925bf6Swillf     if (!(ldap_context)) {
209254925bf6Swillf 	retval = EINVAL;
209354925bf6Swillf 	exit_status++;
209454925bf6Swillf 	return;
209554925bf6Swillf     }
209654925bf6Swillf 
209754925bf6Swillf     /* Read the kerberos container information */
209854925bf6Swillf     if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
209954925bf6Swillf 						     &(ldap_context->krbcontainer))) != 0) {
2100dd9ccd46S 	/* Solaris Kerberos */
2101dd9ccd46S 	com_err(progname, retval, gettext("while reading kerberos container information"));
210254925bf6Swillf 	exit_status++;
210354925bf6Swillf 	return;
210454925bf6Swillf     }
210554925bf6Swillf 
210654925bf6Swillf     retval = krb5_ldap_list_realm(util_context, &list);
210754925bf6Swillf     if (retval != 0) {
210854925bf6Swillf 	krb5_ldap_free_krbcontainer_params(ldap_context->krbcontainer);
210954925bf6Swillf 	ldap_context->krbcontainer = NULL;
2110dd9ccd46S 	/* Solaris Kerberos */
2111dd9ccd46S 	com_err (progname, retval, gettext("while listing realms"));
211254925bf6Swillf 	exit_status++;
211354925bf6Swillf 	return;
211454925bf6Swillf     }
211554925bf6Swillf     /* This is to handle the case of realm not present */
211654925bf6Swillf     if (list == NULL) {
211754925bf6Swillf 	krb5_ldap_free_krbcontainer_params(ldap_context->krbcontainer);
211854925bf6Swillf 	ldap_context->krbcontainer = NULL;
211954925bf6Swillf 	return;
212054925bf6Swillf     }
212154925bf6Swillf 
212254925bf6Swillf     for (plist = list; *plist != NULL; plist++) {
212354925bf6Swillf 	printf("%s\n", *plist);
212454925bf6Swillf     }
212554925bf6Swillf     krb5_ldap_free_krbcontainer_params(ldap_context->krbcontainer);
212654925bf6Swillf     ldap_context->krbcontainer = NULL;
212754925bf6Swillf     krb5_free_list_entries(list);
212854925bf6Swillf     free(list);
212954925bf6Swillf 
213054925bf6Swillf     return;
213154925bf6Swillf }
213254925bf6Swillf 
213354925bf6Swillf /*
213454925bf6Swillf  * Duplicating the following two functions here because
213554925bf6Swillf  * 'krb5_dbe_update_tl_data' uses backend specific memory allocation. The catch
213654925bf6Swillf  * here is that the backend is not initialized - kdb5_ldap_util doesn't go
213754925bf6Swillf  * through DAL.
213854925bf6Swillf  * 1. krb5_dbe_update_tl_data
213954925bf6Swillf  * 2. krb5_dbe_update_mod_princ_data
214054925bf6Swillf  */
214154925bf6Swillf 
214254925bf6Swillf /* Start duplicate code ... */
214354925bf6Swillf 
214454925bf6Swillf static krb5_error_code
214554925bf6Swillf krb5_dbe_update_tl_data_new(context, entry, new_tl_data)
214654925bf6Swillf     krb5_context context;
214754925bf6Swillf     krb5_db_entry *entry;
214854925bf6Swillf     krb5_tl_data *new_tl_data;
214954925bf6Swillf {
215054925bf6Swillf     krb5_tl_data *tl_data = NULL;
215154925bf6Swillf     krb5_octet *tmp;
215254925bf6Swillf 
215354925bf6Swillf     /* copy the new data first, so we can fail cleanly if malloc()
215454925bf6Swillf      * fails */
215554925bf6Swillf /*
215654925bf6Swillf     if ((tmp =
215754925bf6Swillf 	 (krb5_octet *) krb5_db_alloc(context, NULL,
215854925bf6Swillf 				      new_tl_data->tl_data_length)) == NULL)
215954925bf6Swillf */
216054925bf6Swillf     if ((tmp = (krb5_octet *) malloc (new_tl_data->tl_data_length)) == NULL)
216154925bf6Swillf 	return (ENOMEM);
216254925bf6Swillf 
216354925bf6Swillf     /* Find an existing entry of the specified type and point at
216454925bf6Swillf      * it, or NULL if not found */
216554925bf6Swillf 
216654925bf6Swillf     if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) {	/* db_args can be multiple */
216754925bf6Swillf 	for (tl_data = entry->tl_data; tl_data;
216854925bf6Swillf 	     tl_data = tl_data->tl_data_next)
216954925bf6Swillf 	    if (tl_data->tl_data_type == new_tl_data->tl_data_type)
217054925bf6Swillf 		break;
217154925bf6Swillf     }
217254925bf6Swillf 
217354925bf6Swillf     /* if necessary, chain a new record in the beginning and point at it */
217454925bf6Swillf 
217554925bf6Swillf     if (!tl_data) {
217654925bf6Swillf /*
217754925bf6Swillf 	if ((tl_data =
217854925bf6Swillf 	     (krb5_tl_data *) krb5_db_alloc(context, NULL,
217954925bf6Swillf 					    sizeof(krb5_tl_data)))
218054925bf6Swillf 	    == NULL) {
218154925bf6Swillf */
218254925bf6Swillf 	if ((tl_data = (krb5_tl_data *) malloc (sizeof(krb5_tl_data))) == NULL) {
218354925bf6Swillf 	    free(tmp);
218454925bf6Swillf 	    return (ENOMEM);
218554925bf6Swillf 	}
218654925bf6Swillf 	memset(tl_data, 0, sizeof(krb5_tl_data));
218754925bf6Swillf 	tl_data->tl_data_next = entry->tl_data;
218854925bf6Swillf 	entry->tl_data = tl_data;
218954925bf6Swillf 	entry->n_tl_data++;
219054925bf6Swillf     }
219154925bf6Swillf 
219254925bf6Swillf     /* fill in the record */
219354925bf6Swillf 
219454925bf6Swillf     if (tl_data->tl_data_contents)
219554925bf6Swillf 	krb5_db_free(context, tl_data->tl_data_contents);
219654925bf6Swillf 
219754925bf6Swillf     tl_data->tl_data_type = new_tl_data->tl_data_type;
219854925bf6Swillf     tl_data->tl_data_length = new_tl_data->tl_data_length;
219954925bf6Swillf     tl_data->tl_data_contents = tmp;
220054925bf6Swillf     memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
220154925bf6Swillf 
220254925bf6Swillf     return (0);
220354925bf6Swillf }
220454925bf6Swillf 
220554925bf6Swillf static krb5_error_code
220654925bf6Swillf krb5_dbe_update_mod_princ_data_new(context, entry, mod_date, mod_princ)
220754925bf6Swillf     krb5_context	  context;
220854925bf6Swillf     krb5_db_entry	* entry;
220954925bf6Swillf     krb5_timestamp	  mod_date;
221054925bf6Swillf     krb5_const_principal  mod_princ;
221154925bf6Swillf {
221254925bf6Swillf     krb5_tl_data          tl_data;
221354925bf6Swillf 
221454925bf6Swillf     krb5_error_code 	  retval = 0;
221554925bf6Swillf     krb5_octet		* nextloc = 0;
221654925bf6Swillf     char		* unparse_mod_princ = 0;
221754925bf6Swillf     unsigned int	unparse_mod_princ_size;
221854925bf6Swillf 
221954925bf6Swillf     if ((retval = krb5_unparse_name(context, mod_princ,
222054925bf6Swillf 				    &unparse_mod_princ)))
222154925bf6Swillf 	return(retval);
222254925bf6Swillf 
222354925bf6Swillf     unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
222454925bf6Swillf 
222554925bf6Swillf     if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
222654925bf6Swillf 	== NULL) {
222754925bf6Swillf 	free(unparse_mod_princ);
222854925bf6Swillf 	return(ENOMEM);
222954925bf6Swillf     }
223054925bf6Swillf 
223154925bf6Swillf     tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
223254925bf6Swillf     tl_data.tl_data_length = unparse_mod_princ_size + 4;
223354925bf6Swillf     tl_data.tl_data_contents = nextloc;
223454925bf6Swillf 
223554925bf6Swillf     /* Mod Date */
223654925bf6Swillf     krb5_kdb_encode_int32(mod_date, nextloc);
223754925bf6Swillf 
223854925bf6Swillf     /* Mod Princ */
223954925bf6Swillf     memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size);
224054925bf6Swillf 
224154925bf6Swillf     retval = krb5_dbe_update_tl_data_new(context, entry, &tl_data);
224254925bf6Swillf 
224354925bf6Swillf     free(unparse_mod_princ);
224454925bf6Swillf     free(nextloc);
224554925bf6Swillf 
224654925bf6Swillf     return(retval);
224754925bf6Swillf }
224854925bf6Swillf 
224954925bf6Swillf static krb5_error_code
225054925bf6Swillf kdb_ldap_tgt_keysalt_iterate(ksent, ptr)
225154925bf6Swillf     krb5_key_salt_tuple *ksent;
225254925bf6Swillf     krb5_pointer        ptr;
225354925bf6Swillf {
225454925bf6Swillf     krb5_context        context;
225554925bf6Swillf     krb5_error_code     kret;
225654925bf6Swillf     struct iterate_args *iargs;
225754925bf6Swillf     krb5_keyblock       key;
225854925bf6Swillf     krb5_int32          ind;
225954925bf6Swillf     krb5_data   pwd;
226054925bf6Swillf     krb5_db_entry       *entry;
226154925bf6Swillf 
226254925bf6Swillf     iargs = (struct iterate_args *) ptr;
226354925bf6Swillf     kret = 0;
226454925bf6Swillf 
226554925bf6Swillf     context = iargs->ctx;
226654925bf6Swillf     entry = iargs->dbentp;
226754925bf6Swillf 
226854925bf6Swillf     /*
226954925bf6Swillf      * Convert the master key password into a key for this particular
227054925bf6Swillf      * encryption system.
227154925bf6Swillf      */
227254925bf6Swillf     pwd.data = mkey_password;
227354925bf6Swillf     pwd.length = strlen(mkey_password);
227454925bf6Swillf     kret = krb5_c_random_seed(context, &pwd);
227554925bf6Swillf     if (kret)
227654925bf6Swillf 	return kret;
227754925bf6Swillf 
227854925bf6Swillf     /*if (!(kret = krb5_dbe_create_key_data(iargs->ctx, iargs->dbentp))) {*/
227954925bf6Swillf     if ((entry->key_data =
228054925bf6Swillf 	     (krb5_key_data *) realloc(entry->key_data,
228154925bf6Swillf 					    (sizeof(krb5_key_data) *
228254925bf6Swillf 					    (entry->n_key_data + 1)))) == NULL)
228354925bf6Swillf 	return (ENOMEM);
228454925bf6Swillf 
228554925bf6Swillf     memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data));
228654925bf6Swillf     ind = entry->n_key_data++;
228754925bf6Swillf 
228854925bf6Swillf     if (!(kret = krb5_c_make_random_key(context, ksent->ks_enctype,
228954925bf6Swillf 					&key))) {
229054925bf6Swillf 	kret = krb5_dbekd_encrypt_key_data(context,
229154925bf6Swillf 					   iargs->rblock->key,
229254925bf6Swillf 					   &key,
229354925bf6Swillf 					   NULL,
229454925bf6Swillf 					   1,
229554925bf6Swillf 					   &entry->key_data[ind]);
229654925bf6Swillf 	krb5_free_keyblock_contents(context, &key);
229754925bf6Swillf     }
229854925bf6Swillf     /*}*/
229954925bf6Swillf 
230054925bf6Swillf     return(kret);
230154925bf6Swillf }
230254925bf6Swillf /* End duplicate code */
230354925bf6Swillf 
230454925bf6Swillf /*
230554925bf6Swillf  * This function creates service principals when
230654925bf6Swillf  * creating the realm object.
230754925bf6Swillf  */
230854925bf6Swillf static int
230954925bf6Swillf kdb_ldap_create_principal (context, princ, op, pblock)
231054925bf6Swillf     krb5_context context;
231154925bf6Swillf     krb5_principal princ;
231254925bf6Swillf     enum ap_op op;
231354925bf6Swillf     struct realm_info *pblock;
231454925bf6Swillf {
231554925bf6Swillf     int              retval=0, currlen=0, princtype = 2 /* Service Principal */;
231654925bf6Swillf     unsigned char    *curr=NULL;
231754925bf6Swillf     krb5_tl_data     *tl_data=NULL;
231854925bf6Swillf     krb5_db_entry    entry;
231954925bf6Swillf     int              nentry=1;
232054925bf6Swillf     long             mask = 0;
232154925bf6Swillf     krb5_keyblock    key;
232254925bf6Swillf     int              kvno = 0;
232354925bf6Swillf     kdb5_dal_handle *dal_handle = NULL;
232454925bf6Swillf     krb5_ldap_context *ldap_context=NULL;
232554925bf6Swillf     struct iterate_args   iargs;
232654925bf6Swillf     krb5_data       *pdata;
232754925bf6Swillf 
232854925bf6Swillf     if ((pblock == NULL) || (context == NULL)) {
232954925bf6Swillf 	retval = EINVAL;
233054925bf6Swillf 	goto cleanup;
233154925bf6Swillf     }
233254925bf6Swillf     dal_handle = (kdb5_dal_handle *) context->db_context;
233354925bf6Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
233454925bf6Swillf     if (!(ldap_context)) {
233554925bf6Swillf 	retval = EINVAL;
233654925bf6Swillf 	goto cleanup;
233754925bf6Swillf     }
233854925bf6Swillf 
233954925bf6Swillf     memset(&entry, 0, sizeof(entry));
234054925bf6Swillf 
234154925bf6Swillf     tl_data = malloc(sizeof(*tl_data));
234254925bf6Swillf     if (tl_data == NULL) {
234354925bf6Swillf 	retval = ENOMEM;
234454925bf6Swillf 	goto cleanup;
234554925bf6Swillf     }
234654925bf6Swillf     memset(tl_data, 0, sizeof(*tl_data));
234754925bf6Swillf     tl_data->tl_data_length = 1 + 2 + 2 + 1 + 2 + 4;
234854925bf6Swillf     tl_data->tl_data_type = 7; /* KDB_TL_USER_INFO */
234954925bf6Swillf     curr = tl_data->tl_data_contents = malloc(tl_data->tl_data_length);
235054925bf6Swillf     if (tl_data->tl_data_contents == NULL) {
235154925bf6Swillf 	retval = ENOMEM;
235254925bf6Swillf 	goto cleanup;
235354925bf6Swillf     }
235454925bf6Swillf 
235554925bf6Swillf     memset(curr, 1, 1); /* Passing the mask as principal type */
235654925bf6Swillf     curr += 1;
235754925bf6Swillf     currlen = 2;
235854925bf6Swillf     STORE16_INT(curr, currlen);
235954925bf6Swillf     curr += currlen;
236054925bf6Swillf     STORE16_INT(curr, princtype);
236154925bf6Swillf     curr += currlen;
236254925bf6Swillf 
236354925bf6Swillf     mask |= KADM5_PRINCIPAL;
236454925bf6Swillf     mask |= KADM5_ATTRIBUTES ;
236554925bf6Swillf     mask |= KADM5_MAX_LIFE ;
236654925bf6Swillf     mask |= KADM5_MAX_RLIFE ;
236754925bf6Swillf     mask |= KADM5_PRINC_EXPIRE_TIME ;
236854925bf6Swillf     mask |= KADM5_KEY_DATA;
236954925bf6Swillf 
237054925bf6Swillf     entry.tl_data = tl_data;
237154925bf6Swillf     entry.n_tl_data += 1;
237254925bf6Swillf     /* Set the creator's name */
237354925bf6Swillf     {
237454925bf6Swillf 	krb5_timestamp now;
237554925bf6Swillf 	if ((retval = krb5_timeofday(context, &now)))
237654925bf6Swillf 	    goto cleanup;
237754925bf6Swillf 	if ((retval = krb5_dbe_update_mod_princ_data_new(context, &entry,
237854925bf6Swillf 			now, &db_create_princ)))
237954925bf6Swillf 	    goto cleanup;
238054925bf6Swillf     }
238154925bf6Swillf     entry.attributes = pblock->flags;
238254925bf6Swillf     entry.max_life = pblock->max_life;
238354925bf6Swillf     entry.max_renewable_life = pblock->max_rlife;
238454925bf6Swillf     entry.expiration = pblock->expiration;
238554925bf6Swillf     entry.mask = mask;
238654925bf6Swillf     if ((retval = krb5_copy_principal(context, princ, &entry.princ)))
238754925bf6Swillf 	goto cleanup;
238854925bf6Swillf 
238954925bf6Swillf 
239054925bf6Swillf     switch (op) {
239154925bf6Swillf     case TGT_KEY:
239254925bf6Swillf 	if ((pdata = krb5_princ_component(context, princ, 1)) &&
239354925bf6Swillf 	    pdata->length == strlen("history") &&
239454925bf6Swillf 	    !memcmp(pdata->data, "history", strlen("history"))) {
239554925bf6Swillf 
239654925bf6Swillf 	    /* Allocate memory for storing the key */
239754925bf6Swillf 	    if ((entry.key_data = (krb5_key_data *) malloc(
239854925bf6Swillf 					      sizeof(krb5_key_data))) == NULL) {
239954925bf6Swillf 		retval = ENOMEM;
240054925bf6Swillf 		goto cleanup;
240154925bf6Swillf 	    }
240254925bf6Swillf 
240354925bf6Swillf 	    memset(entry.key_data, 0, sizeof(krb5_key_data));
240454925bf6Swillf 	    entry.n_key_data++;
240554925bf6Swillf 
240654925bf6Swillf 	    retval = krb5_c_make_random_key(context, global_params.enctype, &key);
240754925bf6Swillf 	    if (retval) {
240854925bf6Swillf 		goto cleanup;
240954925bf6Swillf 	    }
241054925bf6Swillf 	    kvno = 1; /* New key is getting set */
241154925bf6Swillf 	    retval = krb5_dbekd_encrypt_key_data(context,
241254925bf6Swillf 					&ldap_context->lrparams->mkey,
241354925bf6Swillf 					&key, NULL, kvno,
241454925bf6Swillf 					&entry.key_data[entry.n_key_data - 1]);
241554925bf6Swillf 	    krb5_free_keyblock_contents(context, &key);
241654925bf6Swillf 	    if (retval) {
241754925bf6Swillf 		goto cleanup;
241854925bf6Swillf 	    }
241954925bf6Swillf 	} else {
242054925bf6Swillf 	    /*retval = krb5_c_make_random_key(context, 16, &key) ;*/
242154925bf6Swillf 	    iargs.ctx = context;
242254925bf6Swillf 	    iargs.rblock = pblock;
242354925bf6Swillf 	    iargs.dbentp = &entry;
242454925bf6Swillf 
242554925bf6Swillf 	    /*
242654925bf6Swillf 	     * create a set of random keys by iterating through the key/salt
242754925bf6Swillf 	     * list, ignoring salt types.
242854925bf6Swillf 	     */
242954925bf6Swillf 	    if ((retval = krb5_keysalt_iterate(pblock->kslist,
243054925bf6Swillf 					       pblock->nkslist,
243154925bf6Swillf 					       1,
243254925bf6Swillf 					       kdb_ldap_tgt_keysalt_iterate,
243354925bf6Swillf 					       (krb5_pointer) &iargs)))
243454925bf6Swillf 		return retval;
243554925bf6Swillf 	}
243654925bf6Swillf 	break;
243754925bf6Swillf 
243854925bf6Swillf     case MASTER_KEY:
243954925bf6Swillf 	/* Allocate memory for storing the key */
244054925bf6Swillf 	if ((entry.key_data = (krb5_key_data *) malloc(
244154925bf6Swillf 					      sizeof(krb5_key_data))) == NULL) {
244254925bf6Swillf 	    retval = ENOMEM;
244354925bf6Swillf 	    goto cleanup;
244454925bf6Swillf 	}
244554925bf6Swillf 
244654925bf6Swillf 	memset(entry.key_data, 0, sizeof(krb5_key_data));
244754925bf6Swillf 	entry.n_key_data++;
244854925bf6Swillf 	kvno = 1; /* New key is getting set */
244954925bf6Swillf 	retval = krb5_dbekd_encrypt_key_data(context, pblock->key,
245054925bf6Swillf 					 &ldap_context->lrparams->mkey,
245154925bf6Swillf 					 NULL, kvno,
245254925bf6Swillf 					 &entry.key_data[entry.n_key_data - 1]);
245354925bf6Swillf 	if (retval) {
245454925bf6Swillf 	    goto cleanup;
245554925bf6Swillf 	}
245654925bf6Swillf 	break;
245754925bf6Swillf 
245854925bf6Swillf     case NULL_KEY:
245954925bf6Swillf     default:
246054925bf6Swillf 	break;
246154925bf6Swillf     } /* end of switch */
246254925bf6Swillf 
246354925bf6Swillf     retval = krb5_ldap_put_principal(context, &entry, &nentry, NULL);
246454925bf6Swillf     if (retval) {
246554925bf6Swillf 	com_err(NULL, retval, gettext("while adding entries to database"));
246654925bf6Swillf 	goto cleanup;
246754925bf6Swillf     }
246854925bf6Swillf 
246954925bf6Swillf cleanup:
247054925bf6Swillf     krb5_dbe_free_contents(context, &entry);
247154925bf6Swillf     return retval;
247254925bf6Swillf }
247354925bf6Swillf 
247454925bf6Swillf 
247554925bf6Swillf /*
247654925bf6Swillf  * This function destroys the realm object and the associated principals
247754925bf6Swillf  */
247854925bf6Swillf void
247954925bf6Swillf kdb5_ldap_destroy(argc, argv)
248054925bf6Swillf     int argc;
248154925bf6Swillf     char *argv[];
248254925bf6Swillf {
248354925bf6Swillf     extern char *optarg;
248454925bf6Swillf     extern int optind;
248554925bf6Swillf     int optchar = 0;
248654925bf6Swillf     char buf[5] = {0};
248754925bf6Swillf     krb5_error_code retval = 0;
248854925bf6Swillf     int force = 0;
248954925bf6Swillf     int mask = 0;
249054925bf6Swillf     kdb5_dal_handle *dal_handle = NULL;
249154925bf6Swillf     krb5_ldap_context *ldap_context = NULL;
249254925bf6Swillf #ifdef HAVE_EDIRECTORY
249354925bf6Swillf     int i = 0, rightsmask = 0;
249454925bf6Swillf     krb5_ldap_realm_params *rparams = NULL;
249554925bf6Swillf #endif
249654925bf6Swillf     /* Solaris Kerberos: to remove stash file */
249754925bf6Swillf     char *stash_file = NULL;
249854925bf6Swillf     struct stat stb;
249954925bf6Swillf 
250054925bf6Swillf     optind = 1;
250154925bf6Swillf     while ((optchar = getopt(argc, argv, "f")) != -1) {
250254925bf6Swillf 	switch (optchar) {
250354925bf6Swillf 	case 'f':
250454925bf6Swillf 	    force++;
250554925bf6Swillf 	    break;
250654925bf6Swillf 	case '?':
250754925bf6Swillf 	default:
250854925bf6Swillf 	    db_usage(DESTROY_REALM);
250954925bf6Swillf 	    return;
251054925bf6Swillf 	    /*NOTREACHED*/
251154925bf6Swillf 	}
251254925bf6Swillf     }
251354925bf6Swillf 
251454925bf6Swillf     if (!force) {
251554925bf6Swillf 	printf(gettext("Deleting KDC database of '%s', are you sure?\n"), global_params.realm);
251654925bf6Swillf 	printf(gettext("(type 'yes' to confirm)? "));
251754925bf6Swillf 	if (fgets(buf, sizeof(buf), stdin) == NULL) {
251854925bf6Swillf 	    exit_status++;
251954925bf6Swillf 	    return;
252054925bf6Swillf 	}
252154925bf6Swillf 	if (strcmp(buf, yes)) {
252254925bf6Swillf 	    exit_status++;
252354925bf6Swillf 	    return;
252454925bf6Swillf 	}
252554925bf6Swillf 	printf(gettext("OK, deleting database of '%s'...\n"), global_params.realm);
252654925bf6Swillf     }
252754925bf6Swillf 
252854925bf6Swillf     dal_handle = (kdb5_dal_handle *)util_context->db_context;
252954925bf6Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
253054925bf6Swillf     if (!(ldap_context)) {
2531dd9ccd46S 	/* Solaris Kerberos */
2532dd9ccd46S 	com_err(progname, EINVAL, gettext("while initializing database"));
253354925bf6Swillf 	exit_status++;
253454925bf6Swillf 	return;
253554925bf6Swillf     }
253654925bf6Swillf 
253754925bf6Swillf     /* Read the kerberos container from the LDAP Server */
253854925bf6Swillf     if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
253954925bf6Swillf 						     &(ldap_context->krbcontainer))) != 0) {
2540dd9ccd46S 	/* Solaris Kerberos */
2541dd9ccd46S 	com_err(progname, retval, gettext("while reading kerberos container information"));
254254925bf6Swillf 	exit_status++;
254354925bf6Swillf 	return;
254454925bf6Swillf     }
254554925bf6Swillf 
254654925bf6Swillf     /* Read the Realm information from the LDAP Server */
254754925bf6Swillf     if ((retval = krb5_ldap_read_realm_params(util_context, global_params.realm,
254854925bf6Swillf 					      &(ldap_context->lrparams), &mask)) != 0) {
2549dd9ccd46S 	/* Solaris Kerberos */
2550dd9ccd46S 	com_err(progname, retval, gettext("while reading realm information"));
255154925bf6Swillf 	exit_status++;
255254925bf6Swillf 	return;
255354925bf6Swillf     }
255454925bf6Swillf 
255554925bf6Swillf #ifdef HAVE_EDIRECTORY
255654925bf6Swillf     if ((mask & LDAP_REALM_KDCSERVERS) || (mask & LDAP_REALM_ADMINSERVERS) ||
255754925bf6Swillf 	(mask & LDAP_REALM_PASSWDSERVERS)) {
255854925bf6Swillf 
255954925bf6Swillf 	printf(gettext("Changing rights for the service object. Please wait ... "));
256054925bf6Swillf 	fflush(stdout);
256154925bf6Swillf 
256254925bf6Swillf 	rparams = ldap_context->lrparams;
256354925bf6Swillf 	rightsmask = 0;
256454925bf6Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
256554925bf6Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
256654925bf6Swillf 	if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
256754925bf6Swillf 	    for (i=0; (rparams->kdcservers[i] != NULL); i++) {
256854925bf6Swillf 		if ((retval = krb5_ldap_delete_service_rights(util_context,
256954925bf6Swillf 							      LDAP_KDC_SERVICE, rparams->kdcservers[i],
257054925bf6Swillf 							      rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
257154925bf6Swillf 		    printf(gettext("failed\n"));
2572dd9ccd46S 		    /* Solaris Kerberos */
2573dd9ccd46S 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
257454925bf6Swillf 			    rparams->realm_name);
257554925bf6Swillf 		    return;
257654925bf6Swillf 		}
257754925bf6Swillf 	    }
257854925bf6Swillf 	}
257954925bf6Swillf 	rightsmask = 0;
258054925bf6Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
258154925bf6Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
258254925bf6Swillf 	if ((rparams != NULL) && (rparams->adminservers != NULL)) {
258354925bf6Swillf 	    for (i=0; (rparams->adminservers[i] != NULL); i++) {
258454925bf6Swillf 		if ((retval = krb5_ldap_delete_service_rights(util_context,
258554925bf6Swillf 							      LDAP_ADMIN_SERVICE, rparams->adminservers[i],
258654925bf6Swillf 							      rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
258754925bf6Swillf 		    printf(gettext("failed\n"));
2588dd9ccd46S 		    /* Solaris Kerberos */
2589dd9ccd46S 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
259054925bf6Swillf 			    rparams->realm_name);
259154925bf6Swillf 		    return;
259254925bf6Swillf 		}
259354925bf6Swillf 	    }
259454925bf6Swillf 	}
259554925bf6Swillf 	rightsmask = 0;
259654925bf6Swillf 	rightsmask |= LDAP_REALM_RIGHTS;
259754925bf6Swillf 	rightsmask |= LDAP_SUBTREE_RIGHTS;
259854925bf6Swillf 	if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
259954925bf6Swillf 	    for (i=0; (rparams->passwdservers[i] != NULL); i++) {
260054925bf6Swillf 		if ((retval = krb5_ldap_delete_service_rights(util_context,
260154925bf6Swillf 							      LDAP_PASSWD_SERVICE, rparams->passwdservers[i],
260254925bf6Swillf 							      rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
260354925bf6Swillf 		    printf(gettext("failed\n"));
2604dd9ccd46S 		    /* Solaris Kerberos */
2605dd9ccd46S 		    com_err(progname, retval, gettext("while assigning rights to '%s'"),
260654925bf6Swillf 			    rparams->realm_name);
260754925bf6Swillf 		    return;
260854925bf6Swillf 		}
260954925bf6Swillf 	    }
261054925bf6Swillf 	}
261154925bf6Swillf 	printf(gettext("done\n"));
261254925bf6Swillf     }
261354925bf6Swillf #endif
261454925bf6Swillf     /* Delete the realm container and all the associated principals */
261554925bf6Swillf     retval = krb5_ldap_delete_realm(util_context, global_params.realm);
261654925bf6Swillf     if (retval) {
2617dd9ccd46S 	/* Solaris Kerberos */
2618dd9ccd46S 	com_err(progname, retval, gettext("deleting database of '%s'"), global_params.realm);
261954925bf6Swillf 	exit_status++;
262054925bf6Swillf 	return;
262154925bf6Swillf     }
262254925bf6Swillf 
262354925bf6Swillf     /*
262454925bf6Swillf      * Solaris Kerberos: check for a stash file and delete it if necessary
262554925bf6Swillf      * This behavior exists in the Solaris version of kdb5_util destroy.
262654925bf6Swillf      */
262754925bf6Swillf     if (global_params.stash_file == NULL) {
262854925bf6Swillf 	char stashbuf[MAXPATHLEN+1];
262954925bf6Swillf 	int realm_len = strlen(global_params.realm);
263054925bf6Swillf 
263154925bf6Swillf 	(void) strlcpy(stashbuf, DEFAULT_KEYFILE_STUB, sizeof (stashbuf));
263254925bf6Swillf 
263354925bf6Swillf 	if (realm_len <= (MAXPATHLEN-strlen(stashbuf))) {
263454925bf6Swillf 	    (void) strncat(stashbuf, global_params.realm,
263554925bf6Swillf 		(MAXPATHLEN-strlen(stashbuf)));
263654925bf6Swillf 	} else {
2637dd9ccd46S 	    /* Solaris Kerberos */
2638dd9ccd46S 	    com_err(progname, EINVAL,
263954925bf6Swillf 		gettext("can not determine stash file name for '%s'"),
264054925bf6Swillf 		global_params.realm);
264154925bf6Swillf 	    exit_status++;
264254925bf6Swillf 	    return;
264354925bf6Swillf 	}
264454925bf6Swillf 	stash_file = stashbuf;
264554925bf6Swillf     } else {
264654925bf6Swillf 	stash_file = global_params.stash_file;
264754925bf6Swillf     }
264854925bf6Swillf     /* Make sure stash_file is a regular file before unlinking */
264954925bf6Swillf     if (stat(stash_file, &stb) == 0) {
265054925bf6Swillf 	if ((stb.st_mode & S_IFMT) == S_IFREG) {
265154925bf6Swillf 	    (void)unlink(stash_file);
265254925bf6Swillf 	} else {
2653dd9ccd46S 	    /* Solaris Kerberos */
2654dd9ccd46S 	    com_err(progname, EINVAL,
265554925bf6Swillf 		gettext("stash file '%s' not a regular file, can not delete"),
265654925bf6Swillf 		stash_file);
265754925bf6Swillf 	    exit_status++;
265854925bf6Swillf 	    return;
265954925bf6Swillf 	}
266054925bf6Swillf     } else if (errno != ENOENT) {
266154925bf6Swillf 	/*
266254925bf6Swillf 	 * If the error is something other than the file doesn't exist set an
266354925bf6Swillf 	 * error.
266454925bf6Swillf 	 */
2665dd9ccd46S 	/* Solaris Kerberos */
2666dd9ccd46S 	com_err(progname, EINVAL,
266754925bf6Swillf 	    gettext("could not stat stash file '%s', could not delete"),
266854925bf6Swillf 	    stash_file);
266954925bf6Swillf 	exit_status++;
267054925bf6Swillf 	return;
267154925bf6Swillf     }
267254925bf6Swillf 
267354925bf6Swillf     printf(gettext("** Database of '%s' destroyed.\n"), global_params.realm);
267454925bf6Swillf 
267554925bf6Swillf     return;
267654925bf6Swillf }
2677