Module: RubySMB::Dcerpc::Samr

Defined in:
lib/ruby_smb/dcerpc/samr.rb,
lib/ruby_smb/dcerpc/samr/rpc_sid.rb,
lib/ruby_smb/dcerpc/samr/samr_connect_request.rb,
lib/ruby_smb/dcerpc/samr/samr_connect_response.rb,
lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb,
lib/ruby_smb/dcerpc/samr/samr_open_group_request.rb,
lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb,
lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb,
lib/ruby_smb/dcerpc/samr/sampr_domain_info_buffer.rb,
lib/ruby_smb/dcerpc/samr/samr_delete_user_request.rb,
lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb,
lib/ruby_smb/dcerpc/samr/samr_open_group_response.rb,
lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb,
lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb,
lib/ruby_smb/dcerpc/samr/samr_delete_user_response.rb,
lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb,
lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb,
lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb,
lib/ruby_smb/dcerpc/samr/samr_change_password_user_request.rb,
lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb,
lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb,
lib/ruby_smb/dcerpc/samr/samr_get_members_in_group_request.rb,
lib/ruby_smb/dcerpc/samr/samr_change_password_user_response.rb,
lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb,
lib/ruby_smb/dcerpc/samr/samr_get_members_in_group_response.rb,
lib/ruby_smb/dcerpc/samr/samr_set_information_user2_request.rb,
lib/ruby_smb/dcerpc/samr/samr_create_user2_in_domain_request.rb,
lib/ruby_smb/dcerpc/samr/samr_lookup_names_in_domain_request.rb,
lib/ruby_smb/dcerpc/samr/samr_set_information_user2_response.rb,
lib/ruby_smb/dcerpc/samr/samr_create_user2_in_domain_response.rb,
lib/ruby_smb/dcerpc/samr/samr_lookup_names_in_domain_response.rb,
lib/ruby_smb/dcerpc/samr/samr_query_information_domain_request.rb,
lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb,
lib/ruby_smb/dcerpc/samr/samr_query_information_domain_response.rb,
lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb,
lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb,
lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb,
lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_request.rb,
lib/ruby_smb/dcerpc/samr/samr_unicode_change_password_user2_response.rb,
lib/ruby_smb/dcerpc/samr/samr_enumerate_domains_in_sam_server_request.rb,
lib/ruby_smb/dcerpc/samr/samr_enumerate_domains_in_sam_server_response.rb

Defined Under Namespace

Classes: EncryptedNtOwfPassword, GroupMembership, KerbKeyDataNew, KerbStoredCredentialNew, PencryptedNtOwfPassword, PgroupMembershipArray, PrpcSid, PsamprDomainInfoBuffer, PsamprEncryptedUserPassword, PsamprEnumerationBuffer, PsamprGetGroupsBuffer, PsamprGetMembersBuffer, PsamprRidEnumerationArray, PsamprServerName, PsamprSidInformation, PsamprSidInformationArray, PulongArray, RpcShortBlob, RpcSid, RpcSidIdentifierAuthority, SamprDomainGeneralInformation, SamprDomainGeneralInformation2, SamprDomainInfoBuffer, SamprDomainLockoutInformation, SamprDomainLogoffInformation, SamprDomainModifiedInformation, SamprDomainModifiedInformation2, SamprDomainNameInformation, SamprDomainOemInformation, SamprDomainPasswordInformation, SamprDomainReplicationInformation, SamprDomainServerRoleInformation, SamprDomainStateInformation, SamprEncryptedUserPassword, SamprEncryptedUserPasswordNew, SamprEnumerationBuffer, SamprGetGroupsBuffer, SamprGetMembersBuffer, SamprHandle, SamprLogonHours, SamprPsidArray, SamprRidEnumeration, SamprRidEnumerationArray, SamprSidInformation, SamprSrSecurityDescriptor, SamprUlongArray, SamprUserAllInformation, SamprUserInfoBuffer, SamprUserInternal1Information, SamprUserInternal4InformationNew, SamrChangePasswordUserRequest, SamrChangePasswordUserResponse, SamrCloseHandleRequest, SamrCloseHandleResponse, SamrConnectRequest, SamrConnectResponse, SamrCreateUser2InDomainRequest, SamrCreateUser2InDomainResponse, SamrDeleteUserRequest, SamrDeleteUserResponse, SamrEnumerateDomainsInSamServerRequest, SamrEnumerateDomainsInSamServerResponse, SamrEnumerateUsersInDomainRequest, SamrEnumerateUsersInDomainResponse, SamrGetAliasMembershipRequest, SamrGetAliasMembershipResponse, SamrGetGroupsForUserRequest, SamrGetGroupsForUserResponse, SamrGetMembersInGroupRequest, SamrGetMembersInGroupResponse, SamrLookupDomainInSamServerRequest, SamrLookupDomainInSamServerResponse, SamrLookupNamesInDomainRequest, SamrLookupNamesInDomainResponse, SamrOpenDomainRequest, SamrOpenDomainResponse, SamrOpenGroupRequest, SamrOpenGroupResponse, SamrOpenUserRequest, SamrOpenUserResponse, SamrQueryInformationDomainRequest, SamrQueryInformationDomainResponse, SamrRidToSidRequest, SamrRidToSidResponse, SamrSetInformationUser2Request, SamrSetInformationUser2Response, SamrUnicodeChangePasswordUser2Request, SamrUnicodeChangePasswordUser2Response, UserControlInformation, UserProperties, UserProperty

Constant Summary collapse

UUID =
'12345778-1234-abcd-ef00-0123456789ac'
VER_MAJOR =
1
VER_MINOR =
0
SAMR_CONNECT =

Operation numbers

