“krb5_get_init_creds_keytab” failing with message "Key table entry not found"
kerberos version: krb5-1.5.3
os: windows
i trying login principal using kerberos. during process of initializing kerberos, api “krb5_get_init_creds_keytab” returning failure.
it seems there 2 alternative apis available (viz krb5_get_init_creds_password api , krb5_get_init_creds api) can used instead of krb5_get_init_creds_keytab.
if modify sample program use krb5_get_init_creds_password api, things seems working fine. in actual application don't have handle password. using krb5_get_init_creds_password api not option me.
krb5_get_init_creds api doesn't seem available in version of kerberos using. option left use krb5_get_init_creds_keytab only.
can please take @ sample program , let me know if doing incorrectly.
sample code:
/* * kerberos.h */ #ifndef __kerberos_h__ #define __kerberos_h__ #include <stdio.h> #include <gssapi/gssapi.h> #include <krb5/krb5.h> #include "status.h" #define kerberos_status_code_base 100 #define kerberos_status_message_default "no text available" #define kerberos_status_message_success "success" #define kerberos_status_message_ccache_not_initialized "credentials cache not initialized" #define kerberos_status_message_already_logged_in "already logged in" #define kerberos_status_message_alloc_failure "memory allocation failure" enum ecsmkerberosstatuscode { kerberos_status_code_default = kerberos_status_code_base, kerberos_status_code_success, kerberos_status_code_ccache_not_initialized, kerberos_status_code_already_logged_in, kerberos_status_code_alloc_failure }; class credcache { private: krb5_context m_hcontext; krb5_principal m_pnprincipal; krb5_principal m_pntgs; krb5_ccache m_hcache; char * m_psztgs; char * m_sprincipal; credcache () : m_hcontext (null), m_hcache (null), m_pnprincipal (null), m_pntgs (null), m_psztgs (null), m_sprincipal (null) { } ~credcache(); public: static credcache * getinstance(); status login (char * sservice, file* fp); char* &principal () { return m_sprincipal; } friend class status; private: bool init (); void uninit (); }; #endif // __kerberos_h__ //eof //------------------------------------------------------------------------ /* * kerberos.cpp */ #include "kerberos.h" #include "status.h" /** * credcache functions **/ credcache::~credcache () { uninit(); } credcache * credcache::getinstance() { static credcache thecredcache; return (thecredcache.init()) ? &thecredcache : null; } bool credcache::init () { if (null == m_hcontext) { // initialize kerberos context if (krb5_init_context (&m_hcontext)) return false; } if (null == m_hcache) { // create default credentials cache if (krb5_cc_default (m_hcontext, &m_hcache)) { uninit(); return false; } } return true; } void credcache::uninit() { if (m_hcontext) { if (m_pnprincipal) { krb5_free_principal (m_hcontext, m_pnprincipal); m_pnprincipal = null; } if (m_pntgs) { krb5_free_principal (m_hcontext, m_pntgs); m_pntgs = null; } if (m_psztgs) { krb5_free_unparsed_name (m_hcontext, m_psztgs); m_psztgs = null; } if (m_hcache) { krb5_cc_close (m_hcontext, m_hcache); m_hcache = null; } krb5_free_context (m_hcontext); m_hcontext = null; } } status credcache::login (char* sprincipal, file* fp) { fprintf(fp, "sprincipal: %s. \n",sprincipal); // not proceed unless credential cache has been initialized if (!m_hcontext || !m_hcache) { fprintf(fp, "error: cache not initialized. exiting. \n"); return status (gss_s_failure, kerberos_status_code_ccache_not_initialized); } fprintf(fp, "context , cache initialization ok.\n"); if (m_pnprincipal && m_pntgs && m_psztgs) { fprintf(fp, "service logged in.exiting.\n"); return status (gss_s_complete, kerberos_status_code_already_logged_in); } // make principal ("service/host@realm") krb5_error_code nstatus; nstatus = krb5_parse_name (m_hcontext, sprincipal, &m_pnprincipal); if (nstatus) { fprintf(fp, "krb: parse name failed.\n"); return status (gss_s_failure, nstatus); } fprintf(fp, "krb: parse name returned success.\n"); krb5_data dtgsname = { 0, krb5_tgs_name_size, (char *) krb5_tgs_name }; krb5_data * pdrealm = krb5_princ_realm (m_hcontext, m_pnprincipal); nstatus = krb5_build_principal_ext (m_hcontext, &m_pntgs, pdrealm->length, pdrealm->data, // '@' realm dtgsname.length, dtgsname.data, // krbtgt pdrealm->length, pdrealm->data, // '/' realm 0); if (nstatus) { fprintf(fp, "krb5_build_principal_ext failed.\n"); return status (gss_s_failure, nstatus); } fprintf(fp, "krb5_build_principal_ext: returned success.\n"); nstatus = krb5_unparse_name (m_hcontext, m_pntgs, &m_psztgs); if (nstatus) { fprintf(fp, "krb5_unparse_name failed.\n"); return status (gss_s_failure, nstatus); } fprintf(fp, "krb5_unparse_name: returned success.\n"); krb5_creds credtgt; credtgt.client = m_pnprincipal; credtgt.server = m_pntgs; krb5_get_init_creds_opt hoptions; krb5_get_init_creds_opt_init (&hoptions); krb5_keytab keytab; nstatus = krb5_kt_default (m_hcontext, &keytab); if (nstatus) { fprintf(fp, "krb5_kt_default failed.\n"); return status (gss_s_failure, nstatus); } fprintf(fp, "krb5_kt_default: returned success.\n"); nstatus = krb5_get_init_creds_keytab (m_hcontext, &credtgt, m_pnprincipal, keytab, 0, m_psztgs, &hoptions); if (nstatus) { fprintf(fp, "krb5_get_init_creds_keytab failed.\n"); return status (gss_s_failure, nstatus); } fprintf(fp, "krb5_get_init_creds_keytab: returned: success.\n"); nstatus = krb5_cc_initialize (m_hcontext, m_hcache, m_pnprincipal); if (nstatus) { fprintf(fp, "krb5_cc_initialize failed.\n"); return status (gss_s_failure, nstatus); } fprintf(fp, "krb5_cc_initialize: returned: success.\n"); nstatus = krb5_cc_store_cred (m_hcontext, m_hcache, &credtgt); if (nstatus) { fprintf(fp, "krb5_cc_store_cred failed.\n"); return status (gss_s_failure, nstatus); } fprintf(fp, "krb5_cc_store_cred: returned success.\n"); return status (gss_s_complete, kerberos_status_code_success); } //eof //------------------------------------------------------------------------ /* * status.h */ #ifndef __status_h__ #define __status_h__ #include "gssapi/gssapi.h" #include "krb5/krb5.h" class status { private: static const char * c_armessages []; const char * m_pszmessage; om_uint32 m_nmajor; om_uint32 m_nminor; public: status (); status (om_uint32 nmajor, om_uint32 nminor); //~status (); status &operator= (const status &cstatus); const char * message (); bool fail () const; bool complete () const; bool continue () const; om_uint32 major () const; om_uint32 minor () const; }; #endif //eof //------------------------------------------------------------------------ /* * status.cpp */ #include "kerberos.h" #include "status.h" #define is_kerberos_status_code(x) ((kerberos_status_code_base <= x) && (x <= kerberos_status_code_base + sizeof (status::c_armessages)/sizeof (status::c_armessages[0]) )) const char *status::c_armessages [] = { kerberos_status_message_default, kerberos_status_message_success, kerberos_status_message_ccache_not_initialized, kerberos_status_message_already_logged_in, kerberos_status_message_alloc_failure }; status::status () : m_nmajor (gss_s_failure), m_nminor (kerberos_status_code_default), m_pszmessage (c_armessages[kerberos_status_code_default - kerberos_status_code_base]) { } status::status (om_uint32 nmajor, om_uint32 nminor) : m_nmajor (nmajor), m_nminor (nminor), m_pszmessage (c_armessages[kerberos_status_code_default - kerberos_status_code_base]) { } status& status::operator= (const status &cstatus) { m_nmajor = cstatus.m_nmajor; m_nminor = cstatus.m_nminor; m_pszmessage = cstatus.m_pszmessage; return *this; } const char * status::message () { if (is_kerberos_status_code(m_nminor)) { m_pszmessage = c_armessages [m_nminor - kerberos_status_code_base]; } else // if error code not native error code, try fetch error text kerberos { credcache * pcc = credcache::getinstance(); if (pcc) { char * pszmessage = krb5_get_error_message (pcc->m_hcontext, (krb5_error_code) m_nminor); if (pszmessage && *pszmessage) { m_pszmessage = pszmessage; } else { m_pszmessage = c_armessages[kerberos_status_code_default - kerberos_status_code_base]; } } } return m_pszmessage; } bool status::fail () const { return (gss_error(m_nmajor) != 0); } bool status::complete () const { return (m_nmajor == gss_s_complete); } bool status::continue () const { return (m_nmajor == gss_s_continue_needed); } om_uint32 status::major () const { return m_nmajor; } om_uint32 status::minor () const { return m_nminor; } //eof //------------------------------------------------------------------------ /* * sample.cpp */ // sample.cpp : defines entry point console application. // #include <stdio.h> #include "kerberos.h" #include "status.h" void main() { file* fp; fp = fopen("trace.log","a+"); credcache * pcredcache = credcache::getinstance(); if (!pcredcache) { fprintf(fp, "credcache::getinstance failed.\n"); } char* shttpserviceprincipal = "http/cookie.sample.lab@sample.lab"; fprintf(fp, "credcache::login called.\n"); status kstatus = pcredcache->login (shttpserviceprincipal, fp); if (kstatus.fail()) { fprintf(fp, "kerberos credential cache login failed service principal %s: %s", shttpserviceprincipal, kstatus.message()); } else { fprintf(fp, "request completed successfully."); } fflush(fp); fclose(fp); }
on execution, getting following log entries: credcache::login called.
sprincipal: http/cookie.sample.lab@sample.lab.
context , cache initialization ok.
krb: parse name returned success.
krb5_build_principal_ext: returned success.
krb5_unparse_name: returned success.
krb5_kt_default: returned success.
krb5_get_init_creds_keytab failed.
kerberos credential cache login failed service principal http/cookie.sample.lab@sample.lab: key table entry not found
in advance.
hello,
no idea if can you:
http://tfm.cz/man/3/krb5_get_init_creds_keytab
but programming better place use msdn forums instead one:
http://social.msdn.microsoft.com/forums/en/categories/
best regards meinolf weber disclaimer: posting provided "as is" no warranties or guarantees , , confers no rights.
Windows Server > Directory Services
Comments
Post a Comment