[improvement](libhdfs) Use keytab and principal to login kerberos (#19841)

User keytab and princpal to login kerberos.
And user does not need to execute kinit manually anymore.
This commit is contained in:
Long Zhao
2023-05-22 10:54:21 +08:00
committed by GitHub
parent 76dc5841dc
commit f57b6adba9

View File

@ -49,9 +49,17 @@ Status HDFSCommonBuilder::run_kinit() {
return Status::InvalidArgument("Invalid hdfs_kerberos_principal or hdfs_kerberos_keytab");
}
std::string ticket_path = TICKET_CACHE_PATH + generate_uuid_string();
const char* krb_home = getenv("KRB_HOME");
std::string krb_home_str(krb_home ? krb_home : "");
fmt::memory_buffer kinit_command;
fmt::format_to(kinit_command, "kinit -c {} -R -t {} -k {}", ticket_path, hdfs_kerberos_keytab,
hdfs_kerberos_principal);
if (krb_home_str.empty()) {
fmt::format_to(kinit_command, "kinit -c {} -R -t {} -k {}", ticket_path,
hdfs_kerberos_keytab, hdfs_kerberos_principal);
} else {
// Assign kerberos home in env, get kinit in kerberos home
fmt::format_to(kinit_command, krb_home_str + "/bin/kinit -c {} -R -t {} -k {}", ticket_path,
hdfs_kerberos_keytab, hdfs_kerberos_principal);
}
VLOG_NOTICE << "kinit command: " << fmt::to_string(kinit_command);
std::string msg;
AgentUtils util;
@ -61,8 +69,9 @@ Status HDFSCommonBuilder::run_kinit() {
}
#ifdef USE_LIBHDFS3
hdfsBuilderSetPrincipal(hdfs_builder, hdfs_kerberos_principal.c_str());
hdfsBuilderSetKerbTicketCachePath(hdfs_builder, ticket_path.c_str());
#endif
hdfsBuilderConfSetStr(hdfs_builder, "hadoop.security.kerberos.ticket.cache.path",
ticket_path.c_str());
return Status::OK();
}
@ -105,23 +114,36 @@ Status createHDFSBuilder(const THdfsParams& hdfsParams, HDFSCommonBuilder* build
if (hdfsParams.__isset.hdfs_kerberos_principal) {
builder->need_kinit = true;
builder->hdfs_kerberos_principal = hdfsParams.hdfs_kerberos_principal;
hdfsBuilderSetUserName(builder->get(), hdfsParams.hdfs_kerberos_principal.c_str());
} else if (hdfsParams.__isset.user) {
hdfsBuilderSetUserName(builder->get(), hdfsParams.user.c_str());
#ifdef USE_HADOOP_HDFS
hdfsBuilderSetKerb5Conf(builder->get(), nullptr);
hdfsBuilderSetKeyTabFile(builder->get(), nullptr);
#endif
}
if (hdfsParams.__isset.hdfs_kerberos_keytab) {
builder->need_kinit = true;
builder->hdfs_kerberos_keytab = hdfsParams.hdfs_kerberos_keytab;
#ifdef USE_HADOOP_HDFS
hdfsBuilderSetKeyTabFile(builder->get(), hdfsParams.hdfs_kerberos_keytab.c_str());
#endif
}
// set other conf
if (hdfsParams.__isset.hdfs_conf) {
for (const THdfsConf& conf : hdfsParams.hdfs_conf) {
hdfsBuilderConfSetStr(builder->get(), conf.key.c_str(), conf.value.c_str());
#ifdef USE_HADOOP_HDFS
// Set krb5.conf, we should define java.security.krb5.conf in catalog properties
if (strcmp(conf.key.c_str(), "java.security.krb5.conf") == 0) {
hdfsBuilderSetKerb5Conf(builder->get(), conf.value.c_str());
}
#endif
}
}
if (builder->is_need_kinit()) {
RETURN_IF_ERROR(builder->run_kinit());
} else if (hdfsParams.__isset.user) {
// set hdfs user
hdfsBuilderSetUserName(builder->get(), hdfsParams.user.c_str());
}
return Status::OK();