0x0000
SAMR_CLOSE_HANDLE =
0x0001
SAMR_LOOKUP_DOMAIN_IN_SAM_SERVER =
0x0005
SAMR_ENUMERATE_DOMAINS_IN_SAM_SERVER =
0x0006
SAMR_OPEN_DOMAIN =
0x0007
SAMR_QUERY_INFORMATION_DOMAIN =
0x0008
SAMR_ENUMERATE_USERS_IN_DOMAIN =
0x000D
SAMR_GET_ALIAS_MEMBERSHIP =
0x0010
SAMR_LOOKUP_NAMES_IN_DOMAIN =
0x0011
SAMR_OPEN_GROUP =
0x0013
SAMR_GET_MEMBERS_IN_GROUP =
0x0019
SAMR_OPEN_USER =
0x0022
SAMR_DELETE_USER =
0x0023
SAMR_CHANGE_PASSWORD_USER =
0x0026
SAMR_GET_GROUPS_FOR_USER =
0x0027
SAMR_CREATE_USER2_IN_DOMAIN =
0x0032
SAMR_UNICODE_CHANGE_PASSWORD_USER2 =
0x0037
SAMR_SET_INFORMATION_USER2 =
0x003a
SAMR_CONNECT5 =
0x0040
SAMR_RID_TO_SID =
0x0041
DELETE =
0x00010000
READ_CONTROL =
0x00020000
WRITE_DAC =
0x00040000
WRITE_OWNER =
0x00080000
ACCESS_SYSTEM_SECURITY =
0x01000000
MAXIMUM_ALLOWED =
0x02000000
SAM_SERVER_CONNECT =
0x00000001
SAM_SERVER_SHUTDOWN =
0x00000002
SAM_SERVER_INITIALIZE =
0x00000004
SAM_SERVER_CREATE_DOMAIN =
0x00000008
SAM_SERVER_ENUMERATE_DOMAINS =
0x00000010
SAM_SERVER_LOOKUP_DOMAIN =
0x00000020
SAM_SERVER_ALL_ACCESS =
0x000F003F
SAM_SERVER_READ =
0x00020010
SAM_SERVER_WRITE =
0x0002000E
SAM_SERVER_EXECUTE =
0x00020021
DOMAIN_READ_PASSWORD_PARAMETERS =
0x00000001
DOMAIN_WRITE_PASSWORD_PARAMS =
0x00000002
DOMAIN_READ_OTHER_PARAMETERS =
0x00000004
DOMAIN_WRITE_OTHER_PARAMETERS =
0x00000008
DOMAIN_CREATE_USER =
0x00000010
DOMAIN_CREATE_GROUP =
0x00000020
DOMAIN_CREATE_ALIAS =
0x00000040
DOMAIN_GET_ALIAS_MEMBERSHIP =
0x00000080
DOMAIN_LIST_ACCOUNTS =
0x00000100
DOMAIN_LOOKUP =
0x00000200
DOMAIN_ADMINISTER_SERVER =
0x00000400
DOMAIN_ALL_ACCESS =
0x000F07FF
DOMAIN_READ =
0x00020084
DOMAIN_WRITE =
0x0002047A
DOMAIN_EXECUTE =
0x00020301
GROUP_READ_INFORMATION =
0x00000001
GROUP_WRITE_ACCOUNT =
0x00000002
GROUP_ADD_MEMBER =
0x00000004
GROUP_REMOVE_MEMBER =
0x00000008
GROUP_LIST_MEMBERS =
0x00000010
GROUP_ALL_ACCESS =
0x000F001F
GROUP_READ =
0x00020010
GROUP_WRITE =
0x0002000E
GROUP_EXECUTE =
0x00020001
ALIAS_ADD_MEMBER =
0x00000001
ALIAS_REMOVE_MEMBER =
0x00000002
ALIAS_LIST_MEMBERS =
0x00000004
ALIAS_READ_INFORMATION =
0x00000008
ALIAS_WRITE_ACCOUNT =
0x00000010
ALIAS_ALL_ACCESS =
0x000F001F
ALIAS_READ =
0x00020004
ALIAS_WRITE =
0x00020013
ALIAS_EXECUTE =
0x00020008
USER_READ_GENERAL =
0x00000001
USER_READ_PREFERENCES =
0x00000002
USER_WRITE_PREFERENCES =
0x00000004
USER_READ_LOGON =
0x00000008
USER_READ_ACCOUNT =
0x00000010
USER_WRITE_ACCOUNT =
0x00000020
USER_CHANGE_PASSWORD =
0x00000040
USER_FORCE_PASSWORD_CHANGE =
0x00000080
USER_LIST_GROUPS =
0x00000100
USER_READ_GROUP_INFORMATION =
0x00000200
USER_WRITE_GROUP_INFORMATION =
0x00000400
USER_ALL_ACCESS =
0x000F07FF
USER_READ =
0x0002031A
USER_WRITE =
0x00020044
USER_EXECUTE =
0x00020041
USER_ALL_USERNAME =
0x00000001
USER_ALL_FULLNAME =
0x00000002
USER_ALL_USERID =
0x00000004
USER_ALL_PRIMARYGROUPID =
0x00000008
USER_ALL_ADMINCOMMENT =
0x00000010
USER_ALL_USERCOMMENT =
0x00000020
USER_ALL_HOMEDIRECTORY =
0x00000040
USER_ALL_HOMEDIRECTORYDRIVE =
0x00000080
USER_ALL_SCRIPTPATH =
0x00000100
USER_ALL_PROFILEPATH =
0x00000200
USER_ALL_WORKSTATIONS =
0x00000400
USER_ALL_LASTLOGON =
0x00000800
USER_ALL_LASTLOGOFF =
0x00001000
USER_ALL_LOGONHOURS =
0x00002000
USER_ALL_BADPASSWORDCOUNT =
0x00004000
USER_ALL_LOGONCOUNT =
0x00008000
USER_ALL_PASSWORDCANCHANGE =
0x00010000
USER_ALL_PASSWORDMUSTCHANGE =
0x00020000
USER_ALL_PASSWORDLASTSET =
0x00040000
USER_ALL_ACCOUNTEXPIRES =
0x00080000
USER_ALL_USERACCOUNTCONTROL =
0x00100000
USER_ALL_PARAMETERS =
0x00200000
USER_ALL_COUNTRYCODE =
0x00400000
USER_ALL_CODEPAGE =
0x00800000
USER_ALL_NTPASSWORDPRESENT =
0x01000000
USER_ALL_LMPASSWORDPRESENT =
0x02000000
USER_ALL_PRIVATEDATA =
0x04000000
USER_ALL_PASSWORDEXPIRED =
0x08000000
USER_ALL_SECURITYDESCRIPTOR =
0x10000000
USER_ALL_UNDEFINED_MASK =
0xC0000000
DOMAIN_PASSWORD_INFORMATION =
1
DOMAIN_GENERAL_INFORMATION =
2
DOMAIN_LOGOFF_INFORMATION =
3
DOMAIN_OEM_INFORMATION =
4
DOMAIN_NAME_INFORMATION =
5
DOMAIN_REPLICATION_INFORMATION =
6
DOMAIN_SERVER_ROLE_INFORMATION =
7
DOMAIN_MODIFIED_INFORMATION =
8
DOMAIN_STATE_INFORMATION =
9
DOMAIN_GENERAL_INFORMATION2 =
11
DOMAIN_LOCKOUT_INFORMATION =
12
DOMAIN_MODIFIED_INFORMATION2 =
13
USER_GENERAL_INFORMATION =
1
USER_PREFERENCES_INFORMATION =
2
USER_LOGON_INFORMATION =
3
USER_LOGON_HOURS_INFORMATION =
4
USER_ACCOUNT_INFORMATION =
5
USER_NAME_INFORMATION =
6
USER_ACCOUNT_NAME_INFORMATION =
7
USER_FULL_NAME_INFORMATION =
8
USER_PRIMARY_GROUP_INFORMATION =
9
USER_HOME_INFORMATION =
10
USER_SCRIPT_INFORMATION =
11
USER_PROFILE_INFORMATION =
12
USER_ADMIN_COMMENT_INFORMATION =
13
USER_WORK_STATIONS_INFORMATION =
14
USER_CONTROL_INFORMATION =
16
USER_EXPIRES_INFORMATION =
17
USER_INTERNAL1_INFORMATION =
18
USER_PARAMETERS_INFORMATION =
20
USER_ALL_INFORMATION =
21
USER_INTERNAL4_INFORMATION =
23
USER_INTERNAL5_INFORMATION =
24
USER_INTERNAL4_INFORMATION_NEW =
25
USER_INTERNAL5_INFORMATION_NEW =
26
USER_INTERNAL7_INFORMATION =
31
USER_INTERNAL8_INFORMATION =
32
SAM_DOMAIN_OBJECT =
0x00000000
SAM_GROUP_OBJECT =
0x10000000
SAM_NON_SECURITY_GROUP_OBJECT =
0x10000001
SAM_ALIAS_OBJECT =
0x20000000
SAM_NON_SECURITY_ALIAS_OBJECT =
0x20000001
SAM_USER_OBJECT =
0x30000000
SAM_MACHINE_ACCOUNT =
0x30000001
SAM_TRUST_ACCOUNT =
0x30000002
SAM_APP_BASIC_GROUP =
0x40000000
SAM_APP_QUERY_GROUP =
0x40000001
SE_GROUP_MANDATORY =
0x00000001
SE_GROUP_ENABLED_BY_DEFAULT =
0x00000002
SE_GROUP_ENABLED =
0x00000004
GROUP_TYPE_ACCOUNT_GROUP =
0x00000002
GROUP_TYPE_RESOURCE_GROUP =
0x00000004
GROUP_TYPE_UNIVERSAL_GROUP =
0x00000008
GROUP_TYPE_SECURITY_ENABLED =
0x80000000
GROUP_TYPE_SECURITY_ACCOUNT =
0x80000002
GROUP_TYPE_SECURITY_RESOURCE =
0x80000004
GROUP_TYPE_SECURITY_UNIVERSAL =
0x80000008
USER_ACCOUNT_DISABLED =
0x00000001
USER_HOME_DIRECTORY_REQUIRED =
0x00000002
USER_PASSWORD_NOT_REQUIRED =
0x00000004
USER_TEMP_DUPLICATE_ACCOUNT =
0x00000008
USER_NORMAL_ACCOUNT =
0x00000010
USER_MNS_LOGON_ACCOUNT =
0x00000020
USER_INTERDOMAIN_TRUST_ACCOUNT =
0x00000040
USER_WORKSTATION_TRUST_ACCOUNT =
0x00000080
USER_SERVER_TRUST_ACCOUNT =
0x00000100
USER_DONT_EXPIRE_PASSWORD =
0x00000200
USER_ACCOUNT_AUTO_LOCKED =
0x00000400
USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED =
0x00000800
USER_SMARTCARD_REQUIRED =
0x00001000
USER_TRUSTED_FOR_DELEGATION =
0x00002000
USER_NOT_DELEGATED =
0x00004000
USER_USE_DES_KEY_ONLY =
0x00008000
USER_DONT_REQUIRE_PREAUTH =
0x00010000
USER_PASSWORD_EXPIRED =
0x00020000
USER_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION =
0x00040000
USER_NO_AUTH_DATA_REQUIRED =
0x00080000
USER_PARTIAL_SECRETS_ACCOUNT =
0x00100000
USER_USE_AES_KEYS =
0x00200000
UF_SCRIPT =
0x00000001
UF_ACCOUNTDISABLE =
0x00000002
UF_HOMEDIR_REQUIRED =
0x00000008
UF_LOCKOUT =
0x00000010
UF_PASSWD_NOTREQD =
0x00000020
UF_PASSWD_CANT_CHANGE =
0x00000040
UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED =
0x00000080
UF_TEMP_DUPLICATE_ACCOUNT =
0x00000100
UF_NORMAL_ACCOUNT =
0x00000200
UF_INTERDOMAIN_TRUST_ACCOUNT =
0x00000800
UF_WORKSTATION_TRUST_ACCOUNT =
0x00001000
UF_SERVER_TRUST_ACCOUNT =
0x00002000
UF_DONT_EXPIRE_PASSWD =
0x00010000
UF_MNS_LOGON_ACCOUNT =
0x00020000
UF_SMARTCARD_REQUIRED =
0x00040000
UF_TRUSTED_FOR_DELEGATION =
0x00080000
UF_NOT_DELEGATED =
0x00100000
UF_USE_DES_KEY_ONLY =
0x00200000
UF_DONT_REQUIRE_PREAUTH =
0x00400000
UF_PASSWORD_EXPIRED =
0x00800000
UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION =
0x01000000
UF_NO_AUTH_DATA_REQUIRED =
0x02000000
UF_PARTIAL_SECRETS_ACCOUNT =
0x04000000
UF_USE_AES_KEYS =
0x08000000
DOMAIN_USER_RID_ADMIN =
0x000001F4
DOMAIN_USER_RID_GUEST =
0x000001F5
DOMAIN_USER_RID_KRBTGT =
0x000001F6
DOMAIN_GROUP_RID_ADMINS =
0x00000200
DOMAIN_GROUP_RID_USERS =
0x00000201
DOMAIN_GROUP_RID_COMPUTERS =
0x00000203
DOMAIN_GROUP_RID_CONTROLLERS =
0x00000204
DOMAIN_ALIAS_RID_ADMINS =
0x00000220
DOMAIN_GROUP_RID_READONLY_CONTROLLERS =
0x00000209
KERBEROS_TYPE =
{
  1          => 'dec-cbc-crc',
  3          => 'des-cbc-md5',
  17         => 'aes128-cts-hmac-sha1-96',
  18         => 'aes256-cts-hmac-sha1-96',
  # Windows Server 2008 and later DC includes a KeyType of -140. Not present when the domain functional level is raised to DS_BEHAVIOR_WIN2008 or greater
  # [Appendix_A_24](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/fa61e5fc-f8fb-4d5b-9695-c724af0c3829#Appendix_A_24)
  0xffffff74 => 'rc4_hmac'
}
EncryptedLmOwfPassword =
EncryptedNtOwfPassword
PencryptedLmOwfPassword =
PencryptedNtOwfPassword
WELL_KNOWN_SID_NAME =
{
  [0,0] => 'NULL SID',
  [1,0] => 'Everyone',
  [2,0] => 'LOCAL',
  [2,1] => 'CONSOLE LOGON',
  [3,0] => 'CREATOR OWNER',
  [3,1] => 'CREATOR GROUP',
  [3,2] => 'CREATOR OWNER SERVER',
  [3,3] => 'CREATOR GROUP SERVER',
  [3,4] => 'OWNER RIGHTS',
  [5,1] => 'NT AUTHORITY\\DIALUP',
  [5,2] => 'NT AUTHORITY\\NETWORK',
  [5,3] => 'NT AUTHORITY\\BATCH',
  [5,4] => 'NT AUTHORITY\\INTERACTIVE',
  [5,6] => 'NT AUTHORITY\\SERVICE',
  [5,7] => 'NT AUTHORITY\\ANONYMOUS LOGON',
  [5,8] => 'NT AUTHORITY\\PROXY',
  [5,9] => 'NT AUTHORITY\\ENTERPRISE DOMAIN CONTROLLERS',
  [5,10] => 'NT AUTHORITY\\SELF',
  [5,11] => 'NT AUTHORITY\\Authenticated Users',
  [5,12] => 'NT AUTHORITY\\RESTRICTED',
  [5,13] => 'NT AUTHORITY\\TERMINAL SERVER USER',
  [5,14] => 'NT AUTHORITY\\REMOTE INTERACTIVE LOGON',
  [5,15] => 'NT AUTHORITY\\This Organization',
  [5,17] => 'NT AUTHORITY\\IUSR',
  [5,18] => 'NT AUTHORITY\\SYSTEM',
  [5,19] => 'NT AUTHORITY\\LOCAL SERVICE',
  [5,20] => 'NT AUTHORITY\\NETWORK SERVICE',
  [5,22] => 'NT AUTHORITY\\ENTERPRISE READ-ONLY DOMAIN CONTROLLERS BETA',
  [5,33] => 'NT AUTHORITY\\WRITE RESTRICTED',
  [5,32] => 'Builtin Domain'
}
WELL_KNOWN_RID_NAME =
{
  498 => '(domain)\\Enterprise Read-only Domain Controllers',
  500 => '(domain)\\Administrator',
  501 => '(domain)\\Guest',
  502 => '(domain)\\krbtgt',
  512 => '(domain)\\Domain Admins',
  513 => '(domain)\\Domain Users',
  514 => '(domain)\\Domain Guests',
  515 => '(domain)\\Domain Computers',
  516 => '(domain)\\Domain Controllers',
  517 => '(domain)\\Cert Publishers',
  518 => '(domain)\\Schema Admins',
  519 => '(domain)\\Enterprise Admins',
  520 => '(domain)\\Group Policy Creator Owners',
  521 => '(domain)\\Read-only Domain Controllers',
  522 => '(domain)\\Cloneable Domain Controllers',
  544 => 'BUILTIN\\Administrators',
  545 => 'BUILTIN\\Users',
  546 => 'BUILTIN\\Guests',
  548 => 'BUILTIN\\Account Operators',
  549 => 'BUILTIN\\Server Operators',
  550 => 'BUILTIN\\Print Operators',
  551 => 'BUILTIN\\Backup Operators',
  552 => 'BUILTIN\\Replicator',
  553 => '(domain)\\RAS and IAS Servers',
  554 => 'BUILTIN\\Pre-Windows 2000 Compatible Access',
  555 => 'BUILTIN\\Remote Desktop Users',
  556 => 'BUILTIN\\Network Configuration Operators',
  557 => 'BUILTIN\\Incoming Forest Trust Builders',
  558 => 'BUILTIN\\Performance Monitor Users',
  559 => 'BUILTIN\\Performance Log Users',
  560 => 'BUILTIN\\Windows Authorization Access Group',
  561 => 'BUILTIN\\Terminal Server License Servers',
  562 => 'BUILTIN\\Distributed COM Users',
  568 => 'BUILTIN\\IIS_IUSRS',
  569 => 'BUILTIN\\Cryptographic Operators',
  571 => '(domain)\\Allowed RODC Password Replication Group',
  572 => '(domain)\\Denied RODC Password Replication Group',
  573 => 'BUILTIN\\Event Log Readers',
  574 => 'BUILTIN\\Certificate Service DCOM Access',
  575 => 'BUILTIN\\RDS Remote Access Servers',
  576 => 'BUILTIN\\RDS Endpoint Servers',
  577 => 'BUILTIN\\RDS Management Servers',
  578 => 'BUILTIN\\Hyper-V Administrators',
  579 => 'BUILTIN\\Access Control Assistance Operators',
  580 => 'BUILTIN\\Remote Management Users'
}

