/* Unix SMB/Netbios implementation. Version 3.0 simple kerberos5 routines for active directory 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 02139, USA. */ #include "includes.h" #if HAVE_KRB5 #include /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ static krb5_error_code krb5_mk_req2(krb5_context context, krb5_auth_context *auth_context, const krb5_flags ap_req_options, const char *service, const char *realm, krb5_ccache ccache, krb5_data *outbuf) { krb5_error_code retval; krb5_principal server; krb5_creds * credsp; krb5_creds creds; krb5_data in_data; retval = krb5_build_principal(context, &server, strlen(realm), realm, service, NULL); if (retval) { DEBUG(1,("Failed to build principle for %s@%s\n", service, realm)); return retval; } /* obtain ticket & session key */ memset((char *)&creds, 0, sizeof(creds)); if ((retval = krb5_copy_principal(context, server, &creds.server))) goto cleanup_princ; if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) goto cleanup_creds; if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { DEBUG(1,("krb5_get_credentials failed (%d)\n", retval)); goto cleanup_creds; } in_data.length = 0; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); if (retval) { DEBUG(1,("krb5_mk_req_extended failed (%d)\n", retval)); } krb5_free_creds(context, credsp); cleanup_creds: krb5_free_cred_contents(context, &creds); cleanup_princ: krb5_free_principal(context, server); return retval; } /* get a kerberos5 ticket for the given service */ DATA_BLOB krb5_get_ticket(char *service, char *realm) { krb5_error_code retval; krb5_data packet; krb5_ccache ccdef; krb5_context context; krb5_auth_context auth_context = NULL; DATA_BLOB ret; retval = krb5_init_context(&context); if (retval) { DEBUG(1,("krb5_init_context failed\n")); goto failed; } if ((retval = krb5_cc_default(context, &ccdef))) { DEBUG(1,("krb5_cc_default failed\n")); goto failed; } if ((retval = krb5_mk_req2(context, &auth_context, AP_OPTS_MUTUAL_REQUIRED, service, realm, ccdef, &packet))) { DEBUG(1,("krb5_mk_req2 failed\n")); goto failed; } ret = data_blob(packet.data, packet.length); /* Hmm, heimdal dooesn't have this - what's the correct call? */ /* krb5_free_data_contents(context, &packet); */ krb5_free_context(context); return ret; failed: krb5_free_context(context); return data_blob(NULL, 0); } #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ DATA_BLOB krb5_get_ticket(char *service, char *realm) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); } #endif