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 =
https://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 https://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 =
https://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 https://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 https://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 ComputerName\LocalSystem' 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.
https://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 |