Instance Method Summary collapse

Instance Method Details

#close_handle(sam_handle) ⇒ RubySMB::Dcerpc::Samr::SamprHandle

Closes (that is, releases server-side resources used by) any context handle obtained from this RPC interface

Parameters:

Returns:

Raises:



1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
# File 'lib/ruby_smb/dcerpc/samr.rb', line 1096

def close_handle(sam_handle)
  samr_close_handle_request = SamrCloseHandleRequest.new(sam_handle: sam_handle)
  response = dcerpc_request(samr_close_handle_request)
  begin
    samr_close_handle_response = SamrCloseHandleResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrCloseHandleResponse'
  end
  unless samr_close_handle_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned with samr_connect: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_close_handle_response.error_status.value).join(',')}"
  end
  samr_close_handle_response.sam_handle
end

#samr_change_password_user(user_handle:, old_password: nil, new_password: nil, new_nt_hash: nil, new_lm_hash: nil, old_nt_hash: nil, old_lm_hash: nil) ⇒ Object

Change the password on a user object.

Parameters:

  • user_handle (SamprHandle)

    Handle representing the user to change the password for

  • old_password (String) (defaults to: nil)

    The previous password (either this or old_nt_hash must be specified)

  • new_password (String) (defaults to: nil)

    The password to set on the account

  • new_nt_hash (String) (defaults to: nil)

    The new password's NT hash

  • new_lm_hash (String) (defaults to: nil)

    The new password's LM hash

  • old_nt_hash (String) (defaults to: nil)

    The previous password's NT hash (either this or old_password must be specified)

  • old_lm_hash (String) (defaults to: nil)

    The previous password's LM hash (currently ignored)

