I am writing a c++ hdfs client using libhdfs3. the hdfs was kerberized.So I am trying to acquire the kerberos credentials using gssapi. I wrote the bellow sample to do that.
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");
}
}
This documentation says
If no existing tickets are available for the desired name, but the name has an entry in the default client keytab, the krb5 mechanism will acquire initial tickets for the name using the default client keytab.
But I am getting following error
Can't find client principal hadoop/srinivasanv-ux@SRINI.COM in cache collection
what I am doing wrong here?