154925bf6Swillf /*
278894ffcSmp  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
354925bf6Swillf  * Use is subject to license terms.
454925bf6Swillf  */
554925bf6Swillf 
654925bf6Swillf /*
754925bf6Swillf  * kadmin/ldap_util/kdb5_ldap_util.c
854925bf6Swillf  *
954925bf6Swillf  * (C) Copyright 1990,1991, 1996 by the Massachusetts Institute of Technology.
1054925bf6Swillf  * All Rights Reserved.
1154925bf6Swillf  *
1254925bf6Swillf  * Export of this software from the United States of America may
1354925bf6Swillf  *   require a specific license from the United States Government.
1454925bf6Swillf  *   It is the responsibility of any person or organization contemplating
1554925bf6Swillf  *   export to obtain such a license before exporting.
1654925bf6Swillf  *
1754925bf6Swillf  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
1854925bf6Swillf  * distribute this software and its documentation for any purpose and
1954925bf6Swillf  * without fee is hereby granted, provided that the above copyright
2054925bf6Swillf  * notice appear in all copies and that both that copyright notice and
2154925bf6Swillf  * this permission notice appear in supporting documentation, and that
2254925bf6Swillf  * the name of M.I.T. not be used in advertising or publicity pertaining
2354925bf6Swillf  * to distribution of the software without specific, written prior
2454925bf6Swillf  * permission.  Furthermore if you modify this software you must label
2554925bf6Swillf  * your software as modified software and not distribute it in such a
2654925bf6Swillf  * fashion that it might be confused with the original M.I.T. software.
2754925bf6Swillf  * M.I.T. makes no representations about the suitability of
2854925bf6Swillf  * this software for any purpose.  It is provided "as is" without express
2954925bf6Swillf  * or implied warranty.
3054925bf6Swillf  *
3154925bf6Swillf  *
3254925bf6Swillf  * Edit a KDC database.
3354925bf6Swillf  */
3454925bf6Swillf 
3554925bf6Swillf /*
3654925bf6Swillf  * Copyright (C) 1998 by the FundsXpress, INC.
3754925bf6Swillf  *
3854925bf6Swillf  * All rights reserved.
3954925bf6Swillf  *
4054925bf6Swillf  * Export of this software from the United States of America may require
4154925bf6Swillf  * a specific license from the United States Government.  It is the
4254925bf6Swillf  * responsibility of any person or organization contemplating export to
4354925bf6Swillf  * obtain such a license before exporting.
4454925bf6Swillf  *
4554925bf6Swillf  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
4654925bf6Swillf  * distribute this software and its documentation for any purpose and
4754925bf6Swillf  * without fee is hereby granted, provided that the above copyright
4854925bf6Swillf  * notice appear in all copies and that both that copyright notice and
4954925bf6Swillf  * this permission notice appear in supporting documentation, and that
5054925bf6Swillf  * the name of FundsXpress. not be used in advertising or publicity pertaining
5154925bf6Swillf  * to distribution of the software without specific, written prior
5254925bf6Swillf  * permission.  FundsXpress makes no representations about the suitability of
5354925bf6Swillf  * this software for any purpose.  It is provided "as is" without express
5454925bf6Swillf  * or implied warranty.
5554925bf6Swillf  *
5654925bf6Swillf  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
5754925bf6Swillf  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
5854925bf6Swillf  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
5954925bf6Swillf  */
6054925bf6Swillf 
6154925bf6Swillf /* Copyright (c) 2004-2005, Novell, Inc.
6254925bf6Swillf  * All rights reserved.
6354925bf6Swillf  *
6454925bf6Swillf  * Redistribution and use in source and binary forms, with or without
6554925bf6Swillf  * modification, are permitted provided that the following conditions are met:
6654925bf6Swillf  *
6754925bf6Swillf  *   * Redistributions of source code must retain the above copyright notice,
6854925bf6Swillf  *       this list of conditions and the following disclaimer.
6954925bf6Swillf  *   * Redistributions in binary form must reproduce the above copyright
7054925bf6Swillf  *       notice, this list of conditions and the following disclaimer in the
7154925bf6Swillf  *       documentation and/or other materials provided with the distribution.
7254925bf6Swillf  *   * The copyright holder's name is not used to endorse or promote products
7354925bf6Swillf  *       derived from this software without specific prior written permission.
7454925bf6Swillf  *
7554925bf6Swillf  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
7654925bf6Swillf  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7754925bf6Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7854925bf6Swillf  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
7954925bf6Swillf  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
8054925bf6Swillf  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
8154925bf6Swillf  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8254925bf6Swillf  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
8354925bf6Swillf  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
8454925bf6Swillf  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8554925bf6Swillf  * POSSIBILITY OF SUCH DAMAGE.
8654925bf6Swillf  */
8754925bf6Swillf 
8854925bf6Swillf #include <stdio.h>
8954925bf6Swillf #include <time.h>
9054925bf6Swillf 
9154925bf6Swillf #include <k5-int.h>
9254925bf6Swillf #include <kadm5/admin.h>
9354925bf6Swillf #include <adm_proto.h>
9454925bf6Swillf #include <libintl.h>
9554925bf6Swillf #include <locale.h>
9654925bf6Swillf #include "kdb5_ldap_util.h"
9754925bf6Swillf 
9854925bf6Swillf typedef void (*cmd_func)(int, char **);
9954925bf6Swillf int cmd_index(char *name);
10054925bf6Swillf 
10154925bf6Swillf char *mkey_password = 0;
10254925bf6Swillf int exit_status = 0;
10354925bf6Swillf krb5_context util_context;
10454925bf6Swillf kadm5_config_params global_params;
10554925bf6Swillf krb5_boolean db_inited = FALSE;
10654925bf6Swillf 
10754925bf6Swillf char *progname;
10854925bf6Swillf krb5_boolean manual_mkey = FALSE;
10954925bf6Swillf 
11054925bf6Swillf /*
11154925bf6Swillf  * This function prints the usage of kdb5_ldap_util, which is
11254925bf6Swillf  * the LDAP configuration utility.
11354925bf6Swillf  */
usage()11454925bf6Swillf void usage()
11554925bf6Swillf {
11654925bf6Swillf     fprintf(stderr, "%s: "
11754925bf6Swillf "kdb5_ldap_util [-D user_dn [-w passwd]] [-H ldapuri]\n"
11854925bf6Swillf "\tcmd [cmd_options]\n"
11954925bf6Swillf 
12054925bf6Swillf /* Create realm */
12154925bf6Swillf "create          [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn]\n"
12254925bf6Swillf #ifdef HAVE_EDIRECTORY
12354925bf6Swillf "\t\t[-kdcdn kdc_service_list] [-admindn admin_service_list]\n"
12454925bf6Swillf "\t\t[-pwddn passwd_service_list]\n"
12554925bf6Swillf #endif
12654925bf6Swillf "\t\t[-m|-P password|-sf stashfilename] [-k mkeytype] [-s]\n"
12754925bf6Swillf "\t\t[-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life]\n"
12854925bf6Swillf "\t\t[ticket_flags] [-r realm]\n"
12954925bf6Swillf 
13054925bf6Swillf /* modify realm */
13154925bf6Swillf "modify          [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn]\n"
13254925bf6Swillf #ifdef HAVE_EDIRECTORY
13354925bf6Swillf "\t\t[-kdcdn kdc_service_list |\n"
13454925bf6Swillf "\t\t[-clearkdcdn kdc_service_list] [-addkdcdn kdc_service_list]]\n"
13554925bf6Swillf "\t\t[-admindn admin_service_list | [-clearadmindn admin_service_list]\n"
13654925bf6Swillf "\t\t[-addadmindn admin_service_list]] [-pwddn passwd_service_list |\n"
13754925bf6Swillf "\t\t[-clearpwddn passwd_service_list] [-addpwddn passwd_service_list]]\n"
13854925bf6Swillf #endif
13954925bf6Swillf "\t\t[-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life]\n"
14054925bf6Swillf "\t\t[ticket_flags] [-r realm]\n"
14154925bf6Swillf /* View realm */
14254925bf6Swillf "view            [-r realm]\n"
14354925bf6Swillf 
14454925bf6Swillf /* Destroy realm */
14554925bf6Swillf "destroy	        [-f] [-r realm]\n"
14654925bf6Swillf 
14754925bf6Swillf /* List realms */
14854925bf6Swillf "list\n"
14954925bf6Swillf 
15054925bf6Swillf #ifdef HAVE_EDIRECTORY
15154925bf6Swillf /* Create Service */
15254925bf6Swillf "create_service  {-kdc|-admin|-pwd} [-servicehost service_host_list]\n"
15354925bf6Swillf "\t\t[-realm realm_list] \n"
15454925bf6Swillf "\t\t[-randpw|-fileonly] [-f filename] service_dn\n"
15554925bf6Swillf 
15654925bf6Swillf /* Modify service */
15754925bf6Swillf "modify_service  [-servicehost service_host_list |\n"
15854925bf6Swillf "\t\t[-clearservicehost service_host_list]\n"
15954925bf6Swillf "\t\t[-addservicehost service_host_list]]\n"
16054925bf6Swillf "\t\t[-realm realm_list | [-clearrealm realm_list]\n"
16154925bf6Swillf "\t\t[-addrealm realm_list]] service_dn\n"
16254925bf6Swillf 
16354925bf6Swillf /* View Service */
16454925bf6Swillf "view_service    service_dn\n"
16554925bf6Swillf 
16654925bf6Swillf /* Destroy Service */
16754925bf6Swillf "destroy_service [-force] [-f stashfilename] service_dn\n"
16854925bf6Swillf 
16954925bf6Swillf /* List services */
17054925bf6Swillf "list_service    [-basedn base_dn]\n"
17154925bf6Swillf 
17254925bf6Swillf /* Set Service password */
17354925bf6Swillf "setsrvpw        [-randpw|-fileonly] [-f filename] service_dn\n"
17454925bf6Swillf 
17554925bf6Swillf #else
17654925bf6Swillf 
17754925bf6Swillf /* Stash the service password */
17854925bf6Swillf "stashsrvpw      [-f filename] service_dn\n"
17954925bf6Swillf 
18054925bf6Swillf #endif
18154925bf6Swillf 
18254925bf6Swillf /* Create policy */
18354925bf6Swillf "create_policy   [-r realm] [-maxtktlife max_ticket_life]\n"
18454925bf6Swillf "\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n"
18554925bf6Swillf 
18654925bf6Swillf /* Modify policy */
18754925bf6Swillf "modify_policy   [-r realm] [-maxtktlife max_ticket_life]\n"
18854925bf6Swillf "\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n"
18954925bf6Swillf 
19054925bf6Swillf /* View policy */
19154925bf6Swillf "view_policy     [-r realm] policy\n"
19254925bf6Swillf 
19354925bf6Swillf /* Destroy policy */
19454925bf6Swillf "destroy_policy  [-r realm] [-force] policy\n"
19554925bf6Swillf 
19654925bf6Swillf /* List policies */
19754925bf6Swillf "list_policy     [-r realm]\n",
19854925bf6Swillf     gettext("Usage"));
19954925bf6Swillf }
20054925bf6Swillf 
db_usage(int type)20154925bf6Swillf void db_usage (int type) {
20254925bf6Swillf     /*
20354925bf6Swillf      * This should print usage of 'type' command. For now, we will print usage
20454925bf6Swillf      * of all commands.
20554925bf6Swillf      */
20654925bf6Swillf     usage ();
20754925bf6Swillf }
20854925bf6Swillf 
20954925bf6Swillf /* The help messages for all sub-commands should be in the
21054925bf6Swillf  * same order as listed in this table.
21154925bf6Swillf  */
21254925bf6Swillf static struct _cmd_table {
21354925bf6Swillf     char *name;
21454925bf6Swillf     cmd_func func;
21554925bf6Swillf     int opendb;
21654925bf6Swillf } cmd_table[] = {
21754925bf6Swillf     {"create", kdb5_ldap_create, 1},
21854925bf6Swillf     {"modify", kdb5_ldap_modify, 1},
21954925bf6Swillf     {"view", kdb5_ldap_view, 1},
22054925bf6Swillf     {"destroy", kdb5_ldap_destroy, 1},
22154925bf6Swillf     {"list", kdb5_ldap_list, 1},
22254925bf6Swillf #ifdef HAVE_EDIRECTORY
22354925bf6Swillf     {"create_service", kdb5_ldap_create_service, 1},
22454925bf6Swillf     {"modify_service", kdb5_ldap_modify_service, 1},
22554925bf6Swillf     {"view_service", kdb5_ldap_view_service, 1},
22654925bf6Swillf     {"destroy_service", kdb5_ldap_destroy_service, 1},
22754925bf6Swillf     {"list_service",kdb5_ldap_list_services,1},
22854925bf6Swillf     {"setsrvpw", kdb5_ldap_set_service_password, 0},
22954925bf6Swillf #else
23054925bf6Swillf     {"stashsrvpw", kdb5_ldap_stash_service_password, 0},
23154925bf6Swillf #endif
23254925bf6Swillf     {"create_policy", kdb5_ldap_create_policy, 1},
23354925bf6Swillf     {"modify_policy", kdb5_ldap_modify_policy, 1},
23454925bf6Swillf     {"view_policy", kdb5_ldap_view_policy, 1},
23554925bf6Swillf     {"destroy_policy", kdb5_ldap_destroy_policy, 1},
23654925bf6Swillf     {"list_policy", kdb5_ldap_list_policies, 1},
23754925bf6Swillf     {NULL, NULL, 0},
23854925bf6Swillf };
23954925bf6Swillf 
24054925bf6Swillf 
24154925bf6Swillf /*
24254925bf6Swillf  * The function cmd_lookup returns the structure matching the
24354925bf6Swillf  * command name and returns NULL if nothing matches.
24454925bf6Swillf  */
cmd_lookup(name)24554925bf6Swillf static struct _cmd_table *cmd_lookup(name)
24654925bf6Swillf     char *name;
24754925bf6Swillf {
24854925bf6Swillf     int i;
24954925bf6Swillf 
25054925bf6Swillf     for (i = 0; cmd_table[i].name != NULL; i++)
25154925bf6Swillf 	if (strcmp(cmd_table[i].name, name) == 0)
25254925bf6Swillf 	    return &cmd_table[i];
25354925bf6Swillf 
25454925bf6Swillf     return NULL;
25554925bf6Swillf }
25654925bf6Swillf 
25754925bf6Swillf 
25854925bf6Swillf /*
25954925bf6Swillf  * The function cmd_index provides the offset of the command
26054925bf6Swillf  * in the command table, which can be used to get the corresponding
26154925bf6Swillf  * help from the help message table.
26254925bf6Swillf  */
cmd_index(name)26354925bf6Swillf int cmd_index(name)
26454925bf6Swillf     char *name;
26554925bf6Swillf {
26654925bf6Swillf     int i;
26754925bf6Swillf 
26854925bf6Swillf     if (name == NULL)
26954925bf6Swillf 	return -1;
27054925bf6Swillf 
27154925bf6Swillf     for (i = 0; cmd_table[i].name != NULL; i++)
27254925bf6Swillf 	if (strcmp(cmd_table[i].name, name) == 0)
27354925bf6Swillf 	    return i;
27454925bf6Swillf 
27554925bf6Swillf     return -1;
27654925bf6Swillf }
27754925bf6Swillf 
extended_com_err_fn(const char * myprog,errcode_t code,const char * fmt,va_list args)27854925bf6Swillf static void extended_com_err_fn (const char *myprog, errcode_t code,
27954925bf6Swillf 				 const char *fmt, va_list args)
28054925bf6Swillf {
28154925bf6Swillf     const char *emsg;
28254925bf6Swillf     /* Solaris Kerberos: code should be like that in kdb5_util.c */
28354925bf6Swillf     if (code) {
28454925bf6Swillf 	emsg = krb5_get_error_message (util_context, code);
28554925bf6Swillf 	fprintf (stderr, "%s: %s ", myprog, emsg);
28654925bf6Swillf 	krb5_free_error_message (util_context, emsg);
28754925bf6Swillf     } else {
28854925bf6Swillf 	fprintf (stderr, "%s: ", myprog);
28954925bf6Swillf     }
29054925bf6Swillf     vfprintf (stderr, fmt, args);
29154925bf6Swillf     fprintf (stderr, "\n");
29254925bf6Swillf }
29354925bf6Swillf 
main(argc,argv)29454925bf6Swillf int main(argc, argv)
29554925bf6Swillf     int argc;
29654925bf6Swillf     char *argv[];
29754925bf6Swillf {
29854925bf6Swillf     struct _cmd_table *cmd = NULL;
29954925bf6Swillf     char *koptarg = NULL, **cmd_argv = NULL;
30054925bf6Swillf     int cmd_argc = 0;
30154925bf6Swillf     krb5_error_code retval;
30254925bf6Swillf     int usage_print = 0;
30354925bf6Swillf     int gp_is_static = 1;
30454925bf6Swillf     krb5_error_code db_retval = 1;
30554925bf6Swillf     char *bind_dn = NULL;
30654925bf6Swillf     char *passwd = NULL;
30754925bf6Swillf     char *ldap_server = NULL;
30854925bf6Swillf     unsigned int ldapmask = 0;
30954925bf6Swillf     unsigned int passwd_len = 0;
31054925bf6Swillf     char *prompt = NULL;
31154925bf6Swillf     kdb5_dal_handle *dal_handle = NULL;
31254925bf6Swillf     krb5_ldap_context *ldap_context=NULL;
31354925bf6Swillf     char *value = NULL, *conf_section = NULL;
31454925bf6Swillf     krb5_boolean realm_name_required = TRUE;
31554925bf6Swillf     krb5_boolean print_help_message = FALSE;
31654925bf6Swillf 
31778894ffcSmp     /*
31878894ffcSmp      * Solaris Kerberos:
31978894ffcSmp      * Ensure that "progname" is set before calling com_err.
32078894ffcSmp      */
32178894ffcSmp     progname = (strrchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
32278894ffcSmp 
32354925bf6Swillf     retval = krb5_init_context(&util_context);
32454925bf6Swillf     set_com_err_hook(extended_com_err_fn);
32554925bf6Swillf     if (retval) {
32654925bf6Swillf 	com_err (progname, retval, gettext("while initializing Kerberos code"));
32754925bf6Swillf 	exit_status++;
32854925bf6Swillf 	goto cleanup;
32954925bf6Swillf     }
33054925bf6Swillf 
33154925bf6Swillf     cmd_argv = (char **) malloc(sizeof(char *)*argc);
33254925bf6Swillf     if (cmd_argv == NULL) {
33354925bf6Swillf 	com_err(progname, ENOMEM, gettext("while creating sub-command arguments"));
33454925bf6Swillf 	exit_status++;
33554925bf6Swillf 	goto cleanup;
33654925bf6Swillf     }
33754925bf6Swillf     memset(cmd_argv, 0, sizeof(char *)*argc);
33854925bf6Swillf     cmd_argc = 1;
33954925bf6Swillf 
34054925bf6Swillf     memset(&global_params, 0, sizeof(kadm5_config_params));
34154925bf6Swillf 
34254925bf6Swillf     argv++; argc--;
34354925bf6Swillf     while (*argv) {
34454925bf6Swillf 	if (strcmp(*argv, "--help") == 0) {
34554925bf6Swillf 	    print_help_message = TRUE;
34654925bf6Swillf 	}
34754925bf6Swillf 	if (strcmp(*argv, "-P") == 0 && ARG_VAL) {
34854925bf6Swillf 	    mkey_password = koptarg;
34954925bf6Swillf 	    manual_mkey = TRUE;
35054925bf6Swillf 	} else if (strcmp(*argv, "-r") == 0 && ARG_VAL) {
35154925bf6Swillf 	    global_params.realm = koptarg;
35254925bf6Swillf 	    global_params.mask |= KADM5_CONFIG_REALM;
35354925bf6Swillf 	    /* not sure this is really necessary */
35454925bf6Swillf 	    if ((retval = krb5_set_default_realm(util_context,
35554925bf6Swillf 						 global_params.realm))) {
35654925bf6Swillf 		com_err(progname, retval, gettext("while setting default realm name"));
35754925bf6Swillf 		exit_status++;
35854925bf6Swillf 		goto cleanup;
35954925bf6Swillf 	    }
36054925bf6Swillf 	} else if (strcmp(*argv, "-k") == 0 && ARG_VAL) {
361*dd9ccd46S 	    if (krb5_string_to_enctype(koptarg, &global_params.enctype)) {
362*dd9ccd46S 		/* Solaris Kerberos */
363*dd9ccd46S 		com_err(progname, 0, gettext("%s is an invalid enctype"), koptarg);
364*dd9ccd46S 	    }
36554925bf6Swillf 	    else
36654925bf6Swillf 		global_params.mask |= KADM5_CONFIG_ENCTYPE;
36754925bf6Swillf 	} else if (strcmp(*argv, "-M") == 0 && ARG_VAL) {
36854925bf6Swillf 	    global_params.mkey_name = koptarg;
36954925bf6Swillf 	    global_params.mask |= KADM5_CONFIG_MKEY_NAME;
37054925bf6Swillf 	} else if (strcmp(*argv, "-sf") == 0 && ARG_VAL) {
37154925bf6Swillf 	    global_params.stash_file = koptarg;
37254925bf6Swillf 	    global_params.mask |= KADM5_CONFIG_STASH_FILE;
37354925bf6Swillf 	} else if (strcmp(*argv, "-m") == 0) {
37454925bf6Swillf 	    manual_mkey = TRUE;
37554925bf6Swillf 	    global_params.mkey_from_kbd = 1;
37654925bf6Swillf 	    global_params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
37754925bf6Swillf 	} else if (strcmp(*argv, "-D") == 0 && ARG_VAL) {
37854925bf6Swillf 	    bind_dn = koptarg;
37954925bf6Swillf 	    if (bind_dn == NULL) {
38054925bf6Swillf 		com_err(progname, ENOMEM, gettext("while reading ldap parameters"));
38154925bf6Swillf 		exit_status++;
38254925bf6Swillf 		goto cleanup;
38354925bf6Swillf 	    }
38454925bf6Swillf 	    ldapmask |= CMD_LDAP_D;
38554925bf6Swillf 	} else if (strcmp(*argv, "-w") == 0 && ARG_VAL) {
38654925bf6Swillf 	    passwd = strdup(koptarg);
38754925bf6Swillf 	    if (passwd == NULL) {
38854925bf6Swillf 		com_err(progname, ENOMEM, gettext("while reading ldap parameters"));
38954925bf6Swillf 		exit_status++;
39054925bf6Swillf 		goto cleanup;
39154925bf6Swillf 	    }
39254925bf6Swillf 	    ldapmask |= CMD_LDAP_W;
39354925bf6Swillf 	} else if (strcmp(*argv, "-H") == 0 && ARG_VAL) {
39454925bf6Swillf 	    ldap_server = koptarg;
39554925bf6Swillf 	    if (ldap_server == NULL) {
39654925bf6Swillf 		com_err(progname, ENOMEM, gettext("while reading ldap parameters"));
39754925bf6Swillf 		exit_status++;
39854925bf6Swillf 		goto cleanup;
39954925bf6Swillf 	    }
40054925bf6Swillf 	    ldapmask |= CMD_LDAP_H;
40154925bf6Swillf 	} else if (cmd_lookup(*argv) != NULL) {
40254925bf6Swillf 	    if (cmd_argv[0] == NULL)
40354925bf6Swillf 		cmd_argv[0] = *argv;
40454925bf6Swillf 	    else {
40554925bf6Swillf 		free(cmd_argv);
40654925bf6Swillf 		cmd_argv = NULL;
40754925bf6Swillf 		usage();
40854925bf6Swillf 		goto cleanup;
40954925bf6Swillf 	    }
41054925bf6Swillf 	} else {
41154925bf6Swillf 	    cmd_argv[cmd_argc++] = *argv;
41254925bf6Swillf 	}
41354925bf6Swillf 	argv++; argc--;
41454925bf6Swillf     }
41554925bf6Swillf 
41654925bf6Swillf     if (cmd_argv[0] == NULL) {
41754925bf6Swillf 	free(cmd_argv);
41854925bf6Swillf 	cmd_argv = NULL;
41954925bf6Swillf 	usage();
42054925bf6Swillf 	goto cleanup;
42154925bf6Swillf     }
42254925bf6Swillf 
42354925bf6Swillf     /* if we need to print the help message (because of --help option)
42454925bf6Swillf      * we will print the help corresponding to the sub-command.
42554925bf6Swillf      */
42654925bf6Swillf     if (print_help_message) {
42754925bf6Swillf 	char *cmd_name = cmd_argv[0];
42854925bf6Swillf 	free(cmd_argv);
42954925bf6Swillf 	cmd_argv = NULL;
43054925bf6Swillf 	usage();
43154925bf6Swillf 	goto cleanup;
43254925bf6Swillf     }
43354925bf6Swillf 
43454925bf6Swillf     /* We need to check for the presence of default realm name only in
43554925bf6Swillf      * the case of realm related operations like create, destroy etc.
43654925bf6Swillf      */
43754925bf6Swillf     if ((strcmp(cmd_argv[0], "list") == 0) ||
43854925bf6Swillf         (strcmp(cmd_argv[0], "stashsrvpw") == 0)) {
43954925bf6Swillf         realm_name_required = FALSE;
44054925bf6Swillf     }
44154925bf6Swillf 
44254925bf6Swillf     if (!util_context->default_realm) {
44354925bf6Swillf 	char *temp = NULL;
44454925bf6Swillf 	retval = krb5_get_default_realm(util_context, &temp);
44554925bf6Swillf 	if (retval) {
44654925bf6Swillf 	    if (realm_name_required) {
44754925bf6Swillf 		com_err (progname, retval, gettext("while getting default realm"));
44854925bf6Swillf 		exit_status++;
44954925bf6Swillf 		goto cleanup;
45054925bf6Swillf 	    }
45154925bf6Swillf 	} else
45254925bf6Swillf 	    util_context->default_realm = temp;
45354925bf6Swillf     }
45454925bf6Swillf     /* If we have the realm name, we can safely say that
45554925bf6Swillf      * realm_name is required so that we don't neglect any information.
45654925bf6Swillf      */
45754925bf6Swillf     else
45854925bf6Swillf 	realm_name_required = TRUE;
45954925bf6Swillf 
46054925bf6Swillf     retval = profile_get_string(util_context->profile, KDB_REALM_SECTION,
46154925bf6Swillf 				util_context->default_realm, KDB_MODULE_POINTER,
46254925bf6Swillf 				NULL,
46354925bf6Swillf 				&value);
46454925bf6Swillf 
46554925bf6Swillf     if (!(value)) {
46654925bf6Swillf 	retval = profile_get_string(util_context->profile, KDB_MODULE_DEF_SECTION,
46754925bf6Swillf 				    KDB_MODULE_POINTER, NULL,
46854925bf6Swillf 				    NULL,
46954925bf6Swillf 				    &value);
47054925bf6Swillf 	if (!(value)) {
47154925bf6Swillf 	    if (util_context->default_realm)
47254925bf6Swillf 		conf_section = strdup(util_context->default_realm);
47354925bf6Swillf 	} else {
47454925bf6Swillf 	    conf_section = strdup(value);
47554925bf6Swillf 	    free(value);
47654925bf6Swillf 	}
47754925bf6Swillf     } else {
47854925bf6Swillf 	conf_section = strdup(value);
47954925bf6Swillf 	free(value);
48054925bf6Swillf     }
48154925bf6Swillf 
48254925bf6Swillf     if (realm_name_required) {
483159d09a2SMark Phalan 	retval = kadm5_get_config_params(util_context, 1,
48454925bf6Swillf 					 &global_params, &global_params);
48554925bf6Swillf 	if (retval) {
486*dd9ccd46S 	    /* Solaris Kerberos */
487*dd9ccd46S 	    com_err(progname, retval, gettext("while retreiving configuration parameters"));
48854925bf6Swillf 	    exit_status++;
48954925bf6Swillf 	    goto cleanup;
49054925bf6Swillf 	}
49154925bf6Swillf 	gp_is_static = 0;
49254925bf6Swillf     }
49354925bf6Swillf 
49454925bf6Swillf     if ((retval = krb5_ldap_lib_init()) != 0) {
495*dd9ccd46S 	/* Solaris Kerberos */
496*dd9ccd46S 	com_err(progname, retval, gettext("while initializing error handling"));
49754925bf6Swillf 	exit_status++;
49854925bf6Swillf 	goto cleanup;
49954925bf6Swillf     }
50054925bf6Swillf 
50154925bf6Swillf     /* Initialize the ldap context */
50254925bf6Swillf     ldap_context = calloc(sizeof(krb5_ldap_context), 1);
50354925bf6Swillf     if (ldap_context == NULL) {
504*dd9ccd46S 	/* Solaris Kerberos */
505*dd9ccd46S 	com_err(progname, ENOMEM, gettext("while initializing ldap handle"));
50654925bf6Swillf 	exit_status++;
50754925bf6Swillf 	goto cleanup;
50854925bf6Swillf     }
50954925bf6Swillf 
51054925bf6Swillf     ldap_context->kcontext = util_context;
51154925bf6Swillf 
51254925bf6Swillf     /* If LDAP parameters are specified, replace them with the values from config */
51354925bf6Swillf     if (ldapmask & CMD_LDAP_D) {
51454925bf6Swillf 	/* If password is not specified, prompt for it */
51554925bf6Swillf 	if (passwd == NULL) {
51654925bf6Swillf 	    passwd = (char *)malloc(MAX_PASSWD_LEN);
51754925bf6Swillf 	    if (passwd == NULL) {
518*dd9ccd46S 		/* Solaris Kerberos */
519*dd9ccd46S 		com_err(progname, ENOMEM, gettext("while retrieving ldap configuration"));
52054925bf6Swillf 		exit_status++;
52154925bf6Swillf 		goto cleanup;
52254925bf6Swillf 	    }
52354925bf6Swillf 	    prompt = (char *)malloc(MAX_PASSWD_PROMPT_LEN);
52454925bf6Swillf 	    if (prompt == NULL) {
52554925bf6Swillf 		free(passwd);
52654925bf6Swillf 		passwd = NULL;
527*dd9ccd46S 		/* Solaris Kerberos */
528*dd9ccd46S 		com_err(progname, ENOMEM, gettext("while retrieving ldap configuration"));
52954925bf6Swillf 		exit_status++;
53054925bf6Swillf 		goto cleanup;
53154925bf6Swillf 	    }
53254925bf6Swillf 	    memset(passwd, 0, sizeof(passwd));
53354925bf6Swillf 	    passwd_len = MAX_PASSWD_LEN - 1;
53454925bf6Swillf 	    snprintf(prompt, MAX_PASSWD_PROMPT_LEN, gettext("Password for \"%s\""), bind_dn);
53554925bf6Swillf 
53654925bf6Swillf 	    db_retval = krb5_read_password(util_context, prompt, NULL, passwd, &passwd_len);
53754925bf6Swillf 
53854925bf6Swillf 	    if ((db_retval) || (passwd_len == 0)) {
539*dd9ccd46S 		/* Solaris Kerberos */
540*dd9ccd46S 		com_err(progname, db_retval, gettext("while retrieving ldap configuration"));
54154925bf6Swillf 		free(passwd);
54254925bf6Swillf 		passwd = NULL;
54354925bf6Swillf 		exit_status++;
54454925bf6Swillf 		goto cleanup;
54554925bf6Swillf 	    }
54654925bf6Swillf 	}
54754925bf6Swillf 
54854925bf6Swillf 	ldap_context->bind_pwd = passwd;
54954925bf6Swillf     }
55054925bf6Swillf 
55154925bf6Swillf     /* If ldaphost is specified, release entry filled by configuration & use this */
55254925bf6Swillf     if (ldapmask & CMD_LDAP_H) {
55354925bf6Swillf 
55454925bf6Swillf 	ldap_context->server_info_list = (krb5_ldap_server_info **) calloc (2, sizeof (krb5_ldap_server_info *)) ;
55554925bf6Swillf 	if (ldap_context->server_info_list == NULL) {
556*dd9ccd46S 	    /* Solaris Kerberos */
557*dd9ccd46S 	    com_err(progname, ENOMEM, gettext("while initializing server list"));
55854925bf6Swillf 	    exit_status++;
55954925bf6Swillf 	    goto cleanup;
56054925bf6Swillf 	}
56154925bf6Swillf 
56254925bf6Swillf 	ldap_context->server_info_list[0] = (krb5_ldap_server_info *) calloc (1, sizeof (krb5_ldap_server_info));
56354925bf6Swillf 	if (ldap_context->server_info_list[0] == NULL) {
564*dd9ccd46S 	    /* Solaris Kerberos */
565*dd9ccd46S 	    com_err(progname, ENOMEM, gettext("while initializing server list"));
56654925bf6Swillf 	    exit_status++;
56754925bf6Swillf 	    goto cleanup;
56854925bf6Swillf 	}
56954925bf6Swillf 
57054925bf6Swillf 	ldap_context->server_info_list[0]->server_status = NOTSET;
57154925bf6Swillf 
57254925bf6Swillf 	ldap_context->server_info_list[0]->server_name = strdup(ldap_server);
57354925bf6Swillf 	if (ldap_context->server_info_list[0]->server_name == NULL) {
574*dd9ccd46S 	    /* Solaris Kerberos */
575*dd9ccd46S 	    com_err(progname, ENOMEM, gettext("while initializing server list"));
57654925bf6Swillf 	    exit_status++;
57754925bf6Swillf 	    goto cleanup;
57854925bf6Swillf 	}
57954925bf6Swillf     }
58054925bf6Swillf     if (bind_dn) {
58154925bf6Swillf 	ldap_context->bind_dn = strdup(bind_dn);
58254925bf6Swillf 	if (ldap_context->bind_dn == NULL) {
583*dd9ccd46S 	    /* Solaris Kerberos */
584*dd9ccd46S 	    com_err(progname, ENOMEM, gettext("while retrieving ldap configuration"));
58554925bf6Swillf 	    exit_status++;
58654925bf6Swillf 	    goto cleanup;
58754925bf6Swillf 	}
58854925bf6Swillf     } else
58954925bf6Swillf 	ldap_context->bind_dn = NULL;
59054925bf6Swillf 
59154925bf6Swillf     ldap_context->service_type = SERVICE_DN_TYPE_CLIENT;
59254925bf6Swillf 
59354925bf6Swillf     if (realm_name_required) {
59454925bf6Swillf 	if ((global_params.enctype != ENCTYPE_UNKNOWN) &&
59554925bf6Swillf 	    (!krb5_c_valid_enctype(global_params.enctype))) {
596*dd9ccd46S 	    /* Solaris Kerberos */
597*dd9ccd46S 	    com_err(progname, KRB5_PROG_KEYTYPE_NOSUPP,
59854925bf6Swillf 		    gettext("while setting up enctype %d"), global_params.enctype);
59954925bf6Swillf 	}
60054925bf6Swillf     }
60154925bf6Swillf 
60254925bf6Swillf     cmd = cmd_lookup(cmd_argv[0]);
60354925bf6Swillf 
60454925bf6Swillf     /* Setup DAL handle to access the database */
60554925bf6Swillf     dal_handle = calloc((size_t)1, sizeof(kdb5_dal_handle));
60654925bf6Swillf     if (dal_handle == NULL) {
60754925bf6Swillf 	goto cleanup;
60854925bf6Swillf     }
60954925bf6Swillf     dal_handle->db_context = ldap_context;
61054925bf6Swillf     util_context->db_context = (void *) dal_handle;
61154925bf6Swillf 
61254925bf6Swillf     db_retval = krb5_ldap_read_server_params(util_context, conf_section, KRB5_KDB_SRV_TYPE_OTHER);
61354925bf6Swillf     if (db_retval) {
614*dd9ccd46S 	/* Solaris Kerberos */
615*dd9ccd46S 	com_err(progname, db_retval, gettext("while reading ldap configuration"));
61654925bf6Swillf 	exit_status++;
61754925bf6Swillf 	goto cleanup;
61854925bf6Swillf     }
61954925bf6Swillf 
62054925bf6Swillf     if (cmd->opendb) {
62154925bf6Swillf 	db_retval = krb5_ldap_db_init(util_context, ldap_context);
62254925bf6Swillf 	if (db_retval) {
62354925bf6Swillf 	    com_err(progname, db_retval, gettext("while initializing database"));
62454925bf6Swillf 	    exit_status++;
62554925bf6Swillf 	    goto cleanup;
62654925bf6Swillf 	}
62754925bf6Swillf 	db_inited = TRUE;
62854925bf6Swillf     }
62954925bf6Swillf     (*cmd->func)(cmd_argc, cmd_argv);
63054925bf6Swillf 
63154925bf6Swillf     goto cleanup;
63254925bf6Swillf 
63354925bf6Swillf cleanup:
63454925bf6Swillf     if (passwd)
63554925bf6Swillf 	memset(passwd, 0, sizeof(passwd));
63654925bf6Swillf     if (ldap_context && ldap_context->bind_pwd)
63754925bf6Swillf 	memset(ldap_context->bind_pwd, 0, sizeof(ldap_context->bind_pwd));
63854925bf6Swillf 
63954925bf6Swillf     if (util_context) {
64054925bf6Swillf 	if (gp_is_static == 0)
64154925bf6Swillf 	    kadm5_free_config_params(util_context, &global_params);
64254925bf6Swillf 	krb5_ldap_close(util_context);
64354925bf6Swillf 	krb5_free_context(util_context);
64454925bf6Swillf     }
64554925bf6Swillf 
64654925bf6Swillf     if (cmd_argv)
64754925bf6Swillf 	free(cmd_argv);
64854925bf6Swillf     if (prompt)
64954925bf6Swillf 	free(prompt);
65054925bf6Swillf     if (conf_section)
65154925bf6Swillf 	free(conf_section);
65254925bf6Swillf     if (dal_handle)
65354925bf6Swillf 	free(dal_handle);
65454925bf6Swillf 
65554925bf6Swillf     if (usage_print) {
65654925bf6Swillf 	usage();
65754925bf6Swillf     }
65854925bf6Swillf 
65954925bf6Swillf     return exit_status;
66054925bf6Swillf }
661