Coverage Report

Created: 2026-03-16 19:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/common/kerberos/kerberos_ticket_cache.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <krb5.h>
21
22
#include <atomic>
23
#include <functional>
24
#include <iostream>
25
#include <memory>
26
#include <mutex>
27
#include <thread>
28
#include <vector>
29
30
#include "common/kerberos/kerberos_config.h"
31
#include "common/kerberos/krb5_interface.h"
32
#include "common/status.h"
33
34
namespace doris::kerberos {
35
36
// Structure to hold detailed information about a Kerberos ticket cache
37
struct KerberosTicketInfo {
38
    std::string principal;         // Client principal
39
    std::string keytab_path;       // Path to keytab file
40
    std::string service_principal; // Service principal this credential is for
41
    std::string cache_path;        // Path of ticket cache file
42
    std::string hash_code;         // the hash code from config
43
    int64_t start_time;            // Unix timestamp in seconds
44
    int64_t expiry_time;           // Unix timestamp in seconds
45
    int64_t auth_time;             // Unix timestamp in seconds
46
    long use_count;                // Reference count of the shared_ptr
47
    long refresh_interval_second;  // Refresh interval second
48
};
49
50
// Class responsible for managing Kerberos ticket cache, including initialization,
51
// authentication, and periodic ticket refresh
52
class KerberosTicketCache : public std::enable_shared_from_this<KerberosTicketCache> {
53
public:
54
    // Constructor that takes a Kerberos configuration and an optional KRB5 interface implementation
55
    explicit KerberosTicketCache(
56
            const KerberosConfig& config, const std::string& root_path,
57
            std::unique_ptr<Krb5Interface> krb5_interface = Krb5InterfaceFactory::create());
58
59
    virtual ~KerberosTicketCache();
60
61
    // Prevent copying of ticket cache instances
62
    KerberosTicketCache(const KerberosTicketCache&) = delete;
63
    KerberosTicketCache& operator=(const KerberosTicketCache&) = delete;
64
65
    // Initialize the ticket cache by setting up the cache path and Kerberos context
66
    // Logic: Creates cache directory if needed, initializes KRB5 context and principal
67
    virtual Status initialize();
68
69
    // Perform a fresh Kerberos login using the configured principal and keytab
70
    // Logic: Opens keytab, obtains new credentials, and stores them in the cache
71
    virtual Status login();
72
73
    // Attempt to login using existing cached credentials
74
    // Logic: Resolves the existing ticket cache without obtaining new credentials
75
    virtual Status login_with_cache();
76
77
    // Write the current credentials to the ticket cache file
78
    virtual Status write_ticket_cache();
79
80
    // Refresh Kerberos tickets if they're close to expiration or if forced
81
    // Logic: Checks if refresh is needed based on ticket expiration time,
82
    // performs a new login if necessary
83
    virtual Status refresh_tickets();
84
85
    // Start the background thread for periodic ticket refresh
86
    // Logic: Creates a thread that periodically checks and refreshes tickets
87
    virtual void start_periodic_refresh();
88
89
    // Stop the background ticket refresh thread
90
    virtual void stop_periodic_refresh();
91
92
    // Getters for configuration and cache path
93
0
    virtual const KerberosConfig& get_config() const { return _config; }
94
7
    virtual const std::string get_ticket_cache_path() const { return _ticket_cache_path; }
95
96
    // For testing purposes
97
4
    void set_refresh_thread_sleep_time(std::chrono::milliseconds sleep_time) {
98
4
        _refresh_thread_sleep_time = sleep_time;
99
4
    }
100
101
    // For testing purposes
102
1
    void set_ticket_cache_path(const std::string& mock_path) { _ticket_cache_path = mock_path; }
103
104
    // Get detailed information about all credentials in the current ticket cache
105
    virtual std::vector<KerberosTicketInfo> get_ticket_info();
106
107
0
    int64_t get_ticket_lifetime_sec() const { return _ticket_lifetime_sec; }
108
109
private:
110
    // Initialize the ticket cache file path using principal and keytab information
111
    Status _init_ticket_cache_path();
112
    // Initialize the Kerberos context and principal
113
    Status _initialize_context();
114
    // Clean up Kerberos resources
115
    void _cleanup_context();
116
117
private:
118
    // Kerberos configuration containing principal, keytab, and refresh settings
119
    KerberosConfig _config;
120
    // For testing purposes
121
    std::string _ccache_root_dir;
122
    // Path to the ticket cache file
123
    std::string _ticket_cache_path;
124
    // Kerberos context handle
125
    krb5_context _context {nullptr};
126
    // Credentials cache handle
127
    krb5_ccache _ccache {nullptr};
128
    // Principal handle
129
    krb5_principal _principal {nullptr};
130
    // Ticket lifetime in second
131
    int64_t _ticket_lifetime_sec;
132
133
    // Thread for periodic ticket refresh
134
    std::unique_ptr<std::thread> _refresh_thread;
135
    // Mutex for thread synchronization
136
    std::mutex _mutex;
137
    // Flag to control refresh thread execution
138
    std::atomic<bool> _should_stop_refresh {false};
139
    // Sleep time between refresh checks (in milliseconds)
140
    std::chrono::milliseconds _refresh_thread_sleep_time {5000};
141
142
    // Interface for KRB5 operations
143
    std::unique_ptr<Krb5Interface> _krb5_interface;
144
};
145
146
} // namespace doris::kerberos