Returns:

  • nothing is returned on success

Raises:



987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
# File 'lib/ruby_smb/dcerpc/samr.rb', line 987

def samr_change_password_user(user_handle:, old_password:nil, new_password:nil, new_nt_hash:nil, new_lm_hash:nil, old_nt_hash:nil, old_lm_hash:nil)
  if new_password.nil? == new_nt_hash.nil?
    raise ArgumentError.new('Provide either new password or new password hashes, but not both')
  end

  if old_password.nil? == old_nt_hash.nil?
    raise ArgumentError.new('Provide either old password or old password hashes, but not both')
  end

  if old_password
    old_lm_hash = Net::NTLM.lm_hash(old_password[0..13])
    old_nt_hash = Net::NTLM.ntlm_hash(old_password)
  end

  if new_nt_hash.nil?
    new_nt_hash = Net::NTLM::ntlm_hash(new_password)
    new_lm_hash = Net::NTLM.lm_hash(new_password[0..13])
  elsif new_lm_hash.nil?
    new_lm_hash = Net::NTLM.lm_hash('')
  end
  
  samr_change_password_user_request = SamrChangePasswordUserRequest.new(
    user_handle: user_handle,
    lm_present: 0,
    old_lm_encrypted_with_new_lm: nil,
    new_lm_encrypted_with_old_lm: nil,
    nt_present: 1,
    old_nt_encrypted_with_new_nt: PencryptedNtOwfPassword.new(buffer: EncryptedNtOwfPassword.encrypt_hash(hash: old_nt_hash, key: new_nt_hash)),
    new_nt_encrypted_with_old_nt: PencryptedNtOwfPassword.new(buffer: EncryptedNtOwfPassword.encrypt_hash(hash: new_nt_hash, key: old_nt_hash)),
    nt_cross_encryption_present: 0,
    new_nt_encrypted_with_new_lm: nil,
    lm_cross_encryption_present: 1,
    new_lm_encrypted_with_new_nt: PencryptedNtOwfPassword.new(buffer: EncryptedNtOwfPassword.encrypt_hash(hash: new_lm_hash, key: new_nt_hash)),
  )
  response = dcerpc_request(samr_change_password_user_request)
  begin
    samr_unicode_change_password_user2_response = SamrChangePasswordUserResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrUnicodeChangePasswordUser2Response'
  end
  unless samr_unicode_change_password_user2_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned while changing user password: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_unicode_change_password_user2_response.error_status.value).join(',')}"
  end

  nil
