Module: Puppet::Util::Windows::SID Private
- Extended by:
- FFI::Library
- Included in:
- AccessControlEntry, SecurityDescriptor
- Defined in:
- lib/puppet/util/windows.rb,
lib/puppet/util/windows/sid.rb,
lib/puppet/util/windows/principal.rb
This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.
Defined Under Namespace
Classes: Principal
Constant Summary collapse
- ERROR_NONE_MAPPED =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
missing from Windows::Error
1332
- ERROR_INVALID_SID_STRUCTURE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
1337
- ERROR_TRUSTED_DOMAIN_FAILURE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
1788
- ERROR_TRUSTED_RELATIONSHIP_FAILURE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
1789
- Null =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Well Known SIDs
'S-1-0'
- Nobody =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-0-0'
- World =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-1'
- Everyone =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-1-0'
- Local =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-2'
- Creator =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-3'
- CreatorOwner =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-3-0'
- CreatorGroup =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-3-1'
- CreatorOwnerServer =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-3-2'
- CreatorGroupServer =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-3-3'
- NonUnique =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-4'
- Nt =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5'
- Dialup =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-1'
- Network =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-2'
- Batch =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-3'
- Interactive =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-4'
- Service =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-6'
- Anonymous =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-7'
- Proxy =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-8'
- EnterpriseDomainControllers =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-9'
- PrincipalSelf =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-10'
- AuthenticatedUsers =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-11'
- RestrictedCode =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-12'
- TerminalServerUsers =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-13'
- LocalSystem =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-18'
- NtLocal =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-19'
- NtNetwork =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-20'
- BuiltinAdministrators =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-32-544'
- BuiltinUsers =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-32-545'
- Guests =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-32-546'
- PowerUsers =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-32-547'
- AccountOperators =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-32-548'
- ServerOperators =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-32-549'
- PrintOperators =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-32-550'
- BackupOperators =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-32-551'
- Replicators =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-5-32-552'
- AllAppPackages =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
'S-1-15-2-1'
- MAXIMUM_SID_STRING_LENGTH =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
stackoverflow.com/a/1792930 - 68 bytes, 184 characters in a string
184
Class Method Summary collapse
-
.ads_to_principal(ads_object) ⇒ Object
private
Converts a COM instance of IAdsUser or IAdsGroup to a SID::Principal object, Raises an Error for nil or an object without an objectSID / Name property.
- .get_length_sid(sid_ptr) ⇒ Object private
-
.name_to_principal(name, allow_unresolved = false) ⇒ Object
(also: name_to_sid_object)
private
Convert an account name, e.g.
-
.name_to_sid(name) ⇒ Object
private
Convert an account name, e.g.
-
.octet_string_to_principal(bytes) ⇒ Object
(also: octet_string_to_sid_object)
private
Converts an octet string array of bytes to a SID::Principal object, e.g.
- .octet_string_to_sid_string(sid_bytes) ⇒ Object private
-
.sid_ptr_to_string(psid) ⇒ Object
private
Convert a SID pointer to a SID string, e.g.
-
.sid_to_name(value) ⇒ Object
private
Convert a SID string, e.g.
-
.string_to_sid_ptr(string_sid, &block) ⇒ Object
private
Convert a SID string, e.g.
- .unresolved_principal(name, sid_bytes) ⇒ Object private
-
.valid_sid?(string_sid) ⇒ Boolean
private
Return true if the string is a valid SID, e.g.
Class Method Details
.ads_to_principal(ads_object) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Converts a COM instance of IAdsUser or IAdsGroup to a SID::Principal object, Raises an Error for nil or an object without an objectSID / Name property. This method returns a SID::Principal with the account, domain, SID, etc This method will return instances even when the SID is unresolvable, as may be the case when domain users have been added to local groups, but removed from the domain
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/puppet/util/windows/sid.rb', line 115 def ads_to_principal(ads_object) if !ads_object || !ads_object.respond_to?(:ole_respond_to?) || !ads_object.ole_respond_to?(:objectSID) || !ads_object.ole_respond_to?(:Name) raise Puppet::Error.new("ads_object must be an IAdsUser or IAdsGroup instance") end octet_string_to_principal(ads_object.objectSID) rescue Puppet::Util::Windows::Error => e # if the error is not a lookup / mapping problem, immediately re-raise raise if e.code != ERROR_NONE_MAPPED # if the Name property isn't formatted like a SID, OR if !valid_sid?(ads_object.Name) || # if the objectSID doesn't match the Name property, also raise ((converted = octet_string_to_sid_string(ads_object.objectSID)) != ads_object.Name) raise Puppet::Error.new("ads_object Name: #{ads_object.Name} invalid or does not match objectSID: #{ads_object.objectSID} (#{converted})", e) end unresolved_principal(ads_object.Name, ads_object.objectSID) end |
.get_length_sid(sid_ptr) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
221 222 223 224 225 226 227 228 |
# File 'lib/puppet/util/windows/sid.rb', line 221 def get_length_sid(sid_ptr) # MSDN states IsValidSid should be called on pointer first if ! sid_ptr.kind_of?(FFI::Pointer) || IsValidSid(sid_ptr) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error.new(_("Invalid SID")) end GetLengthSid(sid_ptr) end |
.name_to_principal(name, allow_unresolved = false) ⇒ Object Also known as: name_to_sid_object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Convert an account name, e.g. ‘Administrators’ into a Principal::SID object, e.g. ‘S-1-5-32-544’. The name can be specified as ‘Administrators’, ‘BUILTINAdministrators’, or ‘S-1-5-32-544’, and will return the SID object. Returns nil if the account doesn’t exist. This method returns a SID::Principal with the account, domain, SID, etc
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/puppet/util/windows/sid.rb', line 70 def name_to_principal(name, allow_unresolved = false) # Apparently, we accept a symbol.. name = name.to_s.strip if name # if name is a SID string, convert it to raw bytes for use with lookup_account_sid raw_sid_bytes = nil begin string_to_sid_ptr(name) do |sid_ptr| raw_sid_bytes = sid_ptr.read_array_of_uchar(get_length_sid(sid_ptr)) end rescue => e # Avoid debug logs pollution with valid account names # https://docs.microsoft.com/en-us/windows/win32/api/sddl/nf-sddl-convertstringsidtosidw#return-value Puppet.debug("Could not retrieve raw SID bytes from '#{name}': #{e.}") unless e.code == ERROR_INVALID_SID_STRUCTURE end raw_sid_bytes ? Principal.lookup_account_sid(raw_sid_bytes) : Principal.lookup_account_name(name) rescue => e Puppet.debug("#{e.}") (allow_unresolved && raw_sid_bytes) ? unresolved_principal(name, raw_sid_bytes) : nil end |
.name_to_sid(name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Convert an account name, e.g. ‘Administrators’ into a SID string, e.g. ‘S-1-5-32-544’. The name can be specified as ‘Administrators’, ‘BUILTINAdministrators’, or ‘S-1-5-32-544’, and will return the SID. Returns nil if the account doesn’t exist.
58 59 60 61 62 |
# File 'lib/puppet/util/windows/sid.rb', line 58 def name_to_sid(name) sid = name_to_principal(name) sid ? sid.sid : nil end |
.octet_string_to_principal(bytes) ⇒ Object Also known as: octet_string_to_sid_object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Converts an octet string array of bytes to a SID::Principal object, e.g. [1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0] is the representation for S-1-5-18, the local ‘SYSTEM’ account. Raises an Error for nil or non-array input. This method returns a SID::Principal with the account, domain, SID, etc
99 100 101 102 103 104 105 |
# File 'lib/puppet/util/windows/sid.rb', line 99 def octet_string_to_principal(bytes) if !bytes || !bytes.respond_to?('pack') || bytes.empty? raise Puppet::Util::Windows::Error.new(_("Octet string must be an array of bytes")) end Principal.lookup_account_sid(bytes) end |
.octet_string_to_sid_string(sid_bytes) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
231 232 233 234 235 236 237 238 239 240 |
# File 'lib/puppet/util/windows/sid.rb', line 231 def octet_string_to_sid_string(sid_bytes) sid_string = nil FFI::MemoryPointer.new(:byte, sid_bytes.length) do |sid_ptr| sid_ptr.write_array_of_uchar(sid_bytes) sid_string = Puppet::Util::Windows::SID.sid_ptr_to_string(sid_ptr) end sid_string end |
.sid_ptr_to_string(psid) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Convert a SID pointer to a SID string, e.g. “S-1-5-32-544”.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/puppet/util/windows/sid.rb', line 160 def sid_ptr_to_string(psid) if ! psid.kind_of?(FFI::Pointer) || IsValidSid(psid) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error.new(_("Invalid SID")) end sid_string = nil FFI::MemoryPointer.new(:pointer, 1) do |buffer_ptr| if ConvertSidToStringSidW(psid, buffer_ptr) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error.new(_("Failed to convert binary SID")) end buffer_ptr.read_win32_local_pointer do |wide_string_ptr| if wide_string_ptr.null? raise Puppet::Error.new(_("ConvertSidToStringSidW failed to allocate buffer for sid")) end sid_string = wide_string_ptr.read_arbitrary_wide_string_up_to(MAXIMUM_SID_STRING_LENGTH) end end sid_string end |
.sid_to_name(value) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Convert a SID string, e.g. “S-1-5-32-544” to a name, e.g. ‘BUILTINAdministrators’. Returns nil if an account for that SID does not exist.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/puppet/util/windows/sid.rb', line 139 def sid_to_name(value) sid_bytes = [] begin string_to_sid_ptr(value) do |ptr| sid_bytes = ptr.read_array_of_uchar(get_length_sid(ptr)) end rescue Puppet::Util::Windows::Error => e raise if e.code != ERROR_INVALID_SID_STRUCTURE end Principal.lookup_account_sid(sid_bytes).domain_account rescue nil end |
.string_to_sid_ptr(string_sid, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Convert a SID string, e.g. “S-1-5-32-544” to a pointer (containing the address of the binary SID structure). The returned value can be used in Win32 APIs that expect a PSID, e.g. IsValidSid. The account for this SID may or may not exist.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/puppet/util/windows/sid.rb', line 188 def string_to_sid_ptr(string_sid, &block) FFI::MemoryPointer.from_string_to_wide_string(string_sid) do |lpcwstr| FFI::MemoryPointer.new(:pointer, 1) do |sid_ptr_ptr| if ConvertStringSidToSidW(lpcwstr, sid_ptr_ptr) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error.new(_("Failed to convert string SID: %{string_sid}") % { string_sid: string_sid }) end sid_ptr_ptr.read_win32_local_pointer do |sid_ptr| yield sid_ptr end end end # yielded sid_ptr has already had LocalFree called, nothing to return nil end |
.unresolved_principal(name, sid_bytes) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
244 245 246 247 248 249 250 251 252 253 |
# File 'lib/puppet/util/windows/sid.rb', line 244 def self.unresolved_principal(name, sid_bytes) Principal.new( name, # account sid_bytes, # sid_bytes name, # sid string nil, #domain # https://msdn.microsoft.com/en-us/library/cc245534.aspx?f=255&MSPPError=-2147217396 # Indicates that the type of object could not be determined. For example, no object with that SID exists. :SidTypeUnknown) end |
.valid_sid?(string_sid) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return true if the string is a valid SID, e.g. “S-1-5-32-544”, false otherwise.
208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/puppet/util/windows/sid.rb', line 208 def valid_sid?(string_sid) valid = false begin string_to_sid_ptr(string_sid) { |ptr| valid = ! ptr.nil? && ! ptr.null? } rescue Puppet::Util::Windows::Error => e raise if e.code != ERROR_INVALID_SID_STRUCTURE end valid end |