xref: /freebsd/crypto/heimdal/lib/kadm5/init_c.c (revision ed549cb0c53f8438c52593ce811f6fcc812248e9)
1b528cefcSMark Murray /*
2ae771770SStanislav Sedov  * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray  * modification, are permitted provided that the following conditions
8b528cefcSMark Murray  * are met:
9b528cefcSMark Murray  *
10b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray  *
13b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray  *
17b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
19b528cefcSMark Murray  *    without specific prior written permission.
20b528cefcSMark Murray  *
21b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray  * SUCH DAMAGE.
32b528cefcSMark Murray  */
33b528cefcSMark Murray 
34b528cefcSMark Murray #include "kadm5_locl.h"
35b528cefcSMark Murray #include <sys/types.h>
36ae771770SStanislav Sedov #ifdef HAVE_SYS_SOCKET_H
37b528cefcSMark Murray #include <sys/socket.h>
38ae771770SStanislav Sedov #endif
39ae771770SStanislav Sedov #ifdef HAVE_NETINET_IN_H
40b528cefcSMark Murray #include <netinet/in.h>
41ae771770SStanislav Sedov #endif
42ae771770SStanislav Sedov #ifdef HAVE_NETDB_H
43b528cefcSMark Murray #include <netdb.h>
44ae771770SStanislav Sedov #endif
45b528cefcSMark Murray 
46ae771770SStanislav Sedov RCSID("$Id$");
47b528cefcSMark Murray 
48b528cefcSMark Murray static void
set_funcs(kadm5_client_context * c)49b528cefcSMark Murray set_funcs(kadm5_client_context *c)
50b528cefcSMark Murray {
51b528cefcSMark Murray #define SET(C, F) (C)->funcs.F = kadm5 ## _c_ ## F
52b528cefcSMark Murray     SET(c, chpass_principal);
535e9cd1aeSAssar Westerlund     SET(c, chpass_principal_with_key);
54b528cefcSMark Murray     SET(c, create_principal);
55b528cefcSMark Murray     SET(c, delete_principal);
56b528cefcSMark Murray     SET(c, destroy);
57b528cefcSMark Murray     SET(c, flush);
58b528cefcSMark Murray     SET(c, get_principal);
59b528cefcSMark Murray     SET(c, get_principals);
60b528cefcSMark Murray     SET(c, get_privs);
61b528cefcSMark Murray     SET(c, modify_principal);
62b528cefcSMark Murray     SET(c, randkey_principal);
63b528cefcSMark Murray     SET(c, rename_principal);
64b528cefcSMark Murray }
65b528cefcSMark Murray 
66b528cefcSMark Murray kadm5_ret_t
_kadm5_c_init_context(kadm5_client_context ** ctx,kadm5_config_params * params,krb5_context context)67b528cefcSMark Murray _kadm5_c_init_context(kadm5_client_context **ctx,
68b528cefcSMark Murray 		      kadm5_config_params *params,
69b528cefcSMark Murray 		      krb5_context context)
70b528cefcSMark Murray {
71b528cefcSMark Murray     krb5_error_code ret;
72b528cefcSMark Murray     char *colon;
73b528cefcSMark Murray 
74b528cefcSMark Murray     *ctx = malloc(sizeof(**ctx));
75b528cefcSMark Murray     if(*ctx == NULL)
76b528cefcSMark Murray 	return ENOMEM;
77b528cefcSMark Murray     memset(*ctx, 0, sizeof(**ctx));
78b528cefcSMark Murray     krb5_add_et_list (context, initialize_kadm5_error_table_r);
79b528cefcSMark Murray     set_funcs(*ctx);
80b528cefcSMark Murray     (*ctx)->context = context;
811c43270aSJacques Vidrine     if(params->mask & KADM5_CONFIG_REALM) {
821c43270aSJacques Vidrine 	ret = 0;
83b528cefcSMark Murray 	(*ctx)->realm = strdup(params->realm);
841c43270aSJacques Vidrine 	if ((*ctx)->realm == NULL)
851c43270aSJacques Vidrine 	    ret = ENOMEM;
861c43270aSJacques Vidrine     } else
871c43270aSJacques Vidrine 	ret = krb5_get_default_realm((*ctx)->context, &(*ctx)->realm);
881c43270aSJacques Vidrine     if (ret) {
891c43270aSJacques Vidrine 	free(*ctx);
901c43270aSJacques Vidrine 	return ret;
911c43270aSJacques Vidrine     }
92b528cefcSMark Murray     if(params->mask & KADM5_CONFIG_ADMIN_SERVER)
93b528cefcSMark Murray 	(*ctx)->admin_server = strdup(params->admin_server);
94b528cefcSMark Murray     else {
95b528cefcSMark Murray 	char **hostlist;
96b528cefcSMark Murray 
97b528cefcSMark Murray 	ret = krb5_get_krb_admin_hst (context, &(*ctx)->realm, &hostlist);
981c43270aSJacques Vidrine 	if (ret) {
991c43270aSJacques Vidrine 	    free((*ctx)->realm);
1001c43270aSJacques Vidrine 	    free(*ctx);
101b528cefcSMark Murray 	    return ret;
1021c43270aSJacques Vidrine 	}
103b528cefcSMark Murray 	(*ctx)->admin_server = strdup(*hostlist);
104b528cefcSMark Murray 	krb5_free_krbhst (context, hostlist);
105b528cefcSMark Murray     }
106b528cefcSMark Murray 
1071c43270aSJacques Vidrine     if ((*ctx)->admin_server == NULL) {
1081c43270aSJacques Vidrine 	free((*ctx)->realm);
1091c43270aSJacques Vidrine 	free(*ctx);
110c19800e8SDoug Rabson 	return ENOMEM;
1111c43270aSJacques Vidrine     }
112b528cefcSMark Murray     colon = strchr ((*ctx)->admin_server, ':');
113b528cefcSMark Murray     if (colon != NULL)
114b528cefcSMark Murray 	*colon++ = '\0';
115b528cefcSMark Murray 
116b528cefcSMark Murray     (*ctx)->kadmind_port = 0;
117b528cefcSMark Murray 
118b528cefcSMark Murray     if(params->mask & KADM5_CONFIG_KADMIND_PORT)
119b528cefcSMark Murray 	(*ctx)->kadmind_port = params->kadmind_port;
120b528cefcSMark Murray     else if (colon != NULL) {
121b528cefcSMark Murray 	char *end;
122b528cefcSMark Murray 
123b528cefcSMark Murray 	(*ctx)->kadmind_port = htons(strtol (colon, &end, 0));
124b528cefcSMark Murray     }
125b528cefcSMark Murray     if ((*ctx)->kadmind_port == 0)
126b528cefcSMark Murray 	(*ctx)->kadmind_port = krb5_getportbyname (context, "kerberos-adm",
127b528cefcSMark Murray 						   "tcp", 749);
128b528cefcSMark Murray     return 0;
129b528cefcSMark Murray }
130b528cefcSMark Murray 
131b528cefcSMark Murray static krb5_error_code
get_kadm_ticket(krb5_context context,krb5_ccache id,krb5_principal client,const char * server_name)132b528cefcSMark Murray get_kadm_ticket(krb5_context context,
133b528cefcSMark Murray 		krb5_ccache id,
134b528cefcSMark Murray 		krb5_principal client,
135b528cefcSMark Murray 		const char *server_name)
136b528cefcSMark Murray {
137b528cefcSMark Murray     krb5_error_code ret;
138b528cefcSMark Murray     krb5_creds in, *out;
139b528cefcSMark Murray 
140b528cefcSMark Murray     memset(&in, 0, sizeof(in));
141b528cefcSMark Murray     in.client = client;
142b528cefcSMark Murray     ret = krb5_parse_name(context, server_name, &in.server);
143b528cefcSMark Murray     if(ret)
144b528cefcSMark Murray 	return ret;
145b528cefcSMark Murray     ret = krb5_get_credentials(context, 0, id, &in, &out);
146b528cefcSMark Murray     if(ret == 0)
147b528cefcSMark Murray 	krb5_free_creds(context, out);
148b528cefcSMark Murray     krb5_free_principal(context, in.server);
149b528cefcSMark Murray     return ret;
150b528cefcSMark Murray }
151b528cefcSMark Murray 
152b528cefcSMark Murray static krb5_error_code
get_new_cache(krb5_context context,krb5_principal client,const char * password,krb5_prompter_fct prompter,const char * keytab,const char * server_name,krb5_ccache * ret_cache)153b528cefcSMark Murray get_new_cache(krb5_context context,
154b528cefcSMark Murray 	      krb5_principal client,
155b528cefcSMark Murray 	      const char *password,
156b528cefcSMark Murray 	      krb5_prompter_fct prompter,
157b528cefcSMark Murray 	      const char *keytab,
158b528cefcSMark Murray 	      const char *server_name,
159b528cefcSMark Murray 	      krb5_ccache *ret_cache)
160b528cefcSMark Murray {
161b528cefcSMark Murray     krb5_error_code ret;
162b528cefcSMark Murray     krb5_creds cred;
163c19800e8SDoug Rabson     krb5_get_init_creds_opt *opt;
164b528cefcSMark Murray     krb5_ccache id;
165b528cefcSMark Murray 
166c19800e8SDoug Rabson     ret = krb5_get_init_creds_opt_alloc (context, &opt);
167c19800e8SDoug Rabson     if (ret)
168c19800e8SDoug Rabson 	return ret;
1694137ff4cSJacques Vidrine 
1704137ff4cSJacques Vidrine     krb5_get_init_creds_opt_set_default_flags(context, "kadmin",
1714137ff4cSJacques Vidrine 					      krb5_principal_get_realm(context,
1724137ff4cSJacques Vidrine 								       client),
173c19800e8SDoug Rabson 					      opt);
1744137ff4cSJacques Vidrine 
1754137ff4cSJacques Vidrine 
176c19800e8SDoug Rabson     krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
177c19800e8SDoug Rabson     krb5_get_init_creds_opt_set_proxiable (opt, FALSE);
17813e3f4d6SMark Murray 
179b528cefcSMark Murray     if(password == NULL && prompter == NULL) {
180b528cefcSMark Murray 	krb5_keytab kt;
181b528cefcSMark Murray 	if(keytab == NULL)
182b528cefcSMark Murray 	    ret = krb5_kt_default(context, &kt);
183b528cefcSMark Murray 	else
184b528cefcSMark Murray 	    ret = krb5_kt_resolve(context, keytab, &kt);
185c19800e8SDoug Rabson 	if(ret) {
186c19800e8SDoug Rabson 	    krb5_get_init_creds_opt_free(context, opt);
187b528cefcSMark Murray 	    return ret;
188c19800e8SDoug Rabson 	}
189b528cefcSMark Murray 	ret = krb5_get_init_creds_keytab (context,
190b528cefcSMark Murray 					  &cred,
191b528cefcSMark Murray 					  client,
192b528cefcSMark Murray 					  kt,
193b528cefcSMark Murray 					  0,
194b528cefcSMark Murray 					  server_name,
195c19800e8SDoug Rabson 					  opt);
196b528cefcSMark Murray 	krb5_kt_close(context, kt);
197b528cefcSMark Murray     } else {
198b528cefcSMark Murray 	ret = krb5_get_init_creds_password (context,
199b528cefcSMark Murray 					    &cred,
200b528cefcSMark Murray 					    client,
201b528cefcSMark Murray 					    password,
202b528cefcSMark Murray 					    prompter,
203b528cefcSMark Murray 					    NULL,
204b528cefcSMark Murray 					    0,
205b528cefcSMark Murray 					    server_name,
206c19800e8SDoug Rabson 					    opt);
207b528cefcSMark Murray     }
208c19800e8SDoug Rabson     krb5_get_init_creds_opt_free(context, opt);
209b528cefcSMark Murray     switch(ret){
210b528cefcSMark Murray     case 0:
211b528cefcSMark Murray 	break;
212b528cefcSMark Murray     case KRB5_LIBOS_PWDINTR:	/* don't print anything if it was just C-c:ed */
213b528cefcSMark Murray     case KRB5KRB_AP_ERR_BAD_INTEGRITY:
214b528cefcSMark Murray     case KRB5KRB_AP_ERR_MODIFIED:
215b528cefcSMark Murray 	return KADM5_BAD_PASSWORD;
216b528cefcSMark Murray     default:
217b528cefcSMark Murray 	return ret;
218b528cefcSMark Murray     }
219ae771770SStanislav Sedov     ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
220b528cefcSMark Murray     if(ret)
221b528cefcSMark Murray 	return ret;
222b528cefcSMark Murray     ret = krb5_cc_initialize (context, id, cred.client);
223b528cefcSMark Murray     if (ret)
224b528cefcSMark Murray 	return ret;
225b528cefcSMark Murray     ret = krb5_cc_store_cred (context, id, &cred);
226b528cefcSMark Murray     if (ret)
227b528cefcSMark Murray 	return ret;
228c19800e8SDoug Rabson     krb5_free_cred_contents (context, &cred);
229b528cefcSMark Murray     *ret_cache = id;
230b528cefcSMark Murray     return 0;
231b528cefcSMark Murray }
232b528cefcSMark Murray 
233c19800e8SDoug Rabson /*
234ae771770SStanislav Sedov  * Check the credential cache `id´ to figure out what principal to use
235c19800e8SDoug Rabson  * when talking to the kadmind. If there is a initial kadmin/admin@
236c19800e8SDoug Rabson  * credential in the cache, use that client principal. Otherwise, use
237c19800e8SDoug Rabson  * the client principals first component and add /admin to the
238c19800e8SDoug Rabson  * principal.
239c19800e8SDoug Rabson  */
240c19800e8SDoug Rabson 
241b528cefcSMark Murray static krb5_error_code
get_cache_principal(krb5_context context,krb5_ccache * id,krb5_principal * client)242c19800e8SDoug Rabson get_cache_principal(krb5_context context,
243c19800e8SDoug Rabson 		    krb5_ccache *id,
244c19800e8SDoug Rabson 		    krb5_principal *client)
245c19800e8SDoug Rabson {
246c19800e8SDoug Rabson     krb5_error_code ret;
247c19800e8SDoug Rabson     const char *name, *inst;
248c19800e8SDoug Rabson     krb5_principal p1, p2;
249c19800e8SDoug Rabson 
250c19800e8SDoug Rabson     ret = krb5_cc_default(context, id);
251c19800e8SDoug Rabson     if(ret) {
252c19800e8SDoug Rabson 	*id = NULL;
253c19800e8SDoug Rabson 	return ret;
254c19800e8SDoug Rabson     }
255c19800e8SDoug Rabson 
256c19800e8SDoug Rabson     ret = krb5_cc_get_principal(context, *id, &p1);
257c19800e8SDoug Rabson     if(ret) {
258c19800e8SDoug Rabson 	krb5_cc_close(context, *id);
259c19800e8SDoug Rabson 	*id = NULL;
260c19800e8SDoug Rabson 	return ret;
261c19800e8SDoug Rabson     }
262c19800e8SDoug Rabson 
263c19800e8SDoug Rabson     ret = krb5_make_principal(context, &p2, NULL,
264c19800e8SDoug Rabson 			      "kadmin", "admin", NULL);
265c19800e8SDoug Rabson     if (ret) {
266c19800e8SDoug Rabson 	krb5_cc_close(context, *id);
267c19800e8SDoug Rabson 	*id = NULL;
268c19800e8SDoug Rabson 	krb5_free_principal(context, p1);
269c19800e8SDoug Rabson 	return ret;
270c19800e8SDoug Rabson     }
271c19800e8SDoug Rabson 
272c19800e8SDoug Rabson     {
273c19800e8SDoug Rabson 	krb5_creds in, *out;
274c19800e8SDoug Rabson 	krb5_kdc_flags flags;
275c19800e8SDoug Rabson 
276c19800e8SDoug Rabson 	flags.i = 0;
277c19800e8SDoug Rabson 	memset(&in, 0, sizeof(in));
278c19800e8SDoug Rabson 
279c19800e8SDoug Rabson 	in.client = p1;
280c19800e8SDoug Rabson 	in.server = p2;
281c19800e8SDoug Rabson 
282c19800e8SDoug Rabson 	/* check for initial ticket kadmin/admin */
283c19800e8SDoug Rabson 	ret = krb5_get_credentials_with_flags(context, KRB5_GC_CACHED, flags,
284c19800e8SDoug Rabson 					      *id, &in, &out);
285c19800e8SDoug Rabson 	krb5_free_principal(context, p2);
286c19800e8SDoug Rabson 	if (ret == 0) {
287c19800e8SDoug Rabson 	    if (out->flags.b.initial) {
288c19800e8SDoug Rabson 		*client = p1;
289c19800e8SDoug Rabson 		krb5_free_creds(context, out);
290c19800e8SDoug Rabson 		return 0;
291c19800e8SDoug Rabson 	    }
292c19800e8SDoug Rabson 	    krb5_free_creds(context, out);
293c19800e8SDoug Rabson 	}
294c19800e8SDoug Rabson     }
295c19800e8SDoug Rabson     krb5_cc_close(context, *id);
296c19800e8SDoug Rabson     *id = NULL;
297c19800e8SDoug Rabson 
298c19800e8SDoug Rabson     name = krb5_principal_get_comp_string(context, p1, 0);
299c19800e8SDoug Rabson     inst = krb5_principal_get_comp_string(context, p1, 1);
300c19800e8SDoug Rabson     if(inst == NULL || strcmp(inst, "admin") != 0) {
301c19800e8SDoug Rabson 	ret = krb5_make_principal(context, &p2, NULL, name, "admin", NULL);
302c19800e8SDoug Rabson 	krb5_free_principal(context, p1);
303c19800e8SDoug Rabson 	if(ret != 0)
304c19800e8SDoug Rabson 	    return ret;
305c19800e8SDoug Rabson 
306c19800e8SDoug Rabson 	*client = p2;
307c19800e8SDoug Rabson 	return 0;
308c19800e8SDoug Rabson     }
309c19800e8SDoug Rabson 
310c19800e8SDoug Rabson     *client = p1;
311c19800e8SDoug Rabson 
312c19800e8SDoug Rabson     return 0;
313c19800e8SDoug Rabson }
314c19800e8SDoug Rabson 
315c19800e8SDoug Rabson krb5_error_code
_kadm5_c_get_cred_cache(krb5_context context,const char * client_name,const char * server_name,const char * password,krb5_prompter_fct prompter,const char * keytab,krb5_ccache ccache,krb5_ccache * ret_cache)316c19800e8SDoug Rabson _kadm5_c_get_cred_cache(krb5_context context,
317b528cefcSMark Murray 			const char *client_name,
318b528cefcSMark Murray 			const char *server_name,
319b528cefcSMark Murray 			const char *password,
320b528cefcSMark Murray 			krb5_prompter_fct prompter,
321b528cefcSMark Murray 			const char *keytab,
322b528cefcSMark Murray 			krb5_ccache ccache,
323b528cefcSMark Murray 			krb5_ccache *ret_cache)
324b528cefcSMark Murray {
325b528cefcSMark Murray     krb5_error_code ret;
326b528cefcSMark Murray     krb5_ccache id = NULL;
327b528cefcSMark Murray     krb5_principal default_client = NULL, client = NULL;
328b528cefcSMark Murray 
329b528cefcSMark Murray     /* treat empty password as NULL */
330b528cefcSMark Murray     if(password && *password == '\0')
331b528cefcSMark Murray 	password = NULL;
332b528cefcSMark Murray     if(server_name == NULL)
333b528cefcSMark Murray 	server_name = KADM5_ADMIN_SERVICE;
334b528cefcSMark Murray 
335b528cefcSMark Murray     if(client_name != NULL) {
336b528cefcSMark Murray 	ret = krb5_parse_name(context, client_name, &client);
337b528cefcSMark Murray 	if(ret)
338b528cefcSMark Murray 	    return ret;
339b528cefcSMark Murray     }
340b528cefcSMark Murray 
341c19800e8SDoug Rabson     if(ccache != NULL) {
342c19800e8SDoug Rabson 	id = ccache;
343c19800e8SDoug Rabson 	ret = krb5_cc_get_principal(context, id, &client);
344c19800e8SDoug Rabson 	if(ret)
3458373020dSJacques Vidrine 	    return ret;
346c19800e8SDoug Rabson     } else {
347c19800e8SDoug Rabson 	/* get principal from default cache, ok if this doesn't work */
348b528cefcSMark Murray 
349c19800e8SDoug Rabson 	ret = get_cache_principal(context, &id, &default_client);
350c19800e8SDoug Rabson 	if (ret) {
351c19800e8SDoug Rabson 	    /*
352c19800e8SDoug Rabson 	     * No client was specified by the caller and we cannot
353c19800e8SDoug Rabson 	     * determine the client from a credentials cache.
3548373020dSJacques Vidrine 	     */
355b528cefcSMark Murray 	    const char *user;
356b528cefcSMark Murray 
357b528cefcSMark Murray 	    user = get_default_username ();
358b528cefcSMark Murray 
359c19800e8SDoug Rabson 	    if(user == NULL) {
360ae771770SStanislav Sedov 		krb5_set_error_message(context, KADM5_FAILURE, "Unable to find local user name");
361b528cefcSMark Murray 		return KADM5_FAILURE;
362c19800e8SDoug Rabson 	    }
363c19800e8SDoug Rabson 	    ret = krb5_make_principal(context, &default_client,
364b528cefcSMark Murray 				      NULL, user, "admin", NULL);
365b528cefcSMark Murray 	    if(ret)
366b528cefcSMark Murray 		return ret;
367b528cefcSMark Murray 	}
368b528cefcSMark Murray     }
369c19800e8SDoug Rabson 
370c19800e8SDoug Rabson 
371c19800e8SDoug Rabson     /*
372c19800e8SDoug Rabson      * No client was specified by the caller, but we have a client
373c19800e8SDoug Rabson      * from the default credentials cache.
374c19800e8SDoug Rabson      */
375c19800e8SDoug Rabson     if (client == NULL && default_client != NULL)
376c19800e8SDoug Rabson 	client = default_client;
377c19800e8SDoug Rabson 
378b528cefcSMark Murray 
379ae771770SStanislav Sedov     if(id && client && (default_client == NULL ||
380ae771770SStanislav Sedov 	      krb5_principal_compare(context, client, default_client) != 0)) {
381b528cefcSMark Murray 	ret = get_kadm_ticket(context, id, client, server_name);
382b528cefcSMark Murray 	if(ret == 0) {
383b528cefcSMark Murray 	    *ret_cache = id;
384b528cefcSMark Murray 	    krb5_free_principal(context, default_client);
385b528cefcSMark Murray 	    if (default_client != client)
386b528cefcSMark Murray 		krb5_free_principal(context, client);
387b528cefcSMark Murray 	    return 0;
388b528cefcSMark Murray 	}
389b528cefcSMark Murray 	if(ccache != NULL)
390b528cefcSMark Murray 	    /* couldn't get ticket from cache */
391b528cefcSMark Murray 	    return -1;
392b528cefcSMark Murray     }
393b528cefcSMark Murray     /* get creds via AS request */
394c19800e8SDoug Rabson     if(id && (id != ccache))
395b528cefcSMark Murray 	krb5_cc_close(context, id);
396b528cefcSMark Murray     if (client != default_client)
397b528cefcSMark Murray 	krb5_free_principal(context, default_client);
398b528cefcSMark Murray 
399b528cefcSMark Murray     ret = get_new_cache(context, client, password, prompter, keytab,
400b528cefcSMark Murray 			server_name, ret_cache);
401b528cefcSMark Murray     krb5_free_principal(context, client);
402b528cefcSMark Murray     return ret;
403b528cefcSMark Murray }
404b528cefcSMark Murray 
405b528cefcSMark Murray static kadm5_ret_t
kadm_connect(kadm5_client_context * ctx)4065e9cd1aeSAssar Westerlund kadm_connect(kadm5_client_context *ctx)
407b528cefcSMark Murray {
408b528cefcSMark Murray     kadm5_ret_t ret;
409b528cefcSMark Murray     krb5_principal server;
410b528cefcSMark Murray     krb5_ccache cc;
411ae771770SStanislav Sedov     rk_socket_t s = rk_INVALID_SOCKET;
412b528cefcSMark Murray     struct addrinfo *ai, *a;
413b528cefcSMark Murray     struct addrinfo hints;
414b528cefcSMark Murray     int error;
415b528cefcSMark Murray     char portstr[NI_MAXSERV];
416b528cefcSMark Murray     char *hostname, *slash;
417bbd80c28SJacques Vidrine     char *service_name;
4185e9cd1aeSAssar Westerlund     krb5_context context = ctx->context;
419b528cefcSMark Murray 
420b528cefcSMark Murray     memset (&hints, 0, sizeof(hints));
421b528cefcSMark Murray     hints.ai_socktype = SOCK_STREAM;
422b528cefcSMark Murray     hints.ai_protocol = IPPROTO_TCP;
423b528cefcSMark Murray 
424b528cefcSMark Murray     snprintf (portstr, sizeof(portstr), "%u", ntohs(ctx->kadmind_port));
425b528cefcSMark Murray 
426b528cefcSMark Murray     hostname = ctx->admin_server;
427b528cefcSMark Murray     slash = strchr (hostname, '/');
428b528cefcSMark Murray     if (slash != NULL)
429b528cefcSMark Murray 	hostname = slash + 1;
430b528cefcSMark Murray 
431b528cefcSMark Murray     error = getaddrinfo (hostname, portstr, &hints, &ai);
432c19800e8SDoug Rabson     if (error) {
433ae771770SStanislav Sedov 	krb5_clear_error_message(context);
434b528cefcSMark Murray 	return KADM5_BAD_SERVER_NAME;
435c19800e8SDoug Rabson     }
436b528cefcSMark Murray 
437b528cefcSMark Murray     for (a = ai; a != NULL; a = a->ai_next) {
438b528cefcSMark Murray 	s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
439b528cefcSMark Murray 	if (s < 0)
440b528cefcSMark Murray 	    continue;
441b528cefcSMark Murray 	if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
442ae771770SStanislav Sedov 	    krb5_clear_error_message(context);
443b528cefcSMark Murray 	    krb5_warn (context, errno, "connect(%s)", hostname);
444ae771770SStanislav Sedov 	    rk_closesocket (s);
445b528cefcSMark Murray 	    continue;
446b528cefcSMark Murray 	}
447b528cefcSMark Murray 	break;
448b528cefcSMark Murray     }
449b528cefcSMark Murray     if (a == NULL) {
450b528cefcSMark Murray 	freeaddrinfo (ai);
451ae771770SStanislav Sedov 	krb5_clear_error_message(context);
452b528cefcSMark Murray 	krb5_warnx (context, "failed to contact %s", hostname);
453b528cefcSMark Murray 	return KADM5_FAILURE;
454b528cefcSMark Murray     }
455c19800e8SDoug Rabson     ret = _kadm5_c_get_cred_cache(context,
456c19800e8SDoug Rabson 				  ctx->client_name,
457c19800e8SDoug Rabson 				  ctx->service_name,
4585e9cd1aeSAssar Westerlund 				  NULL, ctx->prompter, ctx->keytab,
4595e9cd1aeSAssar Westerlund 				  ctx->ccache, &cc);
460b528cefcSMark Murray 
461b528cefcSMark Murray     if(ret) {
462b528cefcSMark Murray 	freeaddrinfo (ai);
463ae771770SStanislav Sedov 	rk_closesocket(s);
464b528cefcSMark Murray 	return ret;
465b528cefcSMark Murray     }
466bbd80c28SJacques Vidrine 
467bbd80c28SJacques Vidrine     if (ctx->realm)
468bbd80c28SJacques Vidrine 	asprintf(&service_name, "%s@%s", KADM5_ADMIN_SERVICE, ctx->realm);
469bbd80c28SJacques Vidrine     else
470bbd80c28SJacques Vidrine 	asprintf(&service_name, "%s", KADM5_ADMIN_SERVICE);
471bbd80c28SJacques Vidrine 
472bbd80c28SJacques Vidrine     if (service_name == NULL) {
473bbd80c28SJacques Vidrine 	freeaddrinfo (ai);
474ae771770SStanislav Sedov 	rk_closesocket(s);
475ae771770SStanislav Sedov 	krb5_clear_error_message(context);
476bbd80c28SJacques Vidrine 	return ENOMEM;
477bbd80c28SJacques Vidrine     }
478bbd80c28SJacques Vidrine 
479bbd80c28SJacques Vidrine     ret = krb5_parse_name(context, service_name, &server);
480bbd80c28SJacques Vidrine     free(service_name);
481b528cefcSMark Murray     if(ret) {
482b528cefcSMark Murray 	freeaddrinfo (ai);
4835e9cd1aeSAssar Westerlund 	if(ctx->ccache == NULL)
484b528cefcSMark Murray 	    krb5_cc_close(context, cc);
485ae771770SStanislav Sedov 	rk_closesocket(s);
486b528cefcSMark Murray 	return ret;
487b528cefcSMark Murray     }
488b528cefcSMark Murray     ctx->ac = NULL;
489b528cefcSMark Murray 
490b528cefcSMark Murray     ret = krb5_sendauth(context, &ctx->ac, &s,
491b528cefcSMark Murray 			KADMIN_APPL_VERSION, NULL,
492b528cefcSMark Murray 			server, AP_OPTS_MUTUAL_REQUIRED,
493b528cefcSMark Murray 			NULL, NULL, cc, NULL, NULL, NULL);
494b528cefcSMark Murray     if(ret == 0) {
4955e9cd1aeSAssar Westerlund 	krb5_data params;
4964137ff4cSJacques Vidrine 	kadm5_config_params p;
4974137ff4cSJacques Vidrine 	memset(&p, 0, sizeof(p));
4984137ff4cSJacques Vidrine 	if(ctx->realm) {
4994137ff4cSJacques Vidrine 	    p.mask |= KADM5_CONFIG_REALM;
5004137ff4cSJacques Vidrine 	    p.realm = ctx->realm;
5014137ff4cSJacques Vidrine 	}
5024137ff4cSJacques Vidrine 	ret = _kadm5_marshal_params(context, &p, &params);
503b528cefcSMark Murray 
5045e9cd1aeSAssar Westerlund 	ret = krb5_write_priv_message(context, ctx->ac, &s, &params);
505b528cefcSMark Murray 	krb5_data_free(&params);
5065e9cd1aeSAssar Westerlund 	if(ret) {
5075e9cd1aeSAssar Westerlund 	    freeaddrinfo (ai);
508ae771770SStanislav Sedov 	    rk_closesocket(s);
5095e9cd1aeSAssar Westerlund 	    if(ctx->ccache == NULL)
5105e9cd1aeSAssar Westerlund 		krb5_cc_close(context, cc);
5115e9cd1aeSAssar Westerlund 	    return ret;
5125e9cd1aeSAssar Westerlund 	}
513b528cefcSMark Murray     } else if(ret == KRB5_SENDAUTH_BADAPPLVERS) {
514ae771770SStanislav Sedov 	rk_closesocket(s);
515b528cefcSMark Murray 
516b528cefcSMark Murray 	s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
517b528cefcSMark Murray 	if (s < 0) {
518b528cefcSMark Murray 	    freeaddrinfo (ai);
519ae771770SStanislav Sedov 	    krb5_clear_error_message(context);
520b528cefcSMark Murray 	    return errno;
521b528cefcSMark Murray 	}
522b528cefcSMark Murray 	if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
523ae771770SStanislav Sedov 	    rk_closesocket (s);
524b528cefcSMark Murray 	    freeaddrinfo (ai);
525ae771770SStanislav Sedov 	    krb5_clear_error_message(context);
526b528cefcSMark Murray 	    return errno;
527b528cefcSMark Murray 	}
528b528cefcSMark Murray 	ret = krb5_sendauth(context, &ctx->ac, &s,
529b528cefcSMark Murray 			    KADMIN_OLD_APPL_VERSION, NULL,
530b528cefcSMark Murray 			    server, AP_OPTS_MUTUAL_REQUIRED,
531b528cefcSMark Murray 			    NULL, NULL, cc, NULL, NULL, NULL);
532b528cefcSMark Murray     }
533b528cefcSMark Murray     freeaddrinfo (ai);
534b528cefcSMark Murray     if(ret) {
535ae771770SStanislav Sedov 	rk_closesocket(s);
536b528cefcSMark Murray 	return ret;
537b528cefcSMark Murray     }
538b528cefcSMark Murray 
539b528cefcSMark Murray     krb5_free_principal(context, server);
5405e9cd1aeSAssar Westerlund     if(ctx->ccache == NULL)
541b528cefcSMark Murray 	krb5_cc_close(context, cc);
542b528cefcSMark Murray     ctx->sock = s;
5435e9cd1aeSAssar Westerlund 
5445e9cd1aeSAssar Westerlund     return 0;
5455e9cd1aeSAssar Westerlund }
5465e9cd1aeSAssar Westerlund 
5475e9cd1aeSAssar Westerlund kadm5_ret_t
_kadm5_connect(void * handle)5485e9cd1aeSAssar Westerlund _kadm5_connect(void *handle)
5495e9cd1aeSAssar Westerlund {
5505e9cd1aeSAssar Westerlund     kadm5_client_context *ctx = handle;
5515e9cd1aeSAssar Westerlund     if(ctx->sock == -1)
5525e9cd1aeSAssar Westerlund 	return kadm_connect(ctx);
5535e9cd1aeSAssar Westerlund     return 0;
5545e9cd1aeSAssar Westerlund }
5555e9cd1aeSAssar Westerlund 
5565e9cd1aeSAssar Westerlund static kadm5_ret_t
kadm5_c_init_with_context(krb5_context context,const char * client_name,const char * password,krb5_prompter_fct prompter,const char * keytab,krb5_ccache ccache,const char * service_name,kadm5_config_params * realm_params,unsigned long struct_version,unsigned long api_version,void ** server_handle)5575e9cd1aeSAssar Westerlund kadm5_c_init_with_context(krb5_context context,
5585e9cd1aeSAssar Westerlund 			  const char *client_name,
5595e9cd1aeSAssar Westerlund 			  const char *password,
5605e9cd1aeSAssar Westerlund 			  krb5_prompter_fct prompter,
5615e9cd1aeSAssar Westerlund 			  const char *keytab,
5625e9cd1aeSAssar Westerlund 			  krb5_ccache ccache,
5635e9cd1aeSAssar Westerlund 			  const char *service_name,
5645e9cd1aeSAssar Westerlund 			  kadm5_config_params *realm_params,
5655e9cd1aeSAssar Westerlund 			  unsigned long struct_version,
5665e9cd1aeSAssar Westerlund 			  unsigned long api_version,
5675e9cd1aeSAssar Westerlund 			  void **server_handle)
5685e9cd1aeSAssar Westerlund {
5695e9cd1aeSAssar Westerlund     kadm5_ret_t ret;
570*ed549cb0SCy Schubert     kadm5_client_context *ctx = NULL;
5715e9cd1aeSAssar Westerlund     krb5_ccache cc;
5725e9cd1aeSAssar Westerlund 
5735e9cd1aeSAssar Westerlund     ret = _kadm5_c_init_context(&ctx, realm_params, context);
5745e9cd1aeSAssar Westerlund     if(ret)
5755e9cd1aeSAssar Westerlund 	return ret;
5765e9cd1aeSAssar Westerlund 
5775e9cd1aeSAssar Westerlund     if(password != NULL && *password != '\0') {
578c19800e8SDoug Rabson 	ret = _kadm5_c_get_cred_cache(context,
579c19800e8SDoug Rabson 				      client_name,
580c19800e8SDoug Rabson 				      service_name,
5815e9cd1aeSAssar Westerlund 				      password, prompter, keytab, ccache, &cc);
5825e9cd1aeSAssar Westerlund 	if(ret)
5835e9cd1aeSAssar Westerlund 	    return ret; /* XXX */
5845e9cd1aeSAssar Westerlund 	ccache = cc;
5855e9cd1aeSAssar Westerlund     }
5865e9cd1aeSAssar Westerlund 
5875e9cd1aeSAssar Westerlund 
5885e9cd1aeSAssar Westerlund     if (client_name != NULL)
5895e9cd1aeSAssar Westerlund 	ctx->client_name = strdup(client_name);
5905e9cd1aeSAssar Westerlund     else
5915e9cd1aeSAssar Westerlund 	ctx->client_name = NULL;
5925e9cd1aeSAssar Westerlund     if (service_name != NULL)
5935e9cd1aeSAssar Westerlund 	ctx->service_name = strdup(service_name);
5945e9cd1aeSAssar Westerlund     else
5955e9cd1aeSAssar Westerlund 	ctx->service_name = NULL;
5965e9cd1aeSAssar Westerlund     ctx->prompter = prompter;
5975e9cd1aeSAssar Westerlund     ctx->keytab = keytab;
5985e9cd1aeSAssar Westerlund     ctx->ccache = ccache;
5994137ff4cSJacques Vidrine     /* maybe we should copy the params here */
6005e9cd1aeSAssar Westerlund     ctx->sock = -1;
6015e9cd1aeSAssar Westerlund 
602b528cefcSMark Murray     *server_handle = ctx;
603b528cefcSMark Murray     return 0;
604b528cefcSMark Murray }
605b528cefcSMark Murray 
606b528cefcSMark Murray static kadm5_ret_t
init_context(const char * client_name,const char * password,krb5_prompter_fct prompter,const char * keytab,krb5_ccache ccache,const char * service_name,kadm5_config_params * realm_params,unsigned long struct_version,unsigned long api_version,void ** server_handle)607b528cefcSMark Murray init_context(const char *client_name,
608b528cefcSMark Murray 	     const char *password,
609b528cefcSMark Murray 	     krb5_prompter_fct prompter,
610b528cefcSMark Murray 	     const char *keytab,
611b528cefcSMark Murray 	     krb5_ccache ccache,
612b528cefcSMark Murray 	     const char *service_name,
613b528cefcSMark Murray 	     kadm5_config_params *realm_params,
614b528cefcSMark Murray 	     unsigned long struct_version,
615b528cefcSMark Murray 	     unsigned long api_version,
616b528cefcSMark Murray 	     void **server_handle)
617b528cefcSMark Murray {
618b528cefcSMark Murray     krb5_context context;
619b528cefcSMark Murray     kadm5_ret_t ret;
620b528cefcSMark Murray     kadm5_server_context *ctx;
621b528cefcSMark Murray 
6225e9cd1aeSAssar Westerlund     ret = krb5_init_context(&context);
6235e9cd1aeSAssar Westerlund     if (ret)
6245e9cd1aeSAssar Westerlund 	return ret;
625b528cefcSMark Murray     ret = kadm5_c_init_with_context(context,
626b528cefcSMark Murray 				    client_name,
627b528cefcSMark Murray 				    password,
628b528cefcSMark Murray 				    prompter,
629b528cefcSMark Murray 				    keytab,
630b528cefcSMark Murray 				    ccache,
631b528cefcSMark Murray 				    service_name,
632b528cefcSMark Murray 				    realm_params,
633b528cefcSMark Murray 				    struct_version,
634b528cefcSMark Murray 				    api_version,
635b528cefcSMark Murray 				    server_handle);
636b528cefcSMark Murray     if(ret){
637b528cefcSMark Murray 	krb5_free_context(context);
638b528cefcSMark Murray 	return ret;
639b528cefcSMark Murray     }
640b528cefcSMark Murray     ctx = *server_handle;
641b528cefcSMark Murray     ctx->my_context = 1;
642b528cefcSMark Murray     return 0;
643b528cefcSMark Murray }
644b528cefcSMark Murray 
645b528cefcSMark Murray kadm5_ret_t
kadm5_c_init_with_password_ctx(krb5_context context,const char * client_name,const char * password,const char * service_name,kadm5_config_params * realm_params,unsigned long struct_version,unsigned long api_version,void ** server_handle)646b528cefcSMark Murray kadm5_c_init_with_password_ctx(krb5_context context,
647b528cefcSMark Murray 			       const char *client_name,
648b528cefcSMark Murray 			       const char *password,
649b528cefcSMark Murray 			       const char *service_name,
650b528cefcSMark Murray 			       kadm5_config_params *realm_params,
651b528cefcSMark Murray 			       unsigned long struct_version,
652b528cefcSMark Murray 			       unsigned long api_version,
653b528cefcSMark Murray 			       void **server_handle)
654b528cefcSMark Murray {
655b528cefcSMark Murray     return kadm5_c_init_with_context(context,
656b528cefcSMark Murray 				     client_name,
657b528cefcSMark Murray 				     password,
658b528cefcSMark Murray 				     krb5_prompter_posix,
659b528cefcSMark Murray 				     NULL,
660b528cefcSMark Murray 				     NULL,
661b528cefcSMark Murray 				     service_name,
662b528cefcSMark Murray 				     realm_params,
663b528cefcSMark Murray 				     struct_version,
664b528cefcSMark Murray 				     api_version,
665b528cefcSMark Murray 				     server_handle);
666b528cefcSMark Murray }
667b528cefcSMark Murray 
668b528cefcSMark Murray kadm5_ret_t
kadm5_c_init_with_password(const char * client_name,const char * password,const char * service_name,kadm5_config_params * realm_params,unsigned long struct_version,unsigned long api_version,void ** server_handle)669b528cefcSMark Murray kadm5_c_init_with_password(const char *client_name,
670b528cefcSMark Murray 			   const char *password,
671b528cefcSMark Murray 			   const char *service_name,
672b528cefcSMark Murray 			   kadm5_config_params *realm_params,
673b528cefcSMark Murray 			   unsigned long struct_version,
674b528cefcSMark Murray 			   unsigned long api_version,
675b528cefcSMark Murray 			   void **server_handle)
676b528cefcSMark Murray {
677b528cefcSMark Murray     return init_context(client_name,
678b528cefcSMark Murray 			password,
679b528cefcSMark Murray 			krb5_prompter_posix,
680b528cefcSMark Murray 			NULL,
681b528cefcSMark Murray 			NULL,
682b528cefcSMark Murray 			service_name,
683b528cefcSMark Murray 			realm_params,
684b528cefcSMark Murray 			struct_version,
685b528cefcSMark Murray 			api_version,
686b528cefcSMark Murray 			server_handle);
687b528cefcSMark Murray }
688b528cefcSMark Murray 
689b528cefcSMark Murray kadm5_ret_t
kadm5_c_init_with_skey_ctx(krb5_context context,const char * client_name,const char * keytab,const char * service_name,kadm5_config_params * realm_params,unsigned long struct_version,unsigned long api_version,void ** server_handle)690b528cefcSMark Murray kadm5_c_init_with_skey_ctx(krb5_context context,
691b528cefcSMark Murray 			   const char *client_name,
692b528cefcSMark Murray 			   const char *keytab,
693b528cefcSMark Murray 			   const char *service_name,
694b528cefcSMark Murray 			   kadm5_config_params *realm_params,
695b528cefcSMark Murray 			   unsigned long struct_version,
696b528cefcSMark Murray 			   unsigned long api_version,
697b528cefcSMark Murray 			   void **server_handle)
698b528cefcSMark Murray {
699b528cefcSMark Murray     return kadm5_c_init_with_context(context,
700b528cefcSMark Murray 				     client_name,
701b528cefcSMark Murray 				     NULL,
702b528cefcSMark Murray 				     NULL,
703b528cefcSMark Murray 				     keytab,
704b528cefcSMark Murray 				     NULL,
705b528cefcSMark Murray 				     service_name,
706b528cefcSMark Murray 				     realm_params,
707b528cefcSMark Murray 				     struct_version,
708b528cefcSMark Murray 				     api_version,
709b528cefcSMark Murray 				     server_handle);
710b528cefcSMark Murray }
711b528cefcSMark Murray 
712b528cefcSMark Murray 
713b528cefcSMark Murray kadm5_ret_t
kadm5_c_init_with_skey(const char * client_name,const char * keytab,const char * service_name,kadm5_config_params * realm_params,unsigned long struct_version,unsigned long api_version,void ** server_handle)714b528cefcSMark Murray kadm5_c_init_with_skey(const char *client_name,
715b528cefcSMark Murray 		     const char *keytab,
716b528cefcSMark Murray 		     const char *service_name,
717b528cefcSMark Murray 		     kadm5_config_params *realm_params,
718b528cefcSMark Murray 		     unsigned long struct_version,
719b528cefcSMark Murray 		     unsigned long api_version,
720b528cefcSMark Murray 		     void **server_handle)
721b528cefcSMark Murray {
722b528cefcSMark Murray     return init_context(client_name,
723b528cefcSMark Murray 			NULL,
724b528cefcSMark Murray 			NULL,
725b528cefcSMark Murray 			keytab,
726b528cefcSMark Murray 			NULL,
727b528cefcSMark Murray 			service_name,
728b528cefcSMark Murray 			realm_params,
729b528cefcSMark Murray 			struct_version,
730b528cefcSMark Murray 			api_version,
731b528cefcSMark Murray 			server_handle);
732b528cefcSMark Murray }
733b528cefcSMark Murray 
734b528cefcSMark Murray kadm5_ret_t
kadm5_c_init_with_creds_ctx(krb5_context context,const char * client_name,krb5_ccache ccache,const char * service_name,kadm5_config_params * realm_params,unsigned long struct_version,unsigned long api_version,void ** server_handle)735b528cefcSMark Murray kadm5_c_init_with_creds_ctx(krb5_context context,
736b528cefcSMark Murray 			    const char *client_name,
737b528cefcSMark Murray 			    krb5_ccache ccache,
738b528cefcSMark Murray 			    const char *service_name,
739b528cefcSMark Murray 			    kadm5_config_params *realm_params,
740b528cefcSMark Murray 			    unsigned long struct_version,
741b528cefcSMark Murray 			    unsigned long api_version,
742b528cefcSMark Murray 			    void **server_handle)
743b528cefcSMark Murray {
744b528cefcSMark Murray     return kadm5_c_init_with_context(context,
745b528cefcSMark Murray 				     client_name,
746b528cefcSMark Murray 				     NULL,
747b528cefcSMark Murray 				     NULL,
748b528cefcSMark Murray 				     NULL,
749b528cefcSMark Murray 				     ccache,
750b528cefcSMark Murray 				     service_name,
751b528cefcSMark Murray 				     realm_params,
752b528cefcSMark Murray 				     struct_version,
753b528cefcSMark Murray 				     api_version,
754b528cefcSMark Murray 				     server_handle);
755b528cefcSMark Murray }
756b528cefcSMark Murray 
757b528cefcSMark Murray kadm5_ret_t
kadm5_c_init_with_creds(const char * client_name,krb5_ccache ccache,const char * service_name,kadm5_config_params * realm_params,unsigned long struct_version,unsigned long api_version,void ** server_handle)758b528cefcSMark Murray kadm5_c_init_with_creds(const char *client_name,
759b528cefcSMark Murray 			krb5_ccache ccache,
760b528cefcSMark Murray 			const char *service_name,
761b528cefcSMark Murray 			kadm5_config_params *realm_params,
762b528cefcSMark Murray 			unsigned long struct_version,
763b528cefcSMark Murray 			unsigned long api_version,
764b528cefcSMark Murray 			void **server_handle)
765b528cefcSMark Murray {
766b528cefcSMark Murray     return init_context(client_name,
767b528cefcSMark Murray 			NULL,
768b528cefcSMark Murray 			NULL,
769b528cefcSMark Murray 			NULL,
770b528cefcSMark Murray 			ccache,
771b528cefcSMark Murray 			service_name,
772b528cefcSMark Murray 			realm_params,
773b528cefcSMark Murray 			struct_version,
774b528cefcSMark Murray 			api_version,
775b528cefcSMark Murray 			server_handle);
776b528cefcSMark Murray }
777b528cefcSMark Murray 
778b528cefcSMark Murray #if 0
779b528cefcSMark Murray kadm5_ret_t
780b528cefcSMark Murray kadm5_init(char *client_name, char *pass,
781b528cefcSMark Murray 	   char *service_name,
782b528cefcSMark Murray 	   kadm5_config_params *realm_params,
783b528cefcSMark Murray 	   unsigned long struct_version,
784b528cefcSMark Murray 	   unsigned long api_version,
785b528cefcSMark Murray 	   void **server_handle)
786b528cefcSMark Murray {
787b528cefcSMark Murray }
788b528cefcSMark Murray #endif
789b528cefcSMark Murray 
790