end

#samr_connect(server_name: '', access: MAXIMUM_ALLOWED) ⇒ RubySMB::Dcerpc::Samr::SamprHandle

Returns a handle to a server object.

Parameters:

  • server_name (Char) (defaults to: '')

    the first character of the NETBIOS name of the server (optional)

  • access (Numeric) (defaults to: MAXIMUM_ALLOWED)

    access requested for ServerHandle upon output: bitwise OR of common and server ACCESS_MASK values (defined in lib/ruby_smb/dcerpc/samr.rb).

Returns:

Raises:



633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
# File 'lib/ruby_smb/dcerpc/samr.rb', line 633

def samr_connect(server_name: '', access: MAXIMUM_ALLOWED)
  samr_connect_request = SamrConnectRequest.new(
    server_name: server_name,
    desired_access: access
  )
  response = dcerpc_request(samr_connect_request)
  begin
    samr_connect_response = SamrConnectResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrConnectResponse'
  end
  unless samr_connect_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned with samr_connect: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_connect_response.error_status.value).join(',')}"
  end
  samr_connect_response.server_handle
end

#samr_create_user2_in_domain(domain_handle:, name:, account_type: USER_NORMAL_ACCOUNT, desired_access: GROUP_ALL_ACCESS) ⇒ RubySMB::Dcerpc::Samr::SamprHandle

Create a new user.

Parameters:

  • domain_handle (RubySMB::Dcerpc::Samr::SamprHandle)

    RPC context handle representing the domain object

  • name (String)

    The name of the account to add

  • account_type (Integer) (defaults to: USER_NORMAL_ACCOUNT)

    The type of account to add, one of either USER_NORMAL_ACCOUNT, USER_WORKSTATION_TRUST_ACCOUNT, or USER_SERVER_TRUST_ACCOUNT

  • desired_access (Integer) (defaults to: GROUP_ALL_ACCESS)

    The access requested on the returned object

Returns:

Raises:



667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
# File 'lib/ruby_smb/dcerpc/samr.rb', line 667

def samr_create_user2_in_domain(domain_handle:, name:, account_type: USER_NORMAL_ACCOUNT, desired_access: GROUP_ALL_ACCESS)
  samr_create_request = SamrCreateUser2InDomainRequest.new(
    domain_handle: domain_handle,
    name: name,
    account_type: ,
    desired_access: desired_access
  )
  response = dcerpc_request(samr_create_request)
  begin
    samr_create_response = SamrCreateUser2InDomainResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrCreateUser2InDomainResponse'
  end
  unless samr_create_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned with samr_create_user2_in_domain: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_create_response.error_status.value).join(',')}"
  end

  {
    user_handle: samr_create_response.user_handle,
    granted_access: samr_create_response.granted_access.to_i,
    relative_id: samr_create_response.relative_id.to_i
  }
end

#samr_delete_user(user_handle:) ⇒ Object

Delete an existing user.

Parameters:

Raises:



701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
# File 'lib/ruby_smb/dcerpc/samr.rb', line 701

def samr_delete_user(user_handle:)
  samr_delete_user_request = SamrDeleteUserRequest.new(
    user_handle: user_handle
  )

  response = dcerpc_request(samr_delete_user_request)
  begin
    samr_delete_user_response = SamrDeleteUserResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrDeleteUserResponse'
  end
  unless samr_delete_user_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned while deleting user in SAM server: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_delete_user_response.error_status.value).join(',')}"
  end

  nil
end

#samr_enumerate_domains_in_sam_server(server_handle:, enumeration_context: 0) ⇒ Array<String>

Enumerates all domains on the remote server.

