ruby_smb 2.0.11 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +5 -16
  4. data/examples/auth_capture.rb +28 -0
  5. data/examples/dump_secrets_from_sid.rb +207 -0
  6. data/examples/enum_domain_users.rb +75 -0
  7. data/examples/file_server.rb +76 -0
  8. data/examples/get_computer_info.rb +42 -0
  9. data/examples/query_service_status.rb +42 -4
  10. data/lib/ruby_smb/client.rb +3 -14
  11. data/lib/ruby_smb/create_actions.rb +21 -0
  12. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  13. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  14. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  15. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  16. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  17. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  18. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  19. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  20. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  21. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  22. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  23. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  24. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  25. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  26. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  27. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  28. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  29. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  30. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  31. data/lib/ruby_smb/dcerpc/error.rb +17 -0
  32. data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
  33. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
  34. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
  35. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
  36. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
  37. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
  38. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
  39. data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
  40. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  41. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  42. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  43. data/lib/ruby_smb/dcerpc/request.rb +79 -32
  44. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  45. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  46. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +11 -11
  47. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  48. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  49. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  50. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  51. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  52. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  53. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  54. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  55. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  56. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  57. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  58. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  59. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  60. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  61. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  62. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  63. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  64. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  65. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  66. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  67. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  68. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  69. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  70. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  71. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +13 -25
  72. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
  73. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
  74. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
  75. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
  76. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
  77. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
  78. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
  79. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
  80. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
  81. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
  82. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
  83. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
  84. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
  85. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
  86. data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
  87. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  88. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  89. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +2 -13
  90. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
  91. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
  92. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  93. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  94. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  95. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  96. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  97. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +5 -6
  98. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  99. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  100. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
  101. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  102. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  103. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +0 -9
  104. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
  105. data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
  106. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  107. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  108. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  109. data/lib/ruby_smb/dcerpc.rb +41 -11
  110. data/lib/ruby_smb/field/file_time.rb +1 -1
  111. data/lib/ruby_smb/field/nt_status.rb +20 -1
  112. data/lib/ruby_smb/field/string16.rb +5 -1
  113. data/lib/ruby_smb/fscc/file_information/file_ea_information.rb +14 -0
  114. data/lib/ruby_smb/fscc/file_information/file_network_open_information.rb +22 -0
  115. data/lib/ruby_smb/fscc/file_information/file_stream_information.rb +16 -0
  116. data/lib/ruby_smb/fscc/file_information.rb +29 -0
  117. data/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information.rb +46 -0
  118. data/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information.rb +19 -0
  119. data/lib/ruby_smb/fscc/file_system_information.rb +22 -0
  120. data/lib/ruby_smb/fscc.rb +1 -0
  121. data/lib/ruby_smb/generic_packet.rb +6 -0
  122. data/lib/ruby_smb/gss/provider/authenticator.rb +4 -0
  123. data/lib/ruby_smb/gss/provider/ntlm.rb +13 -3
  124. data/lib/ruby_smb/ntlm.rb +18 -2
  125. data/lib/ruby_smb/server/server_client/negotiation.rb +1 -2
  126. data/lib/ruby_smb/server/server_client/session_setup.rb +44 -33
  127. data/lib/ruby_smb/server/server_client/share_io.rb +28 -0
  128. data/lib/ruby_smb/server/server_client/tree_connect.rb +60 -0
  129. data/lib/ruby_smb/server/server_client.rb +214 -25
  130. data/lib/ruby_smb/server/session.rb +71 -0
  131. data/lib/ruby_smb/server/share/provider/disk.rb +437 -0
  132. data/lib/ruby_smb/server/share/provider/pipe.rb +27 -0
  133. data/lib/ruby_smb/server/share/provider/processor.rb +76 -0
  134. data/lib/ruby_smb/server/share/provider.rb +38 -0
  135. data/lib/ruby_smb/server/share.rb +11 -0
  136. data/lib/ruby_smb/server.rb +35 -3
  137. data/lib/ruby_smb/signing.rb +37 -11
  138. data/lib/ruby_smb/smb1/commands.rb +4 -0
  139. data/lib/ruby_smb/smb1/pipe.rb +4 -0
  140. data/lib/ruby_smb/smb1.rb +0 -1
  141. data/lib/ruby_smb/smb2/bit_field/smb2_header_flags.rb +2 -1
  142. data/lib/ruby_smb/smb2/commands.rb +4 -0
  143. data/lib/ruby_smb/smb2/create_context/request.rb +64 -0
  144. data/lib/ruby_smb/smb2/create_context/response.rb +62 -0
  145. data/lib/ruby_smb/smb2/create_context.rb +74 -22
  146. data/lib/ruby_smb/smb2/packet/create_request.rb +44 -11
  147. data/lib/ruby_smb/smb2/packet/create_response.rb +17 -3
  148. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +1 -1
  149. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +2 -2
  150. data/lib/ruby_smb/smb2/packet/query_info_request.rb +43 -0
  151. data/lib/ruby_smb/smb2/packet/query_info_response.rb +23 -0
  152. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +1 -1
  153. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -0
  154. data/lib/ruby_smb/smb2/packet.rb +2 -0
  155. data/lib/ruby_smb/smb2/pipe.rb +4 -0
  156. data/lib/ruby_smb/smb2.rb +11 -0
  157. data/lib/ruby_smb/smb_error.rb +110 -0
  158. data/lib/ruby_smb/version.rb +1 -1
  159. data/lib/ruby_smb.rb +2 -0
  160. data/ruby_smb.gemspec +1 -1
  161. data/spec/lib/ruby_smb/client_spec.rb +1 -2
  162. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  163. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  164. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  165. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  166. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3792 -1373
  167. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
  168. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
  169. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
  170. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
  171. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  172. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  173. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  174. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  175. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  176. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +29 -28
  177. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  178. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  179. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  180. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  181. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  182. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  183. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  184. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  185. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  186. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  187. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  188. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  189. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  190. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  191. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  192. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  193. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  194. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  195. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +56 -79
  196. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
  197. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
  198. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
  199. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
  200. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
  201. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
  202. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
  203. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
  204. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
  205. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
  206. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
  207. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
  208. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
  209. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
  210. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
  211. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  212. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  213. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +4 -41
  214. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
  215. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
  216. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  217. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  218. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  219. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  220. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  221. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -25
  222. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  223. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  224. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  225. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +10 -22
  226. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  227. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
  228. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
  229. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
  230. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  231. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  232. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  233. data/spec/lib/ruby_smb/field/nt_status_spec.rb +6 -2
  234. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  235. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +4 -0
  236. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +1 -1
  237. data/spec/lib/ruby_smb/server/server_client_spec.rb +36 -53
  238. data/spec/lib/ruby_smb/server/session_spec.rb +38 -0
  239. data/spec/lib/ruby_smb/server/share/provider/disk_spec.rb +61 -0
  240. data/spec/lib/ruby_smb/server/share/provider/pipe_spec.rb +31 -0
  241. data/spec/lib/ruby_smb/server/share/provider_spec.rb +13 -0
  242. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
  243. data/spec/lib/ruby_smb/smb2/bit_field/header_flags_spec.rb +8 -2
  244. data/spec/lib/ruby_smb/smb2/{create_context_spec.rb → create_context/create_context_request_spec.rb} +1 -1
  245. data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +5 -5
  246. data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +9 -5
  247. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +3 -2
  248. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
  249. data/spec/support/bin_helper.rb +9 -0
  250. data.tar.gz.sig +2 -3
  251. metadata +129 -10
  252. metadata.gz.sig +0 -0
  253. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
  254. data/lib/ruby_smb/smb1/create_actions.rb +0 -20
  255. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -135
