155682Smarkm/* 2178825Sdfr * Copyright (c) 1997 - 2004 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 "krb5_locl.h" 35178825SdfrRCSID("$Id: convert_creds.c 22050 2007-11-11 11:20:46Z lha $"); 3655682Smarkm 37120945Snectar#include "krb5-v4compat.h" 38120945Snectar 3955682Smarkmstatic krb5_error_code 4055682Smarkmcheck_ticket_flags(TicketFlags f) 4155682Smarkm{ 4255682Smarkm return 0; /* maybe add some more tests here? */ 4355682Smarkm} 4455682Smarkm 45178825Sdfr/** 46178825Sdfr * Convert the v5 credentials in in_cred to v4-dito in v4creds. This 47178825Sdfr * is done by sending them to the 524 function in the KDC. If 4855682Smarkm * `in_cred' doesn't contain a DES session key, then a new one is 4955682Smarkm * gotten from the KDC and stored in the cred cache `ccache'. 50178825Sdfr * 51178825Sdfr * @param context Kerberos 5 context. 52178825Sdfr * @param in_cred the credential to convert 53178825Sdfr * @param v4creds the converted credential 54178825Sdfr * 55178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 56178825Sdfr * error code is returned, see krb5_get_error_message(). 57178825Sdfr * 58178825Sdfr * @ingroup krb5_v4compat 5955682Smarkm */ 6055682Smarkm 61178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 6255682Smarkmkrb524_convert_creds_kdc(krb5_context context, 6355682Smarkm krb5_creds *in_cred, 6455682Smarkm struct credentials *v4creds) 6555682Smarkm{ 6655682Smarkm krb5_error_code ret; 6755682Smarkm krb5_data reply; 6855682Smarkm krb5_storage *sp; 6955682Smarkm int32_t tmp; 7055682Smarkm krb5_data ticket; 7155682Smarkm char realm[REALM_SZ]; 7255682Smarkm krb5_creds *v5_creds = in_cred; 7355682Smarkm 7455682Smarkm ret = check_ticket_flags(v5_creds->flags.b); 7555682Smarkm if(ret) 7655682Smarkm goto out2; 7755682Smarkm 7872445Sassar { 7990926Snectar krb5_krbhst_handle handle; 8090926Snectar 8190926Snectar ret = krb5_krbhst_init(context, 82178825Sdfr krb5_principal_get_realm(context, 83178825Sdfr v5_creds->server), 8490926Snectar KRB5_KRBHST_KRB524, 8590926Snectar &handle); 8690926Snectar if (ret) 8772445Sassar goto out2; 8890926Snectar 8972445Sassar ret = krb5_sendto (context, 9055682Smarkm &v5_creds->ticket, 9190926Snectar handle, 9255682Smarkm &reply); 9390926Snectar krb5_krbhst_free(context, handle); 9490926Snectar if (ret) 9590926Snectar goto out2; 9672445Sassar } 9755682Smarkm sp = krb5_storage_from_mem(reply.data, reply.length); 9855682Smarkm if(sp == NULL) { 9955682Smarkm ret = ENOMEM; 10078527Sassar krb5_set_error_string (context, "malloc: out of memory"); 10155682Smarkm goto out2; 10255682Smarkm } 10355682Smarkm krb5_ret_int32(sp, &tmp); 10455682Smarkm ret = tmp; 10555682Smarkm if(ret == 0) { 10655682Smarkm memset(v4creds, 0, sizeof(*v4creds)); 10755682Smarkm ret = krb5_ret_int32(sp, &tmp); 10878527Sassar if(ret) 10978527Sassar goto out; 11055682Smarkm v4creds->kvno = tmp; 11155682Smarkm ret = krb5_ret_data(sp, &ticket); 11278527Sassar if(ret) 11378527Sassar goto out; 11455682Smarkm v4creds->ticket_st.length = ticket.length; 11555682Smarkm memcpy(v4creds->ticket_st.dat, ticket.data, ticket.length); 11655682Smarkm krb5_data_free(&ticket); 11755682Smarkm ret = krb5_524_conv_principal(context, 11855682Smarkm v5_creds->server, 11955682Smarkm v4creds->service, 12055682Smarkm v4creds->instance, 12155682Smarkm v4creds->realm); 12278527Sassar if(ret) 12378527Sassar goto out; 12490926Snectar v4creds->issue_date = v5_creds->times.starttime; 125120945Snectar v4creds->lifetime = _krb5_krb_time_to_life(v4creds->issue_date, 126120945Snectar v5_creds->times.endtime); 12755682Smarkm ret = krb5_524_conv_principal(context, v5_creds->client, 12855682Smarkm v4creds->pname, 12955682Smarkm v4creds->pinst, 13055682Smarkm realm); 13178527Sassar if(ret) 13278527Sassar goto out; 13355682Smarkm memcpy(v4creds->session, v5_creds->session.keyvalue.data, 8); 13490926Snectar } else { 13590926Snectar krb5_set_error_string(context, "converting credentials: %s", 13690926Snectar krb5_get_err_text(context, ret)); 13755682Smarkm } 13855682Smarkmout: 13955682Smarkm krb5_storage_free(sp); 14055682Smarkm krb5_data_free(&reply); 14155682Smarkmout2: 14255682Smarkm if (v5_creds != in_cred) 14355682Smarkm krb5_free_creds (context, v5_creds); 14455682Smarkm return ret; 14555682Smarkm} 14690926Snectar 147178825Sdfr/** 148178825Sdfr * Convert the v5 credentials in in_cred to v4-dito in v4creds, 149178825Sdfr * check the credential cache ccache before checking with the KDC. 150178825Sdfr * 151178825Sdfr * @param context Kerberos 5 context. 152178825Sdfr * @param ccache credential cache used to check for des-ticket. 153178825Sdfr * @param in_cred the credential to convert 154178825Sdfr * @param v4creds the converted credential 155178825Sdfr * 156178825Sdfr * @return Returns 0 to indicate success. Otherwise an kerberos et 157178825Sdfr * error code is returned, see krb5_get_error_message(). 158178825Sdfr * 159178825Sdfr * @ingroup krb5_v4compat 160178825Sdfr */ 161178825Sdfr 162178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 16390926Snectarkrb524_convert_creds_kdc_ccache(krb5_context context, 16490926Snectar krb5_ccache ccache, 16590926Snectar krb5_creds *in_cred, 16690926Snectar struct credentials *v4creds) 16790926Snectar{ 16890926Snectar krb5_error_code ret; 16990926Snectar krb5_creds *v5_creds = in_cred; 17090926Snectar krb5_keytype keytype; 17190926Snectar 17290926Snectar keytype = v5_creds->session.keytype; 17390926Snectar 17490926Snectar if (keytype != ENCTYPE_DES_CBC_CRC) { 17590926Snectar /* MIT krb524d doesn't like nothing but des-cbc-crc tickets, 17690926Snectar so go get one */ 17790926Snectar krb5_creds template; 17890926Snectar 17990926Snectar memset (&template, 0, sizeof(template)); 18090926Snectar template.session.keytype = ENCTYPE_DES_CBC_CRC; 18190926Snectar ret = krb5_copy_principal (context, in_cred->client, &template.client); 18290926Snectar if (ret) { 183178825Sdfr krb5_free_cred_contents (context, &template); 18490926Snectar return ret; 18590926Snectar } 18690926Snectar ret = krb5_copy_principal (context, in_cred->server, &template.server); 18790926Snectar if (ret) { 188178825Sdfr krb5_free_cred_contents (context, &template); 18990926Snectar return ret; 19090926Snectar } 19190926Snectar 19290926Snectar ret = krb5_get_credentials (context, 0, ccache, 19390926Snectar &template, &v5_creds); 194178825Sdfr krb5_free_cred_contents (context, &template); 19590926Snectar if (ret) 19690926Snectar return ret; 19790926Snectar } 19890926Snectar 19990926Snectar ret = krb524_convert_creds_kdc(context, v5_creds, v4creds); 20090926Snectar 20190926Snectar if (v5_creds != in_cred) 20290926Snectar krb5_free_creds (context, v5_creds); 20390926Snectar return ret; 20490926Snectar} 205