Parameters:

  • server_handle (RubySMB::Dcerpc::Samr::SamprHandle)

    RPC context handle representing the server object

  • enumeration_context (Integer) (defaults to: 0)

    a cookie used by the server to resume an enumeration

Returns:

  • (Array<String>)

    an array containing the domain names

Raises:



839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
# File 'lib/ruby_smb/dcerpc/samr.rb', line 839

def samr_enumerate_domains_in_sam_server(server_handle:, enumeration_context: 0)
  samr_enum_domains_request = SamrEnumerateDomainsInSamServerRequest.new(
    server_handle: server_handle,
    enumeration_context: enumeration_context,
    prefered_maximum_length: 0xFFFFFFFF
  )
  res = []
  loop do
    samr_enum_domains_request.enumeration_context = enumeration_context
    response = dcerpc_request(samr_enum_domains_request)
    begin
      samr_enum_domains_reponse = SamrEnumerateDomainsInSamServerResponse.read(response)
    rescue IOError
      raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrEnumerateDomainsInSamServerResponse'
    end
    unless samr_enum_domains_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS ||
           samr_enum_domains_reponse.error_status == WindowsError::NTStatus::STATUS_MORE_ENTRIES
      raise RubySMB::Dcerpc::Error::SamrError,
        "Error returned during domains enumeration in SAM server: "\
        "#{WindowsError::NTStatus.find_by_retval(samr_enum_domains_reponse.error_status.value).join(',')}"
    end
    samr_enum_domains_reponse.buffer.buffer.each_with_object(res) do |entry, array|
      array << entry.name.buffer
    end
    break unless samr_enum_domains_reponse.error_status == WindowsError::NTStatus::STATUS_MORE_ENTRIES

    enumeration_context = samr_enum_domains_reponse.enumeration_context
  end

  res
end

#samr_enumerate_users_in_domain(domain_handle:, enumeration_context: 0, user_account_control: USER_NORMAL_ACCOUNT | USER_WORKSTATION_TRUST_ACCOUNT | USER_SERVER_TRUST_ACCOUNT | USER_INTERDOMAIN_TRUST_ACCOUNT) ⇒ Hash<Integer, String>

Enumerates all users in the specified domain.

Parameters:

  • domain_handle (RubySMB::Dcerpc::Samr::SamprHandle)

    RPC context handle representing the domain object

  • enumeration_context (Integer) (defaults to: 0)

    a cookie used by the server to resume an enumeration

  • user_account_control (Integer) (defaults to: USER_NORMAL_ACCOUNT | USER_WORKSTATION_TRUST_ACCOUNT | USER_SERVER_TRUST_ACCOUNT | USER_INTERDOMAIN_TRUST_ACCOUNT)

    a value to use for filtering on the userAccountControl attribute

Returns:

  • (Hash<Integer, String>)

    hash mapping RID and username

Raises:



884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
# File 'lib/ruby_smb/dcerpc/samr.rb', line 884

def samr_enumerate_users_in_domain(domain_handle:,
                                   enumeration_context: 0,
                                   user_account_control: USER_NORMAL_ACCOUNT |
                                                         USER_WORKSTATION_TRUST_ACCOUNT |
                                                         USER_SERVER_TRUST_ACCOUNT |
                                                         USER_INTERDOMAIN_TRUST_ACCOUNT)
  samr_enum_users_request = SamrEnumerateUsersInDomainRequest.new(
    domain_handle: domain_handle,
    user_account_control: ,
    prefered_maximum_length: 0xFFFFFFFF
  )
  res = {}
  loop do
    samr_enum_users_request.enumeration_context = enumeration_context
    response = dcerpc_request(samr_enum_users_request)
    begin
      samr_enum_users_reponse= SamrEnumerateUsersInDomainResponse.read(response)
    rescue IOError
      raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrEnumerateUsersInDomainResponse'
    end
    unless samr_enum_users_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS ||
           samr_enum_users_reponse.error_status == WindowsError::NTStatus::STATUS_MORE_ENTRIES
      raise RubySMB::Dcerpc::Error::SamrError,
        "Error returned during users enumeration in SAM server: "\
        "#{WindowsError::NTStatus.find_by_retval(samr_enum_users_reponse.error_status.value).join(',')}"
    end
    samr_enum_users_reponse.buffer.buffer.each_with_object(res) do |entry, hash|
      hash[entry.relative_id] = entry.name.buffer
    end
    break unless samr_enum_users_reponse.error_status == WindowsError::NTStatus::STATUS_MORE_ENTRIES
    enumeration_context = samr_enum_users_reponse.enumeration_context
  end
  res
end

#samr_get_alias_membership(domain_handle:, sids:) ⇒ Array<RubySMB::Dcerpc::Ndr::NdrUint32>

Returns the union of all aliases that a given set of SIDs is a member of.

Parameters:

Returns:

  • (Array<RubySMB::Dcerpc::Ndr::NdrUint32>)

    The union of all aliases represented by RID's

Raises:



1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
# File 'lib/ruby_smb/dcerpc/samr.rb', line 1122

def samr_get_alias_membership(domain_handle:, sids:)
  sids = [sids] unless sids.is_a?(::Array)
  samr_get_alias_membership_request = SamrGetAliasMembershipRequest.new(
    domain_handle: domain_handle
  )
  sids.each do |sid|
    samr_get_alias_membership_request.sid_array.sids << {sid_pointer: sid}
  end
  response = dcerpc_request(samr_get_alias_membership_request)
  begin
    samr_get_alias_membership_reponse= SamrGetAliasMembershipResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrGetAliasMembershipResponse'
  end
  unless samr_get_alias_membership_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned while getting alias membership: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_get_alias_membership_reponse.error_status.value).join(',')}"
  end
  return [] if samr_get_alias_membership_reponse.membership.element_count == 0
  samr_get_alias_membership_reponse.membership.elements.to_ary
end

#samr_get_group_for_user(user_handle:) ⇒ Array<RubySMB::Dcerpc::Samr::GroupMembership>

Returns a listing of groups that a user is a member of

Parameters:

Returns:

Raises:



1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
# File 'lib/ruby_smb/dcerpc/samr.rb', line 1253

def samr_get_group_for_user(user_handle:)
  samr_get_groups_for_user_request = SamrGetGroupsForUserRequest.new(
    user_handle: user_handle
  )
  response = dcerpc_request(samr_get_groups_for_user_request)
  begin
    samr_get_groups_for_user_reponse= SamrGetGroupsForUserResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrGetGroupsForUserResponse'
  end
  unless samr_get_groups_for_user_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned while getting user groups: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_get_groups_for_user_reponse.error_status.value).join(',')}"
  end
  samr_get_groups_for_user_reponse.groups.groups.to_ary
