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

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

Overview

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

Methods included from Enumerable

uniq

Constructor Details

#initialize(name, native_object = nil) ⇒ ADSIObject


216
217
218
219
# File 'lib/puppet/util/windows/adsi.rb', line 216

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

Class Attribute Details

.object_classObject (readonly)

Is either 'user' or 'group'


117
118
119
# File 'lib/puppet/util/windows/adsi.rb', line 117

def object_class
  @object_class
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name


215
216
217
# File 'lib/puppet/util/windows/adsi.rb', line 215

def name
  @name
end

Class Method Details

.delete(name) ⇒ Object


171
172
173
# File 'lib/puppet/util/windows/adsi.rb', line 171

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

.each(&block) ⇒ Object


203
204
205
206
207
208
209
210
211
212
# File 'lib/puppet/util/windows/adsi.rb', line 203

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


175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/puppet/util/windows/adsi.rb', line 175

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
    return true if sid. == "SidType#{@object_class.capitalize}".to_sym

    # '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.account}"
  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

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


149
150
151
152
153
154
155
156
# File 'lib/puppet/util/windows/adsi.rb', line 149

def get_sids(adsi_child_collection)
  sids = []
  adsi_child_collection.each do |m|
    sids << Puppet::Util::Windows::SID.ads_to_principal(m)
  end

  sids
end

.list_allObject

Raises:

  • (NotImplementedError)

199
200
201
# File 'lib/puppet/util/windows/adsi.rb', line 199

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

.localized_domainsObject


119
120
121
122
123
124
125
126
127
128
# File 'lib/puppet/util/windows/adsi.rb', line 119

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) ⇒ Object


158
159
160
161
162
163
164
165
166
167
168
# File 'lib/puppet/util/windows/adsi.rb', line 158

def name_sid_hash(names)
  return {} if names.nil? || names.empty?

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

  Hash[ sids ]
end

.parse_name(name) ⇒ Object


135
136
137
138
139
140
141
142
143
144
145
# File 'lib/puppet/util/windows/adsi.rb', line 135

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


130
131
132
133
# File 'lib/puppet/util/windows/adsi.rb', line 130

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


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

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

#[]=(attribute, value) ⇒ Object


242
243
244
# File 'lib/puppet/util/windows/adsi.rb', line 242

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

#commitObject


246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/puppet/util/windows/adsi.rb', line 246

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


229
230
231
# File 'lib/puppet/util/windows/adsi.rb', line 229

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

#object_classObject


221
222
223
# File 'lib/puppet/util/windows/adsi.rb', line 221

def object_class
  self.class.object_class
end

#sidObject


233
234
235
# File 'lib/puppet/util/windows/adsi.rb', line 233

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

#uriObject


225
226
227
# File 'lib/puppet/util/windows/adsi.rb', line 225

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