From fb9cacff855f7c2c5851cc71e3b6ed9f2c569f65 Mon Sep 17 00:00:00 2001 From: Johan Danielsson Date: Sat, 23 May 1998 02:56:50 +0000 Subject: [PATCH] Implement init_with_{skey,creds}*. Make use of `password' parameter to init_with_password. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@4907 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/kadm5/init_c.c | 446 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 335 insertions(+), 111 deletions(-) diff --git a/lib/kadm5/init_c.c b/lib/kadm5/init_c.c index 8b2f76aeb..c53cc722d 100644 --- a/lib/kadm5/init_c.c +++ b/lib/kadm5/init_c.c @@ -96,88 +96,182 @@ _kadm5_c_init_context(kadm5_client_context **ctx, } static krb5_error_code -get_cred_cache(krb5_context context, krb5_ccache *cc, - const char *client_name, krb5_prompter_fct prompter) +get_kadm_ticket(krb5_context context, + krb5_ccache id, + krb5_principal client, + const char *server_name) { - krb5_ccache id; - krb5_creds in, *out = NULL; - krb5_principal client, server = NULL; krb5_error_code ret; + krb5_creds in, *out; - if(client_name == NULL) { - ret = krb5_cc_default(context, &id); - ret = krb5_cc_get_principal(context, id, &client); - ret = krb5_parse_name(context, KADM5_ADMIN_SERVICE, &server); - memset(&in, 0, sizeof(in)); - in.client = client; - in.server = server; - ret = krb5_get_credentials(context, 0, id, &in, &out); - if(out != NULL) - krb5_free_creds(context, out); - if(ret == 0) { - *cc = id; - goto out; - } - krb5_cc_close(context, id); - } else - krb5_parse_name(context, client_name, &client); - ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id); - - { - krb5_creds cred; - krb5_get_init_creds_opt opt; - krb5_get_init_creds_opt_init (&opt); - ret = krb5_get_init_creds_password (context, - &cred, - client, - NULL, - prompter, - NULL, - 0, - KADM5_ADMIN_SERVICE, - &opt); - switch(ret){ - case 0: - break; - case KRB5KDC_ERR_NONE: /* XXX hack in krb5_get_init_creds_password */ - exit(1); - case KRB5KRB_AP_ERR_BAD_INTEGRITY: - case KRB5KRB_AP_ERR_MODIFIED: - ret = KADM5_BAD_PASSWORD; - break; - default: - krb5_err(context, 1, ret, "krb5_get_init_creds"); - } - if(ret) { - goto out; - } - ret = krb5_cc_initialize (context, id, cred.client); - if (ret) - return ret; - - ret = krb5_cc_store_cred (context, id, &cred); - if (ret) - return ret; - krb5_free_creds_contents (context, &cred); - *cc = id; - } - -out: - krb5_free_principal(context, client); - krb5_free_principal(context, server); + memset(&in, 0, sizeof(in)); + in.client = client; + ret = krb5_parse_name(context, server_name, &in.server); + if(ret) + return ret; + ret = krb5_get_credentials(context, 0, id, &in, &out); + if(out != NULL) + krb5_free_creds(context, out); + krb5_free_principal(context, in.server); return ret; } +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) +{ + krb5_error_code ret; + krb5_creds cred; + krb5_get_init_creds_opt opt; + krb5_ccache id; + + krb5_get_init_creds_opt_init (&opt); + if(password == NULL && prompter == NULL) { + krb5_keytab kt; + if(keytab == NULL) + ret = krb5_kt_default(context, &kt); + else + ret = krb5_kt_resolve(context, keytab, &kt); + if(ret) + return ret; + ret = krb5_get_init_creds_keytab (context, + &cred, + client, + kt, + 0, + server_name, + &opt); + krb5_kt_close(context, kt); + } else { + ret = krb5_get_init_creds_password (context, + &cred, + client, + password, + prompter, + NULL, + 0, + server_name, + &opt); + } + switch(ret){ + case 0: + break; + case KRB5KDC_ERR_NONE: /* XXX hack in krb5_get_init_creds_password */ + abort(); + case KRB5KRB_AP_ERR_BAD_INTEGRITY: + case KRB5KRB_AP_ERR_MODIFIED: + ret = KADM5_BAD_PASSWORD; + break; + default: + break; + } + ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id); + if(ret) + return ret; + ret = krb5_cc_initialize (context, id, cred.client); + if (ret) + return ret; + ret = krb5_cc_store_cred (context, id, &cred); + if (ret) + return ret; + krb5_free_creds_contents (context, &cred); + *ret_cache = id; + return 0; +} -kadm5_ret_t -kadm5_c_init_with_password_ctx(krb5_context context, - char *client_name, - char *pass, - char *service_name, - kadm5_config_params *realm_params, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) +static krb5_error_code +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) +{ + krb5_error_code ret; + krb5_ccache id = NULL; + krb5_principal default_client = NULL, client = NULL; + + /* treat empty password as NULL */ + if(password && *password == '\0') + password = NULL; + if(server_name == NULL) + server_name = KADM5_ADMIN_SERVICE; + + if(client_name != NULL) { + ret = krb5_parse_name(context, client_name, &client); + if(ret) + return ret; + } + + if(password != NULL || prompter != NULL) { + /* get principal from default cache, ok if this doesn't work */ + ret = krb5_cc_default(context, &id); + if(ret == 0) { + ret = krb5_cc_get_principal(context, id, &default_client); + if(ret) { + krb5_cc_close(context, id); + id = NULL; + } + } + + if(client == NULL) + client = default_client; + if(client == NULL) + /* client_name not passed, and + couldn't get principal from cache */ + return -1; + + if(client == default_client) { + krb5_free_principal(context, default_client); + default_client = NULL; + } + } else if(ccache != NULL) + id = ccache; + + + if(id && (default_client == NULL || + krb5_principal_compare(context, client, default_client))) { + ret = get_kadm_ticket(context, id, client, server_name); + if(ret == 0) { + *ret_cache = id; + krb5_free_principal(context, default_client); + krb5_free_principal(context, client); + return 0; + } + if(ccache != NULL) + /* couldn't get ticket from cache */ + return -1; + } + /* get creds via AS request */ + if(id) + krb5_cc_close(context, id); + krb5_free_principal(context, default_client); + + ret = get_new_cache(context, client, password, prompter, keytab, + server_name, ret_cache); + krb5_free_principal(context, client); + return ret; +} + +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) { kadm5_ret_t ret; kadm5_client_context *ctx; @@ -203,14 +297,27 @@ kadm5_c_init_with_password_ctx(krb5_context context, close(s); return KADM5_RPC_ERROR; } - ret = get_cred_cache(context, &cc, client_name, krb5_prompter_posix); - krb5_parse_name(context, KADM5_ADMIN_SERVICE, &server); + ret = get_cred_cache(context, client_name, service_name, + password, prompter, keytab, ccache, &cc); + + if(ret) { + close(s); + return ret; + } + ret = krb5_parse_name(context, KADM5_ADMIN_SERVICE, &server); + if(ret) { + if(ccache == NULL) + krb5_cc_close(context, cc); + close(s); + return ret; + } ctx->ac = NULL; ret = krb5_sendauth(context, &ctx->ac, &s, KADMIN_APPL_VERSION, NULL, server, AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, cc, NULL, NULL, NULL); krb5_free_principal(context, server); - krb5_cc_close(context, cc); + if(ccache == NULL) + krb5_cc_close(context, cc); if(ret){ close(s); return KADM5_FAILURE; @@ -220,28 +327,34 @@ kadm5_c_init_with_password_ctx(krb5_context context, return 0; } -kadm5_ret_t -kadm5_c_init_with_password(char *client_name, - char *pass, - char *service_name, - kadm5_config_params *realm_params, - unsigned long struct_version, - unsigned long api_version, - void **server_handle) +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) { krb5_context context; kadm5_ret_t ret; kadm5_server_context *ctx; - + krb5_init_context(&context); - ret = kadm5_c_init_with_password_ctx(context, - client_name, - pass, - service_name, - realm_params, - struct_version, - api_version, - server_handle); + ret = kadm5_c_init_with_context(context, + client_name, + password, + prompter, + keytab, + ccache, + service_name, + realm_params, + struct_version, + api_version, + server_handle); if(ret){ krb5_free_context(context); return ret; @@ -251,17 +364,140 @@ kadm5_c_init_with_password(char *client_name, return 0; } -#if 0 kadm5_ret_t -kadm5_init_with_skey(char *client_name, char *keytab, - char *service_name, +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) +{ + return kadm5_c_init_with_context(context, + client_name, + password, + krb5_prompter_posix, + NULL, + NULL, + service_name, + realm_params, + struct_version, + api_version, + server_handle); +} + +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) +{ + return init_context(client_name, + password, + krb5_prompter_posix, + NULL, + NULL, + service_name, + realm_params, + struct_version, + api_version, + server_handle); +} + +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) +{ + return kadm5_c_init_with_context(context, + client_name, + NULL, + NULL, + keytab, + NULL, + service_name, + realm_params, + struct_version, + api_version, + server_handle); +} + + +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) { + return init_context(client_name, + NULL, + NULL, + keytab, + NULL, + service_name, + realm_params, + struct_version, + api_version, + server_handle); } +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) +{ + return kadm5_c_init_with_context(context, + client_name, + NULL, + NULL, + NULL, + ccache, + service_name, + realm_params, + struct_version, + api_version, + server_handle); +} + +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) +{ + return init_context(client_name, + NULL, + NULL, + NULL, + ccache, + service_name, + realm_params, + struct_version, + api_version, + server_handle); +} + +#if 0 kadm5_ret_t kadm5_init(char *client_name, char *pass, char *service_name, @@ -271,17 +507,5 @@ kadm5_init(char *client_name, char *pass, void **server_handle) { } - -kadm5_ret_t -kadm5_init_with_creds(char *client_name, - krb5_ccache ccache, - char *service_name, - kadm5_config_params *params, - krb5_ui_4 struct_version, - krb5_ui_4 api_version, - void **server_handle) -{ -} - - #endif +