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.
311 312 313 314 315 |
# File 'lib/puppet/util/windows/adsi.rb', line 311 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.
540 541 542 |
# File 'lib/puppet/util/windows/adsi.rb', line 540 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.
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
# File 'lib/puppet/util/windows/adsi.rb', line 489 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.
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
# File 'lib/puppet/util/windows/adsi.rb', line 521 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.
544 545 546 |
# File 'lib/puppet/util/windows/adsi.rb', line 544 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.
303 304 305 |
# File 'lib/puppet/util/windows/adsi.rb', line 303 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.
307 308 309 |
# File 'lib/puppet/util/windows/adsi.rb', line 307 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.
322 323 324 325 326 327 328 |
# File 'lib/puppet/util/windows/adsi.rb', line 322 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.
364 365 366 367 |
# File 'lib/puppet/util/windows/adsi.rb', line 364 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.
349 350 351 352 353 |
# File 'lib/puppet/util/windows/adsi.rb', line 349 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.
467 468 469 |
# File 'lib/puppet/util/windows/adsi.rb', line 467 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.
478 479 480 481 482 483 484 485 |
# File 'lib/puppet/util/windows/adsi.rb', line 478 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.
374 375 376 |
# File 'lib/puppet/util/windows/adsi.rb', line 374 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.
340 341 342 343 344 345 346 347 |
# File 'lib/puppet/util/windows/adsi.rb', line 340 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.
471 472 473 474 475 476 |
# File 'lib/puppet/util/windows/adsi.rb', line 471 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.
447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/puppet/util/windows/adsi.rb', line 447 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.
330 331 332 333 334 335 336 337 338 |
# File 'lib/puppet/util/windows/adsi.rb', line 330 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.
318 319 320 |
# File 'lib/puppet/util/windows/adsi.rb', line 318 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.
356 357 358 359 360 |
# File 'lib/puppet/util/windows/adsi.rb', line 356 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.
369 370 371 372 |
# File 'lib/puppet/util/windows/adsi.rb', line 369 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.
382 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 |
# File 'lib/puppet/util/windows/adsi.rb', line 382 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.
459 460 461 |
# File 'lib/puppet/util/windows/adsi.rb', line 459 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.
463 464 465 |
# File 'lib/puppet/util/windows/adsi.rb', line 463 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.
439 440 441 442 |
# File 'lib/puppet/util/windows/adsi.rb', line 439 def userflag_set?(flag) flag_value = ADS_USERFLAGS[flag] || 0 ! (self['UserFlags'] & flag_value).zero? end |