Module: Puppet::Util::Windows::User

Extended by:
FFI::Library, String
Defined in:
lib/puppet/util/windows/user.rb

Defined Under Namespace

Classes: 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
WELL_KNOWN_SID_TYPE =
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

Methods included from FFI::Library

attach_function_private

Methods included from String

wide_string

Class Method Details

.admin?Boolean


10
11
12
13
14
15
16
# File 'lib/puppet/util/windows/user.rb', line 10

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?
  return elevated_supported ? Puppet::Util::Windows::Process.elevated_security? : true
end

.check_token_membershipObject


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
# File 'lib/puppet/util/windows/user.rb', line 31

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.new(_("Failed to create administrators SID"))
      end
    end

    if IsValidSid(sid_pointer) == FFI::WIN32_FALSE
      raise Puppet::Util::Windows::Error.new(_("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.new(_("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

.load_profile(user, password) ⇒ Object


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/puppet/util/windows/user.rb', line 110

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.new(_("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.new(_("Failed to unload user profile %{user}") % { user: user.inspect })
      end
    end
  end
end

.logon_user(name, password, &block) ⇒ Object


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/puppet/util/windows/user.rb', line 77

def logon_user(name, password, &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, password, fLOGON32_LOGON_NETWORK, fLOGON32_PROVIDER_DEFAULT, token_pointer) == FFI::WIN32_FALSE
        if logon_user_by_logon_type(name, password, fLOGON32_LOGON_INTERACTIVE, fLOGON32_PROVIDER_DEFAULT, token_pointer) == FFI::WIN32_FALSE
          raise Puppet::Util::Windows::Error.new(_("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) ⇒ Boolean


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/puppet/util/windows/user.rb', line 60

def password_is?(name, password)
  begin
    logon_user(name, password) { |token| }
  rescue Puppet::Util::Windows::Error => detail

    authenticated_error_codes = Set[
      ,
      ERROR_INVALID_LOGON_HOURS,
      ERROR_INVALID_WORKSTATION,
      ,
    ]

    return authenticated_error_codes.include?(detail.code)
  end
end