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 312 def create(name) 313 # Windows error 1379: The specified local group already exists. 314 raise Puppet::Error.new(_("Cannot create user if group '%{name}' exists.") % { name: name }) if Puppet::Util::Windows::ADSI::Group.exists? name 315 new(name, Puppet::Util::Windows::ADSI.create(name, @object_class)) 316 end
current_sam_compatible_user_name()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 541 def self.current_sam_compatible_user_name 542 current_user_name_with_format(NameSamCompatible) 543 end
current_user_name()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 490 def self.current_user_name 491 user_name = String.new 492 max_length = MAX_USERNAME_LENGTH + 1 # NULL terminated 493 FFI::MemoryPointer.new(max_length * 2) do |buffer| # wide string 494 FFI::MemoryPointer.new(:dword, 1) do |buffer_size| 495 buffer_size.write_dword(max_length) # length in TCHARs 496 497 if GetUserNameW(buffer, buffer_size) == FFI::WIN32_FALSE 498 raise Puppet::Util::Windows::Error.new(_("Failed to get user name")) 499 end 500 # buffer_size includes trailing NULL 501 user_name = buffer.read_wide_string(buffer_size.read_dword - 1) 502 end 503 end 504 505 user_name 506 end
current_user_name_with_format(format)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 522 def self.current_user_name_with_format(format) 523 user_name = String.new 524 max_length = 1024 525 526 FFI::MemoryPointer.new(:lpwstr, max_length * 2 + 1) do |buffer| 527 FFI::MemoryPointer.new(:dword, 1) do |buffer_size| 528 buffer_size.write_dword(max_length + 1) 529 530 if GetUserNameExW(format.to_i, buffer, buffer_size) == FFI::WIN32_FALSE 531 raise Puppet::Util::Windows::Error.new(_("Failed to get user name"), FFI.errno) 532 end 533 534 user_name = buffer.read_wide_string(buffer_size.read_dword).chomp 535 end 536 end 537 538 user_name 539 end
current_user_sid()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 545 def self.current_user_sid 546 Puppet::Util::Windows::SID.name_to_principal(current_user_name) 547 end
list_all()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 304 def list_all 305 Puppet::Util::Windows::ADSI.execquery('select name from win32_useraccount where localaccount = "TRUE"') 306 end
logon(name, password)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 308 def logon(name, password) 309 Puppet::Util::Windows::User.password_is?(name, password) 310 end
Public Instance Methods
add_flag(flag_name, value)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 323 def add_flag(flag_name, value) 324 flag = native_object.Get(flag_name) rescue 0 325 326 native_object.Put(flag_name, flag | value) 327 328 commit 329 end
add_group_sids(*sids)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 365 def add_group_sids(*sids) 366 group_names = sids.map { |s| s.domain_account } 367 add_to_groups(*group_names) 368 end
add_to_groups(*group_names)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 350 def add_to_groups(*group_names) 351 group_names.each do |group_name| 352 Puppet::Util::Windows::ADSI::Group.new(group_name).add_member_sids(sid) 353 end 354 end
Also aliased as: add_to_group
disabled?()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 468 def disabled? 469 userflag_set?(:ADS_UF_ACCOUNTDISABLE) 470 end
expired?()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 479 def expired? 480 expires = native_object.Get('AccountExpirationDate') 481 expires && expires < Time.now 482 rescue WIN32OLERuntimeError => e 483 # This OLE error code indicates the property can't be found in the cache 484 raise e unless e.message =~ /8000500D/m 485 false 486 end
group_sids()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 375 def group_sids 376 self.class.get_sids(native_object.Groups) 377 end
groups()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 341 def groups 342 # https://msdn.microsoft.com/en-us/library/aa746342.aspx 343 # WIN32OLE objects aren't enumerable, so no map 344 groups = [] 345 # Setting WIN32OLE.codepage ensures values are returned as UTF-8 346 native_object.Groups.each {|g| groups << g.Name} rescue nil 347 groups 348 end
locked_out?()
click to toggle source
# File lib/puppet/util/windows/adsi.rb 472 def locked_out? 473 # Note that the LOCKOUT flag is known to be inaccurate when using the 474 # LDAP IADsUser provider, but this class consistently uses the WinNT 475 # provider, which is expected to be accurate. 476 userflag_set?(:ADS_UF_LOCKOUT) 477 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 448 def op_userflags(*flags, &block) 449 # Avoid an unnecessary set + commit operation. 450 return if flags.empty? 451 452 unrecognized_flags = flags.reject { |flag| ADS_USERFLAGS.keys.include?(flag) } 453 unless unrecognized_flags.empty? 454 raise ArgumentError, _("Unrecognized ADS UserFlags: %{unrecognized_flags}") % { unrecognized_flags: unrecognized_flags.join(', ') } 455 end 456 457 self['UserFlags'] = flags.inject(self['UserFlags'], &block) 458 end
password=(password)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 331 def password=(password) 332 if !password.nil? 333 native_object.SetPassword(password) 334 commit 335 end 336 337 fADS_UF_DONT_EXPIRE_PASSWD = 0x10000 338 add_flag("UserFlags", fADS_UF_DONT_EXPIRE_PASSWD) 339 end
password_is?(password)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 319 def password_is?(password) 320 self.class.logon(name, password) 321 end
remove_from_groups(*group_names)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 357 def remove_from_groups(*group_names) 358 group_names.each do |group_name| 359 Puppet::Util::Windows::ADSI::Group.new(group_name).remove_member_sids(sid) 360 end 361 end
Also aliased as: remove_from_group
remove_group_sids(*sids)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 370 def remove_group_sids(*sids) 371 group_names = sids.map { |s| s.domain_account } 372 remove_from_groups(*group_names) 373 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 383 def set_groups(desired_groups, minimum = true) 384 return if desired_groups.nil? 385 386 desired_groups = desired_groups.split(',').map(&:strip) 387 388 current_hash = Hash[ self.group_sids.map { |sid| [sid.sid, sid] } ] 389 desired_hash = self.class.name_sid_hash(desired_groups) 390 391 # First we add the user to all the groups it should be in but isn't 392 if !desired_groups.empty? 393 groups_to_add = (desired_hash.keys - current_hash.keys).map { |sid| desired_hash[sid] } 394 add_group_sids(*groups_to_add) 395 end 396 397 # Then we remove the user from all groups it is in but shouldn't be, if 398 # that's been requested 399 if !minimum 400 if desired_hash.empty? 401 groups_to_remove = current_hash.values 402 else 403 groups_to_remove = (current_hash.keys - desired_hash.keys).map { |sid| current_hash[sid] } 404 end 405 406 remove_group_sids(*groups_to_remove) 407 end 408 end
set_userflags(*flags)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 460 def set_userflags(*flags) 461 op_userflags(*flags) { |userflags, flag| userflags | ADS_USERFLAGS[flag] } 462 end
unset_userflags(*flags)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 464 def unset_userflags(*flags) 465 op_userflags(*flags) { |userflags, flag| userflags & ~ADS_USERFLAGS[flag] } 466 end
userflag_set?(flag)
click to toggle source
# File lib/puppet/util/windows/adsi.rb 440 def userflag_set?(flag) 441 flag_value = ADS_USERFLAGS[flag] || 0 442 ! (self['UserFlags'] & flag_value).zero? 443 end