end

#samr_get_members_in_group(group_handle:) ⇒ Array<Array<String,String>>

Returns a listing of members of the given group

Parameters:

Returns:

  • (Array<Array<String,String>>)

    Array of RID and Attributes

Raises:



1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
# File 'lib/ruby_smb/dcerpc/samr.rb', line 1222

def samr_get_members_in_group(group_handle:)
  samr_get_members_in_group_request = SamrGetMembersInGroupRequest.new(
    group_handle: group_handle
  )
  response = dcerpc_request(samr_get_members_in_group_request)
  begin
    samr_get_members_in_group_response = SamrGetMembersInGroupResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrGetMembersInGroupResponse'
  end
  unless samr_get_members_in_group_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned while getting group membership: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_get_members_in_group_response.error_status.value).join(',')}"
  end
  members = samr_get_members_in_group_response.members.members.to_ary
  attributes = samr_get_members_in_group_response.members.attributes.to_ary

  members.zip(attributes)
end

#samr_lookup_domain(server_handle:, name:) ⇒ RubySMB::Dcerpc::RpcSid

Obtains the SID of a domain object

Parameters:

Returns:

  • (RubySMB::Dcerpc::RpcSid)

    SID value of a domain that corresponds to the Name passed in

Raises:



732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
# File 'lib/ruby_smb/dcerpc/samr.rb', line 732

def samr_lookup_domain(server_handle:, name:)
  samr_lookup_domain_in_sam_server_request = SamrLookupDomainInSamServerRequest.new(
    server_handle: server_handle,
    name: name
  )
  response = dcerpc_request(samr_lookup_domain_in_sam_server_request)
  begin
    samr_lookup_domain_in_sam_server_response = SamrLookupDomainInSamServerResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrLookupDomainInSamServerResponse'
  end
  unless samr_lookup_domain_in_sam_server_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned during domain lookup in SAM server: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_lookup_domain_in_sam_server_response.error_status.value).join(',')}"
  end
  samr_lookup_domain_in_sam_server_response.domain_id
end

#samr_lookup_names_in_domain(domain_handle:, names:) ⇒ Hash<String, Hash<Symbol, Integer>>, Nil

Obtains the SID of a domain object

Parameters:

  • domain_handle (RubySMB::Dcerpc::Samr::SamprHandle)

    RPC context handle representing the domain object

  • name (Array<String>)

    An array of string account names to translate to RIDs.

Returns:

  • (Hash<String, Hash<Symbol, Integer>>, Nil)

    Returns a hash mapping the requested names to their information. Nil is returned if one or more names could not be found.

Raises:



762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
# File 'lib/ruby_smb/dcerpc/samr.rb', line 762

def samr_lookup_names_in_domain(domain_handle:, names:)
  raise ArgumentError.new('names may not be longer than 1000') if names.length > 1000

  samr_lookup_request = SamrLookupNamesInDomainRequest.new(
    domain_handle: domain_handle,
    names_count: names.length,
    names: names
  )
  samr_lookup_request.names.set_max_count(1000)
  response = dcerpc_request(samr_lookup_request)
  begin
    samr_lookup_response = SamrLookupNamesInDomainResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrLookupNamesInDomainResponse'
  end
  return nil if samr_lookup_response.error_status == WindowsError::NTStatus::STATUS_NONE_MAPPED
  return nil if samr_lookup_response.error_status == WindowsError::NTStatus::STATUS_SOME_NOT_MAPPED
  unless samr_lookup_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned during names lookup in SAM server: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_lookup_response.error_status.value).join(',')}"
  end

  result = {}
  names.each_with_index do |name, index|
    result[name] = {
      rid: samr_lookup_response.relative_ids.elements[index].to_i,
      use: samr_lookup_response.use.elements[index].to_i
    }
  end
  result
end

#samr_open_domain(server_handle:, access: MAXIMUM_ALLOWED, domain_id:) ⇒ RubySMB::Dcerpc::Samr::SamprHandle

Returns a handle to a domain object.

Parameters:

  • server_handle (RubySMB::Dcerpc::Samr::SamprHandle)

    RPC context handle representing the server object

  • access (Numeric) (defaults to: MAXIMUM_ALLOWED)

    access requested for ServerHandle upon output: bitwise OR of common and server ACCESS_MASK values (defined in lib/ruby_smb/dcerpc/samr.rb).

  • domain_id (RubySMB::Dcerpc::RpcSid)

    SID value of a domain

Returns:

Raises:



808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
# File 'lib/ruby_smb/dcerpc/samr.rb', line 808

def samr_open_domain(server_handle:, access: MAXIMUM_ALLOWED, domain_id:)
  samr_open_domain_request = SamrOpenDomainRequest.new(
    server_handle: server_handle,
    desired_access: access,
    domain_id: domain_id
  )
  response = dcerpc_request(samr_open_domain_request)
  begin
    samr_open_domain_response = SamrOpenDomainResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrLookupDomainInSamServerResponse'
  end
  unless samr_open_domain_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned during domain lookup in SAM server: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_open_domain_response.error_status.value).join(',')}"
  end
  samr_open_domain_response.domain_handle
end

#samr_open_group(domain_handle:, access: MAXIMUM_ALLOWED, group_id:) ⇒ RubySMB::Dcerpc::Samr::SamprHandle

Returns a handle to a group, given a RID

Parameters:

  • domain_handle (RubySMB::Dcerpc::Samr::SamprHandle)

    An RPC context representing a domain object

  • access (Integer) (defaults to: MAXIMUM_ALLOWED)

    An access control that indicates the requested access for the returned handle. It is a bitwise OR of common ACCESS_MASK and user ACCESS_MASK values (see lib/ruby_smb/dcerpc/samr.rb)

  • group_id (Integer)

    RID of a group

Returns:

Raises:



1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
# File 'lib/ruby_smb/dcerpc/samr.rb', line 1159

def samr_open_group(domain_handle:, access: MAXIMUM_ALLOWED, group_id:)
  samr_open_group_request = SamrOpenGroupRequest.new(
    domain_handle: domain_handle,
    desired_access: access,
    group_id: group_id
  )
  response = dcerpc_request(samr_open_group_request)
  begin
    samr_open_group_response = SamrOpenGroupResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrOpenGroupResponse'
  end
  unless samr_open_group_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned when getting a handle to group #{group_id}: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_open_grou_response.error_status.value).join(',')}"
  end
  samr_open_group_response.group_handle
