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_flagand
https://support.microsoft.com/en-us/help/305144/how-to-use-the-useraccountcontrol-flags-to-manipulate-user-account-profor 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.
312 313 314 315 316 |
# File 'lib/puppet/util/windows/adsi.rb', line 312 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.
541 542 543 |
# File 'lib/puppet/util/windows/adsi.rb', line 541 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.
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
# File 'lib/puppet/util/windows/adsi.rb', line 490 def self.current_user_name user_name = String.new 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.
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 |
# File 'lib/puppet/util/windows/adsi.rb', line 522 def self.current_user_name_with_format(format) user_name = String.new 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.
545 546 547 |
# File 'lib/puppet/util/windows/adsi.rb', line 545 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.
304 305 306 |
# File 'lib/puppet/util/windows/adsi.rb', line 304 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.
308 309 310 |
# File 'lib/puppet/util/windows/adsi.rb', line 308 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.
323 324 325 326 327 328 329 |
# File 'lib/puppet/util/windows/adsi.rb', line 323 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.
365 366 367 368 |
# File 'lib/puppet/util/windows/adsi.rb', line 365 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.
350 351 352 353 354 |
# File 'lib/puppet/util/windows/adsi.rb', line 350 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.
468 469 470 |
# File 'lib/puppet/util/windows/adsi.rb', line 468 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.
479 480 481 482 483 484 485 486 |
# File 'lib/puppet/util/windows/adsi.rb', line 479 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.
375 376 377 |
# File 'lib/puppet/util/windows/adsi.rb', line 375 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.
341 342 343 344 345 346 347 348 |
# File 'lib/puppet/util/windows/adsi.rb', line 341 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.
472 473 474 475 476 477 |
# File 'lib/puppet/util/windows/adsi.rb', line 472 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.
448 449 450 451 452 453 454 455 456 457 458 |
# File 'lib/puppet/util/windows/adsi.rb', line 448 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.
331 332 333 334 335 336 337 338 339 |
# File 'lib/puppet/util/windows/adsi.rb', line 331 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.
319 320 321 |
# File 'lib/puppet/util/windows/adsi.rb', line 319 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.
357 358 359 360 361 |
# File 'lib/puppet/util/windows/adsi.rb', line 357 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.
370 371 372 373 |
# File 'lib/puppet/util/windows/adsi.rb', line 370 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.
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 |
# File 'lib/puppet/util/windows/adsi.rb', line 383 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.
460 461 462 |
# File 'lib/puppet/util/windows/adsi.rb', line 460 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.
464 465 466 |
# File 'lib/puppet/util/windows/adsi.rb', line 464 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.
440 441 442 443 |
# File 'lib/puppet/util/windows/adsi.rb', line 440 def userflag_set?(flag) flag_value = ADS_USERFLAGS[flag] || 0 ! (self['UserFlags'] & flag_value).zero? end |