Class: Puppet::Util::Windows::ADSI::User Private
- Inherits:
-
ADSIObject
- Object
- ADSIObject
- Puppet::Util::Windows::ADSI::User
- Extended by:
- FFI::Library
- Defined in:
- lib/puppet/util/windows.rb,
lib/puppet/util/windows/adsi.rb
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.
Constant Summary collapse
- ADS_USERFLAGS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
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.
{ ADS_UF_SCRIPT: 0x0001, ADS_UF_ACCOUNTDISABLE: 0x0002, ADS_UF_HOMEDIR_REQUIRED: 0x0008, ADS_UF_LOCKOUT: 0x0010, ADS_UF_PASSWD_NOTREQD: 0x0020, ADS_UF_PASSWD_CANT_CHANGE: 0x0040, ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED: 0x0080, ADS_UF_TEMP_DUPLICATE_ACCOUNT: 0x0100, ADS_UF_NORMAL_ACCOUNT: 0x0200, ADS_UF_INTERDOMAIN_TRUST_ACCOUNT: 0x0800, ADS_UF_WORKSTATION_TRUST_ACCOUNT: 0x1000, ADS_UF_SERVER_TRUST_ACCOUNT: 0x2000, ADS_UF_DONT_EXPIRE_PASSWD: 0x10000, ADS_UF_MNS_LOGON_ACCOUNT: 0x20000, ADS_UF_SMARTCARD_REQUIRED: 0x40000, ADS_UF_TRUSTED_FOR_DELEGATION: 0x80000, ADS_UF_NOT_DELEGATED: 0x100000, ADS_UF_USE_DES_KEY_ONLY: 0x200000, ADS_UF_DONT_REQUIRE_PREAUTH: 0x400000, ADS_UF_PASSWORD_EXPIRED: 0x800000, ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: 0x1000000 }
- MAX_USERNAME_LENGTH =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
UNLEN from lmcons.h - stackoverflow.com/a/2155176
256
- NameUnknown =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
docs.microsoft.com/en-us/windows/win32/api/secext/ne-secext-extended_name_format
0
- NameFullyQualifiedDN =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
1
- NameSamCompatible =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
2
- NameDisplay =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
3
- NameUniqueId =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
6
- NameCanonical =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
7
- NameUserPrincipal =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
8
- NameCanonicalEx =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
9
- NameServicePrincipal =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
10
- NameDnsDomain =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
12
- NameGivenName =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
13
- NameSurname =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
14
Instance Attribute Summary
Attributes inherited from ADSIObject
Class Method Summary collapse
- .create(name) ⇒ Object private
- .current_sam_compatible_user_name ⇒ Object private
- .current_user_name ⇒ Object private
- .current_user_name_with_format(format) ⇒ Object private
- .current_user_sid ⇒ Object private
- .list_all ⇒ Object private
- .logon(name, password) ⇒ Object private
Instance Method Summary collapse
- #add_flag(flag_name, value) ⇒ Object private
- #add_group_sids(*sids) ⇒ Object private
- #add_to_groups(*group_names) ⇒ Object (also: #add_to_group) private
- #disabled? ⇒ Boolean private
- #expired? ⇒ Boolean private
- #group_sids ⇒ Object private
- #groups ⇒ Object private
- #locked_out? ⇒ Boolean private
-
#op_userflags(*flags, &block) ⇒ Object
private
Common helper for set_userflags and unset_userflags.
- #password=(password) ⇒ Object private
- #password_is?(password) ⇒ Boolean private
- #remove_from_groups(*group_names) ⇒ Object (also: #remove_from_group) private
- #remove_group_sids(*sids) ⇒ Object private
-
#set_groups(desired_groups, minimum = true) ⇒ Object
private
TODO: This code’s pretty similar to set_members in the Group class.
- #set_userflags(*flags) ⇒ Object private
- #unset_userflags(*flags) ⇒ Object private
- #userflag_set?(flag) ⇒ Boolean private
Methods inherited from ADSIObject
#[], #[]=, #commit, delete, each, exists?, get_sids, #initialize, localized_domains, name_sid_hash, #native_object, #object_class, parse_name, #sid, #uri, uri
Constructor Details
This class inherits a constructor from Puppet::Util::Windows::ADSI::ADSIObject
Class Method Details
.create(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.
318 319 320 321 322 |
# File 'lib/puppet/util/windows/adsi.rb', line 318 def create(name) # Windows error 1379: The specified local group already exists. raise Puppet::Error.new(_("Cannot create user if group '%{name}' exists.") % { name: name }) if Puppet::Util::Windows::ADSI::Group.exists? name new(name, Puppet::Util::Windows::ADSI.create(name, @object_class)) end |
.current_sam_compatible_user_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.
547 548 549 |
# File 'lib/puppet/util/windows/adsi.rb', line 547 def self.current_sam_compatible_user_name current_user_name_with_format(NameSamCompatible) end |
.current_user_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.
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
# File 'lib/puppet/util/windows/adsi.rb', line 496 def self.current_user_name user_name = '' max_length = MAX_USERNAME_LENGTH + 1 # NULL terminated FFI::MemoryPointer.new(max_length * 2) do |buffer| # wide string FFI::MemoryPointer.new(:dword, 1) do |buffer_size| buffer_size.write_dword(max_length) # length in TCHARs if GetUserNameW(buffer, buffer_size) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error.new(_("Failed to get user name")) end # buffer_size includes trailing NULL user_name = buffer.read_wide_string(buffer_size.read_dword - 1) end end user_name end |
.current_user_name_with_format(format) ⇒ 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.
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
# File 'lib/puppet/util/windows/adsi.rb', line 528 def self.current_user_name_with_format(format) user_name = '' max_length = 1024 FFI::MemoryPointer.new(:lpwstr, max_length * 2 + 1) do |buffer| FFI::MemoryPointer.new(:dword, 1) do |buffer_size| buffer_size.write_dword(max_length + 1) if GetUserNameExW(format.to_i, buffer, buffer_size) == FFI::WIN32_FALSE raise Puppet::Util::Windows::Error.new(_("Failed to get user name"), FFI.errno) end user_name = buffer.read_wide_string(buffer_size.read_dword).chomp end end user_name end |
.current_user_sid ⇒ 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.
551 552 553 |
# File 'lib/puppet/util/windows/adsi.rb', line 551 def self.current_user_sid Puppet::Util::Windows::SID.name_to_principal(current_user_name) end |
.list_all ⇒ 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.
310 311 312 |
# File 'lib/puppet/util/windows/adsi.rb', line 310 def list_all Puppet::Util::Windows::ADSI.execquery('select name from win32_useraccount where localaccount = "TRUE"') end |
.logon(name, password) ⇒ 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.
314 315 316 |
# File 'lib/puppet/util/windows/adsi.rb', line 314 def logon(name, password) Puppet::Util::Windows::User.password_is?(name, password) end |
Instance Method Details
#add_flag(flag_name, 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.
329 330 331 332 333 334 335 |
# File 'lib/puppet/util/windows/adsi.rb', line 329 def add_flag(flag_name, value) flag = native_object.Get(flag_name) rescue 0 native_object.Put(flag_name, flag | value) commit end |
#add_group_sids(*sids) ⇒ 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.
371 372 373 374 |
# File 'lib/puppet/util/windows/adsi.rb', line 371 def add_group_sids(*sids) group_names = sids.map { |s| s.domain_account } add_to_groups(*group_names) end |
#add_to_groups(*group_names) ⇒ Object Also known as: add_to_group
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.
356 357 358 359 360 |
# File 'lib/puppet/util/windows/adsi.rb', line 356 def add_to_groups(*group_names) group_names.each do |group_name| Puppet::Util::Windows::ADSI::Group.new(group_name).add_member_sids(sid) end end |
#disabled? ⇒ 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.
474 475 476 |
# File 'lib/puppet/util/windows/adsi.rb', line 474 def disabled? userflag_set?(:ADS_UF_ACCOUNTDISABLE) end |
#expired? ⇒ 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.
485 486 487 488 489 490 491 492 |
# File 'lib/puppet/util/windows/adsi.rb', line 485 def expired? expires = native_object.Get('AccountExpirationDate') expires && expires < Time.now rescue WIN32OLERuntimeError => e # This OLE error code indicates the property can't be found in the cache raise e unless e. =~ /8000500D/m false end |
#group_sids ⇒ 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.
381 382 383 |
# File 'lib/puppet/util/windows/adsi.rb', line 381 def group_sids self.class.get_sids(native_object.Groups) end |
#groups ⇒ 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.
347 348 349 350 351 352 353 354 |
# File 'lib/puppet/util/windows/adsi.rb', line 347 def groups # https://msdn.microsoft.com/en-us/library/aa746342.aspx # WIN32OLE objects aren't enumerable, so no map groups = [] # Setting WIN32OLE.codepage ensures values are returned as UTF-8 native_object.Groups.each {|g| groups << g.Name} rescue nil groups end |
#locked_out? ⇒ 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.
478 479 480 481 482 483 |
# File 'lib/puppet/util/windows/adsi.rb', line 478 def locked_out? # Note that the LOCKOUT flag is known to be inaccurate when using the # LDAP IADsUser provider, but this class consistently uses the WinNT # provider, which is expected to be accurate. userflag_set?(:ADS_UF_LOCKOUT) end |
#op_userflags(*flags, &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.
Common helper for set_userflags and unset_userflags.
454 455 456 457 458 459 460 461 462 463 464 |
# File 'lib/puppet/util/windows/adsi.rb', line 454 def op_userflags(*flags, &block) # Avoid an unnecessary set + commit operation. return if flags.empty? unrecognized_flags = flags.reject { |flag| ADS_USERFLAGS.keys.include?(flag) } unless unrecognized_flags.empty? raise ArgumentError, _("Unrecognized ADS UserFlags: %{unrecognized_flags}") % { unrecognized_flags: unrecognized_flags.join(', ') } end self['UserFlags'] = flags.inject(self['UserFlags'], &block) end |
#password=(password) ⇒ 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.
337 338 339 340 341 342 343 344 345 |
# File 'lib/puppet/util/windows/adsi.rb', line 337 def password=(password) if !password.nil? native_object.SetPassword(password) commit end fADS_UF_DONT_EXPIRE_PASSWD = 0x10000 add_flag("UserFlags", fADS_UF_DONT_EXPIRE_PASSWD) end |
#password_is?(password) ⇒ 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.
325 326 327 |
# File 'lib/puppet/util/windows/adsi.rb', line 325 def password_is?(password) self.class.logon(name, password) end |
#remove_from_groups(*group_names) ⇒ Object Also known as: remove_from_group
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.
363 364 365 366 367 |
# File 'lib/puppet/util/windows/adsi.rb', line 363 def remove_from_groups(*group_names) group_names.each do |group_name| Puppet::Util::Windows::ADSI::Group.new(group_name).remove_member_sids(sid) end end |
#remove_group_sids(*sids) ⇒ 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.
376 377 378 379 |
# File 'lib/puppet/util/windows/adsi.rb', line 376 def remove_group_sids(*sids) group_names = sids.map { |s| s.domain_account } remove_from_groups(*group_names) end |
#set_groups(desired_groups, minimum = true) ⇒ 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.
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.
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 |
# File 'lib/puppet/util/windows/adsi.rb', line 389 def set_groups(desired_groups, minimum = true) return if desired_groups.nil? desired_groups = desired_groups.split(',').map(&:strip) current_hash = Hash[ self.group_sids.map { |sid| [sid.sid, sid] } ] desired_hash = self.class.name_sid_hash(desired_groups) # First we add the user to all the groups it should be in but isn't if !desired_groups.empty? groups_to_add = (desired_hash.keys - current_hash.keys).map { |sid| desired_hash[sid] } add_group_sids(*groups_to_add) end # Then we remove the user from all groups it is in but shouldn't be, if # that's been requested if !minimum if desired_hash.empty? groups_to_remove = current_hash.values else groups_to_remove = (current_hash.keys - desired_hash.keys).map { |sid| current_hash[sid] } end remove_group_sids(*groups_to_remove) end end |
#set_userflags(*flags) ⇒ 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.
466 467 468 |
# File 'lib/puppet/util/windows/adsi.rb', line 466 def set_userflags(*flags) op_userflags(*flags) { |userflags, flag| userflags | ADS_USERFLAGS[flag] } end |
#unset_userflags(*flags) ⇒ 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.
470 471 472 |
# File 'lib/puppet/util/windows/adsi.rb', line 470 def unset_userflags(*flags) op_userflags(*flags) { |userflags, flag| userflags & ~ADS_USERFLAGS[flag] } end |
#userflag_set?(flag) ⇒ 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.
446 447 448 449 |
# File 'lib/puppet/util/windows/adsi.rb', line 446 def userflag_set?(flag) flag_value = ADS_USERFLAGS[flag] || 0 ! (self['UserFlags'] & flag_value).zero? end |