使用gssapi和libhdfs3为hdfs客户机获取kerberos creditionals

x4shl7ld  于 2021-06-01  发布在  Hadoop
关注(0)|答案(0)|浏览(380)

我正在使用libhdfs3编写一个c++hdfs客户机。hdfs被kerberized了。所以我正在尝试使用gssapi获取kerberos凭据。我写了下面的示例来实现这一点。

static void
parse_oid(char *mechanism, gss_OID * oid)
{
    char   *mechstr = 0;
    gss_buffer_desc tok;
    OM_uint32 maj_stat, min_stat;
    size_t i, mechlen = strlen(mechanism);

    if (isdigit((int) mechanism[0])) {
        mechstr = (char *)malloc(mechlen + 5);
        if (!mechstr) {
            fprintf(stderr, "Couldn't allocate mechanism scratch!\n");
            return;
        }
        mechstr[0] = '{';
        mechstr[1] = ' ';
        for (i = 0; i < mechlen; i++)
            mechstr[i + 2] = (mechanism[i] == '.') ? ' ' : mechanism[i];
        mechstr[mechlen + 2] = ' ';
        mechstr[mechlen + 3] = ' ';
        mechstr[mechlen + 4] = '\0';
        tok.value = mechstr;
    } else
        tok.value = mechanism;
    tok.length = strlen((char*)tok.value);
    maj_stat = gss_str_to_oid(&min_stat, &tok, oid);
    if (maj_stat != GSS_S_COMPLETE) {
        display_status("str_to_oid ", maj_stat, min_stat);
        return;
    }
    if (mechstr)
        free(mechstr);
}

static int client_establish_context(gss_OID oid, char *username)
{
    gss_buffer_desc send_tok;
    OM_uint32 maj_stat, min_stat;
    gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
    gss_name_t gss_username = GSS_C_NO_NAME;
    gss_OID_set_desc mechs, *mechsp = GSS_C_NO_OID_SET;

    if (oid != GSS_C_NO_OID) {
        mechs.elements = oid;
        mechs.count = 1;
        mechsp = &mechs;
    } else {
        mechs.elements = NULL;
        mechs.count = 0;
    }
    if (username != NULL) {
        send_tok.value = username;
        send_tok.length = strlen(username);

        maj_stat = gss_import_name(&min_stat, &send_tok,
                (gss_OID) GSS_KRB5_NT_PRINCIPAL_NAME,
                &gss_username);
        if (maj_stat != GSS_S_COMPLETE) {
            display_status("parsing client name ", maj_stat, min_stat);
            printf("Error 1\n");
            return -1;
        }
    }

    maj_stat = gss_acquire_cred(&min_stat,
            gss_username,
            0,
            mechsp,GSS_C_INITIATE,
            &cred, NULL, NULL);

    if (maj_stat != GSS_S_COMPLETE) {
        display_status("acquiring creds ", maj_stat, min_stat);
        gss_release_name(&min_stat, &gss_username);
        printf("Error 2\n");
        return -1;
    }
    gss_release_name(&min_stat, &gss_username);

    (void) gss_release_cred(&min_stat, &cred);
}

int main()
{
    display_file = stdout;
    char *username="hadoop/srinivasanv-ux@SRINI.COM";
    char *mechanism = "{ 1 2 840 113554 1 2 2 }";
    gss_OID oid;
    setenv("KRB5_CLIENT_KTNAME","/home/srini/kafka/keytabs/hadoop.keytab",1);
    parse_oid(mechanism, &oid);
    if (client_establish_context(oid, username) < 0) {
        printf("failed\n");
    }
    else
    {
        printf("success\n");
    }
}

文件上说
如果所需名称没有可用的现有票证,但该名称在默认客户机键表中有一个条目,krb5机制将使用默认客户机键表获取该名称的初始票证。
但我有以下错误
找不到客户端主体hadoop/srinivasanv-ux@srini.com 在缓存集合中
我做错什么了?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题