Я пишу клиент cdf hdfs, используя libhdfs3. hdfs был kerberized. Так что я пытаюсь получить учетные данные kerberos с помощью gssapi. Я написал ниже образец, чтобы сделать это.
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/[email protected]";
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/[email protected] в коллекции кэша
что я тут не так делаю?
Задача ещё не решена.
Других решений пока нет …