ruby_smb 2.0.12 → 2.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +1 -1
  4. data/examples/dump_secrets_from_sid.rb +207 -0
  5. data/examples/enum_domain_users.rb +75 -0
  6. data/examples/get_computer_info.rb +42 -0
  7. data/examples/query_service_status.rb +42 -4
  8. data/lib/ruby_smb/client.rb +3 -14
  9. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  10. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  11. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  12. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  13. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  14. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  15. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  16. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  17. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  18. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  19. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  20. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  21. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  22. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  23. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  24. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  25. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  26. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  27. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  28. data/lib/ruby_smb/dcerpc/error.rb +17 -0
  29. data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
  30. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
  31. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
  32. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
  33. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
  34. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
  35. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
  36. data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
  37. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  38. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  39. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  40. data/lib/ruby_smb/dcerpc/request.rb +79 -32
  41. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  42. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  43. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +11 -11
  44. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  45. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  46. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  47. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  48. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  49. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  50. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  51. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  52. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  53. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  54. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  55. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  56. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  57. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  58. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  59. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  60. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  61. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  62. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  63. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  64. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  65. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  66. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  67. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  68. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +13 -25
  69. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
  70. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
  71. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
  72. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
  73. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
  74. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
  75. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
  76. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
  77. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
  78. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
  79. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
  80. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
  81. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
  82. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
  83. data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
  84. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  85. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  86. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +2 -13
  87. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
  88. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
  89. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  90. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  91. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  92. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  93. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  94. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +5 -6
  95. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  96. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  97. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
  98. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  99. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  100. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +0 -9
  101. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
  102. data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
  103. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  104. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  105. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  106. data/lib/ruby_smb/dcerpc.rb +41 -11
  107. data/lib/ruby_smb/field/file_time.rb +1 -1
  108. data/lib/ruby_smb/field/string16.rb +5 -1
  109. data/lib/ruby_smb/ntlm.rb +18 -2
  110. data/lib/ruby_smb/smb1/pipe.rb +4 -0
  111. data/lib/ruby_smb/smb2/pipe.rb +4 -0
  112. data/lib/ruby_smb/version.rb +1 -1
  113. data/spec/lib/ruby_smb/client_spec.rb +1 -2
  114. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  115. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  116. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  117. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  118. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3792 -1373
  119. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
  120. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
  121. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
  122. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
  123. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  124. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  125. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  126. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  127. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  128. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +29 -28
  129. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  130. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  131. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  132. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  133. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  134. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  135. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  136. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  137. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  138. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  139. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  140. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  141. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  142. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  143. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  144. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  145. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  146. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  147. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +56 -79
  148. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
  149. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
  150. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
  151. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
  152. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
  153. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
  154. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
  155. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
  156. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
  157. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
  158. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
  159. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
  160. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
  161. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
  162. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
  163. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  164. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  165. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +4 -41
  166. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
  167. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
  168. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  169. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  170. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  171. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  172. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  173. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -25
  174. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  175. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  176. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  177. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +10 -22
  178. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  179. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
  180. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
  181. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
  182. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  183. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  184. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  185. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  186. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +1 -1
  187. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
  188. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
  189. data/spec/support/bin_helper.rb +9 -0
  190. data.tar.gz.sig +0 -0
  191. metadata +96 -5
  192. metadata.gz.sig +0 -0
  193. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
  194. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -135
