在kerberos数据库中找不到KDC服务器

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

我安装了带有Kdc服务器和客户端的kerberos。它们都可以工作,我可以通过kinit毫无问题地生成票证。但是,我无法通过MIT Kerberos API来执行此操作。我有以下代码,应使用kdc生成票证:

#include <stdio.h>
#include <krb5.h>
#include <com_err.h>
#include <string.h>
#include <unistd.h>

#define TKT_LIFETIME 30
#define NO_REPLAYCACHE

static void syslog_err(const char* tag, long code, const char*format, va_list args){
    printf("%s: %s in %s\n", tag, error_message(code), format);
}

#define check_code(err, tag)\
    if(err){\
        void (*proc)(const char*, long, const char*, va_list);\
        proc=set_com_err_hook(syslog_err);\
        com_err("Error: ",(err),(tag));\
        (void)set_com_err_hook(proc);\
        goto cleanup;\
    }

int main() {
    const char *username="[email protected]";
    const char *password="pass";
    //const char *host="crypto88-PC";

    const char kt_pathname[256] = "/etc/krb5.keytab";
    const char service[256]="krbtgt/DOMAIN.COM";
    const char host[256]="DOMAIN.COM";
    krb5_error_code err;
    krb5_context context;
    krb5_auth_context auth_context = NULL;
    krb5_creds credentials;
    krb5_principal user_principal,
                    service_principal;
    krb5_keytab keytab=NULL;
    krb5_ccache ccache;
    char ccache_name[L_tmpnam + 8];
    krb5_get_init_creds_opt * gic_options;
#ifndef NO_REPLAYCACHE
    krb5_verify_init_creds_opt vic_options;
#endif
    krb5_data apreq_pkt;
    char myhostname[256],sprinc[256];
    int have_user_principal =0,
        have_service_principal=0,
        have_keytab=0,
        have_credentials=0,
        success=-1;
    apreq_pkt.data=NULL;

/* --------------------------------------------------------------------------------- */

    err = krb5_init_context(&context);
    check_code(err, "init context");

    (void) memset(ccache_name,0,sizeof(ccache_name));
    (void) strcpy(ccache_name, "MEMORY:");
    (void) mkstemp(&ccache_name[7]);
    err = krb5_cc_resolve(context,ccache_name,&ccache);
    /* else:
     * err = krb5_cc_default(context,&ccache);
     */
    if(err != 0) printf("[*] Error resolving credential cache name. Code: %d\n", err);

    err = krb5_parse_name(context, username, &user_principal);

    if(err != 0) printf("[*] Error parsing kerberos name. Code: %d\n", err);
    else have_user_principal=1;
    err = krb5_cc_initialize(context,ccache,user_principal);
    if(err != 0) printf("[*] Error initializing credential cache. Code: %d\n", err);

    (void) memset( (char*)&credentials, 0, sizeof(credentials));

    // TODO: swtich later to: (void) gethostname(myhostname, sizeof(myhostname));


    // TODO: not sure if double pointer.
    krb5_get_init_creds_opt_alloc(context, &gic_options); // Allocate a new initial credential options structure
    krb5_get_init_creds_opt_set_tkt_life(gic_options, TKT_LIFETIME); // Set the ticket lifetime in initial credential options

    err = krb5_get_init_creds_password(context, &credentials, user_principal,password,0,0,0,NULL,gic_options); //Get initial credentials using a password
    switch(err){
        case 0:
            have_credentials=1;
            printf("[*] Successfully received credentials\n");
            break;
        case KRB5KDC_ERR_PREAUTH_FAILED:
            printf("[*] Generic Pre-athentication failure. Unable to login. Access denied.\n");
        case KRB5KRB_AP_ERR_BAD_INTEGRITY:
            printf("[*] Decrypt integrity check failed - no domain controller\n");
        case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
            printf("[*] Bad username or password\n");
        case KRB5_KDC_UNREACH:
            printf("[*] Cannot contact any KDC for requested realm\n");
        case KRB5_LIBOS_PWDINTR:
            printf("[*] Password read interrupted\n");
        case KRB5_REALM_CANT_RESOLVE:
            printf("[*] Cannot resolve network address for KDC in requested realm\n");
        case KRB5KDC_ERR_KEY_EXP:
            printf("[*] Password has expired\n");
        case KRB5_LIBOS_BADPWDMATCH:
            printf("[*] Password mismatch\n");
        case KRB5_CHPW_PWDNULL:
            printf("[*] New password cannot be zero length\n");
        case KRB5_CHPW_FAIL:
            printf("[*] Password change failed\n");
        default:
            success=0;
            break;
    }
    err = krb5_cc_store_cred(context, ccache, &credentials); // Store credentials in a credential cache
    if (err != 0)
        printf("[*] Failed storing credentials in credential cache\n");

    char ***realmsp=malloc(sizeof(***realmsp));
    err = krb5_get_host_realm(context, NULL,realmsp);
    check_code(err, "krb5_get_host_realm");
    free(realmsp);


    err = krb5_sname_to_principal(context,host,service,KRB5_NT_SRV_HST,&service_principal); //Generate a full principal name from a service name KRB5_NT_UNKNOWN
    check_code(err, "sname_to_principal");
    have_service_principal=1;

    err = krb5_kt_resolve(context,kt_pathname,&keytab); //Get a handle for a key table
    check_code(err, "kt_resolve");
    have_keytab=1;

    /*
     * A replay cache keeps track of all authenticators recenntly presented to a service. If a duplicate authneitcation request is detected in the replay cache,
     * an error message is sent to application program
     */

#ifndef NO_REPLAYCACHE

    krb5_verify_init_creds_opt_init(&vic_options); //Initialize a credential verification options structure
    krb5_verify_init_creds_opt_set_ap_req_nofail(&vic_options,1); //Set whether credential verification is required
    err = krb5_verify_init_creds(context, &credentials, service_principal, keytab,0,&vic_options); //Verify initial credentials against a keytab
    check_code(err,"verify init credentials");
#else
//**********************************************CODE FAILES IN THE FOLLOWING FUNCTION **********************
    err = krb5_mk_req(context,&auth_context,0,service,host,NULL,ccache,&apreq_pkt);

    if(auth_context){
        krb5_auth_con_free(context,auth_context); //Free a krb5_auth_context structure.
        auth_context=NULL;
    }
    err = krb5_auth_con_init(context,&auth_context); //Create and initialize an authentication context
    if (err!=0)
        printf("[*] Failed to initialize an authentication context\n");
    err = krb5_auth_con_setflags(context,auth_context,~KRB5_AUTH_CONTEXT_DO_TIME); //Set a flags field in a krb5_auth_context structure
    if (err!=0)
        printf("[*] Failed to set flags in context structure\n");
    err = krb5_rd_req(context,&auth_context,&apreq_pkt,service_principal,keytab,NULL,NULL); // This function parses, decrypts and verifies a AP-REQ message
    if (err!=0)
        printf("[*] Failed to decrypt/parse AP-REQ message \n");
    if(auth_context){
        krb5_auth_con_free(context,auth_context); //Free a krb5_auth_context structure.
        auth_context=NULL;
    }
#endif
    err = krb5_cc_destroy(context,ccache);
    if (err!=0)
        printf("[*] Failed to destroy kerberos context \n");
    else
        success=1;



    cleanup:
    if(apreq_pkt.data)
        krb5_free_data_contents(context,&apreq_pkt); // Free the contents of a krb5_data structure and zero the data field
    if(have_keytab){
        krb5_kt_close(context,keytab);
        if (err!=0)
            printf("[*] Failed to destroy the keytab \n"); //Close a key table handle
    }
    if(have_user_principal)
        krb5_free_principal(context,user_principal);
    if(have_service_principal)
        krb5_free_principal(context,service_principal);
    if(have_credentials)
        krb5_free_cred_contents(context,&credentials);
    if(context)
        krb5_free_context(context);

    return 0;
}

当代码到达“ krb5_mk_req”函数时,它将失败,并显示以下错误:“在Kerberos数据库中找不到服务器”。我尝试了许多与服务+主机的组合,但没有一个起作用。在kinit中,我可以使用“ kinit -S [email protected]”生成有效的票证。我想念什么?(DOMAIN.COM不是我的真实域名)

非常感谢!

api kerberos kdc
1个回答
0
投票

似乎您必须创建数据库(如果尚不可用),否则必须在kerberos配置文件中对其进行配置。请检查下面的链接,该链接说明了如何创建或配置kdc数据库。https://www.thetechnojournals.com/2019/12/setting-up-kerberos-in-mac-os-x.html

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