end

#samr_open_user(domain_handle:, access: MAXIMUM_ALLOWED, user_id:) ⇒ RubySMB::Dcerpc::Samr::SamprHandle

Returns a handle to a user, given a RID

Parameters:

  • domain_handle (RubySMB::Dcerpc::Samr::SamprHandle)

    An RPC context representing a domain object

  • access (Integer) (defaults to: MAXIMUM_ALLOWED)

    An access control that indicates the requested access for the returned handle. It is a bitwise OR of common ACCESS_MASK and user ACCESS_MASK values (see lib/ruby_smb/dcerpc/samr.rb)

  • user_id (Integer)

    RID of a user account

Returns:

Raises:



1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
# File 'lib/ruby_smb/dcerpc/samr.rb', line 1193

def samr_open_user(domain_handle:, access: MAXIMUM_ALLOWED, user_id:)
  samr_open_user_request = SamrOpenUserRequest.new(
    domain_handle: domain_handle,
    desired_access: access,
    user_id: user_id
  )
  response = dcerpc_request(samr_open_user_request)
  begin
    samr_open_user_response = SamrOpenUserResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrOpenUserResponse'
  end
  unless samr_open_user_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned when getting a handle to user #{user_id}: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_open_user_response.error_status.value).join(',')}"
  end
  samr_open_user_response.user_handle
end

#samr_query_information_domain(domain_handle:, info_class:) ⇒ BinData::Choice

Returns domain information.

Parameters:

Returns:

  • (BinData::Choice)

    The requested information.



1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
# File 'lib/ruby_smb/dcerpc/samr.rb', line 1277

def samr_query_information_domain(domain_handle:, info_class:)
  samr_request = SamrQueryInformationDomainRequest.new(
    domain_handle: domain_handle,
    domain_information_class: info_class
  )
  response = dcerpc_request(samr_request)
  begin
    samr_response = SamrQueryInformationDomainResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrQueryInformationDomainResponse'
  end
  unless samr_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned while querying domain information: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_response.error_status.value).join(',')}"
  end
  samr_response.buffer.buffer
end

#samr_rid_to_sid(object_handle:, rid:) ⇒ String

Returns the SID of an account, given a RID.

Parameters:

  • rid (Numeric)

    the RID

Returns:

  • (String)

    The SID of the account referenced by RID

Raises:



927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
# File 'lib/ruby_smb/dcerpc/samr.rb', line 927

def samr_rid_to_sid(object_handle:, rid:)
  samr_rid_to_sid_request = SamrRidToSidRequest.new(
    object_handle: object_handle,
    rid: rid
  )
  response = dcerpc_request(samr_rid_to_sid_request)
  begin
    samr_rid_to_sid_response = SamrRidToSidResponse.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrRidToSidResponse'
  end
  unless samr_rid_to_sid_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned during SID lookup in SAM server: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_rid_to_sid_response.error_status.value).join(',')}"
  end
  samr_rid_to_sid_response.sid
end

#samr_set_information_user2(user_handle:, user_info:) ⇒ Object

Update attributes on a user object.

Parameters:

Returns:

  • nothing is returned on success

Raises:



955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
# File 'lib/ruby_smb/dcerpc/samr.rb', line 955

def samr_set_information_user2(user_handle:, user_info:)
  samr_set_information_user2_request = SamrSetInformationUser2Request.new(
    user_handle: user_handle,
    buffer: 
  )
  response = dcerpc_request(samr_set_information_user2_request)
  begin
    samr_set_information_user2_response = SamrSetInformationUser2Response.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrSetInformationUser2Response'
  end
  unless samr_set_information_user2_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned while setting user information: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_set_information_user2_response.error_status.value).join(',')}"
  end

  nil
end

#samr_unicode_change_password_user2(server_name: "", target_username:, old_password: nil, new_password:, old_nt_hash: nil, old_lm_hash: nil) ⇒ Object

Change the password on a user.

Parameters:

  • server_name (String) (defaults to: "")

    The server name; can be ignored by the server

  • target_username (String)

    The user for which we're changing the password

  • old_password (String) (defaults to: nil)

    The previous password (either this or old_nt_hash must be specified)

  • new_password (String)

    The password to set on the account

  • old_nt_hash (String) (defaults to: nil)

    The previous password's NT hash (either this or old_password must be specified)

  • old_lm_hash (String) (defaults to: nil)

    The previous password's LM hash (currently ignored)

Returns:

  • nothing is returned on success

Raises:



1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
# File 'lib/ruby_smb/dcerpc/samr.rb', line 1048

def samr_unicode_change_password_user2(server_name: "", target_username:, old_password:nil, new_password:, old_nt_hash:nil, old_lm_hash:nil)
  #if old_lm_hash.nil? != old_nt_hash.nil?
  #  raise ArgumentError.new('If providing the previous NT/LM hash, must provide both')
  #end
  if old_password.nil? == old_nt_hash.nil?
    raise ArgumentError.new('Provide either old password or old password hashes, but not both')
  end

  if old_password
    old_lm_hash = Net::NTLM.lm_hash(old_password[0..13])
    old_nt_hash = Net::NTLM.ntlm_hash(old_password)
  end

  new_nt_hash = Net::NTLM::ntlm_hash(new_password)

  samr_unicode_change_password_user2_request = SamrUnicodeChangePasswordUser2Request.new(
    server_name: server_name,
    user_name: target_username,
    new_password_encrypted_with_old_nt: SamprEncryptedUserPassword.new(buffer: SamprEncryptedUserPassword.encrypt_password(new_password, old_nt_hash)),
    old_nt_owf_password_encrypted_with_new_nt: PencryptedNtOwfPassword.new(buffer: EncryptedNtOwfPassword.encrypt_hash(hash: old_nt_hash, key: new_nt_hash)),
    lm_present: 0
  )
  samr_unicode_change_password_user2_request
  response = dcerpc_request(samr_unicode_change_password_user2_request)
  begin
    samr_unicode_change_password_user2_response = SamrUnicodeChangePasswordUser2Response.read(response)
  rescue IOError
    raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrUnicodeChangePasswordUser2Response'
  end
  unless samr_unicode_change_password_user2_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
    raise RubySMB::Dcerpc::Error::SamrError,
      "Error returned while changing user password: "\
      "#{WindowsError::NTStatus.find_by_retval(samr_unicode_change_password_user2_response.error_status.value).join(',')}"
  end

  nil
end