@@ -0,0 +1,23 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Samr
4
+
5
+ # [3.1.5.13.5 SamrRidToSid (Opnum 65)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/00ff8192-a4f6-45ba-9f65-917e46b6a693)
6
+ class SamrRidToSidResponse < BinData::Record
7
+ attr_reader :opnum
8
+
9
+ endian :little
10
+
11
+ prpc_sid :sid
12
+ ndr_uint32 :error_status
13
+
14
+ def initialize_instance
15
+ super
16
+ @opnum = SAMR_RID_TO_SID
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,613 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Samr
4
+
5
+ UUID = '12345778-1234-abcd-ef00-0123456789ac'
6
+ VER_MAJOR = 1
7
+ VER_MINOR = 0
8
+
9
+ # Operation numbers
10
+ SAMR_CONNECT = 0x0000
11
+ SAMR_CLOSE_HANDLE = 0x0001
12
+ SAMR_LOOKUP_DOMAIN_IN_SAM_SERVER = 0x0005
13
+ SAMR_OPEN_DOMAIN = 0x0007
14
+ SAMR_ENUMERATE_USERS_IN_DOMAIN = 0x000D
15
+ SAMR_GET_ALIAS_MEMBERSHIP = 0x0010
16
+ SAMR_OPEN_USER = 0x0022
17
+ SAMR_GET_GROUPS_FOR_USER = 0x0027
18
+ SAMR_RID_TO_SID = 0x0041
19
+
20
+ class SamprHandle < Ndr::NdrContextHandle; end
21
+
22
+ # [2.2.10.2 USER_PROPERTY](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/7c0f2eca-1783-450b-b5a0-754cf11f22c9)
23
+ class UserProperty < BinData::Record
24
+ endian :little
25
+
26
+ uint16 :name_length, initial_value: -> { property_name.num_bytes }
27
+ uint16 :value_length, initial_value: -> { property_value.num_bytes }
28
+ uint16 :reserved
29
+ string16 :property_name, read_length: :name_length
30
+ string :property_value, read_length: :value_length
31
+ end
32
+
33
+ # [2.2.10.1 USER_PROPERTIES](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/8263e7ab-aba9-43d2-8a36-3a9cb2dd3dad)
34
+ class UserProperties < BinData::Record
35
+ endian :little
36
+
37
+ uint32 :reserved1
38
+ uint32 :struct_length, initial_value: -> { num_bytes - 12 }
39
+ uint16 :reserved2
40
+ uint16 :reserved3
41
+ string :reserved4, length: 96
42
+ uint16 :property_signature, initial_value: 0x50
43
+ uint16 :property_count, initial_value: -> { user_properties.size }
44
+ array :user_properties, type: :user_property, initial_length: :property_count
45
+ uint8 :reserved5
46
+ end
47
+
48
+ class KerbKeyDataNew < BinData::Record
49
+ endian :little
50
+
51
+ uint16 :reserved1
52
+ uint16 :reserved2
53
+ uint32 :reserved3
54
+ uint32 :iteration_count
55
+ uint32 :key_type
56
+ uint32 :key_length
57
+ uint32 :key_offset
58
+ end
59
+
60
+ # [2.2.10.6 Primary:Kerberos-Newer-Keys - KERB_STORED_CREDENTIAL_NEW](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/08cb3ca7-954b-45e3-902e-77512fe3ba8e)
61
+ class KerbStoredCredentialNew < BinData::Record
62
+ endian :little
63
+
64
+ uint16 :revision
65
+ uint16 :flags
66
+ uint16 :credential_count
67
+ uint16 :service_credential_count
68
+ uint16 :old_credential_count
69
+ uint16 :older_credential_count
70
+ uint16 :default_salt_length
71
+ uint16 :default_salt_maximum_length
72
+ uint32 :default_salt_offset
73
+ uint32 :default_iteration_count
74
+ array :credentials, type: :kerb_key_data_new, initial_length: :credential_count
75
+ array :service_credentials, type: :kerb_key_data_new, initial_length: :service_credential_count
76
+ array :old_credentials, type: :kerb_key_data_new, initial_length: :old_credential_count
77
+ array :older_credentials, type: :kerb_key_data_new, initial_length: :older_credential_count
78
+ string :default_salt, read_length: -> { credentials.map { |e| e.key_offset }.min - @obj.abs_offset }
79
+ string :key_values, read_length: -> { credentials.map { |e| e.key_length }.sum }
80
+
81
+ def get_key_values
82
+ credentials.map do |credential|
83
+ offset = credential.key_offset - key_values.abs_offset
84
+ key_values[offset, credential.key_length]
85
+ end
86
+ end
87
+ end
88
+
89
+
90
+ #################################
91
+ # Constants #
92
+ #################################
93
+
94
+
95
+ ################
96
+ # ACCESS_MASK Values
97
+
98
+ # [2.2.1.1 Common ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/15b9ebf7-161d-4c83-a672-dceb2ac8c448)
99
+ DELETE = 0x00010000
100
+ READ_CONTROL = 0x00020000
101
+ WRITE_DAC = 0x00040000
102
+ WRITE_OWNER = 0x00080000
103
+ ACCESS_SYSTEM_SECURITY = 0x01000000
104
+ MAXIMUM_ALLOWED = 0x02000000
105
+
106
+
107
+ # [2.2.1.3 Server ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/e8afb15e-c053-4984-b84b-66877236e141)
108
+ SAM_SERVER_CONNECT = 0x00000001
109
+ SAM_SERVER_SHUTDOWN = 0x00000002
110
+ SAM_SERVER_INITIALIZE = 0x00000004
111
+ SAM_SERVER_CREATE_DOMAIN = 0x00000008
112
+ SAM_SERVER_ENUMERATE_DOMAINS = 0x00000010
113
+ SAM_SERVER_LOOKUP_DOMAIN = 0x00000020
114
+ SAM_SERVER_ALL_ACCESS = 0x000F003F
115
+ SAM_SERVER_READ = 0x00020010
116
+ SAM_SERVER_WRITE = 0x0002000E
117
+ SAM_SERVER_EXECUTE = 0x00020021
118
+
119
+ # [2.2.1.4 Domain ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/aef23495-f6aa-48e9-aebc-22e022a2b4eb)
120
+ DOMAIN_READ_PASSWORD_PARAMETERS = 0x00000001
121
+ DOMAIN_WRITE_PASSWORD_PARAMS = 0x00000002
122
+ DOMAIN_READ_OTHER_PARAMETERS = 0x00000004
123
+ DOMAIN_WRITE_OTHER_PARAMETERS = 0x00000008
124
+ DOMAIN_CREATE_USER = 0x00000010
125
+ DOMAIN_CREATE_GROUP = 0x00000020
126
+ DOMAIN_CREATE_ALIAS = 0x00000040
127
+ DOMAIN_GET_ALIAS_MEMBERSHIP = 0x00000080
128
+ DOMAIN_LIST_ACCOUNTS = 0x00000100
129
+ DOMAIN_LOOKUP = 0x00000200
130
+ DOMAIN_ADMINISTER_SERVER = 0x00000400
131
+ DOMAIN_ALL_ACCESS = 0x000F07FF
132
+ DOMAIN_READ = 0x00020084
133
+ DOMAIN_WRITE = 0x0002047A
134
+ DOMAIN_EXECUTE = 0x00020301
135
+
136
+ # [2.2.1.5 Group ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/f24f9fa8-798d-4e7d-a110-a5eda6900f41)
137
+ GROUP_READ_INFORMATION = 0x00000001
138
+ GROUP_WRITE_ACCOUNT = 0x00000002
139
+ GROUP_ADD_MEMBER = 0x00000004
140
+ GROUP_REMOVE_MEMBER = 0x00000008
141
+ GROUP_LIST_MEMBERS = 0x00000010
142
+ GROUP_ALL_ACCESS = 0x000F001F
143
+ GROUP_READ = 0x00020010
144
+ GROUP_WRITE = 0x0002000E
145
+ GROUP_EXECUTE = 0x00020001
146
+
147
+ # [2.2.1.6 Alias ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/2da21c6c-5b15-46c8-bd4e-6a8443216e1a)
148
+ ALIAS_ADD_MEMBER = 0x00000001
149
+ ALIAS_REMOVE_MEMBER = 0x00000002
150
+ ALIAS_LIST_MEMBERS = 0x00000004
151
+ ALIAS_READ_INFORMATION = 0x00000008
152
+ ALIAS_WRITE_ACCOUNT = 0x00000010
153
+ ALIAS_ALL_ACCESS = 0x000F001F
154
+ ALIAS_READ = 0x00020004
155
+ ALIAS_WRITE = 0x00020013
156
+ ALIAS_EXECUTE = 0x00020008
157
+
158
+ # [2.2.1.7 User ACCESS_MASK Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/c0be3f43-bcf9-43ee-b027-3d02ab372c53)
159
+ USER_READ_GENERAL = 0x00000001
160
+ USER_READ_PREFERENCES = 0x00000002
161
+ USER_WRITE_PREFERENCES = 0x00000004
162
+ USER_READ_LOGON = 0x00000008
163
+ USER_READ_ACCOUNT = 0x00000010
164
+ USER_WRITE_ACCOUNT = 0x00000020
165
+ USER_CHANGE_PASSWORD = 0x00000040
166
+ USER_FORCE_PASSWORD_CHANGE = 0x00000080
167
+ USER_LIST_GROUPS = 0x00000100
168
+ USER_READ_GROUP_INFORMATION = 0x00000200
169
+ USER_WRITE_GROUP_INFORMATION = 0x00000400
170
+ USER_ALL_ACCESS = 0x000F07FF
171
+ USER_READ = 0x0002031A
172
+ USER_WRITE = 0x00020044
173
+ USER_EXECUTE = 0x00020041
174
+
175
+ # [2.2.1.8 USER_ALL Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/2675c176-72e0-4ac9-ae6d-cdd87b8ba520)
176
+ USER_ALL_USERNAME = 0x00000001
177
+ USER_ALL_FULLNAME = 0x00000002
178
+ USER_ALL_USERID = 0x00000004
179
+ USER_ALL_PRIMARYGROUPID = 0x00000008
180
+ USER_ALL_ADMINCOMMENT = 0x00000010
181
+ USER_ALL_USERCOMMENT = 0x00000020
182
+ USER_ALL_HOMEDIRECTORY = 0x00000040
183
+ USER_ALL_HOMEDIRECTORYDRIVE = 0x00000080
184
+ USER_ALL_SCRIPTPATH = 0x00000100
185
+ USER_ALL_PROFILEPATH = 0x00000200
186
+ USER_ALL_WORKSTATIONS = 0x00000400
187
+ USER_ALL_LASTLOGON = 0x00000800
188
+ USER_ALL_LASTLOGOFF = 0x00001000
189
+ USER_ALL_LOGONHOURS = 0x00002000
190
+ USER_ALL_BADPASSWORDCOUNT = 0x00004000
191
+ USER_ALL_LOGONCOUNT = 0x00008000
192
+ USER_ALL_PASSWORDCANCHANGE = 0x00010000
193
+ USER_ALL_PASSWORDMUSTCHANGE = 0x00020000
194
+ USER_ALL_PASSWORDLASTSET = 0x00040000
195
+ USER_ALL_ACCOUNTEXPIRES = 0x00080000
196
+ USER_ALL_USERACCOUNTCONTROL = 0x00100000
197
+ USER_ALL_PARAMETERS = 0x00200000
198
+ USER_ALL_COUNTRYCODE = 0x00400000
199
+ USER_ALL_CODEPAGE = 0x00800000
200
+ USER_ALL_NTPASSWORDPRESENT = 0x01000000
201
+ USER_ALL_LMPASSWORDPRESENT = 0x02000000
202
+ USER_ALL_PRIVATEDATA = 0x04000000
203
+ USER_ALL_PASSWORDEXPIRED = 0x08000000
204
+ USER_ALL_SECURITYDESCRIPTOR = 0x10000000
205
+ USER_ALL_UNDEFINED_MASK = 0xC0000000
206
+
207
+ # [2.2.1.9 ACCOUNT_TYPE Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/e742be45-665d-4576-b872-0bc99d1e1fbe)
208
+ SAM_DOMAIN_OBJECT = 0x00000000
209
+ SAM_GROUP_OBJECT = 0x10000000
210
+ SAM_NON_SECURITY_GROUP_OBJECT = 0x10000001
211
+ SAM_ALIAS_OBJECT = 0x20000000
212
+ SAM_NON_SECURITY_ALIAS_OBJECT = 0x20000001
213
+ SAM_USER_OBJECT = 0x30000000
214
+ SAM_MACHINE_ACCOUNT = 0x30000001
215
+ SAM_TRUST_ACCOUNT = 0x30000002
216
+ SAM_APP_BASIC_GROUP = 0x40000000
217
+ SAM_APP_QUERY_GROUP = 0x40000001
218
+
219
+ # [2.2.1.10 SE_GROUP Attributes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/9e093bd2-e451-4dd5-9700-97b977d7ebb2)
220
+ SE_GROUP_MANDATORY = 0x00000001
221
+ SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002
222
+ SE_GROUP_ENABLED = 0x00000004
223
+
224
+ # [2.2.1.11 GROUP_TYPE Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1f8d7ea1-fcc1-4833-839a-f94d67c08fcd)
225
+ GROUP_TYPE_ACCOUNT_GROUP = 0x00000002
226
+ GROUP_TYPE_RESOURCE_GROUP = 0x00000004
227
+ GROUP_TYPE_UNIVERSAL_GROUP = 0x00000008
228
+ GROUP_TYPE_SECURITY_ENABLED = 0x80000000
229
+ GROUP_TYPE_SECURITY_ACCOUNT = 0x80000002
230
+ GROUP_TYPE_SECURITY_RESOURCE = 0x80000004
231
+ GROUP_TYPE_SECURITY_UNIVERSAL = 0x80000008
232
+
233
+ # [2.2.1.12 USER_ACCOUNT Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/b10cfda1-f24f-441b-8f43-80cb93e786ec)
234
+ USER_ACCOUNT_DISABLED = 0x00000001
235
+ USER_HOME_DIRECTORY_REQUIRED = 0x00000002
236
+ USER_PASSWORD_NOT_REQUIRED = 0x00000004
237
+ USER_TEMP_DUPLICATE_ACCOUNT = 0x00000008
238
+ USER_NORMAL_ACCOUNT = 0x00000010
239
+ USER_MNS_LOGON_ACCOUNT = 0x00000020
240
+ USER_INTERDOMAIN_TRUST_ACCOUNT = 0x00000040
241
+ USER_WORKSTATION_TRUST_ACCOUNT = 0x00000080
242
+ USER_SERVER_TRUST_ACCOUNT = 0x00000100
243
+ USER_DONT_EXPIRE_PASSWORD = 0x00000200
244
+ USER_ACCOUNT_AUTO_LOCKED = 0x00000400
245
+ USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000800
246
+ USER_SMARTCARD_REQUIRED = 0x00001000
247
+ USER_TRUSTED_FOR_DELEGATION = 0x00002000
248
+ USER_NOT_DELEGATED = 0x00004000
249
+ USER_USE_DES_KEY_ONLY = 0x00008000
250
+ USER_DONT_REQUIRE_PREAUTH = 0x00010000
251
+ USER_PASSWORD_EXPIRED = 0x00020000
252
+ USER_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x00040000
253
+ USER_NO_AUTH_DATA_REQUIRED = 0x00080000
254
+ USER_PARTIAL_SECRETS_ACCOUNT = 0x00100000
255
+ USER_USE_AES_KEYS = 0x00200000
256
+
257
+ # [2.2.1.13 UF_FLAG Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/10bf6c8e-34af-4cf9-8dff-6b6330922863)
258
+ UF_SCRIPT = 0x00000001
259
+ UF_ACCOUNTDISABLE = 0x00000002
260
+ UF_HOMEDIR_REQUIRED = 0x00000008
261
+ UF_LOCKOUT = 0x00000010
262
+ UF_PASSWD_NOTREQD = 0x00000020
263
+ UF_PASSWD_CANT_CHANGE = 0x00000040
264
+ UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000080
265
+ UF_TEMP_DUPLICATE_ACCOUNT = 0x00000100
266
+ UF_NORMAL_ACCOUNT = 0x00000200
267
+ UF_INTERDOMAIN_TRUST_ACCOUNT = 0x00000800
268
+ UF_WORKSTATION_TRUST_ACCOUNT = 0x00001000
269
+ UF_SERVER_TRUST_ACCOUNT = 0x00002000
270
+ UF_DONT_EXPIRE_PASSWD = 0x00010000
271
+ UF_MNS_LOGON_ACCOUNT = 0x00020000
272
+ UF_SMARTCARD_REQUIRED = 0x00040000
273
+ UF_TRUSTED_FOR_DELEGATION = 0x00080000
274
+ UF_NOT_DELEGATED = 0x00100000
275
+ UF_USE_DES_KEY_ONLY = 0x00200000
276
+ UF_DONT_REQUIRE_PREAUTH = 0x00400000
277
+ UF_PASSWORD_EXPIRED = 0x00800000
278
+ UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x01000000
279
+ UF_NO_AUTH_DATA_REQUIRED = 0x02000000
280
+ UF_PARTIAL_SECRETS_ACCOUNT = 0x04000000
281
+ UF_USE_AES_KEYS = 0x08000000
282
+
283
+ # [2.2.1.14 Predefined RIDs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/565a6584-3061-4ede-a531-f5c53826504b)
284
+ DOMAIN_USER_RID_ADMIN = 0x000001F4
285
+ DOMAIN_USER_RID_GUEST = 0x000001F5
286
+ DOMAIN_USER_RID_KRBTGT = 0x000001F6
287
+ DOMAIN_GROUP_RID_ADMINS = 0x00000200
288
+ DOMAIN_GROUP_RID_USERS = 0x00000201
289
+ DOMAIN_GROUP_RID_COMPUTERS = 0x00000203
290
+ DOMAIN_GROUP_RID_CONTROLLERS = 0x00000204
291
+ DOMAIN_ALIAS_RID_ADMINS = 0x00000220
292
+ DOMAIN_GROUP_RID_READONLY_CONTROLLERS = 0x00000209
293
+
294
+ # [2.2.10.8 Kerberos Encryption Algorithm Identifiers](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1355fa6b-d097-4ecc-8d5e-75b3a6533e04)
295
+ KERBEROS_TYPE = {
296
+ 1 => 'dec-cbc-crc',
297
+ 3 => 'des-cbc-md5',
298
+ 17 => 'aes128-cts-hmac-sha1-96',
299
+ 18 => 'aes256-cts-hmac-sha1-96',
300
+ 0xffffff74 => 'rc4_hmac'
301
+ }
302
+
303
+ require 'ruby_smb/dcerpc/samr/rpc_sid'
304
+
305
+ require 'ruby_smb/dcerpc/samr/samr_connect_request'
306
+ require 'ruby_smb/dcerpc/samr/samr_connect_response'
307
+ require 'ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request'
308
+ require 'ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response'
309
+ require 'ruby_smb/dcerpc/samr/samr_open_domain_request'
310
+ require 'ruby_smb/dcerpc/samr/samr_open_domain_response'
311
+ require 'ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request'
312
+ require 'ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response'
313
+ require 'ruby_smb/dcerpc/samr/samr_rid_to_sid_request'
314
+ require 'ruby_smb/dcerpc/samr/samr_rid_to_sid_response'
315
+ require 'ruby_smb/dcerpc/samr/samr_close_handle_request'
316
+ require 'ruby_smb/dcerpc/samr/samr_close_handle_response'
317
+ require 'ruby_smb/dcerpc/samr/samr_get_alias_membership_request'
318
+ require 'ruby_smb/dcerpc/samr/samr_get_alias_membership_response'
319
+ require 'ruby_smb/dcerpc/samr/samr_open_user_request'
320
+ require 'ruby_smb/dcerpc/samr/samr_open_user_response'
321
+ require 'ruby_smb/dcerpc/samr/samr_get_groups_for_user_request'
322
+ require 'ruby_smb/dcerpc/samr/samr_get_groups_for_user_response'
323
+
324
+ # Returns a handle to a server object.
325
+ #
326
+ # @param server_name [Char] the first character of the NETBIOS name of
327
+ # the server (optional)
328
+ # @param access [Numeric] access requested for ServerHandle upon output:
329
+ # bitwise OR of common and server ACCESS_MASK values (defined in
330
+ # lib/ruby_smb/dcerpc/samr.rb).
331
+ # @return [RubySMB::Dcerpc::Samr::SamprHandle] handle to the server object.
332
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
333
+ # SamrConnectResponse packet
334
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
335
+ # is not STATUS_SUCCESS
336
+ def samr_connect(server_name: '', access: MAXIMUM_ALLOWED)
337
+ samr_connect_request = SamrConnectRequest.new(
338
+ server_name: server_name,
339
+ desired_access: access
340
+ )
341
+ response = dcerpc_request(samr_connect_request)
342
+ begin
343
+ samr_connect_response = SamrConnectResponse.read(response)
344
+ rescue IOError
345
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrConnectResponse'
346
+ end
347
+ unless samr_connect_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
348
+ raise RubySMB::Dcerpc::Error::SamrError,
349
+ "Error returned with samr_connect: "\
350
+ "#{WindowsError::NTStatus.find_by_retval(samr_connect_response.error_status.value).join(',')}"
351
+ end
352
+ samr_connect_response.server_handle
353
+ end
354
+
355
+ # Obtains the SID of a domain object
356
+ #
357
+ # @param server_handle [RubySMB::Dcerpc::Samr::SamprHandle] RPC context
358
+ # handle representing the server object
359
+ # @param name [String] The domain name
360
+ # @return [RubySMB::Dcerpc::RpcSid] SID value of a domain that
361
+ # corresponds to the Name passed in
362
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
363
+ # SamrLookupDomainInSamServerResponse packet
364
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
365
+ # is not STATUS_SUCCESS
366
+ def samr_lookup_domain(server_handle:, name:)
367
+ samr_lookup_domain_in_sam_server_request = SamrLookupDomainInSamServerRequest.new(
368
+ server_handle: server_handle,
369
+ name: name
370
+ )
371
+ response = dcerpc_request(samr_lookup_domain_in_sam_server_request)
372
+ begin
373
+ samr_lookup_domain_in_sam_server_response = SamrLookupDomainInSamServerResponse.read(response)
374
+ rescue IOError
375
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrLookupDomainInSamServerResponse'
376
+ end
377
+ unless samr_lookup_domain_in_sam_server_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
378
+ raise RubySMB::Dcerpc::Error::SamrError,
379
+ "Error returned during domain lookup in SAM server: "\
380
+ "#{WindowsError::NTStatus.find_by_retval(samr_lookup_domain_in_sam_server_response.error_status.value).join(',')}"
381
+ end
382
+ samr_lookup_domain_in_sam_server_response.domain_id
383
+ end
384
+
385
+ # Returns a handle to a domain object.
386
+ #
387
+ # @param server_handle [RubySMB::Dcerpc::Samr::SamprHandle] RPC context
388
+ # handle representing the server object
389
+ # @param access [Numeric] access requested for ServerHandle upon output:
390
+ # bitwise OR of common and server ACCESS_MASK values (defined in
391
+ # lib/ruby_smb/dcerpc/samr.rb).
392
+ # @param domain_id [RubySMB::Dcerpc::RpcSid] SID value of a domain
393
+ # @return [RubySMB::Dcerpc::Samr::SamprHandle] handle to the domain object.
394
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
395
+ # SamrOpenDomainResponse packet
396
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
397
+ # is not STATUS_SUCCESS
398
+ def samr_open_domain(server_handle:, access: MAXIMUM_ALLOWED, domain_id:)
399
+ samr_open_domain_request = SamrOpenDomainRequest.new(
400
+ server_handle: server_handle,
401
+ desired_access: access,
402
+ domain_id: domain_id
403
+ )
404
+ response = dcerpc_request(samr_open_domain_request)
405
+ begin
406
+ samr_open_domain_response = SamrOpenDomainResponse.read(response)
407
+ rescue IOError
408
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrLookupDomainInSamServerResponse'
409
+ end
410
+ unless samr_open_domain_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
411
+ raise RubySMB::Dcerpc::Error::SamrError,
412
+ "Error returned during domain lookup in SAM server: "\
413
+ "#{WindowsError::NTStatus.find_by_retval(samr_open_domain_response.error_status.value).join(',')}"
414
+ end
415
+ samr_open_domain_response.domain_handle
416
+ end
417
+
418
+ # Enumerates all users in the specified domain.
419
+ #
420
+ # @param domain_handle [RubySMB::Dcerpc::Samr::SamprHandle] RPC context
421
+ # handle representing the domain object
422
+ # @return [Hash] hash mapping RID and username
423
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
424
+ # SamrEnumerateUsersInDomainResponse packet
425
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
426
+ # is not STATUS_SUCCESS
427
+ def samr_enumerate_users_in_domain(domain_handle:,
428
+ enumeration_context: 0,
429
+ user_account_control: USER_NORMAL_ACCOUNT |
430
+ USER_WORKSTATION_TRUST_ACCOUNT |
431
+ USER_SERVER_TRUST_ACCOUNT |
432
+ USER_INTERDOMAIN_TRUST_ACCOUNT)
433
+ samr_enum_users_request = SamrEnumerateUsersInDomainRequest.new(
434
+ domain_handle: domain_handle,
435
+ user_account_control: user_account_control,
436
+ prefered_maximum_length: 0xFFFFFFFF
437
+ )
438
+ res = {}
439
+ loop do
440
+ samr_enum_users_request.enumeration_context = enumeration_context
441
+ response = dcerpc_request(samr_enum_users_request)
442
+ begin
443
+ samr_enum_users_reponse= SamrEnumerateUsersInDomainResponse.read(response)
444
+ rescue IOError
445
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrEnumerateUsersInDomainResponse'
446
+ end
447
+ unless samr_enum_users_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS ||
448
+ samr_enum_users_reponse.error_status == WindowsError::NTStatus::STATUS_MORE_ENTRIES
449
+ raise RubySMB::Dcerpc::Error::SamrError,
450
+ "Error returned during users enumeration in SAM server: "\
451
+ "#{WindowsError::NTStatus.find_by_retval(samr_enum_users_reponse.error_status.value).join(',')}"
452
+ end
453
+ samr_enum_users_reponse.buffer.buffer.each_with_object(res) do |entry, hash|
454
+ hash[entry.relative_id] = entry.name.buffer
455
+ end
456
+ break unless samr_enum_users_reponse.error_status == WindowsError::NTStatus::STATUS_MORE_ENTRIES
457
+ enumeration_context = samr_enum_users_reponse.enumeration_context
458
+ end
459
+ res
460
+ end
461
+
462
+ # Returns the SID of an account, given a RID.
463
+ #
464
+ # @param rid [Numeric] the RID
465
+ # @return [String] The SID of the account referenced by RID
466
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
467
+ # SamrRidToSidResponse packet
468
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
469
+ # is not STATUS_SUCCESS
470
+ def samr_rid_to_sid(object_handle:, rid:)
471
+ samr_rid_to_sid_request = SamrRidToSidRequest.new(
472
+ object_handle: object_handle,
473
+ rid: rid
474
+ )
475
+ response = dcerpc_request(samr_rid_to_sid_request)
476
+ begin
477
+ samr_rid_to_sid_response = SamrRidToSidResponse.read(response)
478
+ rescue IOError
479
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrRidToSidResponse'
480
+ end
481
+ unless samr_rid_to_sid_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
482
+ raise RubySMB::Dcerpc::Error::SamrError,
483
+ "Error returned during SID lookup in SAM server: "\
484
+ "#{WindowsError::NTStatus.find_by_retval(samr_rid_to_sid_response.error_status.value).join(',')}"
485
+ end
486
+ samr_rid_to_sid_response.sid
487
+ end
488
+
489
+ # Closes (that is, releases server-side resources used by) any context
490
+ # handle obtained from this RPC interface
491
+ #
492
+ # @param sam_handle [RubySMB::Dcerpc::Samr::SamprHandle] An RPC context
493
+ # handle to close
494
+ # @return [RubySMB::Dcerpc::Samr::SamprHandle] A zero handle on success
495
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
496
+ # SamrCloseHandle packet
497
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
498
+ # is not STATUS_SUCCESS
499
+ def close_handle(sam_handle)
500
+ samr_close_handle_request = SamrCloseHandleRequest.new(sam_handle: sam_handle)
501
+ response = dcerpc_request(samr_close_handle_request)
502
+ begin
503
+ samr_close_handle_response = SamrCloseHandleResponse.read(response)
504
+ rescue IOError
505
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrCloseHandleResponse'
506
+ end
507
+ unless samr_close_handle_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
508
+ raise RubySMB::Dcerpc::Error::SamrError,
509
+ "Error returned with samr_connect: "\
510
+ "#{WindowsError::NTStatus.find_by_retval(samr_close_handle_response.error_status.value).join(',')}"
511
+ end
512
+ samr_close_handle_response.sam_handle
513
+ end
514
+
515
+ # Returns the union of all aliases that a given set of SIDs is a member of.
516
+ #
517
+ # @param domain_handle [RubySMB::Dcerpc::Samr::SamprHandle] An RPC context
518
+ # representing a domain object.
519
+ # @param sids [Array<RubySMB::Dcerpc::Samr::RpcSid>, RubySMB::Dcerpc::Samr::RpcSid] List of SID's
520
+ # @return [Array<RubySMB::Dcerpc::Ndr::NdrUint32>] The union of all aliases represented by RID's
521
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
522
+ # SamrGetAliasMembership packet
523
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
524
+ # is not STATUS_SUCCESS
525
+ def samr_get_alias_membership(domain_handle:, sids:)
526
+ sids = [sids] unless sids.is_a?(::Array)
527
+ samr_get_alias_membership_request = SamrGetAliasMembershipRequest.new(
528
+ domain_handle: domain_handle
529
+ )
530
+ sids.each do |sid|
531
+ samr_get_alias_membership_request.sid_array.sids << {sid_pointer: sid}
532
+ end
533
+ response = dcerpc_request(samr_get_alias_membership_request)
534
+ begin
535
+ samr_get_alias_membership_reponse= SamrGetAliasMembershipResponse.read(response)
536
+ rescue IOError
537
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrGetAliasMembershipResponse'
538
+ end
539
+ unless samr_get_alias_membership_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS
540
+ raise RubySMB::Dcerpc::Error::SamrError,
541
+ "Error returned while getting alias membership: "\
542
+ "#{WindowsError::NTStatus.find_by_retval(samr_get_alias_membership_reponse.error_status.value).join(',')}"
543
+ end
544
+ return [] if samr_get_alias_membership_reponse.membership.elem_count == 0
545
+ samr_get_alias_membership_reponse.membership.elements.to_ary
546
+ end
547
+
548
+ # Returns a handle to a user, given a RID
549
+ #
550
+ # @param domain_handle [RubySMB::Dcerpc::Samr::SamprHandle] An RPC context
551
+ # representing a domain object
552
+ # @param access [Integer] An access control that indicates the requested
553
+ # access for the returned handle. It is a bitwise OR of common
554
+ # ACCESS_MASK and user ACCESS_MASK values (see
555
+ # lib/ruby_smb/dcerpc/samr.rb)
556
+ # @param user_id [Integer] RID of a user account
557
+ # @return [RubySMB::Dcerpc::Samr::SamprHandle] The user handle
558
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
559
+ # SamrOpenUser packet
560
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
561
+ # is not STATUS_SUCCESS
562
+ def samr_open_user(domain_handle:, access: MAXIMUM_ALLOWED, user_id:)
563
+ samr_open_user_request = SamrOpenUserRequest.new(
564
+ domain_handle: domain_handle,
565
+ desired_access: access,
566
+ user_id: user_id
567
+ )
568
+ response = dcerpc_request(samr_open_user_request)
569
+ begin
570
+ samr_open_user_response = SamrOpenUserResponse.read(response)
571
+ rescue IOError
572
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrOpenUserResponse'
573
+ end
574
+ unless samr_open_user_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
575
+ raise RubySMB::Dcerpc::Error::SamrError,
576
+ "Error returned when getting a handle to user #{user_id}: "\
577
+ "#{WindowsError::NTStatus.find_by_retval(samr_open_user_response.error_status.value).join(',')}"
578
+ end
579
+ samr_open_user_response.user_handle
580
+ end
581
+
582
+ # Returns a listing of groups that a user is a member of
583
+ #
584
+ # @param user_handle [RubySMB::Dcerpc::Samr::SamprHandle] An RPC context
585
+ # representing a user object.
586
+ # @return [Array<RubySMB::Dcerpc::Samr::GroupMembership>] Array of
587
+ # GroupMembership containing RID and Attributes
588
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
589
+ # SamrGetGroupsForUser packet
590
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
591
+ # is not STATUS_SUCCESS
592
+ def samr_get_group_for_user(user_handle:)
593
+ samr_get_groups_for_user_request = SamrGetGroupsForUserRequest.new(
594
+ user_handle: user_handle
595
+ )
596
+ response = dcerpc_request(samr_get_groups_for_user_request)
597
+ begin
598
+ samr_get_groups_for_user_reponse= SamrGetGroupsForUserResponse.read(response)
599
+ rescue IOError
600
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading SamrGetGroupsForUserResponse'
601
+ end
602
+ unless samr_get_groups_for_user_reponse.error_status == WindowsError::NTStatus::STATUS_SUCCESS
603
+ raise RubySMB::Dcerpc::Error::SamrError,
604
+ "Error returned while getting user groups: "\
605
+ "#{WindowsError::NTStatus.find_by_retval(samr_get_groups_for_user_reponse.error_status.value).join(',')}"
606
+ end
607
+ samr_get_groups_for_user_reponse.groups.groups.to_ary
608
+ end
609
+
610
+ end
611
+ end
612
+ end
613
+
@@ -0,0 +1,26 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+
4
+ # [2.2.2.11 sec_trailer Structure](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rpce/ab45c6a5-951a-4096-b805-7347674dc6ab)
5
+ class SecTrailer < Ndr::NdrStruct
6
+ # Disabling auto alignment since it is handled by the parent structure directly
7
+ default_parameter byte_align: 1
8
+ endian :little
9
+
10
+ ndr_uint8 :auth_type
11
+ ndr_uint8 :auth_level
12
+ ndr_uint8 :auth_pad_length, initial_value: -> { get_auth_pad_length(@obj) }
13
+ ndr_uint8 :auth_reserved
14
+ ndr_uint32 :auth_context_id
15
+
16
+ def get_auth_pad_length(obj)
17
+ parent = obj&.parent&.parent
18
+ if parent&.respond_to?(:auth_pad)
19
+ return parent.auth_pad.length if parent.auth_pad.respond_to?(:length)
20
+ end
21
+ 0
22
+ end
23
+ end
24
+
25
+ end
26
+ end