2001-10-11 11:42:52 +04:00
/*
Unix SMB / Netbios implementation .
Version 3.0
2001-10-12 08:49:42 +04:00
simple kerberos5 routines for active directory
2001-10-11 11:42:52 +04:00
Copyright ( C ) Andrew Tridgell 2001
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2001-11-29 02:54:07 +03:00
# ifdef HAVE_KRB5
2001-10-11 14:29:17 +04:00
/*
we can ' t use krb5_mk_req because w2k wants the service to be in a particular format
*/
2001-10-11 11:42:52 +04:00
static krb5_error_code krb5_mk_req2 ( krb5_context context ,
krb5_auth_context * auth_context ,
const krb5_flags ap_req_options ,
2001-10-22 00:51:27 +04:00
const char * principal ,
2001-10-11 11:42:52 +04:00
krb5_ccache ccache ,
krb5_data * outbuf )
{
2001-10-11 17:13:06 +04:00
krb5_error_code retval ;
krb5_principal server ;
krb5_creds * credsp ;
krb5_creds creds ;
krb5_data in_data ;
2001-10-22 00:51:27 +04:00
retval = krb5_parse_name ( context , principal , & server ) ;
2001-10-11 17:13:06 +04:00
if ( retval ) {
2001-10-22 00:51:27 +04:00
DEBUG ( 1 , ( " Failed to parse principal %s \n " , principal ) ) ;
2001-10-11 17:13:06 +04:00
return retval ;
}
/* obtain ticket & session key */
memset ( ( char * ) & creds , 0 , sizeof ( creds ) ) ;
2001-10-20 10:50:24 +04:00
if ( ( retval = krb5_copy_principal ( context , server , & creds . server ) ) ) {
DEBUG ( 1 , ( " krb5_copy_principal failed (%s) \n " ,
error_message ( retval ) ) ) ;
2001-10-11 17:13:06 +04:00
goto cleanup_princ ;
2001-10-20 10:50:24 +04:00
}
2001-10-11 17:13:06 +04:00
2001-10-20 10:50:24 +04:00
if ( ( retval = krb5_cc_get_principal ( context , ccache , & creds . client ) ) ) {
DEBUG ( 1 , ( " krb5_cc_get_principal failed (%s) \n " ,
error_message ( retval ) ) ) ;
2001-10-11 17:13:06 +04:00
goto cleanup_creds ;
2001-10-20 10:50:24 +04:00
}
2001-10-11 17:13:06 +04:00
if ( ( retval = krb5_get_credentials ( context , 0 ,
ccache , & creds , & credsp ) ) ) {
2001-12-19 12:53:30 +03:00
DEBUG ( 1 , ( " krb5_get_credentials failed for %s (%s) \n " ,
principal , error_message ( retval ) ) ) ;
2001-10-11 17:13:06 +04:00
goto cleanup_creds ;
}
2001-10-11 11:42:52 +04:00
2001-10-11 17:13:06 +04:00
in_data . length = 0 ;
retval = krb5_mk_req_extended ( context , auth_context , ap_req_options ,
& in_data , credsp , outbuf ) ;
if ( retval ) {
2001-10-20 10:50:24 +04:00
DEBUG ( 1 , ( " krb5_mk_req_extended failed (%s) \n " ,
error_message ( retval ) ) ) ;
2001-10-11 17:13:06 +04:00
}
krb5_free_creds ( context , credsp ) ;
2001-10-11 11:42:52 +04:00
cleanup_creds :
2001-10-11 17:13:06 +04:00
krb5_free_cred_contents ( context , & creds ) ;
2001-10-11 11:42:52 +04:00
cleanup_princ :
2001-10-11 17:13:06 +04:00
krb5_free_principal ( context , server ) ;
2001-10-11 11:42:52 +04:00
2001-10-11 17:13:06 +04:00
return retval ;
2001-10-11 11:42:52 +04:00
}
/*
get a kerberos5 ticket for the given service
*/
2001-10-22 00:51:27 +04:00
DATA_BLOB krb5_get_ticket ( char * principal )
2001-10-11 11:42:52 +04:00
{
krb5_error_code retval ;
2001-10-11 17:13:06 +04:00
krb5_data packet ;
2001-10-11 11:42:52 +04:00
krb5_ccache ccdef ;
krb5_context context ;
krb5_auth_context auth_context = NULL ;
DATA_BLOB ret ;
2001-11-24 17:16:41 +03:00
krb5_enctype enc_types [ ] = { ENCTYPE_DES_CBC_MD5 , ENCTYPE_NULL } ;
2001-10-11 11:42:52 +04:00
retval = krb5_init_context ( & context ) ;
if ( retval ) {
2001-10-20 10:50:24 +04:00
DEBUG ( 1 , ( " krb5_init_context failed (%s) \n " ,
error_message ( retval ) ) ) ;
2001-10-11 11:42:52 +04:00
goto failed ;
}
if ( ( retval = krb5_cc_default ( context , & ccdef ) ) ) {
2001-10-20 10:50:24 +04:00
DEBUG ( 1 , ( " krb5_cc_default failed (%s) \n " ,
error_message ( retval ) ) ) ;
2001-10-11 11:42:52 +04:00
goto failed ;
}
2001-11-24 17:16:41 +03:00
if ( ( retval = krb5_set_default_tgs_ktypes ( context , enc_types ) ) ) {
DEBUG ( 1 , ( " krb5_set_default_tgs_ktypes failed (%s) \n " ,
error_message ( retval ) ) ) ;
goto failed ;
}
2001-10-11 11:42:52 +04:00
if ( ( retval = krb5_mk_req2 ( context ,
& auth_context ,
2001-10-18 14:26:06 +04:00
0 ,
2001-10-22 00:51:27 +04:00
principal ,
2001-10-11 17:13:06 +04:00
ccdef , & packet ) ) ) {
2001-10-11 11:42:52 +04:00
goto failed ;
}
ret = data_blob ( packet . data , packet . length ) ;
2001-10-16 16:02:18 +04:00
/* Hmm, heimdal dooesn't have this - what's the correct call? */
/* krb5_free_data_contents(context, &packet); */
2001-10-11 14:29:17 +04:00
krb5_free_context ( context ) ;
2001-10-11 11:42:52 +04:00
return ret ;
failed :
2001-10-11 14:29:17 +04:00
krb5_free_context ( context ) ;
2001-10-11 11:42:52 +04:00
return data_blob ( NULL , 0 ) ;
}
# else /* HAVE_KRB5 */
2001-10-12 08:49:42 +04:00
/* this saves a few linking headaches */
2001-10-22 00:51:27 +04:00
DATA_BLOB krb5_get_ticket ( char * principal )
2001-10-12 08:49:42 +04:00
{
DEBUG ( 0 , ( " NO KERBEROS SUPPORT \n " ) ) ;
return data_blob ( NULL , 0 ) ;
}
2001-10-11 11:42:52 +04:00
# endif