“kinit”程序没有添加到缓存?

问题描述 投票:0回答:1

我尝试通过代码实现

kinit
命令。

经过一番努力,我可以在 Linux Rocky 8.5 上使用 krb5 成功运行它。

我的问题是,运行我的程序没有任何错误后,运行时我看不到任何东西

klist
, 当运行
kinit -kt test.keytab username@DOMAIN
时,我可以在运行
klist
时看到 Kerberos 票证。

我只是想知道我错过了什么。 我希望它与上面的

kinit
一样使用默认缓存运行。

#include <krb5.h>
#include <iostream>
#include <string>

#define RESULT_OK(X) ((X)==0)

int kinit(const std::string& username, const std::string& domain, const std::string& password, bool password_is_keytab) 
{
    krb5_context context=NULL;
    krb5_principal principal=NULL;
    krb5_creds creds;
    krb5_keytab keytab=NULL;

    // Init Kerberos context
    krb5_error_code ret = krb5_init_context(&context);
    if (RESULT_OK(ret)) 
    {
        // Parse the principal name, create principal
        ret = krb5_parse_name(context, (username + "@" + domain).c_str(), &principal);
        if(RESULT_OK(ret))
        {
            if(password_is_keytab)
            {
                ret = krb5_kt_resolve(context, password.c_str(), &keytab);
                if(RESULT_OK(ret))
                {
                    ret = krb5_get_init_creds_keytab(context, &creds, principal, keytab, 0, NULL, NULL);
                    if(RESULT_OK(ret))
                    {
                        //OK
                    }
                    else 
                    {
                        std::cerr<<"krb5_get_init_creds_keytab:"<<krb5_get_error_message(context)<<std::endl;
                    }
                }
                else
                {
                    std::cerr<<"krb5_kt_resolve:"<<krb5_get_error_message(context)<<std::endl;
                }
            }
            else
            {
                ret = krb5_get_init_creds_password(context, &creds, principal, password.c_str(),NULL, NULL, 0, NULL, NULL);
                if(RESULT_OK(ret))
                {
                    //OK
                }
                else
                {
                    std::cerr<<"krb5_get_init_creds_password:"<<krb5_get_error_message(context)<<std::endl;
                }
            }
        }
        else
        {
            std::cerr<<"krb5_parse_name:"<<krb5_get_error_message(context)<<std::endl;
        }
    }
    else
    {
        // Handle error
        std::cerr<<"krb5_init_context:"<<krb5_get_error_message(context)<<std::endl;        
    }

    if(RESULT_OK(ret))
    {
        krb5_ccache cache = NULL;
        ret = krb5_cc_default(context, &cache);
        if(RESULT_OK(ret))
        {
            ret = krb5_cc_initialize(context, cache, principal);
            if(RESULT_OK(ret))
            {
                ret = krb5_cc_store_cred(context, cache, &creds);
                if(RESULT_OK(ret))              
                {
                    std::cout<<"kinit succeeded"<<std::endl;
                }
                else
                {
                    std::cerr<<"krb5_cc_store_cred:"<<krb5_get_error_message(context)<<std::endl;
                }
            }
            else
            {
                std::cerr<<"krb5_cc_initialize:"<<krb5_get_error_message(context)<<std::endl;
            }
        }
        else
        {
            std::cerr<<"krb5_cc_default:"<<krb5_get_error_message(context)<<std::endl;
        }

        if(cache) krb5_cc_destroy(context, cache);
    }


    if(keytab) krb5_kt_close(context, keytab);
    krb5_free_cred_contents(context, &creds);
    if(principal) krb5_free_principal(context, principal);
    if(context) krb5_free_context(context);
    
    return ret;
}

int main()
{
    std::string username = "username";
    std::string domain = "DOMAIN";
    std::string keytab = "/etc/keytab/test.keytab";
    int res = kinit(username, domain, keytab, 1);
    std::cout<<"res = "<<res<<std::endl; 
    return res;
} 
c++ linux kerberos
1个回答
0
投票

您最后会打电话给

krb5_cc_destroy()
。正如文档所说,它的工作原理类似于
kdestroy
:

此函数销毁cache的任何现有内容并关闭它的句柄。

要关闭手柄而不破坏内容,请使用

krb5_cc_close()

© www.soinside.com 2019 - 2024. All rights reserved.