Class: Puppet::Util::Windows::ADSI::ADSIObject Private

Inherits:
Object
  • Object
show all
Extended by:
Enumerable
Defined in:
lib/puppet/util/windows/adsi.rb,
lib/puppet/util/windows.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Common base class shared by the User and Group classes below.

Direct Known Subclasses

Group, User

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, native_object = nil) ⇒ ADSIObject

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.

Returns a new instance of ADSIObject.



254
255
256
257
# File 'lib/puppet/util/windows/adsi.rb', line 254

def initialize(name, native_object = nil)
  @name = name
  @native_object = native_object
end

Class Attribute Details

.object_classObject (readonly)

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.

Is either ‘user’ or ‘group’



143
144
145
# File 'lib/puppet/util/windows/adsi.rb', line 143

def object_class
  @object_class
end

Instance Attribute Details

#nameObject (readonly)

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.



253
254
255
# File 'lib/puppet/util/windows/adsi.rb', line 253

def name
  @name
end

Class Method Details

.delete(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.



204
205
206
# File 'lib/puppet/util/windows/adsi.rb', line 204

def delete(name)
  Puppet::Util::Windows::ADSI.delete(name, @object_class)
end

.each(&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.



241
242
243
244
245
246
247
248
249
250
# File 'lib/puppet/util/windows/adsi.rb', line 241

def each(&block)
  objects = []
  list_all.each do |o|
    # Setting WIN32OLE.codepage in the microsoft_windows feature ensures
    # values are returned as UTF-8
    objects << new(o.name)
  end

  objects.each(&block)
end

.exists?(name_or_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.

Returns:

  • (Boolean)


208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/puppet/util/windows/adsi.rb', line 208

def exists?(name_or_sid)
  well_known = false
  if (sid = Puppet::Util::Windows::SID.name_to_principal(name_or_sid))
    # Examples of SidType include SidTypeUser, SidTypeGroup
    if sid. == "SidType#{@object_class.capitalize}".to_sym
      # Check if we're getting back a local user when domain-joined
      return true unless [:MEMBER_WORKSTATION, :MEMBER_SERVER].include?(Puppet::Util::Windows::ADSI.domain_role)
      # The resource domain and the computer name are not always case-matching
      return sid.domain.casecmp(Puppet::Util::Windows::ADSI.computer_name) == 0
    end

    # 'well known group' is special as it can be a group like Everyone OR a user like SYSTEM
    # so try to resolve it
    # https://msdn.microsoft.com/en-us/library/cc234477.aspx
    well_known = sid. == :SidTypeWellKnownGroup
    return false if sid. != :SidTypeAlias && !well_known
    name_or_sid = "#{sid.domain}\\#{sid.}"
  end

  object = Puppet::Util::Windows::ADSI.connect(uri(*parse_name(name_or_sid)))
  object.Class.downcase == @object_class
rescue
  # special accounts like SYSTEM or special groups like Authenticated Users cannot
  # resolve via monikers like WinNT://./SYSTEM,user or WinNT://./Authenticated Users,group
  # -- they'll fail to connect. thus, given a validly resolved SID, this failure is
  # ambiguous as it may indicate either a group like Service or an account like SYSTEM
  well_known
end

.get_sids(adsi_child_collection) ⇒ 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.

returns Puppet::Util::Windows::SID::Principal[] may contain objects that represent unresolvable SIDs



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/puppet/util/windows/adsi.rb', line 175

def get_sids(adsi_child_collection)
  sids = []
  adsi_child_collection.each do |m|
    sids << Puppet::Util::Windows::SID.ads_to_principal(m)
  rescue Puppet::Util::Windows::Error => e
    case e.code
    when Puppet::Util::Windows::SID::ERROR_TRUSTED_RELATIONSHIP_FAILURE, Puppet::Util::Windows::SID::ERROR_TRUSTED_DOMAIN_FAILURE
      sids << Puppet::Util::Windows::SID.unresolved_principal(m.name, m.sid)
    else
      raise e
    end
  end

  sids
end

.list_allObject

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.

Raises:

  • (NotImplementedError)


237
238
239
# File 'lib/puppet/util/windows/adsi.rb', line 237

def list_all
  raise NotImplementedError, _("Subclass must implement class-level method 'list_all'!")
end

.localized_domainsObject

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.



145
146
147
148
149
150
151
152
153
154
# File 'lib/puppet/util/windows/adsi.rb', line 145

def localized_domains
  @localized_domains ||= [
    # localized version of BUILTIN
    # for instance VORDEFINIERT on German Windows
    Puppet::Util::Windows::SID.sid_to_name('S-1-5-32').upcase,
    # localized version of NT AUTHORITY (can't use S-1-5)
    # for instance AUTORITE NT on French Windows
    Puppet::Util::Windows::SID.name_to_principal('SYSTEM').domain.upcase
  ]
end

.name_sid_hash(names, allow_unresolved = false) ⇒ 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.



191
192
193
194
195
196
197
198
199
200
201
# File 'lib/puppet/util/windows/adsi.rb', line 191

def name_sid_hash(names, allow_unresolved = false)
  return {} if names.nil? || names.empty?

  sids = names.map do |name|
    sid = Puppet::Util::Windows::SID.name_to_principal(name, allow_unresolved)
    raise Puppet::Error.new( _("Could not resolve name: %{name}") % { name: name } ) if !sid
    [sid.sid, sid]
  end

  Hash[ sids ]
end

.parse_name(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.



161
162
163
164
165
166
167
168
169
170
171
# File 'lib/puppet/util/windows/adsi.rb', line 161

def parse_name(name)
  if name =~ /\//
    raise Puppet::Error.new( _("Value must be in DOMAIN\\%{object_class} style syntax") % { object_class: @object_class } )
  end

  matches = name.scan(/((.*)\\)?(.*)/)
  domain = matches[0][1] || '.'
   = matches[0][2]

  return , domain
end

.uri(name, host = '.') ⇒ 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.



156
157
158
159
# File 'lib/puppet/util/windows/adsi.rb', line 156

def uri(name, host = '.')
  host = '.' if (localized_domains << Socket.gethostname.upcase).include?(host.upcase)
  Puppet::Util::Windows::ADSI.uri(name, @object_class, host)
end

Instance Method Details

#[](attribute) ⇒ 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.



275
276
277
278
# File 'lib/puppet/util/windows/adsi.rb', line 275

def [](attribute)
  # Setting WIN32OLE.codepage ensures values are returned as UTF-8
  native_object.Get(attribute)
end

#[]=(attribute, 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.



280
281
282
# File 'lib/puppet/util/windows/adsi.rb', line 280

def []=(attribute, value)
  native_object.Put(attribute, value)
end

#commitObject

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.



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/puppet/util/windows/adsi.rb', line 284

def commit
  begin
    native_object.SetInfo
  rescue WIN32OLERuntimeError => e
    # ERROR_BAD_USERNAME 2202L from winerror.h
    if e.message =~ /8007089A/m
      raise Puppet::Error.new(
        _("Puppet is not able to create/delete domain %{object_class} objects with the %{object_class} resource.") % { object_class: object_class },
      )
    end

    raise Puppet::Error.new( _("%{object_class} update failed: %{error}") % { object_class: object_class.capitalize, error: e }, e )
  end
  self
end

#native_objectObject

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.



267
268
269
# File 'lib/puppet/util/windows/adsi.rb', line 267

def native_object
  @native_object ||= Puppet::Util::Windows::ADSI.connect(self.class.uri(*self.class.parse_name(name)))
end

#object_classObject

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.



259
260
261
# File 'lib/puppet/util/windows/adsi.rb', line 259

def object_class
  self.class.object_class
end

#sidObject

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.



271
272
273
# File 'lib/puppet/util/windows/adsi.rb', line 271

def sid
  @sid ||= Puppet::Util::Windows::SID.octet_string_to_principal(native_object.objectSID)
end

#uriObject

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.



263
264
265
# File 'lib/puppet/util/windows/adsi.rb', line 263

def uri
  self.class.uri(sid., sid.domain)
end