hadoop_common/security/
user_group_information.rs

1use super::User;
2use std::{collections::HashMap, env, sync::Mutex};
3
4const HADOOP_PROXY_USER: &str = "HADOOP_PROXY_USER";
5
6/// Information about the logged in user.
7static LOGIN_USER_REF: Mutex<Option<UserGroupInformation>> = Mutex::new(None);
8
9/// User and group information for Hadoop.
10/// This class provides methods to determine the
11/// user's username and groups. It supports both the Windows, Unix and Kerberos
12/// login modules.
13#[derive(Clone, Copy)]
14pub struct UserGroupInformation {
15    user: User,
16}
17
18impl UserGroupInformation {
19    /// A method to initialize the fields that depend on a configuration.
20    /// Must be called before useKerberos or groups is used.
21    fn ensure_initialized() {
22        // TODO
23    }
24
25    /// Return the current user, including any doAs in the current stack.
26    pub fn get_current_user() -> anyhow::Result<Self> {
27        Self::ensure_initialized();
28        // TODO: use context user if any
29        Self::get_login_user()
30    }
31
32    /// Get the currently logged in user.  If no explicit login has occurred,
33    /// the user will automatically be logged in with either kerberos credentials
34    /// if available, or as the local OS user, based on security settings.
35    pub fn get_login_user() -> anyhow::Result<Self> {
36        Self::ensure_initialized();
37        // TODO: confirm whether to use Atomic or Mutex for LOGIN_USER_REF
38        if let Some(login_user) = *LOGIN_USER_REF.lock().unwrap() {
39            return Ok(login_user);
40        }
41        let new_login_user = Self::create_login_user(None)?;
42        let login_user = *LOGIN_USER_REF.lock().unwrap().get_or_insert_with(|| {
43            new_login_user.spawn_auto_renewal_thread_for_user_creds(false);
44            new_login_user
45        });
46        Ok(login_user)
47    }
48
49    fn create_login_user(subject: Option<&str>) -> anyhow::Result<Self> {
50        let real_user = Self::do_subject_login(subject, None)?;
51
52        // If the HADOOP_PROXY_USER environment variable
53        // is specified, create a proxy user as the logged in user.
54        let proxy_user = env::var(HADOOP_PROXY_USER).ok().filter(|p| !p.is_empty());
55        let login_user = proxy_user.map_or(real_user, |p| Self::create_proxy_user(&p, &real_user));
56
57        // TODO: load tokens from files and base64 encoding
58
59        Ok(login_user)
60    }
61
62    /// Spawn a thread to do periodic renewals of kerberos credentials. NEVER
63    /// directly call this method. This method should only be used for ticket cache
64    /// based kerberos credentials.
65    fn spawn_auto_renewal_thread_for_user_creds(&self, _force: bool) {
66        // TODO
67    }
68
69    /// Create a proxy user using username of the effective user and the ugi of the
70    /// real user.
71    pub fn create_proxy_user(_user: &str, real_user: &Self) -> Self {
72        // TODO
73        real_user.to_owned()
74    }
75
76    /// Get the user's login name.
77    pub fn get_short_user_name(&self) -> String {
78        self.user.get_short_name()
79    }
80
81    /// Get the user's full principal name.
82    pub fn get_user_name(&self) -> String {
83        self.user.get_name()
84    }
85
86    /// Login a subject with the given parameters.  If the subject is null,
87    /// the login context used to create the subject will be attached.
88    fn do_subject_login(
89        _subject: Option<&str>,
90        _params: Option<HashMap<String, String>>,
91    ) -> anyhow::Result<Self> {
92        // TODO
93        Ok(Self { user: User {} })
94    }
95}