This is an automated email from the ASF dual-hosted git repository.

laiyingchun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git


The following commit(s) were added to refs/heads/master by this push:
     new 72c8f2f75 feat(security): Support to use the principal of Unix account 
for authentication (#1569)
72c8f2f75 is described below

commit 72c8f2f753eba3bc06ce9c75da61510e8a35a6d2
Author: WHBANG <[email protected]>
AuthorDate: Fri Aug 11 14:50:33 2023 +0800

    feat(security): Support to use the principal of Unix account for 
authentication (#1569)
    
    https://github.com/apache/incubator-pegasus/issues/1568
    
    When kerberos authentication is enabled:
    - The  config 'krb5_keytab' and 'krb5_principal' is not empty, which means 
that pegasus
    completes the kinit action by itself.
    - When the value of both is empty, the user needs to complete the kinit 
action by himself,
    and pegasus will obtain the principal of the current unix account for 
authentication.
---
 src/runtime/security/init.cpp          | 10 ++++++++++
 src/runtime/security/kinit_context.cpp | 28 ++++++++++++++++++++++++++++
 src/runtime/security/kinit_context.h   |  1 +
 3 files changed, 39 insertions(+)

diff --git a/src/runtime/security/init.cpp b/src/runtime/security/init.cpp
index 36d78e567..870dd3220 100644
--- a/src/runtime/security/init.cpp
+++ b/src/runtime/security/init.cpp
@@ -23,11 +23,14 @@
 #include "utils/errors.h"
 #include "utils/flags.h"
 #include "utils/fmt_logging.h"
+#include "utils/strings.h"
 
 namespace dsn {
 namespace security {
+DSN_DECLARE_bool(enable_auth);
 DSN_DECLARE_string(krb5_config);
 DSN_DECLARE_string(krb5_keytab);
+DSN_DECLARE_string(krb5_principal);
 
 /***
  * set kerberos envs(for more details:
@@ -43,6 +46,13 @@ void set_krb5_env(bool is_server)
 
 error_s init_kerberos(bool is_server)
 {
+    // When FLAGS_enable_auth is set but lacks of necessary parameters to 
execute kinit by itself,
+    // then try to obtain the principal under the current Unix account for 
identity
+    // authentication automatically.
+    if (FLAGS_enable_auth && utils::is_empty(FLAGS_krb5_keytab) &&
+        utils::is_empty(FLAGS_krb5_principal)) {
+        return run_get_principal_without_kinit();
+    }
     // set kerberos env
     set_krb5_env(is_server);
 
diff --git a/src/runtime/security/kinit_context.cpp 
b/src/runtime/security/kinit_context.cpp
index 08ff5eea8..7b281d5d3 100644
--- a/src/runtime/security/kinit_context.cpp
+++ b/src/runtime/security/kinit_context.cpp
@@ -93,6 +93,9 @@ class kinit_context : public utils::singleton<kinit_context>
 public:
     // implementation of 'kinit -k -t <keytab_file> <principal>'
     error_s kinit();
+    // If kinit has been executed outside the program, then directly obtain 
the principal
+    // information of the unix account for permission verification.
+    error_s get_principal_without_kinit();
     const std::string &username() const { return _user_name; }
 
 private:
@@ -174,6 +177,26 @@ error_s kinit_context::kinit()
     return error_s::ok();
 }
 
+// obtain _principal info under the current unix account for permission 
verification.
+error_s kinit_context::get_principal_without_kinit()
+{
+    // get krb5_ctx
+    init_krb5_ctx();
+
+    // acquire credential cache handle
+    KRB5_RETURN_NOT_OK(krb5_cc_default(_krb5_context, &_ccache),
+                       "couldn't acquire credential cache handle");
+
+    // get '_principal' from '_ccache'
+    KRB5_RETURN_NOT_OK(krb5_cc_get_principal(_krb5_context, _ccache, 
&_principal),
+                       "get principal from cache failed");
+
+    // get '_user_name' from '_principal'
+    RETURN_NOT_OK(parse_username_from_principal());
+
+    return error_s::ok();
+}
+
 void kinit_context::init_krb5_ctx()
 {
     static std::once_flag once;
@@ -333,6 +356,11 @@ error_s kinit_context::wrap_krb5_err(krb5_error_code 
krb5_err, const std::string
 
 error_s run_kinit() { return kinit_context::instance().kinit(); }
 
+error_s run_get_principal_without_kinit()
+{
+    return kinit_context::instance().get_principal_without_kinit();
+}
+
 const std::string &get_username() { return 
kinit_context::instance().username(); }
 } // namespace security
 } // namespace dsn
diff --git a/src/runtime/security/kinit_context.h 
b/src/runtime/security/kinit_context.h
index 05a0de399..bb97a43f2 100644
--- a/src/runtime/security/kinit_context.h
+++ b/src/runtime/security/kinit_context.h
@@ -24,6 +24,7 @@
 namespace dsn {
 namespace security {
 extern error_s run_kinit();
+extern error_s run_get_principal_without_kinit();
 extern const std::string &get_username();
 } // namespace security
 } // namespace dsn


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to