1*54925bf6Swillf /*
2*54925bf6Swillf  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3*54925bf6Swillf  * Use is subject to license terms.
4*54925bf6Swillf  */
5*54925bf6Swillf 
6*54925bf6Swillf #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*54925bf6Swillf 
8*54925bf6Swillf /*
9*54925bf6Swillf  * kadmin/ldap_util/kdb5_ldap_util.c
10*54925bf6Swillf  *
11*54925bf6Swillf  * (C) Copyright 1990,1991, 1996 by the Massachusetts Institute of Technology.
12*54925bf6Swillf  * All Rights Reserved.
13*54925bf6Swillf  *
14*54925bf6Swillf  * Export of this software from the United States of America may
15*54925bf6Swillf  *   require a specific license from the United States Government.
16*54925bf6Swillf  *   It is the responsibility of any person or organization contemplating
17*54925bf6Swillf  *   export to obtain such a license before exporting.
18*54925bf6Swillf  *
19*54925bf6Swillf  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
20*54925bf6Swillf  * distribute this software and its documentation for any purpose and
21*54925bf6Swillf  * without fee is hereby granted, provided that the above copyright
22*54925bf6Swillf  * notice appear in all copies and that both that copyright notice and
23*54925bf6Swillf  * this permission notice appear in supporting documentation, and that
24*54925bf6Swillf  * the name of M.I.T. not be used in advertising or publicity pertaining
25*54925bf6Swillf  * to distribution of the software without specific, written prior
26*54925bf6Swillf  * permission.  Furthermore if you modify this software you must label
27*54925bf6Swillf  * your software as modified software and not distribute it in such a
28*54925bf6Swillf  * fashion that it might be confused with the original M.I.T. software.
29*54925bf6Swillf  * M.I.T. makes no representations about the suitability of
30*54925bf6Swillf  * this software for any purpose.  It is provided "as is" without express
31*54925bf6Swillf  * or implied warranty.
32*54925bf6Swillf  *
33*54925bf6Swillf  *
34*54925bf6Swillf  * Edit a KDC database.
35*54925bf6Swillf  */
36*54925bf6Swillf 
37*54925bf6Swillf /*
38*54925bf6Swillf  * Copyright (C) 1998 by the FundsXpress, INC.
39*54925bf6Swillf  *
40*54925bf6Swillf  * All rights reserved.
41*54925bf6Swillf  *
42*54925bf6Swillf  * Export of this software from the United States of America may require
43*54925bf6Swillf  * a specific license from the United States Government.  It is the
44*54925bf6Swillf  * responsibility of any person or organization contemplating export to
45*54925bf6Swillf  * obtain such a license before exporting.
46*54925bf6Swillf  *
47*54925bf6Swillf  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
48*54925bf6Swillf  * distribute this software and its documentation for any purpose and
49*54925bf6Swillf  * without fee is hereby granted, provided that the above copyright
50*54925bf6Swillf  * notice appear in all copies and that both that copyright notice and
51*54925bf6Swillf  * this permission notice appear in supporting documentation, and that
52*54925bf6Swillf  * the name of FundsXpress. not be used in advertising or publicity pertaining
53*54925bf6Swillf  * to distribution of the software without specific, written prior
54*54925bf6Swillf  * permission.  FundsXpress makes no representations about the suitability of
55*54925bf6Swillf  * this software for any purpose.  It is provided "as is" without express
56*54925bf6Swillf  * or implied warranty.
57*54925bf6Swillf  *
58*54925bf6Swillf  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
59*54925bf6Swillf  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
60*54925bf6Swillf  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
61*54925bf6Swillf  */
62*54925bf6Swillf 
63*54925bf6Swillf /* Copyright (c) 2004-2005, Novell, Inc.
64*54925bf6Swillf  * All rights reserved.
65*54925bf6Swillf  *
66*54925bf6Swillf  * Redistribution and use in source and binary forms, with or without
67*54925bf6Swillf  * modification, are permitted provided that the following conditions are met:
68*54925bf6Swillf  *
69*54925bf6Swillf  *   * Redistributions of source code must retain the above copyright notice,
70*54925bf6Swillf  *       this list of conditions and the following disclaimer.
71*54925bf6Swillf  *   * Redistributions in binary form must reproduce the above copyright
72*54925bf6Swillf  *       notice, this list of conditions and the following disclaimer in the
73*54925bf6Swillf  *       documentation and/or other materials provided with the distribution.
74*54925bf6Swillf  *   * The copyright holder's name is not used to endorse or promote products
75*54925bf6Swillf  *       derived from this software without specific prior written permission.
76*54925bf6Swillf  *
77*54925bf6Swillf  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
78*54925bf6Swillf  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
79*54925bf6Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80*54925bf6Swillf  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
81*54925bf6Swillf  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
82*54925bf6Swillf  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
83*54925bf6Swillf  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
84*54925bf6Swillf  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
85*54925bf6Swillf  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
86*54925bf6Swillf  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
87*54925bf6Swillf  * POSSIBILITY OF SUCH DAMAGE.
88*54925bf6Swillf  */
89*54925bf6Swillf 
90*54925bf6Swillf #include <stdio.h>
91*54925bf6Swillf #include <time.h>
92*54925bf6Swillf 
93*54925bf6Swillf #include <k5-int.h>
94*54925bf6Swillf #include <kadm5/admin.h>
95*54925bf6Swillf #include <adm_proto.h>
96*54925bf6Swillf #include <libintl.h>
97*54925bf6Swillf #include <locale.h>
98*54925bf6Swillf #include "kdb5_ldap_util.h"
99*54925bf6Swillf 
100*54925bf6Swillf typedef void (*cmd_func)(int, char **);
101*54925bf6Swillf int cmd_index(char *name);
102*54925bf6Swillf 
103*54925bf6Swillf char *mkey_password = 0;
104*54925bf6Swillf int exit_status = 0;
105*54925bf6Swillf krb5_context util_context;
106*54925bf6Swillf kadm5_config_params global_params;
107*54925bf6Swillf krb5_boolean db_inited = FALSE;
108*54925bf6Swillf 
109*54925bf6Swillf char *progname;
110*54925bf6Swillf krb5_boolean manual_mkey = FALSE;
111*54925bf6Swillf 
112*54925bf6Swillf /*
113*54925bf6Swillf  * This function prints the usage of kdb5_ldap_util, which is
114*54925bf6Swillf  * the LDAP configuration utility.
115*54925bf6Swillf  */
116*54925bf6Swillf void usage()
117*54925bf6Swillf {
118*54925bf6Swillf     fprintf(stderr, "%s: "
119*54925bf6Swillf "kdb5_ldap_util [-D user_dn [-w passwd]] [-H ldapuri]\n"
120*54925bf6Swillf "\tcmd [cmd_options]\n"
121*54925bf6Swillf 
122*54925bf6Swillf /* Create realm */
123*54925bf6Swillf "create          [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn]\n"
124*54925bf6Swillf #ifdef HAVE_EDIRECTORY
125*54925bf6Swillf "\t\t[-kdcdn kdc_service_list] [-admindn admin_service_list]\n"
126*54925bf6Swillf "\t\t[-pwddn passwd_service_list]\n"
127*54925bf6Swillf #endif
128*54925bf6Swillf "\t\t[-m|-P password|-sf stashfilename] [-k mkeytype] [-s]\n"
129*54925bf6Swillf "\t\t[-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life]\n"
130*54925bf6Swillf "\t\t[ticket_flags] [-r realm]\n"
131*54925bf6Swillf 
132*54925bf6Swillf /* modify realm */
133*54925bf6Swillf "modify          [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn]\n"
134*54925bf6Swillf #ifdef HAVE_EDIRECTORY
135*54925bf6Swillf "\t\t[-kdcdn kdc_service_list |\n"
136*54925bf6Swillf "\t\t[-clearkdcdn kdc_service_list] [-addkdcdn kdc_service_list]]\n"
137*54925bf6Swillf "\t\t[-admindn admin_service_list | [-clearadmindn admin_service_list]\n"
138*54925bf6Swillf "\t\t[-addadmindn admin_service_list]] [-pwddn passwd_service_list |\n"
139*54925bf6Swillf "\t\t[-clearpwddn passwd_service_list] [-addpwddn passwd_service_list]]\n"
140*54925bf6Swillf #endif
141*54925bf6Swillf "\t\t[-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life]\n"
142*54925bf6Swillf "\t\t[ticket_flags] [-r realm]\n"
143*54925bf6Swillf /* View realm */
144*54925bf6Swillf "view            [-r realm]\n"
145*54925bf6Swillf 
146*54925bf6Swillf /* Destroy realm */
147*54925bf6Swillf "destroy	        [-f] [-r realm]\n"
148*54925bf6Swillf 
149*54925bf6Swillf /* List realms */
150*54925bf6Swillf "list\n"
151*54925bf6Swillf 
152*54925bf6Swillf #ifdef HAVE_EDIRECTORY
153*54925bf6Swillf /* Create Service */
154*54925bf6Swillf "create_service  {-kdc|-admin|-pwd} [-servicehost service_host_list]\n"
155*54925bf6Swillf "\t\t[-realm realm_list] \n"
156*54925bf6Swillf "\t\t[-randpw|-fileonly] [-f filename] service_dn\n"
157*54925bf6Swillf 
158*54925bf6Swillf /* Modify service */
159*54925bf6Swillf "modify_service  [-servicehost service_host_list |\n"
160*54925bf6Swillf "\t\t[-clearservicehost service_host_list]\n"
161*54925bf6Swillf "\t\t[-addservicehost service_host_list]]\n"
162*54925bf6Swillf "\t\t[-realm realm_list | [-clearrealm realm_list]\n"
163*54925bf6Swillf "\t\t[-addrealm realm_list]] service_dn\n"
164*54925bf6Swillf 
165*54925bf6Swillf /* View Service */
166*54925bf6Swillf "view_service    service_dn\n"
167*54925bf6Swillf 
168*54925bf6Swillf /* Destroy Service */
169*54925bf6Swillf "destroy_service [-force] [-f stashfilename] service_dn\n"
170*54925bf6Swillf 
171*54925bf6Swillf /* List services */
172*54925bf6Swillf "list_service    [-basedn base_dn]\n"
173*54925bf6Swillf 
174*54925bf6Swillf /* Set Service password */
175*54925bf6Swillf "setsrvpw        [-randpw|-fileonly] [-f filename] service_dn\n"
176*54925bf6Swillf 
177*54925bf6Swillf #else
178*54925bf6Swillf 
179*54925bf6Swillf /* Stash the service password */
180*54925bf6Swillf "stashsrvpw      [-f filename] service_dn\n"
181*54925bf6Swillf 
182*54925bf6Swillf #endif
183*54925bf6Swillf 
184*54925bf6Swillf /* Create policy */
185*54925bf6Swillf "create_policy   [-r realm] [-maxtktlife max_ticket_life]\n"
186*54925bf6Swillf "\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n"
187*54925bf6Swillf 
188*54925bf6Swillf /* Modify policy */
189*54925bf6Swillf "modify_policy   [-r realm] [-maxtktlife max_ticket_life]\n"
190*54925bf6Swillf "\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n"
191*54925bf6Swillf 
192*54925bf6Swillf /* View policy */
193*54925bf6Swillf "view_policy     [-r realm] policy\n"
194*54925bf6Swillf 
195*54925bf6Swillf /* Destroy policy */
196*54925bf6Swillf "destroy_policy  [-r realm] [-force] policy\n"
197*54925bf6Swillf 
198*54925bf6Swillf /* List policies */
199*54925bf6Swillf "list_policy     [-r realm]\n",
200*54925bf6Swillf     gettext("Usage"));
201*54925bf6Swillf }
202*54925bf6Swillf 
203*54925bf6Swillf void db_usage (int type) {
204*54925bf6Swillf     /*
205*54925bf6Swillf      * This should print usage of 'type' command. For now, we will print usage
206*54925bf6Swillf      * of all commands.
207*54925bf6Swillf      */
208*54925bf6Swillf     usage ();
209*54925bf6Swillf }
210*54925bf6Swillf 
211*54925bf6Swillf /* The help messages for all sub-commands should be in the
212*54925bf6Swillf  * same order as listed in this table.
213*54925bf6Swillf  */
214*54925bf6Swillf static struct _cmd_table {
215*54925bf6Swillf     char *name;
216*54925bf6Swillf     cmd_func func;
217*54925bf6Swillf     int opendb;
218*54925bf6Swillf } cmd_table[] = {
219*54925bf6Swillf     {"create", kdb5_ldap_create, 1},
220*54925bf6Swillf     {"modify", kdb5_ldap_modify, 1},
221*54925bf6Swillf     {"view", kdb5_ldap_view, 1},
222*54925bf6Swillf     {"destroy", kdb5_ldap_destroy, 1},
223*54925bf6Swillf     {"list", kdb5_ldap_list, 1},
224*54925bf6Swillf #ifdef HAVE_EDIRECTORY
225*54925bf6Swillf     {"create_service", kdb5_ldap_create_service, 1},
226*54925bf6Swillf     {"modify_service", kdb5_ldap_modify_service, 1},
227*54925bf6Swillf     {"view_service", kdb5_ldap_view_service, 1},
228*54925bf6Swillf     {"destroy_service", kdb5_ldap_destroy_service, 1},
229*54925bf6Swillf     {"list_service",kdb5_ldap_list_services,1},
230*54925bf6Swillf     {"setsrvpw", kdb5_ldap_set_service_password, 0},
231*54925bf6Swillf #else
232*54925bf6Swillf     {"stashsrvpw", kdb5_ldap_stash_service_password, 0},
233*54925bf6Swillf #endif
234*54925bf6Swillf     {"create_policy", kdb5_ldap_create_policy, 1},
235*54925bf6Swillf     {"modify_policy", kdb5_ldap_modify_policy, 1},
236*54925bf6Swillf     {"view_policy", kdb5_ldap_view_policy, 1},
237*54925bf6Swillf     {"destroy_policy", kdb5_ldap_destroy_policy, 1},
238*54925bf6Swillf     {"list_policy", kdb5_ldap_list_policies, 1},
239*54925bf6Swillf     {NULL, NULL, 0},
240*54925bf6Swillf };
241*54925bf6Swillf 
242*54925bf6Swillf 
243*54925bf6Swillf /*
244*54925bf6Swillf  * The function cmd_lookup returns the structure matching the
245*54925bf6Swillf  * command name and returns NULL if nothing matches.
246*54925bf6Swillf  */
247*54925bf6Swillf static struct _cmd_table *cmd_lookup(name)
248*54925bf6Swillf     char *name;
249*54925bf6Swillf {
250*54925bf6Swillf     int i;
251*54925bf6Swillf 
252*54925bf6Swillf     for (i = 0; cmd_table[i].name != NULL; i++)
253*54925bf6Swillf 	if (strcmp(cmd_table[i].name, name) == 0)
254*54925bf6Swillf 	    return &cmd_table[i];
255*54925bf6Swillf 
256*54925bf6Swillf     return NULL;
257*54925bf6Swillf }
258*54925bf6Swillf 
259*54925bf6Swillf 
260*54925bf6Swillf /*
261*54925bf6Swillf  * The function cmd_index provides the offset of the command
262*54925bf6Swillf  * in the command table, which can be used to get the corresponding
263*54925bf6Swillf  * help from the help message table.
264*54925bf6Swillf  */
265*54925bf6Swillf int cmd_index(name)
266*54925bf6Swillf     char *name;
267*54925bf6Swillf {
268*54925bf6Swillf     int i;
269*54925bf6Swillf 
270*54925bf6Swillf     if (name == NULL)
271*54925bf6Swillf 	return -1;
272*54925bf6Swillf 
273*54925bf6Swillf     for (i = 0; cmd_table[i].name != NULL; i++)
274*54925bf6Swillf 	if (strcmp(cmd_table[i].name, name) == 0)
275*54925bf6Swillf 	    return i;
276*54925bf6Swillf 
277*54925bf6Swillf     return -1;
278*54925bf6Swillf }
279*54925bf6Swillf 
280*54925bf6Swillf static void extended_com_err_fn (const char *myprog, errcode_t code,
281*54925bf6Swillf 				 const char *fmt, va_list args)
282*54925bf6Swillf {
283*54925bf6Swillf     const char *emsg;
284*54925bf6Swillf     /* Solaris Kerberos: code should be like that in kdb5_util.c */
285*54925bf6Swillf     if (code) {
286*54925bf6Swillf 	emsg = krb5_get_error_message (util_context, code);
287*54925bf6Swillf 	fprintf (stderr, "%s: %s ", myprog, emsg);
288*54925bf6Swillf 	krb5_free_error_message (util_context, emsg);
289*54925bf6Swillf     } else {
290*54925bf6Swillf 	fprintf (stderr, "%s: ", myprog);
291*54925bf6Swillf     }
292*54925bf6Swillf     vfprintf (stderr, fmt, args);
293*54925bf6Swillf     fprintf (stderr, "\n");
294*54925bf6Swillf }
295*54925bf6Swillf 
296*54925bf6Swillf int main(argc, argv)
297*54925bf6Swillf     int argc;
298*54925bf6Swillf     char *argv[];
299*54925bf6Swillf {
300*54925bf6Swillf     struct _cmd_table *cmd = NULL;
301*54925bf6Swillf     char *koptarg = NULL, **cmd_argv = NULL;
302*54925bf6Swillf     int cmd_argc = 0;
303*54925bf6Swillf     krb5_error_code retval;
304*54925bf6Swillf     int usage_print = 0;
305*54925bf6Swillf     int gp_is_static = 1;
306*54925bf6Swillf     krb5_error_code db_retval = 1;
307*54925bf6Swillf     char *bind_dn = NULL;
308*54925bf6Swillf     char *passwd = NULL;
309*54925bf6Swillf     char *ldap_server = NULL;
310*54925bf6Swillf     unsigned int ldapmask = 0;
311*54925bf6Swillf     unsigned int passwd_len = 0;
312*54925bf6Swillf     char *prompt = NULL;
313*54925bf6Swillf     kdb5_dal_handle *dal_handle = NULL;
314*54925bf6Swillf     krb5_ldap_context *ldap_context=NULL;
315*54925bf6Swillf     char *value = NULL, *conf_section = NULL;
316*54925bf6Swillf     krb5_boolean realm_name_required = TRUE;
317*54925bf6Swillf     krb5_boolean print_help_message = FALSE;
318*54925bf6Swillf 
319*54925bf6Swillf     retval = krb5_init_context(&util_context);
320*54925bf6Swillf     set_com_err_hook(extended_com_err_fn);
321*54925bf6Swillf     if (retval) {
322*54925bf6Swillf 	com_err (progname, retval, gettext("while initializing Kerberos code"));
323*54925bf6Swillf 	exit_status++;
324*54925bf6Swillf 	goto cleanup;
325*54925bf6Swillf     }
326*54925bf6Swillf 
327*54925bf6Swillf     progname = (strrchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
328*54925bf6Swillf 
329*54925bf6Swillf     cmd_argv = (char **) malloc(sizeof(char *)*argc);
330*54925bf6Swillf     if (cmd_argv == NULL) {
331*54925bf6Swillf 	com_err(progname, ENOMEM, gettext("while creating sub-command arguments"));
332*54925bf6Swillf 	exit_status++;
333*54925bf6Swillf 	goto cleanup;
334*54925bf6Swillf     }
335*54925bf6Swillf     memset(cmd_argv, 0, sizeof(char *)*argc);
336*54925bf6Swillf     cmd_argc = 1;
337*54925bf6Swillf 
338*54925bf6Swillf     memset(&global_params, 0, sizeof(kadm5_config_params));
339*54925bf6Swillf 
340*54925bf6Swillf     argv++; argc--;
341*54925bf6Swillf     while (*argv) {
342*54925bf6Swillf 	if (strcmp(*argv, "--help") == 0) {
343*54925bf6Swillf 	    print_help_message = TRUE;
344*54925bf6Swillf 	}
345*54925bf6Swillf 	if (strcmp(*argv, "-P") == 0 && ARG_VAL) {
346*54925bf6Swillf 	    mkey_password = koptarg;
347*54925bf6Swillf 	    manual_mkey = TRUE;
348*54925bf6Swillf 	} else if (strcmp(*argv, "-r") == 0 && ARG_VAL) {
349*54925bf6Swillf 	    global_params.realm = koptarg;
350*54925bf6Swillf 	    global_params.mask |= KADM5_CONFIG_REALM;
351*54925bf6Swillf 	    /* not sure this is really necessary */
352*54925bf6Swillf 	    if ((retval = krb5_set_default_realm(util_context,
353*54925bf6Swillf 						 global_params.realm))) {
354*54925bf6Swillf 		com_err(progname, retval, gettext("while setting default realm name"));
355*54925bf6Swillf 		exit_status++;
356*54925bf6Swillf 		goto cleanup;
357*54925bf6Swillf 	    }
358*54925bf6Swillf 	} else if (strcmp(*argv, "-k") == 0 && ARG_VAL) {
359*54925bf6Swillf 	    if (krb5_string_to_enctype(koptarg, &global_params.enctype))
360*54925bf6Swillf 		com_err(argv[0], 0, gettext("%s is an invalid enctype"), koptarg);
361*54925bf6Swillf 	    else
362*54925bf6Swillf 		global_params.mask |= KADM5_CONFIG_ENCTYPE;
363*54925bf6Swillf 	} else if (strcmp(*argv, "-M") == 0 && ARG_VAL) {
364*54925bf6Swillf 	    global_params.mkey_name = koptarg;
365*54925bf6Swillf 	    global_params.mask |= KADM5_CONFIG_MKEY_NAME;
366*54925bf6Swillf 	} else if (strcmp(*argv, "-sf") == 0 && ARG_VAL) {
367*54925bf6Swillf 	    global_params.stash_file = koptarg;
368*54925bf6Swillf 	    global_params.mask |= KADM5_CONFIG_STASH_FILE;
369*54925bf6Swillf 	} else if (strcmp(*argv, "-m") == 0) {
370*54925bf6Swillf 	    manual_mkey = TRUE;
371*54925bf6Swillf 	    global_params.mkey_from_kbd = 1;
372*54925bf6Swillf 	    global_params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
373*54925bf6Swillf 	} else if (strcmp(*argv, "-D") == 0 && ARG_VAL) {
374*54925bf6Swillf 	    bind_dn = koptarg;
375*54925bf6Swillf 	    if (bind_dn == NULL) {
376*54925bf6Swillf 		com_err(progname, ENOMEM, gettext("while reading ldap parameters"));
377*54925bf6Swillf 		exit_status++;
378*54925bf6Swillf 		goto cleanup;
379*54925bf6Swillf 	    }
380*54925bf6Swillf 	    ldapmask |= CMD_LDAP_D;
381*54925bf6Swillf 	} else if (strcmp(*argv, "-w") == 0 && ARG_VAL) {
382*54925bf6Swillf 	    passwd = strdup(koptarg);
383*54925bf6Swillf 	    if (passwd == NULL) {
384*54925bf6Swillf 		com_err(progname, ENOMEM, gettext("while reading ldap parameters"));
385*54925bf6Swillf 		exit_status++;
386*54925bf6Swillf 		goto cleanup;
387*54925bf6Swillf 	    }
388*54925bf6Swillf 	    ldapmask |= CMD_LDAP_W;
389*54925bf6Swillf 	} else if (strcmp(*argv, "-H") == 0 && ARG_VAL) {
390*54925bf6Swillf 	    ldap_server = koptarg;
391*54925bf6Swillf 	    if (ldap_server == NULL) {
392*54925bf6Swillf 		com_err(progname, ENOMEM, gettext("while reading ldap parameters"));
393*54925bf6Swillf 		exit_status++;
394*54925bf6Swillf 		goto cleanup;
395*54925bf6Swillf 	    }
396*54925bf6Swillf 	    ldapmask |= CMD_LDAP_H;
397*54925bf6Swillf 	} else if (cmd_lookup(*argv) != NULL) {
398*54925bf6Swillf 	    if (cmd_argv[0] == NULL)
399*54925bf6Swillf 		cmd_argv[0] = *argv;
400*54925bf6Swillf 	    else {
401*54925bf6Swillf 		free(cmd_argv);
402*54925bf6Swillf 		cmd_argv = NULL;
403*54925bf6Swillf 		usage();
404*54925bf6Swillf 		goto cleanup;
405*54925bf6Swillf 	    }
406*54925bf6Swillf 	} else {
407*54925bf6Swillf 	    cmd_argv[cmd_argc++] = *argv;
408*54925bf6Swillf 	}
409*54925bf6Swillf 	argv++; argc--;
410*54925bf6Swillf     }
411*54925bf6Swillf 
412*54925bf6Swillf     if (cmd_argv[0] == NULL) {
413*54925bf6Swillf 	free(cmd_argv);
414*54925bf6Swillf 	cmd_argv = NULL;
415*54925bf6Swillf 	usage();
416*54925bf6Swillf 	goto cleanup;
417*54925bf6Swillf     }
418*54925bf6Swillf 
419*54925bf6Swillf     /* if we need to print the help message (because of --help option)
420*54925bf6Swillf      * we will print the help corresponding to the sub-command.
421*54925bf6Swillf      */
422*54925bf6Swillf     if (print_help_message) {
423*54925bf6Swillf 	char *cmd_name = cmd_argv[0];
424*54925bf6Swillf 	free(cmd_argv);
425*54925bf6Swillf 	cmd_argv = NULL;
426*54925bf6Swillf 	usage();
427*54925bf6Swillf 	goto cleanup;
428*54925bf6Swillf     }
429*54925bf6Swillf 
430*54925bf6Swillf     /* We need to check for the presence of default realm name only in
431*54925bf6Swillf      * the case of realm related operations like create, destroy etc.
432*54925bf6Swillf      */
433*54925bf6Swillf     if ((strcmp(cmd_argv[0], "list") == 0) ||
434*54925bf6Swillf         (strcmp(cmd_argv[0], "stashsrvpw") == 0)) {
435*54925bf6Swillf         realm_name_required = FALSE;
436*54925bf6Swillf     }
437*54925bf6Swillf 
438*54925bf6Swillf     if (!util_context->default_realm) {
439*54925bf6Swillf 	char *temp = NULL;
440*54925bf6Swillf 	retval = krb5_get_default_realm(util_context, &temp);
441*54925bf6Swillf 	if (retval) {
442*54925bf6Swillf 	    if (realm_name_required) {
443*54925bf6Swillf 		com_err (progname, retval, gettext("while getting default realm"));
444*54925bf6Swillf 		exit_status++;
445*54925bf6Swillf 		goto cleanup;
446*54925bf6Swillf 	    }
447*54925bf6Swillf 	} else
448*54925bf6Swillf 	    util_context->default_realm = temp;
449*54925bf6Swillf     }
450*54925bf6Swillf     /* If we have the realm name, we can safely say that
451*54925bf6Swillf      * realm_name is required so that we don't neglect any information.
452*54925bf6Swillf      */
453*54925bf6Swillf     else
454*54925bf6Swillf 	realm_name_required = TRUE;
455*54925bf6Swillf 
456*54925bf6Swillf     retval = profile_get_string(util_context->profile, KDB_REALM_SECTION,
457*54925bf6Swillf 				util_context->default_realm, KDB_MODULE_POINTER,
458*54925bf6Swillf 				NULL,
459*54925bf6Swillf 				&value);
460*54925bf6Swillf 
461*54925bf6Swillf     if (!(value)) {
462*54925bf6Swillf 	retval = profile_get_string(util_context->profile, KDB_MODULE_DEF_SECTION,
463*54925bf6Swillf 				    KDB_MODULE_POINTER, NULL,
464*54925bf6Swillf 				    NULL,
465*54925bf6Swillf 				    &value);
466*54925bf6Swillf 	if (!(value)) {
467*54925bf6Swillf 	    if (util_context->default_realm)
468*54925bf6Swillf 		conf_section = strdup(util_context->default_realm);
469*54925bf6Swillf 	} else {
470*54925bf6Swillf 	    conf_section = strdup(value);
471*54925bf6Swillf 	    free(value);
472*54925bf6Swillf 	}
473*54925bf6Swillf     } else {
474*54925bf6Swillf 	conf_section = strdup(value);
475*54925bf6Swillf 	free(value);
476*54925bf6Swillf     }
477*54925bf6Swillf 
478*54925bf6Swillf     if (realm_name_required) {
479*54925bf6Swillf 	/* Solaris kerberos: using older kadm5_get_config_params interface */
480*54925bf6Swillf 	retval = kadm5_get_config_params(util_context, NULL, NULL,
481*54925bf6Swillf 					 &global_params, &global_params);
482*54925bf6Swillf 	if (retval) {
483*54925bf6Swillf 	    com_err(argv[0], retval, gettext("while retreiving configuration parameters"));
484*54925bf6Swillf 	    exit_status++;
485*54925bf6Swillf 	    goto cleanup;
486*54925bf6Swillf 	}
487*54925bf6Swillf 	gp_is_static = 0;
488*54925bf6Swillf     }
489*54925bf6Swillf 
490*54925bf6Swillf     if ((retval = krb5_ldap_lib_init()) != 0) {
491*54925bf6Swillf 	com_err(argv[0], retval, gettext("while initializing error handling"));
492*54925bf6Swillf 	exit_status++;
493*54925bf6Swillf 	goto cleanup;
494*54925bf6Swillf     }
495*54925bf6Swillf 
496*54925bf6Swillf     /* Initialize the ldap context */
497*54925bf6Swillf     ldap_context = calloc(sizeof(krb5_ldap_context), 1);
498*54925bf6Swillf     if (ldap_context == NULL) {
499*54925bf6Swillf 	com_err(argv[0], ENOMEM, gettext("while initializing ldap handle"));
500*54925bf6Swillf 	exit_status++;
501*54925bf6Swillf 	goto cleanup;
502*54925bf6Swillf     }
503*54925bf6Swillf 
504*54925bf6Swillf     ldap_context->kcontext = util_context;
505*54925bf6Swillf 
506*54925bf6Swillf     /* If LDAP parameters are specified, replace them with the values from config */
507*54925bf6Swillf     if (ldapmask & CMD_LDAP_D) {
508*54925bf6Swillf 	/* If password is not specified, prompt for it */
509*54925bf6Swillf 	if (passwd == NULL) {
510*54925bf6Swillf 	    passwd = (char *)malloc(MAX_PASSWD_LEN);
511*54925bf6Swillf 	    if (passwd == NULL) {
512*54925bf6Swillf 		com_err(argv[0], ENOMEM, gettext("while retrieving ldap configuration"));
513*54925bf6Swillf 		exit_status++;
514*54925bf6Swillf 		goto cleanup;
515*54925bf6Swillf 	    }
516*54925bf6Swillf 	    prompt = (char *)malloc(MAX_PASSWD_PROMPT_LEN);
517*54925bf6Swillf 	    if (prompt == NULL) {
518*54925bf6Swillf 		free(passwd);
519*54925bf6Swillf 		passwd = NULL;
520*54925bf6Swillf 		com_err(argv[0], ENOMEM, gettext("while retrieving ldap configuration"));
521*54925bf6Swillf 		exit_status++;
522*54925bf6Swillf 		goto cleanup;
523*54925bf6Swillf 	    }
524*54925bf6Swillf 	    memset(passwd, 0, sizeof(passwd));
525*54925bf6Swillf 	    passwd_len = MAX_PASSWD_LEN - 1;
526*54925bf6Swillf 	    snprintf(prompt, MAX_PASSWD_PROMPT_LEN, gettext("Password for \"%s\""), bind_dn);
527*54925bf6Swillf 
528*54925bf6Swillf 	    db_retval = krb5_read_password(util_context, prompt, NULL, passwd, &passwd_len);
529*54925bf6Swillf 
530*54925bf6Swillf 	    if ((db_retval) || (passwd_len == 0)) {
531*54925bf6Swillf 		com_err(argv[0], ENOMEM, gettext("while retrieving ldap configuration"));
532*54925bf6Swillf 		free(passwd);
533*54925bf6Swillf 		passwd = NULL;
534*54925bf6Swillf 		exit_status++;
535*54925bf6Swillf 		goto cleanup;
536*54925bf6Swillf 	    }
537*54925bf6Swillf 	}
538*54925bf6Swillf 
539*54925bf6Swillf 	ldap_context->bind_pwd = passwd;
540*54925bf6Swillf     }
541*54925bf6Swillf 
542*54925bf6Swillf     /* If ldaphost is specified, release entry filled by configuration & use this */
543*54925bf6Swillf     if (ldapmask & CMD_LDAP_H) {
544*54925bf6Swillf 
545*54925bf6Swillf 	ldap_context->server_info_list = (krb5_ldap_server_info **) calloc (2, sizeof (krb5_ldap_server_info *)) ;
546*54925bf6Swillf 	if (ldap_context->server_info_list == NULL) {
547*54925bf6Swillf 	    com_err(argv[0], ENOMEM, gettext("while initializing server list"));
548*54925bf6Swillf 	    exit_status++;
549*54925bf6Swillf 	    goto cleanup;
550*54925bf6Swillf 	}
551*54925bf6Swillf 
552*54925bf6Swillf 	ldap_context->server_info_list[0] = (krb5_ldap_server_info *) calloc (1, sizeof (krb5_ldap_server_info));
553*54925bf6Swillf 	if (ldap_context->server_info_list[0] == NULL) {
554*54925bf6Swillf 	    com_err(argv[0], ENOMEM, gettext("while initializing server list"));
555*54925bf6Swillf 	    exit_status++;
556*54925bf6Swillf 	    goto cleanup;
557*54925bf6Swillf 	}
558*54925bf6Swillf 
559*54925bf6Swillf 	ldap_context->server_info_list[0]->server_status = NOTSET;
560*54925bf6Swillf 
561*54925bf6Swillf 	ldap_context->server_info_list[0]->server_name = strdup(ldap_server);
562*54925bf6Swillf 	if (ldap_context->server_info_list[0]->server_name == NULL) {
563*54925bf6Swillf 	    com_err(argv[0], ENOMEM, gettext("while initializing server list"));
564*54925bf6Swillf 	    exit_status++;
565*54925bf6Swillf 	    goto cleanup;
566*54925bf6Swillf 	}
567*54925bf6Swillf     }
568*54925bf6Swillf     if (bind_dn) {
569*54925bf6Swillf 	ldap_context->bind_dn = strdup(bind_dn);
570*54925bf6Swillf 	if (ldap_context->bind_dn == NULL) {
571*54925bf6Swillf 	    com_err(argv[0], ENOMEM, gettext("while retrieving ldap configuration"));
572*54925bf6Swillf 	    exit_status++;
573*54925bf6Swillf 	    goto cleanup;
574*54925bf6Swillf 	}
575*54925bf6Swillf     } else
576*54925bf6Swillf 	ldap_context->bind_dn = NULL;
577*54925bf6Swillf 
578*54925bf6Swillf     ldap_context->service_type = SERVICE_DN_TYPE_CLIENT;
579*54925bf6Swillf 
580*54925bf6Swillf     if (realm_name_required) {
581*54925bf6Swillf 	if ((global_params.enctype != ENCTYPE_UNKNOWN) &&
582*54925bf6Swillf 	    (!krb5_c_valid_enctype(global_params.enctype))) {
583*54925bf6Swillf 	    com_err(argv[0], KRB5_PROG_KEYTYPE_NOSUPP,
584*54925bf6Swillf 		    gettext("while setting up enctype %d"), global_params.enctype);
585*54925bf6Swillf 	}
586*54925bf6Swillf     }
587*54925bf6Swillf 
588*54925bf6Swillf     cmd = cmd_lookup(cmd_argv[0]);
589*54925bf6Swillf 
590*54925bf6Swillf     /* Setup DAL handle to access the database */
591*54925bf6Swillf     dal_handle = calloc((size_t)1, sizeof(kdb5_dal_handle));
592*54925bf6Swillf     if (dal_handle == NULL) {
593*54925bf6Swillf 	goto cleanup;
594*54925bf6Swillf     }
595*54925bf6Swillf     dal_handle->db_context = ldap_context;
596*54925bf6Swillf     util_context->db_context = (void *) dal_handle;
597*54925bf6Swillf 
598*54925bf6Swillf     db_retval = krb5_ldap_read_server_params(util_context, conf_section, KRB5_KDB_SRV_TYPE_OTHER);
599*54925bf6Swillf     if (db_retval) {
600*54925bf6Swillf 	com_err(argv[0], db_retval, gettext("while reading ldap configuration"));
601*54925bf6Swillf 	exit_status++;
602*54925bf6Swillf 	goto cleanup;
603*54925bf6Swillf     }
604*54925bf6Swillf 
605*54925bf6Swillf     if (cmd->opendb) {
606*54925bf6Swillf 	db_retval = krb5_ldap_db_init(util_context, ldap_context);
607*54925bf6Swillf 	if (db_retval) {
608*54925bf6Swillf 	    com_err(progname, db_retval, gettext("while initializing database"));
609*54925bf6Swillf 	    exit_status++;
610*54925bf6Swillf 	    goto cleanup;
611*54925bf6Swillf 	}
612*54925bf6Swillf 	db_inited = TRUE;
613*54925bf6Swillf     }
614*54925bf6Swillf     (*cmd->func)(cmd_argc, cmd_argv);
615*54925bf6Swillf 
616*54925bf6Swillf     goto cleanup;
617*54925bf6Swillf 
618*54925bf6Swillf cleanup:
619*54925bf6Swillf     if (passwd)
620*54925bf6Swillf 	memset(passwd, 0, sizeof(passwd));
621*54925bf6Swillf     if (ldap_context && ldap_context->bind_pwd)
622*54925bf6Swillf 	memset(ldap_context->bind_pwd, 0, sizeof(ldap_context->bind_pwd));
623*54925bf6Swillf 
624*54925bf6Swillf     if (util_context) {
625*54925bf6Swillf 	if (gp_is_static == 0)
626*54925bf6Swillf 	    kadm5_free_config_params(util_context, &global_params);
627*54925bf6Swillf 	krb5_ldap_close(util_context);
628*54925bf6Swillf 	krb5_free_context(util_context);
629*54925bf6Swillf     }
630*54925bf6Swillf 
631*54925bf6Swillf     if (cmd_argv)
632*54925bf6Swillf 	free(cmd_argv);
633*54925bf6Swillf     if (prompt)
634*54925bf6Swillf 	free(prompt);
635*54925bf6Swillf     if (conf_section)
636*54925bf6Swillf 	free(conf_section);
637*54925bf6Swillf     if (dal_handle)
638*54925bf6Swillf 	free(dal_handle);
639*54925bf6Swillf 
640*54925bf6Swillf     if (usage_print) {
641*54925bf6Swillf 	usage();
642*54925bf6Swillf     }
643*54925bf6Swillf 
644*54925bf6Swillf     return exit_status;
645*54925bf6Swillf }
646