Module: Puppet::Util::Windows::User
- Extended by:
- FFI::Library, String
- Defined in:
- lib/puppet/util/windows/user.rb
Defined Under Namespace
Classes: LSA_OBJECT_ATTRIBUTES, LSA_UNICODE_STRING, PROFILEINFO
Constant Summary collapse
- SECURITY_MAX_SID_SIZE =
68
- ERROR_ACCOUNT_RESTRICTION =
msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx These error codes indicate successful authentication but failure to logon for a separate reason
1327
- ERROR_INVALID_LOGON_HOURS =
1328
- ERROR_INVALID_WORKSTATION =
1329
- ERROR_ACCOUNT_DISABLED =
1331
- POLICY_VIEW_LOCAL_INFORMATION =
ACCESS_MASK flags for Policy Objects docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lsad/b61b7268-987a-420b-84f9-6c75f8dc8558
0x00000001
- POLICY_VIEW_AUDIT_INFORMATION =
0x00000002
- POLICY_GET_PRIVATE_INFORMATION =
0x00000004
- POLICY_TRUST_ADMIN =
0x00000008
- POLICY_CREATE_ACCOUNT =
0x00000010
- POLICY_CREATE_SECRET =
0x00000020
- POLICY_CREATE_PRIVILEGE =
0x00000040
- POLICY_SET_DEFAULT_QUOTA_LIMITS =
0x00000080
- POLICY_SET_AUDIT_REQUIREMENTS =
0x00000100
- POLICY_AUDIT_LOG_ADMIN =
0x00000200
- POLICY_SERVER_ADMIN =
0x00000400
- POLICY_LOOKUP_NAMES =
0x00000800
- POLICY_NOTIFICATION =
0x00001000
- WELL_KNOWN_SID_TYPE =
msdn.microsoft.com/en-us/library/windows/desktop/aa379650(v=vs.85).aspx rubocop:disable Layout/SpaceBeforeComma
enum( :WinNullSid , 0, :WinWorldSid , 1, :WinLocalSid , 2, :WinCreatorOwnerSid , 3, :WinCreatorGroupSid , 4, :WinCreatorOwnerServerSid , 5, :WinCreatorGroupServerSid , 6, :WinNtAuthoritySid , 7, :WinDialupSid , 8, :WinNetworkSid , 9, :WinBatchSid , 10, :WinInteractiveSid , 11, :WinServiceSid , 12, :WinAnonymousSid , 13, :WinProxySid , 14, :WinEnterpriseControllersSid , 15, :WinSelfSid , 16, :WinAuthenticatedUserSid , 17, :WinRestrictedCodeSid , 18, :WinTerminalServerSid , 19, :WinRemoteLogonIdSid , 20, :WinLogonIdsSid , 21, :WinLocalSystemSid , 22, :WinLocalServiceSid , 23, :WinNetworkServiceSid , 24, :WinBuiltinDomainSid , 25, :WinBuiltinAdministratorsSid , 26, :WinBuiltinUsersSid , 27, :WinBuiltinGuestsSid , 28, :WinBuiltinPowerUsersSid , 29, :WinBuiltinAccountOperatorsSid , 30, :WinBuiltinSystemOperatorsSid , 31, :WinBuiltinPrintOperatorsSid , 32, :WinBuiltinBackupOperatorsSid , 33, :WinBuiltinReplicatorSid , 34, :WinBuiltinPreWindows2000CompatibleAccessSid , 35, :WinBuiltinRemoteDesktopUsersSid , 36, :WinBuiltinNetworkConfigurationOperatorsSid , 37, :WinAccountAdministratorSid , 38, :WinAccountGuestSid , 39, :WinAccountKrbtgtSid , 40, :WinAccountDomainAdminsSid , 41, :WinAccountDomainUsersSid , 42, :WinAccountDomainGuestsSid , 43, :WinAccountComputersSid , 44, :WinAccountControllersSid , 45, :WinAccountCertAdminsSid , 46, :WinAccountSchemaAdminsSid , 47, :WinAccountEnterpriseAdminsSid , 48, :WinAccountPolicyAdminsSid , 49, :WinAccountRasAndIasServersSid , 50, :WinNTLMAuthenticationSid , 51, :WinDigestAuthenticationSid , 52, :WinSChannelAuthenticationSid , 53, :WinThisOrganizationSid , 54, :WinOtherOrganizationSid , 55, :WinBuiltinIncomingForestTrustBuildersSid , 56, :WinBuiltinPerfMonitoringUsersSid , 57, :WinBuiltinPerfLoggingUsersSid , 58, :WinBuiltinAuthorizationAccessSid , 59, :WinBuiltinTerminalServerLicenseServersSid , 60, :WinBuiltinDCOMUsersSid , 61, :WinBuiltinIUsersSid , 62, :WinIUserSid , 63, :WinBuiltinCryptoOperatorsSid , 64, :WinUntrustedLabelSid , 65, :WinLowLabelSid , 66, :WinMediumLabelSid , 67, :WinHighLabelSid , 68, :WinSystemLabelSid , 69, :WinWriteRestrictedCodeSid , 70, :WinCreatorOwnerRightsSid , 71, :WinCacheablePrincipalsGroupSid , 72, :WinNonCacheablePrincipalsGroupSid , 73, :WinEnterpriseReadonlyControllersSid , 74, :WinAccountReadonlyControllersSid , 75, :WinBuiltinEventLogReadersGroup , 76, :WinNewEnterpriseReadonlyControllersSid , 77, :WinBuiltinCertSvcDComAccessGroup , 78, :WinMediumPlusLabelSid , 79, :WinLocalLogonSid , 80, :WinConsoleLogonSid , 81, :WinThisOrganizationCertificateSid , 82, :WinApplicationPackageAuthoritySid , 83, :WinBuiltinAnyPackageSid , 84, :WinCapabilityInternetClientSid , 85, :WinCapabilityInternetClientServerSid , 86, :WinCapabilityPrivateNetworkClientServerSid , 87, :WinCapabilityPicturesLibrarySid , 88, :WinCapabilityVideosLibrarySid , 89, :WinCapabilityMusicLibrarySid , 90, :WinCapabilityDocumentsLibrarySid , 91, :WinCapabilitySharedUserCertificatesSid , 92, :WinCapabilityEnterpriseAuthenticationSid , 93, :WinCapabilityRemovableStorageSid , 94 )
Class Method Summary collapse
- .admin? ⇒ Boolean
- .check_token_membership ⇒ Object
-
.default_system_account?(name) ⇒ Boolean
Check if a given user is one of the default system accounts These accounts do not have a password and all checks done through logon attempt will fail docs.microsoft.com/en-us/windows/security/identity-protection/access-control/local-accounts#default-local-system-accounts.
- .get_rights(name) ⇒ Object
- .load_profile(user, password) ⇒ Object
-
.localsystem?(name) ⇒ Boolean
The name of the account in all locales is ‘LocalSystem`.
- .logon_user(name, password, domain = '.', &block) ⇒ Object
- .password_is?(name, password, domain = '.') ⇒ Boolean
- .remove_rights(name, rights) ⇒ Object
- .set_rights(name, rights) ⇒ Object
Methods included from String
Class Method Details
.admin? ⇒ Boolean
11 12 13 14 15 16 17 |
# File 'lib/puppet/util/windows/user.rb', line 11 def admin? return false unless check_token_membership # if Vista or later, check for unrestricted process token elevated_supported = Puppet::Util::Windows::Process.supports_elevated_security? elevated_supported ? Puppet::Util::Windows::Process.elevated_security? : true end |
.check_token_membership ⇒ Object
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 |
# File 'lib/puppet/util/windows/user.rb', line 48 def check_token_membership is_admin = false FFI::MemoryPointer.new(:byte, SECURITY_MAX_SID_SIZE) do |sid_pointer| FFI::MemoryPointer.new(:dword, 1) do |size_pointer| size_pointer.write_uint32(SECURITY_MAX_SID_SIZE) if CreateWellKnownSid(:WinBuiltinAdministratorsSid, FFI::Pointer::NULL, sid_pointer, size_pointer) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error, _("Failed to create administrators SID") end end if IsValidSid(sid_pointer) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error, _("Invalid SID") end FFI::MemoryPointer.new(:win32_bool, 1) do |ismember_pointer| if CheckTokenMembership(FFI::Pointer::NULL_HANDLE, sid_pointer, ismember_pointer) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error, _("Failed to check membership") end # Is administrators SID enabled in calling thread's access token? is_admin = ismember_pointer.read_win32_bool end end is_admin end |
.default_system_account?(name) ⇒ Boolean
Check if a given user is one of the default system accounts These accounts do not have a password and all checks done through logon attempt will fail docs.microsoft.com/en-us/windows/security/identity-protection/access-control/local-accounts#default-local-system-accounts
31 32 33 34 |
# File 'lib/puppet/util/windows/user.rb', line 31 def default_system_account?(name) user_sid = Puppet::Util::Windows::SID.name_to_sid(name) [Puppet::Util::Windows::SID::LocalSystem, Puppet::Util::Windows::SID::NtLocal, Puppet::Util::Windows::SID::NtNetwork].include?(user_sid) end |
.get_rights(name) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/puppet/util/windows/user.rb', line 146 def get_rights(name) user_info = Puppet::Util::Windows::SID.name_to_principal(name.sub(/^\.\\/, "#{Puppet::Util::Windows::ADSI.computer_name}\\")) return "" unless user_info rights = [] rights_pointer = FFI::MemoryPointer.new(:pointer) number_of_rights = FFI::MemoryPointer.new(:ulong) sid_pointer = FFI::MemoryPointer.new(:byte, user_info.sid_bytes.length).write_array_of_uchar(user_info.sid_bytes) new_lsa_policy_handle do |policy_handle| result = LsaEnumerateAccountRights(policy_handle.read_pointer, sid_pointer, rights_pointer, number_of_rights) check_lsa_nt_status_and_raise_failures(result, "LsaEnumerateAccountRights") end number_of_rights.read_ulong.times do |index| right = LSA_UNICODE_STRING.new(rights_pointer.read_pointer + index * LSA_UNICODE_STRING.size) rights << right[:Buffer].read_arbitrary_wide_string_up_to end result = LsaFreeMemory(rights_pointer.read_pointer) check_lsa_nt_status_and_raise_failures(result, "LsaFreeMemory") rights.join(",") end |
.load_profile(user, password) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/puppet/util/windows/user.rb', line 123 def load_profile(user, password) logon_user(user, password) do |token| FFI::MemoryPointer.from_string_to_wide_string(user) do |lpUserName| pi = PROFILEINFO.new pi[:dwSize] = PROFILEINFO.size pi[:dwFlags] = 1 # PI_NOUI - prevents display of profile error msgs pi[:lpUserName] = lpUserName # Load the profile. Since it doesn't exist, it will be created if LoadUserProfileW(token, pi.pointer) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error, _("Failed to load user profile %{user}") % { user: user.inspect } end Puppet.debug("Loaded profile for #{user}") if UnloadUserProfile(token, pi[:hProfile]) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error, _("Failed to unload user profile %{user}") % { user: user.inspect } end end end end |
.localsystem?(name) ⇒ Boolean
The name of the account in all locales is ‘LocalSystem`. `.LocalSystem` or `ComputerNameLocalSystem’ can also be used. This account is not recognized by the security subsystem, so you cannot specify its name in a call to the ‘LookupAccountName` function. docs.microsoft.com/en-us/windows/win32/services/localsystem-account
23 24 25 |
# File 'lib/puppet/util/windows/user.rb', line 23 def localsystem?(name) ["LocalSystem", ".\\LocalSystem", "#{Puppet::Util::Windows::ADSI.computer_name}\\LocalSystem"].any? { |s| s.casecmp(name) == 0 } end |
.logon_user(name, password, domain = '.', &block) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/puppet/util/windows/user.rb', line 91 def logon_user(name, password, domain = '.', &block) fLOGON32_PROVIDER_DEFAULT = 0 fLOGON32_LOGON_INTERACTIVE = 2 fLOGON32_LOGON_NETWORK = 3 token = nil begin FFI::MemoryPointer.new(:handle, 1) do |token_pointer| # try logon using network else try logon using interactive mode if logon_user_by_logon_type(name, domain, password, fLOGON32_LOGON_NETWORK, fLOGON32_PROVIDER_DEFAULT, token_pointer) == FFI::WIN32_FALSE if logon_user_by_logon_type(name, domain, password, fLOGON32_LOGON_INTERACTIVE, fLOGON32_PROVIDER_DEFAULT, token_pointer) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error, _("Failed to logon user %{name}") % { name: name.inspect } end end yield token = token_pointer.read_handle end ensure FFI::WIN32.CloseHandle(token) if token end # token has been closed by this point true end |
.password_is?(name, password, domain = '.') ⇒ Boolean
77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/puppet/util/windows/user.rb', line 77 def password_is?(name, password, domain = '.') logon_user(name, password, domain) { |token| } rescue Puppet::Util::Windows::Error => detail authenticated_error_codes = Set[ ERROR_ACCOUNT_RESTRICTION, ERROR_INVALID_LOGON_HOURS, ERROR_INVALID_WORKSTATION, ERROR_ACCOUNT_DISABLED, ] authenticated_error_codes.include?(detail.code) end |
.remove_rights(name, rights) ⇒ Object
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/puppet/util/windows/user.rb', line 184 def remove_rights(name, rights) rights_pointer = new_lsa_unicode_strings_pointer(rights) user_info = Puppet::Util::Windows::SID.name_to_principal(name.sub(/^\.\\/, "#{Puppet::Util::Windows::ADSI.computer_name}\\")) sid_pointer = FFI::MemoryPointer.new(:byte, user_info.sid_bytes.length).write_array_of_uchar(user_info.sid_bytes) new_lsa_policy_handle do |policy_handle| result = LsaRemoveAccountRights(policy_handle.read_pointer, sid_pointer, false, rights_pointer, rights.size) check_lsa_nt_status_and_raise_failures(result, "LsaRemoveAccountRights") end end |
.set_rights(name, rights) ⇒ Object
172 173 174 175 176 177 178 179 180 181 |
# File 'lib/puppet/util/windows/user.rb', line 172 def set_rights(name, rights) rights_pointer = new_lsa_unicode_strings_pointer(rights) user_info = Puppet::Util::Windows::SID.name_to_principal(name.sub(/^\.\\/, "#{Puppet::Util::Windows::ADSI.computer_name}\\")) sid_pointer = FFI::MemoryPointer.new(:byte, user_info.sid_bytes.length).write_array_of_uchar(user_info.sid_bytes) new_lsa_policy_handle do |policy_handle| result = LsaAddAccountRights(policy_handle.read_pointer, sid_pointer, rights_pointer, rights.size) check_lsa_nt_status_and_raise_failures(result, "LsaAddAccountRights") end end |