1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
use std::sync::Arc;
use crate::core::client::{VimClient, Result};
/// The *UserDirectory* managed object provides information about users
/// and groups on a vSphere server and ESX hosts.
///
/// The method
/// *UserDirectory.RetrieveUserGroups* returns a list
/// of user account data. The method can perform a search operation based on
/// specific criteria - user name, group name, sub-string or string matching,
/// and, on Windows, domain. Use the results as input
/// to the AuthorizationManager methods
/// *AuthorizationManager.SetEntityPermissions* and
/// *AuthorizationManager.ResetEntityPermissions*.
///
/// The content of the returned results depends on the server environment:
/// - On a Windows host, *UserDirectory.RetrieveUserGroups* can search
/// from the set of trusted domains on the host, including the primary
/// domain of the system. A special domain (specified as an
/// empty string - "") refers to the users and groups local
/// to the host.
/// - On an ESX Server or a Linux host, the search operates on the
/// users and groups defined in the /etc/passwd file. Always specify
/// an empty string ("") for the domain argument.
/// If the /etc/passwd file contains Sun NIS or NIS+ users and groups,
/// RetrieveUserGroups returns information about these accounts as well.
#[derive(Clone)]
pub struct UserDirectory {
client: Arc<dyn VimClient>,
mo_id: String,
}
impl UserDirectory {
pub fn new(client: Arc<dyn VimClient>, mo_id: &str) -> Self {
Self {
client,
mo_id: mo_id.to_string(),
}
}
/// Returns a list of *UserSearchResult* objects describing the
/// users and groups defined for the server.
/// - On Windows, the search for users and groups is restricted to
/// the given domain. If you omit the domain argument, then
/// the search is performed on local users and groups.
/// - On ESX Server (or Linux systems), the method returns the list
/// of users and groups that are specified in the /etc/passwd file.
/// If the password file contains Sun NIS or NIS+ users and groups,
/// the returned list includes information about those as well.
///
/// You must hold the Authorization.ModifyPermissions privilege to invoke this
/// method. If you hold the privilege on any ManagedEntity, you will
/// have access to user and group information for the server.
///
/// As of vSphere API 5.1:
/// - Local user groups on ESXi are not supported and this method will
/// not return information about local groups on the ESXi host.
/// Information about Active Directory groups is not affected.
/// - Some special system users on ESXi like 'nfsnobody' and 'daemon'
/// will be filtered out by this method.
///
/// ## Parameters:
///
/// ### domain
/// Domain to be searched. If not set, then the method searches
/// the local machine.
///
/// ### search_str
/// Case insensitive substring used to filter results;
/// the search string is compared to the login and full name for users,
/// and the name and description for groups. Leave
/// this blank to match all users.
///
/// ### belongs_to_group
/// If present, the returned list contains only users or groups
/// that directly belong to the specified group. Users or groups that
/// have indirect membership will not be included in the list.
///
/// ### belongs_to_user
/// If present, the returned list contains only groups that directly
/// contain the specified user. Groups that indirectly contain
/// the user will not be included in the list.
///
/// ### exact_match
/// Indicates the searchStr passed should match a user or
/// group name exactly.
///
/// ### find_users
/// True, if users should be included in the result.
///
/// ### find_groups
/// True, if groups should be included in the result.
///
/// ## Errors:
///
/// ***NotSupported***: If you specify a domain for systems that do not support
/// domains, such as an ESX Server. The method also throws
/// NotSupported if you specify membership (belongsToGroup or
/// belongsToUser) and the server does not support
/// by-membership queries.
///
/// ***NotFound***: If any of the domain, belongsToGroup, or belongsToUser
/// arguments refer to entities that do not exist.
pub async fn retrieve_user_groups(&self, domain: Option<&str>, search_str: &str, belongs_to_group: Option<&str>, belongs_to_user: Option<&str>, exact_match: bool, find_users: bool, find_groups: bool) -> Result<Option<Vec<Box<dyn crate::types::traits::UserSearchResultTrait>>>> {
let input = RetrieveUserGroupsRequestType {domain, search_str, belongs_to_group, belongs_to_user, exact_match, find_users, find_groups, };
let bytes_opt = self.client.invoke_optional("", "UserDirectory", &self.mo_id, "RetrieveUserGroups", Some(&input)).await?;
match bytes_opt {
Some(ref b) => Ok(Some(crate::core::client::unmarshal_array(self.client.transport(), b)?)),
None => Ok(None),
}
}
/// List of Windows domains available for user searches, if the underlying
/// system supports windows domain membership.
///
/// ***Required privileges:*** System.View
pub async fn domain_list(&self) -> Result<Option<Vec<String>>> {
let pv_opt = self.client.fetch_property_raw("", "UserDirectory", &self.mo_id, "domainList").await?;
match pv_opt {
Some(pv) => Ok(Some(crate::core::client::extract_property(pv)?)),
None => Ok(None),
}
}
}
struct RetrieveUserGroupsRequestType<'a> {
domain: Option<&'a str>,
search_str: &'a str,
belongs_to_group: Option<&'a str>,
belongs_to_user: Option<&'a str>,
exact_match: bool,
find_users: bool,
find_groups: bool,
}
impl<'a> miniserde::Serialize for RetrieveUserGroupsRequestType<'a> {
fn begin(&self) -> miniserde::ser::Fragment<'_> {
miniserde::ser::Fragment::Map(Box::new(RetrieveUserGroupsRequestTypeSer { data: self, seq: 0 }))
}
}
struct RetrieveUserGroupsRequestTypeSer<'b, 'a> {
data: &'b RetrieveUserGroupsRequestType<'a>,
seq: usize,
}
impl<'b, 'a> miniserde::ser::Map for RetrieveUserGroupsRequestTypeSer<'b, 'a> {
fn next(&mut self) -> Option<(std::borrow::Cow<'_, str>, &dyn miniserde::Serialize)> {
loop {
let seq = self.seq;
self.seq += 1;
match seq {
0 => return Some((std::borrow::Cow::Borrowed("_typeName"), &"RetrieveUserGroupsRequestType")),
1 => {
let Some(ref val) = self.data.domain else { continue; };
return Some((std::borrow::Cow::Borrowed("domain"), val as &dyn miniserde::Serialize));
}
2 => return Some((std::borrow::Cow::Borrowed("searchStr"), &self.data.search_str as &dyn miniserde::Serialize)),
3 => {
let Some(ref val) = self.data.belongs_to_group else { continue; };
return Some((std::borrow::Cow::Borrowed("belongsToGroup"), val as &dyn miniserde::Serialize));
}
4 => {
let Some(ref val) = self.data.belongs_to_user else { continue; };
return Some((std::borrow::Cow::Borrowed("belongsToUser"), val as &dyn miniserde::Serialize));
}
5 => return Some((std::borrow::Cow::Borrowed("exactMatch"), &self.data.exact_match as &dyn miniserde::Serialize)),
6 => return Some((std::borrow::Cow::Borrowed("findUsers"), &self.data.find_users as &dyn miniserde::Serialize)),
7 => return Some((std::borrow::Cow::Borrowed("findGroups"), &self.data.find_groups as &dyn miniserde::Serialize)),
_ => return None,
}
}
}
}