@@ -0,0 +1,909 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Drsr
4
+
5
+ UUID = 'E3514235-4B06-11D1-AB04-00C04FC2DCD2'
6
+ VER_MAJOR = 4
7
+ VER_MINOR = 0
8
+
9
+ # [5.138 NTSAPI_CLIENT_GUID](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/d4ff2fb2-bf57-455e-9646-426a92737d6e)
10
+ NTSAPI_CLIENT_GUID = 'e24d201a-4fd6-11d1-a3da-0000f875ae0d'
11
+
12
+ # Operation numbers
13
+ DRS_BIND = 0x0000
14
+ DRS_UNBIND = 0x0001
15
+ DRS_GET_NC_CHANGES = 0x0003
16
+ DRS_CRACK_NAMES = 0x000C
17
+ DRS_DOMAIN_CONTROLLER_INFO = 0x0010
18
+
19
+
20
+ # DRS_EXTENSIONS_INT Flags
21
+ # [5.39 DRS_EXTENSIONS_INT](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/3ee529b1-23db-4996-948a-042f04998e91)
22
+ DRS_EXT_BASE = 0x00000001
23
+ DRS_EXT_ASYNCREPL = 0x00000002
24
+ DRS_EXT_REMOVEAPI = 0x00000004
25
+ DRS_EXT_MOVEREQ_V2 = 0x00000008
26
+ DRS_EXT_GETCHG_DEFLATE = 0x00000010
27
+ DRS_EXT_DCINFO_V1 = 0x00000020
28
+ DRS_EXT_RESTORE_USN_OPTIMIZATION = 0x00000040
29
+ DRS_EXT_ADDENTRY = 0x00000080
30
+ DRS_EXT_KCC_EXECUTE = 0x00000100
31
+ DRS_EXT_ADDENTRY_V2 = 0x00000200
32
+ DRS_EXT_LINKED_VALUE_REPLICATION = 0x00000400
33
+ DRS_EXT_DCINFO_V2 = 0x00000800
34
+ DRS_EXT_INSTANCE_TYPE_NOT_REQ_ON_MOD = 0x00001000
35
+ DRS_EXT_CRYPTO_BIND = 0x00002000
36
+ DRS_EXT_GET_REPL_INFO = 0x00004000
37
+ DRS_EXT_STRONG_ENCRYPTION = 0x00008000
38
+ DRS_EXT_DCINFO_VFFFFFFFF = 0x00010000
39
+ DRS_EXT_TRANSITIVE_MEMBERSHIP = 0x00020000
40
+ DRS_EXT_ADD_SID_HISTORY = 0x00040000
41
+ DRS_EXT_POST_BETA3 = 0x00080000
42
+ DRS_EXT_GETCHGREQ_V5 = 0x00100000
43
+ DRS_EXT_GETMEMBERSHIPS2 = 0x00200000
44
+ DRS_EXT_GETCHGREQ_V6 = 0x00400000
45
+ DRS_EXT_NONDOMAIN_NCS = 0x00800000
46
+ DRS_EXT_GETCHGREQ_V8 = 0x01000000
47
+ DRS_EXT_GETCHGREPLY_V5 = 0x02000000
48
+ DRS_EXT_GETCHGREPLY_V6 = 0x04000000
49
+ DRS_EXT_GETCHGREPLY_V9 = 0x00000100
50
+ DRS_EXT_WHISTLER_BETA3 = 0x08000000
51
+ DRS_EXT_W2K3_DEFLATE = 0x10000000
52
+ DRS_EXT_GETCHGREQ_V10 = 0x20000000
53
+ DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART2 = 0x40000000
54
+ DRS_EXT_RESERVED_FOR_WIN2K_OR_DOTNET_PART3 = 0x80000000
55
+
56
+ # DRS_EXTENSIONS_INT FlagsExt
57
+ # [5.39 DRS_EXTENSIONS_INT](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/3ee529b1-23db-4996-948a-042f04998e91)
58
+ DRS_EXT_ADAM = 0x00000001
59
+ DRS_EXT_LH_BETA2 = 0x00000002
60
+ DRS_EXT_RECYCLE_BIN = 0x00000004
61
+ # DRS_EXT_GETCHGREPLY_V9 = 0x00000100 (already defined)
62
+ DRS_EXT_RPC_CORRELATIONID_1 = 0x00000400
63
+
64
+
65
+ # [5.41 DRS_OPTIONS](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/ac9c8a11-cd46-4080-acbf-9faa86344030)
66
+ DRS_ASYNC_OP = 0x00000001
67
+ DRS_GETCHG_CHECK = 0x00000002
68
+ DRS_UPDATE_NOTIFICATION = 0x00000002
69
+ DRS_ADD_REF = 0x00000004
70
+ DRS_SYNC_ALL = 0x00000008
71
+ DRS_DEL_REF = 0x00000008
72
+ DRS_WRIT_REP = 0x00000010
73
+ DRS_INIT_SYNC = 0x00000020
74
+ DRS_PER_SYNC = 0x00000040
75
+ DRS_MAIL_REP = 0x00000080
76
+ DRS_ASYNC_REP = 0x00000100
77
+ DRS_IGNORE_ERROR = 0x00000100
78
+ DRS_TWOWAY_SYNC = 0x00000200
79
+ DRS_CRITICAL_ONLY = 0x00000400
80
+ DRS_GET_ANC = 0x00000800
81
+ DRS_GET_NC_SIZE = 0x00001000
82
+ DRS_LOCAL_ONLY = 0x00001000
83
+ DRS_NONGC_RO_REP = 0x00002000
84
+ DRS_SYNC_BYNAME = 0x00004000
85
+ DRS_REF_OK = 0x00004000
86
+ DRS_FULL_SYNC_NOW = 0x00008000
87
+ DRS_NO_SOURCE = 0x00008000
88
+ DRS_FULL_SYNC_IN_PROGRESS = 0x00010000
89
+ DRS_FULL_SYNC_PACKET = 0x00020000
90
+ DRS_SYNC_REQUEUE = 0x00040000
91
+ DRS_SYNC_URGENT = 0x00080000
92
+ DRS_REF_GCSPN = 0x00100000
93
+ DRS_NO_DISCARD = 0x00100000
94
+ DRS_NEVER_SYNCED = 0x00200000
95
+ DRS_SPECIAL_SECRET_PROCESSING = 0x00400000
96
+ DRS_INIT_SYNC_NOW = 0x00800000
97
+ DRS_PREEMPTED = 0x01000000
98
+ DRS_SYNC_FORCED = 0x02000000
99
+ DRS_DISABLE_AUTO_SYNC = 0x04000000
100
+ DRS_DISABLE_PERIODIC_SYNC = 0x08000000
101
+ DRS_USE_COMPRESSION = 0x10000000
102
+ DRS_NEVER_NOTIFY = 0x20000000
103
+ DRS_SYNC_PAS = 0x40000000
104
+ DRS_GET_ALL_GROUP_MEMBERSHIP = 0x80000000
105
+
106
+ # [4.1.10.2.22 EXOP_REQ Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/05de65ee-af0d-46d1-a9c8-4f0f856031cb)
107
+ EXOP_FSMO_REQ_ROLE = 0x00000001
108
+ EXOP_FSMO_REQ_RID_ALLOC = 0x00000002
109
+ EXOP_FSMO_RID_REQ_ROLE = 0x00000003
110
+ EXOP_FSMO_REQ_PDC = 0x00000004
111
+ EXOP_FSMO_ABANDON_ROLE = 0x00000005
112
+ EXOP_REPL_OBJ = 0x00000006
113
+ EXOP_REPL_SECRETS = 0x00000007
114
+
115
+ # Enumeration for identifying a compression algorithm.
116
+ # [4.1.10.2.18 DRS_COMP_ALG_TYPE](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/bb303730-0667-49f0-b117-288404c4b4cb)
117
+ DRS_COMP_ALG_NONE = 0,
118
+ DRS_COMP_ALG_UNUSED = 1,
119
+ DRS_COMP_ALG_MSZIP = 2,
120
+ DRS_COMP_ALG_WIN2K3 = 3
121
+
122
+ # [4.1.10.2.21 EXOP_ERR Codes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/bb303730-0667-49f0-b117-288404c4b4cb)
123
+ EXOP_ERR_SUCCESS = 0x00000001
124
+ EXOP_ERR_UNKNOWN_OP = 0x00000002
125
+ EXOP_ERR_FSMO_NOT_OWNER = 0x00000003
126
+ EXOP_ERR_UPDATE_ERR = 0x00000004
127
+ EXOP_ERR_EXCEPTION = 0x00000005
128
+ EXOP_ERR_UNKNOWN_CALLER = 0x00000006
129
+ EXOP_ERR_RID_ALLOC = 0x00000007
130
+ EXOP_ERR_FSMO_OWNER_DELETED = 0x00000008
131
+ EXOP_ERR_FSMO_PENDING_OP = 0x00000009
132
+ EXOP_ERR_MISMATCH = 0x0000000A
133
+ EXOP_ERR_COULDNT_CONTACT = 0x0000000B
134
+ EXOP_ERR_FSMO_REFUSING_ROLES = 0x0000000C
135
+ EXOP_ERR_DIR_ERROR = 0x0000000D
136
+ EXOP_ERR_FSMO_MISSING_SETTINGS = 0x0000000E
137
+ EXOP_ERR_ACCESS_DENIED = 0x0000000F
138
+ EXOP_ERR_PARAM_ERROR = 0x00000010
139
+
140
+ # DRS_MSG_CRACKREQ_V1 dwFlags
141
+ # [4.1.4.1.2 DRS_MSG_CRACKREQ_V1](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/b47debc0-59ee-40e4-ad0f-4bc9f96043b2)
142
+ DS_NAME_FLAG_GCVERIFY = 0x00000004
143
+ DS_NAME_FLAG_TRUST_REFERRAL = 0x00000008
144
+ DS_NAME_FLAG_PRIVATE_RESOLVE_FPOS = 0x80000000
145
+
146
+ # [4.1.4.1.3 DS_NAME_FORMAT](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/73c73cf2-0824-4d65-97f4-f56244f3e8a6)
147
+ DS_UNKNOWN_NAME = 0x00000000,
148
+ DS_FQDN_1779_NAME = 0x00000001,
149
+ DS_NT4_ACCOUNT_NAME = 0x00000002,
150
+ DS_DISPLAY_NAME = 0x00000003,
151
+ DS_UNIQUE_ID_NAME = 0x00000006,
152
+ DS_CANONICAL_NAME = 0x00000007,
153
+ DS_USER_PRINCIPAL_NAME = 0x00000008,
154
+ DS_CANONICAL_NAME_EX = 0x00000009,
155
+ DS_SERVICE_PRINCIPAL_NAME = 0x0000000A,
156
+ DS_SID_OR_SID_HISTORY_NAME = 0x0000000B,
157
+ DS_DNS_DOMAIN_NAME = 0x0000000C
158
+
159
+ # formatOffered: DS_NAME_FORMAT flags, plus these flags
160
+ DS_LIST_SITES = 0xFFFFFFFF
161
+ DS_LIST_SERVERS_IN_SITE = 0xFFFFFFFE
162
+ DS_LIST_DOMAINS_IN_SITE = 0xFFFFFFFD
163
+ DS_LIST_SERVERS_FOR_DOMAIN_IN_SITE = 0xFFFFFFFC
164
+ DS_LIST_INFO_FOR_SERVER = 0xFFFFFFFB
165
+ DS_LIST_ROLES = 0xFFFFFFFA
166
+ DS_NT4_ACCOUNT_NAME_SANS_DOMAIN = 0xFFFFFFF9
167
+ DS_MAP_SCHEMA_GUID = 0xFFFFFFF8
168
+ DS_LIST_DOMAINS = 0xFFFFFFF7
169
+ DS_LIST_NCS = 0xFFFFFFF6
170
+ DS_ALT_SECURITY_IDENTITIES_NAME = 0xFFFFFFF5
171
+ DS_STRING_SID_NAME = 0xFFFFFFF4
172
+ DS_LIST_SERVERS_WITH_DCS_IN_SITE = 0xFFFFFFF3
173
+ DS_LIST_GLOBAL_CATALOG_SERVERS = 0xFFFFFFF1
174
+ DS_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX = 0xFFFFFFF0
175
+ DS_USER_PRINCIPAL_NAME_AND_ALTSECID = 0xFFFFFFEF
176
+
177
+ # formatDesired: DS_NAME_FORMAT flags, plus these flags
178
+ DS_USER_PRINCIPAL_NAME_FOR_LOGON = 0xFFFFFFF2
179
+ # DS_STRING_SID_NAME = 0xFFFFFFF4 (already defined)
180
+
181
+
182
+
183
+ ATTRTYP_TO_ATTID = {
184
+ 'userPrincipalName' => '1.2.840.113556.1.4.656',
185
+ 'sAMAccountName' => '1.2.840.113556.1.4.221',
186
+ 'unicodePwd' => '1.2.840.113556.1.4.90',
187
+ 'dBCSPwd' => '1.2.840.113556.1.4.55',
188
+ 'ntPwdHistory' => '1.2.840.113556.1.4.94',
189
+ 'lmPwdHistory' => '1.2.840.113556.1.4.160',
190
+ 'supplementalCredentials' => '1.2.840.113556.1.4.125',
191
+ 'objectSid' => '1.2.840.113556.1.4.146',
192
+ 'pwdLastSet' => '1.2.840.113556.1.4.96',
193
+ 'userAccountControl' => '1.2.840.113556.1.4.8',
194
+ 'accountExpires' => '1.2.840.113556.1.4.159',
195
+ 'lastLogonTimestamp' => '1.2.840.113556.1.4.1696'
196
+ }
197
+
198
+ class DrsHandle < Ndr::NdrContextHandle; end
199
+
200
+ class DrsConfStringz16 < Ndr::NdrConfArray
201
+ extend Ndr::ArrayClassPlugin
202
+ default_parameters type: :ndr_wide_char
203
+ end
204
+
205
+ # [5.50 DSNAME](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/385d478f-3eb6-4d2c-ac58-f25c4debdd86)
206
+ class DsName < Ndr::NdrStruct
207
+ default_parameter byte_align: 4
208
+ endian :little
209
+
210
+ # We don't want to include ref_id (4 bytes) if it is a pointer
211
+ ndr_uint32 :struct_len, initial_value: -> { @obj.parent.respond_to?(:ref_id) ? num_bytes - 4 : num_bytes }
212
+ ndr_uint32 :sid_len
213
+ uuid :guid
214
+ string :sid, byte_align: 1, length: 28
215
+ ndr_uint32 :name_len, initial_value: -> { string_name.max_count - 1 }
216
+ drs_conf_stringz16 :string_name
217
+ end
218
+
219
+ class DsNamePtr < DsName
220
+ default_parameters referent_byte_align: 4
221
+ extend Ndr::PointerClassPlugin
222
+ end
223
+
224
+ # [5.209 USN](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/1be1e991-a2db-4f91-9953-8eab69f60e64)
225
+ class Usn < BinData::Int64le
226
+ default_parameter byte_align: 8
227
+ end
228
+
229
+ # [5.210 USN_VECTOR](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/595d11b8-6ca7-4a61-bd56-3e6a2b99b76b)
230
+ class UsnVector < Ndr::NdrStruct
231
+ default_parameter byte_align: 8
232
+
233
+ usn :usn_high_obj_update
234
+ usn :usn_reserved
235
+ usn :usn_high_prop_update
236
+ end
237
+
238
+ # [5.202 UPTODATE_CURSOR_V1](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/cf88f341-fb49-4cd5-b7e2-6920cbd91f1b)
239
+ class UptodateCursorV1 < Ndr::NdrStruct
240
+ default_parameter byte_align: 8
241
+
242
+ uuid :uuid_dsa
243
+ usn :usn_high_prop_update
244
+ end
245
+
246
+ # [5.204 UPTODATE_VECTOR_V1_EXT](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/462b424a-b50a-4c4a-a81f-48d0f4cf40fe)
247
+ class UptodateVectorV1Ext < Ndr::NdrStruct
248
+ default_parameter byte_align: 8
249
+
250
+ ndr_uint32 :dw_version
251
+ ndr_uint32 :dw_reserved1
252
+ ndr_uint32 :c_num_cursors
253
+ ndr_uint32 :dw_reserved2
254
+ ndr_conf_array :rg_cursors, type: :uptodate_cursor_v1
255
+ end
256
+
257
+ class UptodateVectorV1ExtPtr < UptodateVectorV1Ext
258
+ default_parameters referent_byte_align: 8
259
+ extend Ndr::PointerClassPlugin
260
+ end
261
+
262
+ module AttrtypRequestPlugin
263
+ # [5.16.4 ATTRTYP-to-OID Conversion](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/6f53317f-2263-48ee-86c1-4580bf97232c)
264
+ def add_attrtyp_from_oid(oid, to_field: :p_partial_attr_set)
265
+ last_value = oid.split('.').last.to_i
266
+ binary_oid = OpenSSL::ASN1::ObjectId.new(oid).to_der[2..-1]
267
+ if last_value < 128
268
+ oid_prefix = binary_oid[0...-1].bytes
269
+ else
270
+ oid_prefix = binary_oid[0...-2].bytes
271
+ end
272
+
273
+ prefix_table = self.prefix_table_dest.p_prefix_entry
274
+ prefix_table.instantiate_referent if prefix_table.is_null_ptr?
275
+ pos = prefix_table.size
276
+ index = prefix_table.to_ary.index { |e| e.prefix.elements == oid_prefix }
277
+ if index
278
+ pos = index
279
+ else
280
+ entry = PrefixTableEntry.new(ndx: pos)
281
+ entry.prefix.elements = oid_prefix
282
+ prefix_table << entry
283
+ end
284
+
285
+ lower_word = last_value % 0x4000
286
+ # mark it so that it is known to not be the whole lastValue
287
+ lower_word += 0x8000 if last_value >= 0x4000
288
+ upper_word = pos
289
+ attrtyp = (upper_word << 16) + lower_word
290
+ attr_set_field = send(to_field)
291
+ attr_set_field.instantiate_referent if attr_set_field.is_null_ptr?
292
+ attr_set_field.rg_partial_attr << attrtyp
293
+ end
294
+ end
295
+
296
+ module AttrtypResponsePlugin
297
+ # [5.16.4 ATTRTYP-to-OID Conversion](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/6f53317f-2263-48ee-86c1-4580bf97232c)
298
+ def oid_from_attid(attr_typ)
299
+ upper_word = attr_typ / 0x10000
300
+ lower_word = attr_typ % 0x10000
301
+ prefix_table = self.prefix_table_src.p_prefix_entry
302
+ binary_oid = nil
303
+ prefix_table.each do |prefix_table_entry|
304
+ if prefix_table_entry.ndx == upper_word
305
+ binary_oid = prefix_table_entry.prefix.elements.to_ary.pack('C*')
306
+ if lower_word < 128
307
+ binary_oid << [lower_word].pack('C')
308
+ else
309
+ lower_word -= 0x8000 if lower_word >= 0x8000
310
+ binary_oid << [((lower_word / 128) % 128) + 128].pack('C')
311
+ binary_oid << [lower_word % 128].pack('C')
312
+ end
313
+ break
314
+ end
315
+ end
316
+
317
+ return unless binary_oid
318
+ OpenSSL::ASN1.decode("\x06#{[binary_oid.length].pack('C')}#{binary_oid}").value
319
+ end
320
+ end
321
+
322
+ # [5.14 ATTRTYP](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/91173129-08e6-497c-8266-b5ac0aa5f983)
323
+ class Attrtyp < Ndr::NdrUint32; end
324
+
325
+ # [5.146 PARTIAL_ATTR_VECTOR_V1_EXT](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/1d5c1b34-daa4-4761-a8b5-d3c0146a0e30)
326
+ class PartialAttrVectorV1Ext < Ndr::NdrStruct
327
+ default_parameter byte_align: 4
328
+
329
+ ndr_uint32 :dw_version, initial_value: 1
330
+ ndr_uint32 :dw_reserved1
331
+ ndr_uint32 :c_attrs, initial_value: -> { rg_partial_attr.max_count }
332
+ ndr_conf_array :rg_partial_attr, type: :attrtyp
333
+ end
334
+
335
+ class PartialAttrVectorV1ExtPtr < PartialAttrVectorV1Ext
336
+ default_parameters referent_byte_align: 4
337
+ extend Ndr::PointerClassPlugin
338
+ end
339
+
340
+ class DrsByteArrayPtr < Ndr::NdrConfArray
341
+ default_parameters type: :ndr_uint8
342
+ extend Ndr::PointerClassPlugin
343
+ end
344
+
345
+ # [5.143 OID_t](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/cbc2b761-8938-4591-a9f7-2d1512ed7f05)
346
+ class OidT < Ndr::NdrStruct
347
+ default_parameter byte_align: 4
348
+
349
+ ndr_uint32 :oid_length, initial_value: -> { elements.max_count }
350
+ drs_byte_array_ptr :elements
351
+ end
352
+
353
+ # [5.154 PrefixTableEntry](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/d26d36cd-10c4-4b27-a84e-98336abf357a)
354
+ class PrefixTableEntry < Ndr::NdrStruct
355
+ default_parameter byte_align: 4
356
+
357
+ ndr_uint32 :ndx
358
+ oid_t :prefix
359
+ end
360
+
361
+ class PrefixTableEntryArrayPtr < Ndr::NdrConfArray
362
+ default_parameter type: :prefix_table_entry
363
+ extend Ndr::PointerClassPlugin
364
+ end
365
+
366
+ # [5.180 SCHEMA_PREFIX_TABLE](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/9b371267-e8b8-4c69-9979-02dae02e5e38)
367
+ class SchemaPrefixTable < Ndr::NdrStruct
368
+ default_parameter byte_align: 4
369
+
370
+ ndr_uint32 :prefix_count, initial_value: -> { p_prefix_entry.max_count }
371
+ prefix_table_entry_array_ptr :p_prefix_entry
372
+ end
373
+
374
+ class DrsConfStringz < Ndr::NdrConfArray
375
+ extend Ndr::ArrayClassPlugin
376
+ default_parameters type: :ndr_char
377
+ end
378
+
379
+ # [5.132 MTX_ADDR](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/107b7c0e-0f0d-4fe2-8232-14ec3b78f40d)
380
+ class MtxAddr < Ndr::NdrStruct
381
+ default_parameter byte_align: 4
382
+
383
+ ndr_uint32 :mtx_name_len, initial_value: -> { mtx_name.length }
384
+ drs_conf_stringz :mtx_name
385
+ end
386
+
387
+ class MtxAddrPtr < MtxAddr
388
+ default_parameters referent_byte_align: 4
389
+ extend Ndr::PointerClassPlugin
390
+ end
391
+
392
+ # [5.219 VAR_SIZE_BUFFER_WITH_VERSION](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/589574c1-eaa1-456f-ac53-de597b2cff6b)
393
+ class VarSizeBufferWithVersion < Ndr::NdrStruct
394
+ default_parameter byte_align: 8
395
+
396
+ ndr_uint32 :ul_version
397
+ ndr_uint32 :cb_byte_buffer, initial_value: -> { rg_buffer.size }
398
+ ndr_uint64 :ul_padding
399
+ ndr_conf_array :rg_buffer, type: :ndr_uint8
400
+ end
401
+
402
+ class VarSizeBufferWithVersionPtr < VarSizeBufferWithVersion
403
+ default_parameters referent_byte_align: 8
404
+ extend Ndr::PointerClassPlugin
405
+ end
406
+
407
+ # [5.16 ATTRVAL](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/cc002cbf-efe0-42f8-9295-a5a6577263d4)
408
+ class Attrval < Ndr::NdrStruct
409
+ default_parameter byte_align: 4
410
+
411
+ ndr_uint32 :val_len, initial_value: -> { p_val.length }
412
+ drs_byte_array_ptr :p_val
413
+ end
414
+
415
+ class AttrvalArrayPtr < Ndr::NdrConfArray
416
+ default_parameters type: :attrval
417
+ extend Ndr::PointerClassPlugin
418
+ end
419
+
420
+ # [5.17 ATTRVALBLOCK](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/b526370f-dfe5-4e85-9041-90d07bc16ff5)
421
+ class Attrvalblock < Ndr::NdrStruct
422
+ default_parameter byte_align: 4
423
+
424
+ ndr_uint32 :val_count, initial_value: -> { p_aval.length }
425
+ attrval_array_ptr :p_aval
426
+ end
427
+
428
+ # [5.9 ATTR](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/a2db41e2-7803-4d3c-a499-0fee92b1c149)
429
+ class Attr < Ndr::NdrStruct
430
+ default_parameter byte_align: 4
431
+
432
+ attrtyp :attr_typ
433
+ attrvalblock :attr_val
434
+ end
435
+
436
+ class AttrArrayPtr < Ndr::NdrConfArray
437
+ default_parameters type: :attr
438
+ extend Ndr::PointerClassPlugin
439
+ end
440
+
441
+ # [5.10 ATTRBLOCK](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/f81324b8-6400-41b5-bc25-5117589c602a)
442
+ class Attrblock < Ndr::NdrStruct
443
+ default_parameter byte_align: 4
444
+
445
+ ndr_uint32 :attr_count, initial_value: -> { p_attr.length }
446
+ attr_array_ptr :p_attr
447
+ end
448
+
449
+ # [5.53 ENTINF](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/6d69822e-adb6-4977-8553-c2d529c17e5b)
450
+ class Entinf < Ndr::NdrStruct
451
+ default_parameter byte_align: 4
452
+
453
+ ds_name_ptr :p_name
454
+ ndr_uint32 :ul_flags
455
+ attrblock :attr_block
456
+ end
457
+
458
+ # [5.51 DSTIME](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/a72a16b9-73e4-41ca-a5c1-afc5fc54e175)
459
+ class Dstime < BinData::Int64le
460
+ default_parameter byte_align: 8
461
+ end
462
+
463
+ # [5.155 PROPERTY_META_DATA_EXT](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/aef7ebde-c305-4224-95fd-585c86b19c38)
464
+ class PropertyMetaDataExt < Ndr::NdrStruct
465
+ default_parameter byte_align: 8
466
+
467
+ ndr_uint32 :dw_version
468
+ dstime :time_changed
469
+ uuid :uuid_dsa_originating
470
+ usn :usn_originating
471
+ end
472
+
473
+ # [5.156 PROPERTY_META_DATA_EXT_VECTOR](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/22bccd51-1e7d-4502-aef8-b84da983f94f)
474
+ class PropertyMetaDataExtVector < Ndr::NdrStruct
475
+ default_parameter byte_align: 8
476
+
477
+ ndr_uint32 :c_num_props, initial_value: -> { rg_meta_data.size }
478
+ ndr_conf_array :rg_meta_data, type: :property_meta_data_ext
479
+ end
480
+
481
+ class PropertyMetaDataExtVectorPtr < PropertyMetaDataExtVector
482
+ default_parameters referent_byte_align: 8
483
+ extend Ndr::PointerClassPlugin
484
+ end
485
+
486
+ # [5.162 REPLENTINFLIST](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/c38b0412-cf00-4b0c-b4f4-4662a4484a00)
487
+ class ReplentinflistPtr < Ndr::NdrStruct
488
+ default_parameters byte_align: 4, referent_byte_align: 4
489
+ extend Ndr::PointerClassPlugin
490
+
491
+ replentinflist_ptr :p_next_ent_inf
492
+ entinf :entinf
493
+ ndr_boolean :f_is_nc_prefix
494
+ uuid_ptr :p_parent_guid
495
+ property_meta_data_ext_vector_ptr :p_meta_data_ext
496
+ end
497
+
498
+ # [4.1.10.2.19 DRS_COMPRESSED_BLOB](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/6d3e7f57-3ef8-46e0-a6ad-e9331f297957)
499
+ class DrsCompressedBlob < Ndr::NdrStruct
500
+ default_parameter byte_align: 4
501
+
502
+ ndr_uint32 :cb_uncompressed_size
503
+ ndr_uint32 :cb_compressed_size
504
+ ndr_conf_array :pb_compressed_data, type: :ndr_uint8
505
+ end
506
+
507
+ # [5.215 VALUE_META_DATA_EXT_V1](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/7530cf2e-a2ad-4716-a570-8383f8b1846f)
508
+ class ValueMetaDataExtV1 < Ndr::NdrStruct
509
+ default_parameter byte_align: 8
510
+
511
+ dstime :time_created
512
+ property_meta_data_ext :meta_data
513
+ end
514
+
515
+ # [5.167 REPLVALINF_V1](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/22946fbf-170e-4ab4-82c7-dabdfd97bf5a)
516
+ class ReplvalinfV1 < Ndr::NdrStruct
517
+ default_parameter byte_align: 8
518
+
519
+ ds_name_ptr :p_object
520
+ attrtyp :attr_typ
521
+ attrval :aval
522
+ ndr_boolean :f_is_present
523
+ value_meta_data_ext_v1 :meta_data
524
+ end
525
+
526
+ class ReplvalinfV1ArrayPtr < Ndr::NdrConfArray
527
+ default_parameters type: :replvalinf_v1
528
+ extend Ndr::PointerClassPlugin
529
+ end
530
+
531
+ # [4.1.10.2.18 DRS_COMP_ALG_TYPE](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/bb303730-0667-49f0-b117-288404c4b4cb)
532
+ class DrsCompAlgType < Ndr::NdrUint32; end
533
+
534
+ # [5.216 VALUE_META_DATA_EXT_V3](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/eab72899-a828-427d-8384-9a51ffdb77e1)
535
+ class ValueMetaDataExtV3 < Ndr::NdrStruct
536
+ default_parameter byte_align: 8
537
+
538
+ dstime :time_created
539
+ property_meta_data_ext :meta_data
540
+ ndr_uint32 :unused1
541
+ ndr_uint32 :unused2
542
+ ndr_uint32 :unused3
543
+ dstime :time_expired
544
+ end
545
+
546
+ # [5.168 REPLVALINF_V3](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/9c15369b-b7d2-437a-b73d-66a92c367795)
547
+ class ReplvalinfV3 < Ndr::NdrStruct
548
+ default_parameter byte_align: 8
549
+
550
+ ds_name_ptr :p_object
551
+ attrtyp :attr_typ
552
+ attrval :aval
553
+ ndr_boolean :f_is_present
554
+ value_meta_data_ext_v3 :meta_data
555
+ end
556
+
557
+ class ReplvalinfV3ArrayPtr < Ndr::NdrConfArray
558
+ default_parameters type: :replvalinf_v3
559
+ extend Ndr::PointerClassPlugin
560
+ end
561
+
562
+ # [5.203 UPTODATE_CURSOR_V2](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/d3e30021-b6ac-413e-b08a-b69b9b0c6592)
563
+ class UptodateCursorV2 < Ndr::NdrStruct
564
+ default_parameter byte_align: 8
565
+
566
+ uuid :uuid_dsa
567
+ usn :usn_high_prop_update
568
+ dstime :time_last_sync_success
569
+ end
570
+
571
+ #[5.205 UPTODATE_VECTOR_V2_EXT](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/cebd1ccb-891b-4268-b056-4b714cdf981e)
572
+ class UptodateVectorV2Ext < Ndr::NdrStruct
573
+ default_parameter byte_align: 8
574
+
575
+ ndr_uint32 :dw_version
576
+ ndr_uint32 :dw_reserved1
577
+ ndr_uint32 :c_num_cursors
578
+ ndr_uint32 :dw_reserved2
579
+ ndr_conf_array :rg_cursors, type: :uptodate_cursor_v2
580
+ end
581
+
582
+ class UptodateVectorV2ExtPtr < UptodateVectorV2Ext
583
+ default_parameters referent_byte_align: 8
584
+ extend Ndr::PointerClassPlugin
585
+ end
586
+
587
+
588
+ require 'ruby_smb/dcerpc/drsr/drs_extensions'
589
+ require 'ruby_smb/dcerpc/drsr/drs_bind_request'
590
+ require 'ruby_smb/dcerpc/drsr/drs_bind_response'
591
+ require 'ruby_smb/dcerpc/drsr/drs_unbind_request'
592
+ require 'ruby_smb/dcerpc/drsr/drs_unbind_response'
593
+ require 'ruby_smb/dcerpc/drsr/drs_domain_controller_info_request'
594
+ require 'ruby_smb/dcerpc/drsr/drs_domain_controller_info_response'
595
+ require 'ruby_smb/dcerpc/drsr/drs_crack_names_request'
596
+ require 'ruby_smb/dcerpc/drsr/drs_crack_names_response'
597
+ require 'ruby_smb/dcerpc/drsr/drs_get_nc_changes_request'
598
+ require 'ruby_smb/dcerpc/drsr/drs_get_nc_changes_response'
599
+
600
+
601
+ # Creates a context handle that is necessary to call any other method in this interface
602
+ #
603
+ # @return [RubySMB::Dcerpc::Drsr::DrsHandle] Context handle
604
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
605
+ # DrsBind packet
606
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
607
+ # is not STATUS_SUCCESS
608
+ def drs_bind
609
+ drs_extensions_int = DrsExtensionsInt.new(
610
+ dw_flags: DRS_EXT_GETCHGREQ_V6 | DRS_EXT_GETCHGREPLY_V6 | DRS_EXT_GETCHGREQ_V8 | DRS_EXT_STRONG_ENCRYPTION,
611
+ dw_ext_caps: 0xFFFFFFFF
612
+ )
613
+ drs_bind_request = DrsBindRequest.new(pext_client: drs_extensions_int)
614
+ response = dcerpc_request(
615
+ drs_bind_request,
616
+ auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
617
+ auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
618
+ )
619
+ begin
620
+ drs_bind_response = DrsBindResponse.read(response)
621
+ rescue IOError
622
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading DrsBindResponse'
623
+ end
624
+ unless drs_bind_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
625
+ raise RubySMB::Dcerpc::Error::DrsrError,
626
+ "Error returned with drs_bind: "\
627
+ "#{WindowsError::NTStatus.find_by_retval(drs_bind_response.error_status.value).join(',')}"
628
+ end
629
+
630
+ ppext_server = drs_bind_response.ppext_server
631
+ raw_drs_extensions_int = ppext_server.cb.to_binary_s + ppext_server.rgb.to_binary_s
632
+ drs_extensions_int_response = DrsExtensionsInt.new
633
+ # If dwExtCaps is not included, just add zeros to parse it correctly
634
+ raw_drs_extensions_int << "\x00".b * (drs_extensions_int.num_bytes - ppext_server.cb)
635
+ drs_extensions_int_response.read(raw_drs_extensions_int)
636
+
637
+ unless drs_extensions_int_response.dw_repl_epoch == 0
638
+ # Different epoch, we have to call DRSBind again
639
+ drs_extensions_int.dw_repl_epoch = drs_extensions_int_response.dw_repl_epoch
640
+ drs_bind_request.pext_client.assign(drs_extensions_int)
641
+ response = dcerpc_request(
642
+ drs_bind_request,
643
+ auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
644
+ auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
645
+ )
646
+ begin
647
+ drs_bind_response = DrsBindResponse.read(response)
648
+ rescue IOError
649
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading DrsBindResponse'
650
+ end
651
+ unless drs_bind_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
652
+ raise RubySMB::Dcerpc::Error::DrsrError,
653
+ "Error returned with drs_bind: "\
654
+ "#{WindowsError::NTStatus.find_by_retval(drs_bind_response.error_status.value).join(',')}"
655
+ end
656
+ end
657
+
658
+ drs_bind_response.ph_drs
659
+ end
660
+
661
+ # Destroys a context handle previously created by the #drs_bind method
662
+ #
663
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
664
+ # DrsUnbind packet
665
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
666
+ # is not STATUS_SUCCESS
667
+ def drs_unbind(ph_drs)
668
+ drs_unbind_request = DrsUnbindRequest.new(ph_drs: ph_drs)
669
+ response = dcerpc_request(
670
+ drs_unbind_request,
671
+ auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
672
+ auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
673
+ )
674
+ begin
675
+ drs_unbind_response = DrsUnbindResponse.read(response)
676
+ rescue IOError
677
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading DrsUnbindResponse'
678
+ end
679
+ unless drs_unbind_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
680
+ raise RubySMB::Dcerpc::Error::DrsrError,
681
+ "Error returned with drs_unbind: "\
682
+ "#{WindowsError::NTStatus.find_by_retval(drs_unbind_response.error_status.value).join(',')}"
683
+ end
684
+
685
+ nil
686
+ end
687
+
688
+ # Retrieves information about DCs in a given domain
689
+ #
690
+ # @param h_drs [RubySMB::Dcerpc::Drsr::DrsHandle] Context handle
691
+ # previously created by the #drs_bind method
692
+ # @param domain [String] Domain name
693
+ # @return [Array<RubySMB::Dcerpc::Drsr::DsDomainControllerInfo1wPtr>]
694
+ # Array of DsDomainControllerInfo1wPtr containing information about DCs
695
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
696
+ # DrsDomainControllerInfo packet
697
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
698
+ # is not STATUS_SUCCESS
699
+ def drs_domain_controller_info(h_drs, domain)
700
+ drs_domain_controller_info_request = DrsDomainControllerInfoRequest.new(
701
+ h_drs: h_drs,
702
+ pmsg_in: {
703
+ switch_type: 1,
704
+ msg_dcinfo: {
705
+ domain: domain,
706
+ info_level: 2
707
+ }
708
+ }
709
+ )
710
+ response = dcerpc_request(
711
+ drs_domain_controller_info_request,
712
+ auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
713
+ auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
714
+ )
715
+ begin
716
+ drs_domain_controller_info_response = DrsDomainControllerInfoResponse.read(response)
717
+ rescue IOError
718
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading DrsDomainControllerInfoResponse'
719
+ end
720
+ unless drs_domain_controller_info_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
721
+ raise RubySMB::Dcerpc::Error::DrsrError,
722
+ "Error returned with drs_domain_controller_info: "\
723
+ "#{WindowsError::NTStatus.find_by_retval(drs_domain_controller_info_response.error_status.value).join(',')}"
724
+ end
725
+
726
+ drs_domain_controller_info_response.pmsg_out.msg_dcinfo.r_items.to_ary
727
+ end
728
+
729
+ # Looks up each of a set of objects in the directory and returns it to
730
+ # the caller in the requested format
731
+ #
732
+ # @param h_drs [RubySMB::Dcerpc::Drsr::DrsHandle] Context handle
733
+ # previously created by the #drs_bind method
734
+ # @param flags [Integer] Flags (see `DRS_MSG_CRACKREQ_V1 dwFlags` in this
735
+ # file)
736
+ # @param format_offered [Integer] The format of the names in rp_names
737
+ # (see DS_NAME_FORMAT constants in this file )
738
+ # @param format_desired [Integer] The format of the names returned
739
+ # (see DS_NAME_FORMAT constants in this file )
740
+ # @param rp_names [Array<String>] Input names to translate
741
+ # @return [Array<RubySMB::Dcerpc::Drsr::DsNameResultItemwPtr>]
742
+ # Array of DsNameResultItemwPtr containing the translated names
743
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
744
+ # DrsCrackNames packet
745
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
746
+ # is not STATUS_SUCCESS
747
+ def drs_crack_names(h_drs, flags: 0, format_offered: DS_SID_OR_SID_HISTORY_NAME, format_desired: DS_UNIQUE_ID_NAME, rp_names: [])
748
+ drs_crack_names_request = DrsCrackNamesRequest.new(
749
+ h_drs: h_drs,
750
+ pmsg_in: {
751
+ switch_type: 1,
752
+ msg_crack: {
753
+ dw_flags: flags,
754
+ format_offered: format_offered,
755
+ format_desired: format_desired,
756
+ rp_names: rp_names
757
+ }
758
+ }
759
+ )
760
+ response = dcerpc_request(
761
+ drs_crack_names_request,
762
+ auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
763
+ auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
764
+ )
765
+ begin
766
+ drs_crack_names_response = DrsCrackNamesResponse.read(response)
767
+ rescue IOError
768
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading DrsCrackNamesResponse'
769
+ end
770
+ unless drs_crack_names_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
771
+ raise RubySMB::Dcerpc::Error::DrsrError,
772
+ "Error returned with drs_crack_names: "\
773
+ "#{WindowsError::NTStatus.find_by_retval(drs_crack_names_response.error_status.value).join(',')}"
774
+ end
775
+
776
+ drs_crack_names_response.pmsg_out.msg_crack.p_result.r_items.to_ary
777
+ end
778
+
779
+ # [4.1.10.2.20 ENCRYPTED_PAYLOAD](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/7b60d2b3-5bb1-49aa-aefc-fa887e683977)
780
+ class EncryptedPayload < BinData::Record
781
+ endian :little
782
+
783
+ uint8_array :salt, initial_length: 16
784
+ uint32 :check_sum
785
+ uint8_array :encrypted_data, read_until: :eof
786
+ end
787
+
788
+ # [4.1.10.6.17 DecryptValuesIfNecessary](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/a14e34f0-69ff-484e-820c-1170c63c19ab)
789
+ def decrypt_attribute_value(attribute)
790
+ unless @session_key
791
+ raise RubySMB::Error::EncryptionError, 'Unable to decrypt attribute value: session key is empty'
792
+ end
793
+ encrypted_payload = EncryptedPayload.read(attribute)
794
+
795
+ signature = OpenSSL::Digest::MD5.digest(@session_key + encrypted_payload.salt.to_binary_s)
796
+ rc4 = OpenSSL::Cipher.new('rc4')
797
+ rc4.decrypt
798
+ rc4.key = signature
799
+ plain_text = rc4.update(
800
+ encrypted_payload.check_sum.to_binary_s +
801
+ encrypted_payload.encrypted_data.to_binary_s
802
+ )
803
+ plain_text += rc4.final
804
+
805
+ plain_text[4..-1]
806
+ end
807
+
808
+ # From [MS-LSAD] [5.1.3 DES-ECB-LM Cipher Definition](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lsad/32a2c8af-dc6e-4662-918d-ef333d570dd2)
809
+ def transform_key(input_key)
810
+ output_key = []
811
+ output_key << (input_key[0].ord >> 0x01).chr
812
+ output_key << (((input_key[0].ord & 0x01) << 6) | (input_key[1].ord >> 2)).chr
813
+ output_key << (((input_key[1].ord & 0x03) << 5) | (input_key[2].ord >> 3)).chr
814
+ output_key << (((input_key[2].ord & 0x07) << 4) | (input_key[3].ord >> 4)).chr
815
+ output_key << (((input_key[3].ord & 0x0F) << 3) | (input_key[4].ord >> 5)).chr
816
+ output_key << (((input_key[4].ord & 0x1F) << 2) | (input_key[5].ord >> 6)).chr
817
+ output_key << (((input_key[5].ord & 0x3F) << 1) | (input_key[6].ord >> 7)).chr
818
+ output_key << (input_key[6].ord & 0x7F).chr
819
+
820
+ output_key.map { |byte| ((byte.ord << 1) & 0xFE).chr }.join
821
+ end
822
+
823
+ # From [MS-SAMR] [2.2.11.1.3 Deriving Key1 and Key2 from a Little-Endian, Unsigned Integer Key](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/b1b0094f-2546-431f-b06d-582158a9f2bb)
824
+ def derive_key(base_key)
825
+ key = [base_key].pack('L<')
826
+ key1 = [key[0] , key[1] , key[2] , key[3] , key[0] , key[1] , key[2]]
827
+ key2 = [key[3] , key[0] , key[1] , key[2] , key[3] , key[0] , key[1]]
828
+ [transform_key(key1.join), transform_key(key2.join)]
829
+ end
830
+
831
+ def remove_des_layer(crypted_hash, rid)
832
+ key1, key2 = derive_key(rid)
833
+
834
+ des = OpenSSL::Cipher.new('des-ecb')
835
+ des.decrypt
836
+ des.key = key1
837
+ des.padding = 0
838
+ decrypted_hash = des.update(crypted_hash[0,8])
839
+ decrypted_hash += des.final
840
+
841
+ des.reset
842
+ des.decrypt
843
+ des.key = key2
844
+ des.padding = 0
845
+ decrypted_hash += des.update(crypted_hash[8..-1])
846
+ decrypted_hash += des.final
847
+
848
+ decrypted_hash
849
+ end
850
+
851
+ # Replicates updates from an NC replica on the server
852
+ #
853
+ # @param h_drs [RubySMB::Dcerpc::Drsr::DrsHandle] Context handle
854
+ # previously created by the #drs_bind method
855
+ # @param nc_guid [String] GUID of the DSName representing the NC
856
+ # (naming context) root of the replica to replicate
857
+ # @param nc_guid [String] DSA GUID of the DC.
858
+ # @return [RubySMB::Dcerpc::Drsr::DrsGetNcChangesResponse] Response
859
+ # structure containing the updates
860
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a
861
+ # DrsGetNcChanges packet
862
+ # @raise [RubySMB::Dcerpc::Error::SamrError] if the response error status
863
+ # is not STATUS_SUCCESS
864
+ def drs_get_nc_changes(h_drs, nc_guid:, dsa_object_guid:)
865
+ drs_get_nc_changes_request = DrsGetNcChangesRequest.new(
866
+ h_drs: h_drs,
867
+ dw_in_version: 8,
868
+ pmsg_in: {
869
+ msg_getchg: {
870
+ uuid_dsa_obj_dest: dsa_object_guid,
871
+ uuid_invoc_id_src: dsa_object_guid,
872
+ p_nc: {
873
+ guid: nc_guid,
874
+ string_name: ["\0"]
875
+ },
876
+ ul_flags: DRS_INIT_SYNC | DRS_WRIT_REP,
877
+ c_max_objects: 1,
878
+ ul_extended_op: EXOP_REPL_OBJ
879
+ }
880
+ }
881
+ )
882
+
883
+ ATTRTYP_TO_ATTID.values.each do |oid|
884
+ drs_get_nc_changes_request.pmsg_in.msg_getchg.add_attrtyp_from_oid(oid)
885
+ end
886
+
887
+ response = dcerpc_request(
888
+ drs_get_nc_changes_request,
889
+ auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
890
+ auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT
891
+ )
892
+ begin
893
+ drs_get_nc_changes_response = DrsGetNcChangesResponse.read(response)
894
+ rescue IOError
895
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading DrsGetNcChangesResponse'
896
+ end
897
+ unless drs_get_nc_changes_response.error_status == WindowsError::NTStatus::STATUS_SUCCESS
898
+ raise RubySMB::Dcerpc::Error::DrsrError,
899
+ "Error returned with drs_get_nc_changes: "\
900
+ "#{WindowsError::NTStatus.find_by_retval(drs_get_nc_changes_response.error_status.value).join(',')}"
901
+ end
902
+
903
+ drs_get_nc_changes_response
904
+ end
905
+
906
+ end
907
+ end
908
+ end
909
+