From f57b6adba91a652f06690d61e1c8b65e670dbdf3 Mon Sep 17 00:00:00 2001 From: Long Zhao <294514940@qq.com> Date: Mon, 22 May 2023 10:54:21 +0800 Subject: [PATCH] [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. --- be/src/io/hdfs_builder.cpp | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/be/src/io/hdfs_builder.cpp b/be/src/io/hdfs_builder.cpp index ca629e4401..be1281441a 100644 --- a/be/src/io/hdfs_builder.cpp +++ b/be/src/io/hdfs_builder.cpp @@ -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();