Class: Puppet::Util::Windows::ADSI::Group

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

uniq

Methods included from Shared

get_sids, localized_domains, name_sid_hash, parse_name

Constructor Details

#initialize(name, native_group = nil) ⇒ Group

Returns a new instance of Group.



420
421
422
423
# File 'lib/puppet/util/windows/adsi.rb', line 420

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

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



419
420
421
# File 'lib/puppet/util/windows/adsi.rb', line 419

def name
  @name
end

#native_groupObject



418
419
420
# File 'lib/puppet/util/windows/adsi.rb', line 418

def native_group
  @native_group
end

#sidObject (readonly)

Returns the value of attribute sid.



419
420
421
# File 'lib/puppet/util/windows/adsi.rb', line 419

def sid
  @sid
end

Class Method Details

.create(name) ⇒ Object

Raises:



503
504
505
506
507
# File 'lib/puppet/util/windows/adsi.rb', line 503

def self.create(name)
  # Windows error 2224: The account already exists.
  raise Puppet::Error.new( _("Cannot create group if user '%{name}' exists.") % { name: name } ) if Puppet::Util::Windows::ADSI::User.exists? name
  new(name, Puppet::Util::Windows::ADSI.create(name, 'group'))
end

.delete(name) ⇒ Object



531
532
533
# File 'lib/puppet/util/windows/adsi.rb', line 531

def self.delete(name)
  Puppet::Util::Windows::ADSI.delete(name, 'group')
end

.each(&block) ⇒ Object



535
536
537
538
539
540
541
542
543
544
545
546
# File 'lib/puppet/util/windows/adsi.rb', line 535

def self.each(&block)
  wql = Puppet::Util::Windows::ADSI.execquery('select name from win32_group where localaccount = "TRUE"')

  groups = []
  wql.each do |g|
    # Setting WIN32OLE.codepage in the microsoft_windows feature ensures
    # values are returned as UTF-8
    groups << new(g.name)
  end

  groups.each(&block)
end

.exists?(name_or_sid) ⇒ Boolean

Returns:

  • (Boolean)


509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
# File 'lib/puppet/util/windows/adsi.rb', line 509

def self.exists?(name_or_sid)
  well_known = false
  if (sid = Puppet::Util::Windows::SID.name_to_sid_object(name_or_sid))
    return true if sid. == :SidTypeGroup

    # '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

  user = Puppet::Util::Windows::ADSI.connect(Group.uri(*Group.parse_name(name_or_sid)))
  user.Class == 'Group'
rescue
  # special groups like Authenticated Users cannot resolve via moniker like WinNT://./Authenticated Users,group
  # and thus fail to connect - so 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

Instance Method Details

#add_member_sids(*sids) ⇒ Object



454
455
456
457
458
# File 'lib/puppet/util/windows/adsi.rb', line 454

def add_member_sids(*sids)
  sids.each do |sid|
    native_group.Add(Puppet::Util::Windows::ADSI.sid_uri(sid))
  end
end

#commitObject



437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/puppet/util/windows/adsi.rb', line 437

def commit
  begin
    native_group.SetInfo unless native_group.nil?
  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 groups with the group resource."),
        e
      )
    end

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

#member_sidsObject



475
476
477
# File 'lib/puppet/util/windows/adsi.rb', line 475

def member_sids
  self.class.get_sids(native_group.Members)
end

#membersObject



466
467
468
469
470
471
472
473
# File 'lib/puppet/util/windows/adsi.rb', line 466

def members
  # WIN32OLE objects aren't enumerable, so no map
  members = []
  # Setting WIN32OLE.codepage in the microsoft_windows feature ensures
  # values are returned as UTF-8
  native_group.Members.each {|m| members << m.Name}
  members
end

#remove_member_sids(*sids) ⇒ Object



460
461
462
463
464
# File 'lib/puppet/util/windows/adsi.rb', line 460

def remove_member_sids(*sids)
  sids.each do |sid|
    native_group.Remove(Puppet::Util::Windows::ADSI.sid_uri(sid))
  end
end

#set_members(desired_members, inclusive = true) ⇒ Object



479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
# File 'lib/puppet/util/windows/adsi.rb', line 479

def set_members(desired_members, inclusive = true)
  return if desired_members.nil?

  current_hash = Hash[ self.member_sids.map { |sid| [sid.sid, sid] } ]
  desired_hash = self.class.name_sid_hash(desired_members)

  # First we add all missing members
  if !desired_hash.empty?
    members_to_add = (desired_hash.keys - current_hash.keys).map { |sid| desired_hash[sid] }
    add_member_sids(*members_to_add)
  end

  # Then we remove all extra members if inclusive
  if inclusive
    if desired_hash.empty?
      members_to_remove = current_hash.values
    else
      members_to_remove = (current_hash.keys - desired_hash.keys).map { |sid| current_hash[sid] }
    end

    remove_member_sids(*members_to_remove)
  end
end

#uriObject



425
426
427
# File 'lib/puppet/util/windows/adsi.rb', line 425

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