init_c.c revision 90926
155682Smarkm/*
290926Snectar * Copyright (c) 1997 - 2002 Kungliga Tekniska H�gskolan
355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
455682Smarkm * All rights reserved.
555682Smarkm *
655682Smarkm * Redistribution and use in source and binary forms, with or without
755682Smarkm * modification, are permitted provided that the following conditions
855682Smarkm * are met:
955682Smarkm *
1055682Smarkm * 1. Redistributions of source code must retain the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
2055682Smarkm *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "kadm5_locl.h"
3555682Smarkm#include <sys/types.h>
3655682Smarkm#include <sys/socket.h>
3755682Smarkm#include <netinet/in.h>
3855682Smarkm#include <netdb.h>
3955682Smarkm
4090926SnectarRCSID("$Id: init_c.c,v 1.42 2002/02/08 18:31:49 joda Exp $");
4155682Smarkm
4255682Smarkmstatic void
4355682Smarkmset_funcs(kadm5_client_context *c)
4455682Smarkm{
4555682Smarkm#define SET(C, F) (C)->funcs.F = kadm5 ## _c_ ## F
4655682Smarkm    SET(c, chpass_principal);
4772445Sassar    SET(c, chpass_principal_with_key);
4855682Smarkm    SET(c, create_principal);
4955682Smarkm    SET(c, delete_principal);
5055682Smarkm    SET(c, destroy);
5155682Smarkm    SET(c, flush);
5255682Smarkm    SET(c, get_principal);
5355682Smarkm    SET(c, get_principals);
5455682Smarkm    SET(c, get_privs);
5555682Smarkm    SET(c, modify_principal);
5655682Smarkm    SET(c, randkey_principal);
5755682Smarkm    SET(c, rename_principal);
5855682Smarkm}
5955682Smarkm
6055682Smarkmkadm5_ret_t
6155682Smarkm_kadm5_c_init_context(kadm5_client_context **ctx,
6255682Smarkm		      kadm5_config_params *params,
6355682Smarkm		      krb5_context context)
6455682Smarkm{
6555682Smarkm    krb5_error_code ret;
6655682Smarkm    char *colon;
6755682Smarkm
6855682Smarkm    *ctx = malloc(sizeof(**ctx));
6955682Smarkm    if(*ctx == NULL)
7055682Smarkm	return ENOMEM;
7155682Smarkm    memset(*ctx, 0, sizeof(**ctx));
7255682Smarkm    krb5_add_et_list (context, initialize_kadm5_error_table_r);
7355682Smarkm    set_funcs(*ctx);
7455682Smarkm    (*ctx)->context = context;
7555682Smarkm    if(params->mask & KADM5_CONFIG_REALM)
7655682Smarkm	(*ctx)->realm = strdup(params->realm);
7755682Smarkm    else
7855682Smarkm	krb5_get_default_realm((*ctx)->context, &(*ctx)->realm);
7955682Smarkm    if(params->mask & KADM5_CONFIG_ADMIN_SERVER)
8055682Smarkm	(*ctx)->admin_server = strdup(params->admin_server);
8155682Smarkm    else {
8255682Smarkm	char **hostlist;
8355682Smarkm
8455682Smarkm	ret = krb5_get_krb_admin_hst (context, &(*ctx)->realm, &hostlist);
8555682Smarkm	if (ret)
8655682Smarkm	    return ret;
8755682Smarkm	(*ctx)->admin_server = strdup(*hostlist);
8855682Smarkm	krb5_free_krbhst (context, hostlist);
8955682Smarkm    }
9055682Smarkm
9155682Smarkm    if ((*ctx)->admin_server == NULL)
9255682Smarkm	return ENOMEM;
9355682Smarkm    colon = strchr ((*ctx)->admin_server, ':');
9455682Smarkm    if (colon != NULL)
9555682Smarkm	*colon++ = '\0';
9655682Smarkm
9755682Smarkm    (*ctx)->kadmind_port = 0;
9855682Smarkm
9955682Smarkm    if(params->mask & KADM5_CONFIG_KADMIND_PORT)
10055682Smarkm	(*ctx)->kadmind_port = params->kadmind_port;
10155682Smarkm    else if (colon != NULL) {
10255682Smarkm	char *end;
10355682Smarkm
10455682Smarkm	(*ctx)->kadmind_port = htons(strtol (colon, &end, 0));
10555682Smarkm    }
10655682Smarkm    if ((*ctx)->kadmind_port == 0)
10755682Smarkm	(*ctx)->kadmind_port = krb5_getportbyname (context, "kerberos-adm",
10855682Smarkm						   "tcp", 749);
10955682Smarkm    return 0;
11055682Smarkm}
11155682Smarkm
11255682Smarkmstatic krb5_error_code
11355682Smarkmget_kadm_ticket(krb5_context context,
11455682Smarkm		krb5_ccache id,
11555682Smarkm		krb5_principal client,
11655682Smarkm		const char *server_name)
11755682Smarkm{
11855682Smarkm    krb5_error_code ret;
11955682Smarkm    krb5_creds in, *out;
12055682Smarkm
12155682Smarkm    memset(&in, 0, sizeof(in));
12255682Smarkm    in.client = client;
12355682Smarkm    ret = krb5_parse_name(context, server_name, &in.server);
12455682Smarkm    if(ret)
12555682Smarkm	return ret;
12655682Smarkm    ret = krb5_get_credentials(context, 0, id, &in, &out);
12755682Smarkm    if(ret == 0)
12855682Smarkm	krb5_free_creds(context, out);
12955682Smarkm    krb5_free_principal(context, in.server);
13055682Smarkm    return ret;
13155682Smarkm}
13255682Smarkm
13355682Smarkmstatic krb5_error_code
13455682Smarkmget_new_cache(krb5_context context,
13555682Smarkm	      krb5_principal client,
13655682Smarkm	      const char *password,
13755682Smarkm	      krb5_prompter_fct prompter,
13855682Smarkm	      const char *keytab,
13955682Smarkm	      const char *server_name,
14055682Smarkm	      krb5_ccache *ret_cache)
14155682Smarkm{
14255682Smarkm    krb5_error_code ret;
14355682Smarkm    krb5_creds cred;
14455682Smarkm    krb5_get_init_creds_opt opt;
14555682Smarkm    krb5_ccache id;
14655682Smarkm
14755682Smarkm    krb5_get_init_creds_opt_init (&opt);
14890926Snectar
14990926Snectar    krb5_get_init_creds_opt_set_default_flags(context, "kadmin",
15090926Snectar					      krb5_principal_get_realm(context,
15190926Snectar								       client),
15290926Snectar					      &opt);
15390926Snectar
15490926Snectar
15557416Smarkm    krb5_get_init_creds_opt_set_forwardable (&opt, FALSE);
15657416Smarkm    krb5_get_init_creds_opt_set_proxiable (&opt, FALSE);
15757416Smarkm
15855682Smarkm    if(password == NULL && prompter == NULL) {
15955682Smarkm	krb5_keytab kt;
16055682Smarkm	if(keytab == NULL)
16155682Smarkm	    ret = krb5_kt_default(context, &kt);
16255682Smarkm	else
16355682Smarkm	    ret = krb5_kt_resolve(context, keytab, &kt);
16455682Smarkm	if(ret)
16555682Smarkm	    return ret;
16655682Smarkm	ret = krb5_get_init_creds_keytab (context,
16755682Smarkm					  &cred,
16855682Smarkm					  client,
16955682Smarkm					  kt,
17055682Smarkm					  0,
17155682Smarkm					  server_name,
17255682Smarkm					  &opt);
17355682Smarkm	krb5_kt_close(context, kt);
17455682Smarkm    } else {
17555682Smarkm	ret = krb5_get_init_creds_password (context,
17655682Smarkm					    &cred,
17755682Smarkm					    client,
17855682Smarkm					    password,
17955682Smarkm					    prompter,
18055682Smarkm					    NULL,
18155682Smarkm					    0,
18255682Smarkm					    server_name,
18355682Smarkm					    &opt);
18455682Smarkm    }
18555682Smarkm    switch(ret){
18655682Smarkm    case 0:
18755682Smarkm	break;
18855682Smarkm    case KRB5_LIBOS_PWDINTR:	/* don't print anything if it was just C-c:ed */
18955682Smarkm    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
19055682Smarkm    case KRB5KRB_AP_ERR_MODIFIED:
19155682Smarkm	return KADM5_BAD_PASSWORD;
19255682Smarkm    default:
19355682Smarkm	return ret;
19455682Smarkm    }
19555682Smarkm    ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id);
19655682Smarkm    if(ret)
19755682Smarkm	return ret;
19855682Smarkm    ret = krb5_cc_initialize (context, id, cred.client);
19955682Smarkm    if (ret)
20055682Smarkm	return ret;
20155682Smarkm    ret = krb5_cc_store_cred (context, id, &cred);
20255682Smarkm    if (ret)
20355682Smarkm	return ret;
20455682Smarkm    krb5_free_creds_contents (context, &cred);
20555682Smarkm    *ret_cache = id;
20655682Smarkm    return 0;
20755682Smarkm}
20855682Smarkm
20955682Smarkmstatic krb5_error_code
21055682Smarkmget_cred_cache(krb5_context context,
21155682Smarkm	       const char *client_name,
21255682Smarkm	       const char *server_name,
21355682Smarkm	       const char *password,
21455682Smarkm	       krb5_prompter_fct prompter,
21555682Smarkm	       const char *keytab,
21655682Smarkm	       krb5_ccache ccache,
21755682Smarkm	       krb5_ccache *ret_cache)
21855682Smarkm{
21955682Smarkm    krb5_error_code ret;
22055682Smarkm    krb5_ccache id = NULL;
22155682Smarkm    krb5_principal default_client = NULL, client = NULL;
22255682Smarkm
22355682Smarkm    /* treat empty password as NULL */
22455682Smarkm    if(password && *password == '\0')
22555682Smarkm	password = NULL;
22655682Smarkm    if(server_name == NULL)
22755682Smarkm	server_name = KADM5_ADMIN_SERVICE;
22855682Smarkm
22955682Smarkm    if(client_name != NULL) {
23055682Smarkm	ret = krb5_parse_name(context, client_name, &client);
23155682Smarkm	if(ret)
23255682Smarkm	    return ret;
23355682Smarkm    }
23455682Smarkm
23555682Smarkm    if(password != NULL || prompter != NULL) {
23655682Smarkm	/* get principal from default cache, ok if this doesn't work */
23755682Smarkm	ret = krb5_cc_default(context, &id);
23855682Smarkm	if(ret == 0) {
23955682Smarkm	    ret = krb5_cc_get_principal(context, id, &default_client);
24055682Smarkm	    if(ret) {
24155682Smarkm		krb5_cc_close(context, id);
24255682Smarkm		id = NULL;
24355682Smarkm	    }
24455682Smarkm	}
24555682Smarkm
24655682Smarkm	if(client == NULL)
24755682Smarkm	    client = default_client;
24855682Smarkm	if(client == NULL) {
24955682Smarkm	    const char *user;
25055682Smarkm
25155682Smarkm	    user = get_default_username ();
25255682Smarkm
25355682Smarkm	    if(user == NULL)
25455682Smarkm		return KADM5_FAILURE;
25555682Smarkm	    ret = krb5_make_principal(context, &client,
25655682Smarkm				      NULL, user, "admin", NULL);
25755682Smarkm	    if(ret)
25855682Smarkm		return ret;
25955682Smarkm	}
26055682Smarkm	if(client != default_client) {
26155682Smarkm	    krb5_free_principal(context, default_client);
26255682Smarkm	    default_client = NULL;
26355682Smarkm	    if (id != NULL) {
26455682Smarkm		krb5_cc_close(context, id);
26555682Smarkm		id = NULL;
26655682Smarkm	    }
26755682Smarkm	}
26855682Smarkm    } else if(ccache != NULL)
26955682Smarkm	id = ccache;
27055682Smarkm
27155682Smarkm
27255682Smarkm    if(id && (default_client == NULL ||
27355682Smarkm	      krb5_principal_compare(context, client, default_client))) {
27455682Smarkm	ret = get_kadm_ticket(context, id, client, server_name);
27555682Smarkm	if(ret == 0) {
27655682Smarkm	    *ret_cache = id;
27755682Smarkm	    krb5_free_principal(context, default_client);
27855682Smarkm	    if (default_client != client)
27955682Smarkm		krb5_free_principal(context, client);
28055682Smarkm	    return 0;
28155682Smarkm	}
28255682Smarkm	if(ccache != NULL)
28355682Smarkm	    /* couldn't get ticket from cache */
28455682Smarkm	    return -1;
28555682Smarkm    }
28655682Smarkm    /* get creds via AS request */
28755682Smarkm    if(id)
28855682Smarkm	krb5_cc_close(context, id);
28955682Smarkm    if (client != default_client)
29055682Smarkm	krb5_free_principal(context, default_client);
29155682Smarkm
29255682Smarkm    ret = get_new_cache(context, client, password, prompter, keytab,
29355682Smarkm			server_name, ret_cache);
29455682Smarkm    krb5_free_principal(context, client);
29555682Smarkm    return ret;
29655682Smarkm}
29755682Smarkm
29872445Sassarstatic kadm5_ret_t
29972445Sassarkadm_connect(kadm5_client_context *ctx)
30055682Smarkm{
30155682Smarkm    kadm5_ret_t ret;
30255682Smarkm    krb5_principal server;
30355682Smarkm    krb5_ccache cc;
30455682Smarkm    int s;
30555682Smarkm    struct addrinfo *ai, *a;
30655682Smarkm    struct addrinfo hints;
30755682Smarkm    int error;
30855682Smarkm    char portstr[NI_MAXSERV];
30955682Smarkm    char *hostname, *slash;
31072445Sassar    krb5_context context = ctx->context;
31155682Smarkm
31255682Smarkm    memset (&hints, 0, sizeof(hints));
31355682Smarkm    hints.ai_socktype = SOCK_STREAM;
31455682Smarkm    hints.ai_protocol = IPPROTO_TCP;
31572445Sassar
31655682Smarkm    snprintf (portstr, sizeof(portstr), "%u", ntohs(ctx->kadmind_port));
31755682Smarkm
31855682Smarkm    hostname = ctx->admin_server;
31955682Smarkm    slash = strchr (hostname, '/');
32055682Smarkm    if (slash != NULL)
32155682Smarkm	hostname = slash + 1;
32255682Smarkm
32355682Smarkm    error = getaddrinfo (hostname, portstr, &hints, &ai);
32455682Smarkm    if (error)
32555682Smarkm	return KADM5_BAD_SERVER_NAME;
32655682Smarkm
32755682Smarkm    for (a = ai; a != NULL; a = a->ai_next) {
32855682Smarkm	s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
32955682Smarkm	if (s < 0)
33055682Smarkm	    continue;
33155682Smarkm	if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
33255682Smarkm	    krb5_warn (context, errno, "connect(%s)", hostname);
33355682Smarkm	    close (s);
33455682Smarkm	    continue;
33555682Smarkm	}
33655682Smarkm	break;
33755682Smarkm    }
33855682Smarkm    if (a == NULL) {
33955682Smarkm	freeaddrinfo (ai);
34055682Smarkm	krb5_warnx (context, "failed to contact %s", hostname);
34155682Smarkm	return KADM5_FAILURE;
34255682Smarkm    }
34372445Sassar    ret = get_cred_cache(context, ctx->client_name, ctx->service_name,
34472445Sassar			 NULL, ctx->prompter, ctx->keytab,
34572445Sassar			 ctx->ccache, &cc);
34655682Smarkm
34755682Smarkm    if(ret) {
34855682Smarkm	freeaddrinfo (ai);
34955682Smarkm	close(s);
35055682Smarkm	return ret;
35155682Smarkm    }
35255682Smarkm    ret = krb5_parse_name(context, KADM5_ADMIN_SERVICE, &server);
35355682Smarkm    if(ret) {
35455682Smarkm	freeaddrinfo (ai);
35572445Sassar	if(ctx->ccache == NULL)
35655682Smarkm	    krb5_cc_close(context, cc);
35755682Smarkm	close(s);
35855682Smarkm	return ret;
35955682Smarkm    }
36055682Smarkm    ctx->ac = NULL;
36155682Smarkm
36255682Smarkm    ret = krb5_sendauth(context, &ctx->ac, &s,
36355682Smarkm			KADMIN_APPL_VERSION, NULL,
36455682Smarkm			server, AP_OPTS_MUTUAL_REQUIRED,
36555682Smarkm			NULL, NULL, cc, NULL, NULL, NULL);
36655682Smarkm    if(ret == 0) {
36772445Sassar	krb5_data params;
36890926Snectar	kadm5_config_params p;
36990926Snectar	memset(&p, 0, sizeof(p));
37090926Snectar	if(ctx->realm) {
37190926Snectar	    p.mask |= KADM5_CONFIG_REALM;
37290926Snectar	    p.realm = ctx->realm;
37390926Snectar	}
37490926Snectar	ret = _kadm5_marshal_params(context, &p, &params);
37555682Smarkm
37672445Sassar	ret = krb5_write_priv_message(context, ctx->ac, &s, &params);
37755682Smarkm	krb5_data_free(&params);
37872445Sassar	if(ret) {
37972445Sassar	    freeaddrinfo (ai);
38072445Sassar	    close(s);
38172445Sassar	    if(ctx->ccache == NULL)
38272445Sassar		krb5_cc_close(context, cc);
38372445Sassar	    return ret;
38472445Sassar	}
38555682Smarkm    } else if(ret == KRB5_SENDAUTH_BADAPPLVERS) {
38655682Smarkm	close(s);
38755682Smarkm
38855682Smarkm	s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
38955682Smarkm	if (s < 0) {
39055682Smarkm	    freeaddrinfo (ai);
39155682Smarkm	    return errno;
39255682Smarkm	}
39355682Smarkm	if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
39455682Smarkm	    close (s);
39555682Smarkm	    freeaddrinfo (ai);
39655682Smarkm	    return errno;
39755682Smarkm	}
39855682Smarkm	ret = krb5_sendauth(context, &ctx->ac, &s,
39955682Smarkm			    KADMIN_OLD_APPL_VERSION, NULL,
40055682Smarkm			    server, AP_OPTS_MUTUAL_REQUIRED,
40155682Smarkm			    NULL, NULL, cc, NULL, NULL, NULL);
40255682Smarkm    }
40355682Smarkm    freeaddrinfo (ai);
40455682Smarkm    if(ret) {
40555682Smarkm	close(s);
40655682Smarkm	return ret;
40755682Smarkm    }
40855682Smarkm
40955682Smarkm    krb5_free_principal(context, server);
41072445Sassar    if(ctx->ccache == NULL)
41155682Smarkm	krb5_cc_close(context, cc);
41255682Smarkm    if(ret) {
41355682Smarkm	close(s);
41455682Smarkm	return ret;
41555682Smarkm    }
41655682Smarkm    ctx->sock = s;
41772445Sassar
41872445Sassar    return 0;
41972445Sassar}
42072445Sassar
42172445Sassarkadm5_ret_t
42272445Sassar_kadm5_connect(void *handle)
42372445Sassar{
42472445Sassar    kadm5_client_context *ctx = handle;
42572445Sassar    if(ctx->sock == -1)
42672445Sassar	return kadm_connect(ctx);
42772445Sassar    return 0;
42872445Sassar}
42972445Sassar
43072445Sassarstatic kadm5_ret_t
43172445Sassarkadm5_c_init_with_context(krb5_context context,
43272445Sassar			  const char *client_name,
43372445Sassar			  const char *password,
43472445Sassar			  krb5_prompter_fct prompter,
43572445Sassar			  const char *keytab,
43672445Sassar			  krb5_ccache ccache,
43772445Sassar			  const char *service_name,
43872445Sassar			  kadm5_config_params *realm_params,
43972445Sassar			  unsigned long struct_version,
44072445Sassar			  unsigned long api_version,
44172445Sassar			  void **server_handle)
44272445Sassar{
44372445Sassar    kadm5_ret_t ret;
44472445Sassar    kadm5_client_context *ctx;
44572445Sassar    krb5_ccache cc;
44672445Sassar
44772445Sassar    ret = _kadm5_c_init_context(&ctx, realm_params, context);
44872445Sassar    if(ret)
44972445Sassar	return ret;
45072445Sassar
45172445Sassar    if(password != NULL && *password != '\0') {
45272445Sassar	ret = get_cred_cache(context, client_name, service_name,
45372445Sassar			     password, prompter, keytab, ccache, &cc);
45472445Sassar	if(ret)
45572445Sassar	    return ret; /* XXX */
45672445Sassar	ccache = cc;
45772445Sassar    }
45872445Sassar
45972445Sassar
46072445Sassar    if (client_name != NULL)
46172445Sassar	ctx->client_name = strdup(client_name);
46272445Sassar    else
46372445Sassar	ctx->client_name = NULL;
46472445Sassar    if (service_name != NULL)
46572445Sassar	ctx->service_name = strdup(service_name);
46672445Sassar    else
46772445Sassar	ctx->service_name = NULL;
46872445Sassar    ctx->prompter = prompter;
46972445Sassar    ctx->keytab = keytab;
47072445Sassar    ctx->ccache = ccache;
47190926Snectar    /* maybe we should copy the params here */
47272445Sassar    ctx->sock = -1;
47372445Sassar
47455682Smarkm    *server_handle = ctx;
47555682Smarkm    return 0;
47655682Smarkm}
47755682Smarkm
47855682Smarkmstatic kadm5_ret_t
47955682Smarkminit_context(const char *client_name,
48055682Smarkm	     const char *password,
48155682Smarkm	     krb5_prompter_fct prompter,
48255682Smarkm	     const char *keytab,
48355682Smarkm	     krb5_ccache ccache,
48455682Smarkm	     const char *service_name,
48555682Smarkm	     kadm5_config_params *realm_params,
48655682Smarkm	     unsigned long struct_version,
48755682Smarkm	     unsigned long api_version,
48855682Smarkm	     void **server_handle)
48955682Smarkm{
49055682Smarkm    krb5_context context;
49155682Smarkm    kadm5_ret_t ret;
49255682Smarkm    kadm5_server_context *ctx;
49355682Smarkm
49472445Sassar    ret = krb5_init_context(&context);
49572445Sassar    if (ret)
49672445Sassar	return ret;
49755682Smarkm    ret = kadm5_c_init_with_context(context,
49855682Smarkm				    client_name,
49955682Smarkm				    password,
50055682Smarkm				    prompter,
50155682Smarkm				    keytab,
50255682Smarkm				    ccache,
50355682Smarkm				    service_name,
50455682Smarkm				    realm_params,
50555682Smarkm				    struct_version,
50655682Smarkm				    api_version,
50755682Smarkm				    server_handle);
50855682Smarkm    if(ret){
50955682Smarkm	krb5_free_context(context);
51055682Smarkm	return ret;
51155682Smarkm    }
51255682Smarkm    ctx = *server_handle;
51355682Smarkm    ctx->my_context = 1;
51455682Smarkm    return 0;
51555682Smarkm}
51655682Smarkm
51755682Smarkmkadm5_ret_t
51855682Smarkmkadm5_c_init_with_password_ctx(krb5_context context,
51955682Smarkm			       const char *client_name,
52055682Smarkm			       const char *password,
52155682Smarkm			       const char *service_name,
52255682Smarkm			       kadm5_config_params *realm_params,
52355682Smarkm			       unsigned long struct_version,
52455682Smarkm			       unsigned long api_version,
52555682Smarkm			       void **server_handle)
52655682Smarkm{
52755682Smarkm    return kadm5_c_init_with_context(context,
52855682Smarkm				     client_name,
52955682Smarkm				     password,
53055682Smarkm				     krb5_prompter_posix,
53155682Smarkm				     NULL,
53255682Smarkm				     NULL,
53355682Smarkm				     service_name,
53455682Smarkm				     realm_params,
53555682Smarkm				     struct_version,
53655682Smarkm				     api_version,
53755682Smarkm				     server_handle);
53855682Smarkm}
53955682Smarkm
54055682Smarkmkadm5_ret_t
54155682Smarkmkadm5_c_init_with_password(const char *client_name,
54255682Smarkm			   const char *password,
54355682Smarkm			   const char *service_name,
54455682Smarkm			   kadm5_config_params *realm_params,
54555682Smarkm			   unsigned long struct_version,
54655682Smarkm			   unsigned long api_version,
54755682Smarkm			   void **server_handle)
54855682Smarkm{
54955682Smarkm    return init_context(client_name,
55055682Smarkm			password,
55155682Smarkm			krb5_prompter_posix,
55255682Smarkm			NULL,
55355682Smarkm			NULL,
55455682Smarkm			service_name,
55555682Smarkm			realm_params,
55655682Smarkm			struct_version,
55755682Smarkm			api_version,
55855682Smarkm			server_handle);
55955682Smarkm}
56055682Smarkm
56155682Smarkmkadm5_ret_t
56255682Smarkmkadm5_c_init_with_skey_ctx(krb5_context context,
56355682Smarkm			   const char *client_name,
56455682Smarkm			   const char *keytab,
56555682Smarkm			   const char *service_name,
56655682Smarkm			   kadm5_config_params *realm_params,
56755682Smarkm			   unsigned long struct_version,
56855682Smarkm			   unsigned long api_version,
56955682Smarkm			   void **server_handle)
57055682Smarkm{
57155682Smarkm    return kadm5_c_init_with_context(context,
57255682Smarkm				     client_name,
57355682Smarkm				     NULL,
57455682Smarkm				     NULL,
57555682Smarkm				     keytab,
57655682Smarkm				     NULL,
57755682Smarkm				     service_name,
57855682Smarkm				     realm_params,
57955682Smarkm				     struct_version,
58055682Smarkm				     api_version,
58155682Smarkm				     server_handle);
58255682Smarkm}
58355682Smarkm
58455682Smarkm
58555682Smarkmkadm5_ret_t
58655682Smarkmkadm5_c_init_with_skey(const char *client_name,
58755682Smarkm		     const char *keytab,
58855682Smarkm		     const char *service_name,
58955682Smarkm		     kadm5_config_params *realm_params,
59055682Smarkm		     unsigned long struct_version,
59155682Smarkm		     unsigned long api_version,
59255682Smarkm		     void **server_handle)
59355682Smarkm{
59455682Smarkm    return init_context(client_name,
59555682Smarkm			NULL,
59655682Smarkm			NULL,
59755682Smarkm			keytab,
59855682Smarkm			NULL,
59955682Smarkm			service_name,
60055682Smarkm			realm_params,
60155682Smarkm			struct_version,
60255682Smarkm			api_version,
60355682Smarkm			server_handle);
60455682Smarkm}
60555682Smarkm
60655682Smarkmkadm5_ret_t
60755682Smarkmkadm5_c_init_with_creds_ctx(krb5_context context,
60855682Smarkm			    const char *client_name,
60955682Smarkm			    krb5_ccache ccache,
61055682Smarkm			    const char *service_name,
61155682Smarkm			    kadm5_config_params *realm_params,
61255682Smarkm			    unsigned long struct_version,
61355682Smarkm			    unsigned long api_version,
61455682Smarkm			    void **server_handle)
61555682Smarkm{
61655682Smarkm    return kadm5_c_init_with_context(context,
61755682Smarkm				     client_name,
61855682Smarkm				     NULL,
61955682Smarkm				     NULL,
62055682Smarkm				     NULL,
62155682Smarkm				     ccache,
62255682Smarkm				     service_name,
62355682Smarkm				     realm_params,
62455682Smarkm				     struct_version,
62555682Smarkm				     api_version,
62655682Smarkm				     server_handle);
62755682Smarkm}
62855682Smarkm
62955682Smarkmkadm5_ret_t
63055682Smarkmkadm5_c_init_with_creds(const char *client_name,
63155682Smarkm			krb5_ccache ccache,
63255682Smarkm			const char *service_name,
63355682Smarkm			kadm5_config_params *realm_params,
63455682Smarkm			unsigned long struct_version,
63555682Smarkm			unsigned long api_version,
63655682Smarkm			void **server_handle)
63755682Smarkm{
63855682Smarkm    return init_context(client_name,
63955682Smarkm			NULL,
64055682Smarkm			NULL,
64155682Smarkm			NULL,
64255682Smarkm			ccache,
64355682Smarkm			service_name,
64455682Smarkm			realm_params,
64555682Smarkm			struct_version,
64655682Smarkm			api_version,
64755682Smarkm			server_handle);
64855682Smarkm}
64955682Smarkm
65055682Smarkm#if 0
65155682Smarkmkadm5_ret_t
65255682Smarkmkadm5_init(char *client_name, char *pass,
65355682Smarkm	   char *service_name,
65455682Smarkm	   kadm5_config_params *realm_params,
65555682Smarkm	   unsigned long struct_version,
65655682Smarkm	   unsigned long api_version,
65755682Smarkm	   void **server_handle)
65855682Smarkm{
65955682Smarkm}
66055682Smarkm#endif
66155682Smarkm
662