class Puppet::Util::Windows::ADSI::User
Constants
- ADS_USERFLAGS
Declare all of the available user flags on the system. Note that ADS_UF is read as ADS_UserFlag
https://docs.microsoft.com/en-us/windows/desktop/api/iads/ne-iads-ads_user_flag
and
https://support.microsoft.com/en-us/help/305144/how-to-use-the-useraccountcontrol-flags-to-manipulate-user-account-pro
for the flag values.
- MAX_USERNAME_LENGTH
UNLEN from lmcons.h - stackoverflow.com/a/2155176
- NameCanonical
- NameCanonicalEx
- NameDisplay
- NameDnsDomain
- NameFullyQualifiedDN
- NameGivenName
- NameSamCompatible
- NameServicePrincipal
- NameSurname
- NameUniqueId
- NameUnknown
docs.microsoft.com/en-us/windows/win32/api/secext/ne-secext-extended_name_format
- NameUserPrincipal
Public Class Methods
create(name)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 311 def create(name) 312 # Windows error 1379: The specified local group already exists. 313 raise Puppet::Error.new(_("Cannot create user if group '%{name}' exists.") % { name: name }) if Puppet::Util::Windows::ADSI::Group.exists? name 314 new(name, Puppet::Util::Windows::ADSI.create(name, @object_class)) 315 end
current_sam_compatible_user_name()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 540 def self.current_sam_compatible_user_name 541 current_user_name_with_format(NameSamCompatible) 542 end
current_user_name()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 489 def self.current_user_name 490 user_name = '' 491 max_length = MAX_USERNAME_LENGTH + 1 # NULL terminated 492 FFI::MemoryPointer.new(max_length * 2) do |buffer| # wide string 493 FFI::MemoryPointer.new(:dword, 1) do |buffer_size| 494 buffer_size.write_dword(max_length) # length in TCHARs 495 496 if GetUserNameW(buffer, buffer_size) == FFI::WIN32_FALSE 497 raise Puppet::Util::Windows::Error.new(_("Failed to get user name")) 498 end 499 # buffer_size includes trailing NULL 500 user_name = buffer.read_wide_string(buffer_size.read_dword - 1) 501 end 502 end 503 504 user_name 505 end
current_user_name_with_format(format)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 521 def self.current_user_name_with_format(format) 522 user_name = '' 523 max_length = 1024 524 525 FFI::MemoryPointer.new(:lpwstr, max_length * 2 + 1) do |buffer| 526 FFI::MemoryPointer.new(:dword, 1) do |buffer_size| 527 buffer_size.write_dword(max_length + 1) 528 529 if GetUserNameExW(format.to_i, buffer, buffer_size) == FFI::WIN32_FALSE 530 raise Puppet::Util::Windows::Error.new(_("Failed to get user name"), FFI.errno) 531 end 532 533 user_name = buffer.read_wide_string(buffer_size.read_dword).chomp 534 end 535 end 536 537 user_name 538 end
current_user_sid()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 544 def self.current_user_sid 545 Puppet::Util::Windows::SID.name_to_principal(current_user_name) 546 end
list_all()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 303 def list_all 304 Puppet::Util::Windows::ADSI.execquery('select name from win32_useraccount where localaccount = "TRUE"') 305 end
logon(name, password)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 307 def logon(name, password) 308 Puppet::Util::Windows::User.password_is?(name, password) 309 end
Public Instance Methods
add_flag(flag_name, value)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 322 def add_flag(flag_name, value) 323 flag = native_object.Get(flag_name) rescue 0 324 325 native_object.Put(flag_name, flag | value) 326 327 commit 328 end
add_group_sids(*sids)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 364 def add_group_sids(*sids) 365 group_names = sids.map { |s| s.domain_account } 366 add_to_groups(*group_names) 367 end
add_to_groups(*group_names)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 349 def add_to_groups(*group_names) 350 group_names.each do |group_name| 351 Puppet::Util::Windows::ADSI::Group.new(group_name).add_member_sids(sid) 352 end 353 end
Also aliased as: add_to_group
disabled?()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 467 def disabled? 468 userflag_set?(:ADS_UF_ACCOUNTDISABLE) 469 end
expired?()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 478 def expired? 479 expires = native_object.Get('AccountExpirationDate') 480 expires && expires < Time.now 481 rescue WIN32OLERuntimeError => e 482 # This OLE error code indicates the property can't be found in the cache 483 raise e unless e.message =~ /8000500D/m 484 false 485 end
group_sids()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 374 def group_sids 375 self.class.get_sids(native_object.Groups) 376 end
groups()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 340 def groups 341 # https://msdn.microsoft.com/en-us/library/aa746342.aspx 342 # WIN32OLE objects aren't enumerable, so no map 343 groups = [] 344 # Setting WIN32OLE.codepage ensures values are returned as UTF-8 345 native_object.Groups.each {|g| groups << g.Name} rescue nil 346 groups 347 end
locked_out?()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 471 def locked_out? 472 # Note that the LOCKOUT flag is known to be inaccurate when using the 473 # LDAP IADsUser provider, but this class consistently uses the WinNT 474 # provider, which is expected to be accurate. 475 userflag_set?(:ADS_UF_LOCKOUT) 476 end
op_userflags(*flags, &block)
click to toggle source
Common helper for set_userflags
and unset_userflags.
@api private
# File lib/puppet/util/windows/adsi.rb 447 def op_userflags(*flags, &block) 448 # Avoid an unnecessary set + commit operation. 449 return if flags.empty? 450 451 unrecognized_flags = flags.reject { |flag| ADS_USERFLAGS.keys.include?(flag) } 452 unless unrecognized_flags.empty? 453 raise ArgumentError, _("Unrecognized ADS UserFlags: %{unrecognized_flags}") % { unrecognized_flags: unrecognized_flags.join(', ') } 454 end 455 456 self['UserFlags'] = flags.inject(self['UserFlags'], &block) 457 end
password=(password)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 330 def password=(password) 331 if !password.nil? 332 native_object.SetPassword(password) 333 commit 334 end 335 336 fADS_UF_DONT_EXPIRE_PASSWD = 0x10000 337 add_flag("UserFlags", fADS_UF_DONT_EXPIRE_PASSWD) 338 end
password_is?(password)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 318 def password_is?(password) 319 self.class.logon(name, password) 320 end
remove_from_groups(*group_names)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 356 def remove_from_groups(*group_names) 357 group_names.each do |group_name| 358 Puppet::Util::Windows::ADSI::Group.new(group_name).remove_member_sids(sid) 359 end 360 end
Also aliased as: remove_from_group
remove_group_sids(*sids)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 369 def remove_group_sids(*sids) 370 group_names = sids.map { |s| s.domain_account } 371 remove_from_groups(*group_names) 372 end
set_groups(desired_groups, minimum = true)
click to toggle source
TODO: This code's pretty similar to set_members in the Group
class. Would be nice to refactor them into the ADSIObject
class at some point. This was not done originally because these use different methods to do stuff that are also aliased to other methods, so the shared code isn't exactly a 1:1 mapping.
# File lib/puppet/util/windows/adsi.rb 382 def set_groups(desired_groups, minimum = true) 383 return if desired_groups.nil? 384 385 desired_groups = desired_groups.split(',').map(&:strip) 386 387 current_hash = Hash[ self.group_sids.map { |sid| [sid.sid, sid] } ] 388 desired_hash = self.class.name_sid_hash(desired_groups) 389 390 # First we add the user to all the groups it should be in but isn't 391 if !desired_groups.empty? 392 groups_to_add = (desired_hash.keys - current_hash.keys).map { |sid| desired_hash[sid] } 393 add_group_sids(*groups_to_add) 394 end 395 396 # Then we remove the user from all groups it is in but shouldn't be, if 397 # that's been requested 398 if !minimum 399 if desired_hash.empty? 400 groups_to_remove = current_hash.values 401 else 402 groups_to_remove = (current_hash.keys - desired_hash.keys).map { |sid| current_hash[sid] } 403 end 404 405 remove_group_sids(*groups_to_remove) 406 end 407 end
set_userflags(*flags)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 459 def set_userflags(*flags) 460 op_userflags(*flags) { |userflags, flag| userflags | ADS_USERFLAGS[flag] } 461 end
unset_userflags(*flags)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 463 def unset_userflags(*flags) 464 op_userflags(*flags) { |userflags, flag| userflags & ~ADS_USERFLAGS[flag] } 465 end
userflag_set?(flag)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 439 def userflag_set?(flag) 440 flag_value = ADS_USERFLAGS[flag] || 0 441 ! (self['UserFlags'] & flag_value).zero? 442 end