puppet 6.15.0-x86-mingw32 → 6.19.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (418) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -7
  3. data/Gemfile +4 -2
  4. data/Gemfile.lock +29 -27
  5. data/README.md +3 -4
  6. data/Rakefile +4 -12
  7. data/lib/puppet.rb +32 -8
  8. data/lib/puppet/agent.rb +18 -4
  9. data/lib/puppet/agent/locker.rb +0 -7
  10. data/lib/puppet/application/agent.rb +23 -8
  11. data/lib/puppet/application/apply.rb +18 -20
  12. data/lib/puppet/application/device.rb +1 -1
  13. data/lib/puppet/application/doc.rb +1 -1
  14. data/lib/puppet/application/lookup.rb +16 -4
  15. data/lib/puppet/application/plugin.rb +1 -0
  16. data/lib/puppet/application/ssl.rb +1 -1
  17. data/lib/puppet/configurer.rb +61 -21
  18. data/lib/puppet/configurer/downloader.rb +31 -10
  19. data/lib/puppet/confine.rb +2 -2
  20. data/lib/puppet/confine/any.rb +1 -1
  21. data/lib/puppet/context/trusted_information.rb +14 -8
  22. data/lib/puppet/daemon.rb +13 -27
  23. data/lib/puppet/defaults.rb +119 -39
  24. data/lib/puppet/environments.rb +51 -10
  25. data/lib/puppet/face/catalog.rb +1 -1
  26. data/lib/puppet/face/config.rb +46 -16
  27. data/lib/puppet/face/facts.rb +1 -1
  28. data/lib/puppet/face/help.rb +29 -3
  29. data/lib/puppet/face/module/search.rb +5 -0
  30. data/lib/puppet/face/node.rb +3 -3
  31. data/lib/puppet/face/node/clean.rb +2 -2
  32. data/lib/puppet/face/plugin.rb +1 -1
  33. data/lib/puppet/face/status.rb +1 -1
  34. data/lib/puppet/feature/base.rb +1 -1
  35. data/lib/puppet/file_bucket/dipper.rb +1 -1
  36. data/lib/puppet/file_serving/http_metadata.rb +14 -2
  37. data/lib/puppet/file_serving/metadata.rb +4 -1
  38. data/lib/puppet/file_serving/mount/locales.rb +1 -2
  39. data/lib/puppet/file_serving/mount/pluginfacts.rb +1 -2
  40. data/lib/puppet/file_serving/mount/plugins.rb +1 -2
  41. data/lib/puppet/file_serving/terminus_selector.rb +7 -8
  42. data/lib/puppet/file_system/file_impl.rb +4 -4
  43. data/lib/puppet/file_system/uniquefile.rb +12 -16
  44. data/lib/puppet/forge.rb +1 -1
  45. data/lib/puppet/forge/cache.rb +1 -1
  46. data/lib/puppet/forge/repository.rb +4 -7
  47. data/lib/puppet/functions/filter.rb +1 -0
  48. data/lib/puppet/functions/lstrip.rb +4 -4
  49. data/lib/puppet/functions/new.rb +8 -3
  50. data/lib/puppet/functions/reverse_each.rb +1 -1
  51. data/lib/puppet/functions/rstrip.rb +4 -4
  52. data/lib/puppet/functions/step.rb +1 -1
  53. data/lib/puppet/functions/strip.rb +4 -4
  54. data/lib/puppet/gettext/config.rb +5 -5
  55. data/lib/puppet/gettext/module_translations.rb +4 -4
  56. data/lib/puppet/http.rb +1 -0
  57. data/lib/puppet/http/client.rb +28 -12
  58. data/lib/puppet/http/external_client.rb +0 -6
  59. data/lib/puppet/http/redirector.rb +9 -7
  60. data/lib/puppet/http/resolver.rb +5 -8
  61. data/lib/puppet/http/resolver/server_list.rb +18 -36
  62. data/lib/puppet/http/resolver/settings.rb +4 -4
  63. data/lib/puppet/http/resolver/srv.rb +5 -5
  64. data/lib/puppet/http/response.rb +19 -0
  65. data/lib/puppet/http/service.rb +3 -1
  66. data/lib/puppet/http/service/compiler.rb +1 -1
  67. data/lib/puppet/http/service/file_server.rb +1 -1
  68. data/lib/puppet/http/service/puppetserver.rb +39 -0
  69. data/lib/puppet/http/session.rb +5 -4
  70. data/lib/puppet/indirector.rb +1 -1
  71. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  72. data/lib/puppet/indirector/exec.rb +1 -1
  73. data/lib/puppet/indirector/facts/facter.rb +3 -3
  74. data/lib/puppet/indirector/facts/yaml.rb +1 -1
  75. data/lib/puppet/indirector/file_content/http.rb +5 -0
  76. data/lib/puppet/indirector/file_content/rest.rb +1 -1
  77. data/lib/puppet/indirector/file_metadata/http.rb +28 -8
  78. data/lib/puppet/indirector/file_metadata/rest.rb +2 -2
  79. data/lib/puppet/indirector/hiera.rb +4 -0
  80. data/lib/puppet/indirector/indirection.rb +1 -1
  81. data/lib/puppet/indirector/json.rb +1 -1
  82. data/lib/puppet/indirector/msgpack.rb +1 -1
  83. data/lib/puppet/indirector/report/processor.rb +2 -2
  84. data/lib/puppet/indirector/request.rb +5 -5
  85. data/lib/puppet/indirector/rest.rb +7 -1
  86. data/lib/puppet/indirector/yaml.rb +1 -1
  87. data/lib/puppet/module.rb +1 -2
  88. data/lib/puppet/network/format_support.rb +2 -2
  89. data/lib/puppet/network/http/api/indirected_routes.rb +1 -1
  90. data/lib/puppet/network/http/api/master/v3/environment.rb +3 -0
  91. data/lib/puppet/network/http/api/master/v3/environments.rb +0 -1
  92. data/lib/puppet/network/http/compression.rb +7 -0
  93. data/lib/puppet/network/http/connection.rb +2 -0
  94. data/lib/puppet/network/http/connection_adapter.rb +184 -0
  95. data/lib/puppet/network/http/nocache_pool.rb +1 -0
  96. data/lib/puppet/network/http/route.rb +2 -2
  97. data/lib/puppet/network/http_pool.rb +2 -2
  98. data/lib/puppet/node/environment.rb +12 -5
  99. data/lib/puppet/node/facts.rb +17 -0
  100. data/lib/puppet/pal/catalog_compiler.rb +5 -0
  101. data/lib/puppet/pal/pal_impl.rb +31 -4
  102. data/lib/puppet/parameter.rb +1 -1
  103. data/lib/puppet/parser/ast/leaf.rb +5 -5
  104. data/lib/puppet/parser/ast/pops_bridge.rb +0 -4
  105. data/lib/puppet/parser/compiler.rb +29 -26
  106. data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +2 -0
  107. data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +2 -0
  108. data/lib/puppet/parser/environment_compiler.rb +4 -1
  109. data/lib/puppet/parser/functions.rb +21 -17
  110. data/lib/puppet/parser/functions/create_resources.rb +11 -7
  111. data/lib/puppet/parser/functions/filter.rb +1 -0
  112. data/lib/puppet/parser/resource.rb +3 -2
  113. data/lib/puppet/parser/resource/param.rb +6 -0
  114. data/lib/puppet/parser/type_loader.rb +2 -2
  115. data/lib/puppet/pops/adaptable.rb +7 -13
  116. data/lib/puppet/pops/adapters.rb +8 -4
  117. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -3
  118. data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -5
  119. data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
  120. data/lib/puppet/pops/issues.rb +5 -0
  121. data/lib/puppet/pops/loader/runtime3_type_loader.rb +4 -2
  122. data/lib/puppet/pops/loaders.rb +18 -11
  123. data/lib/puppet/pops/lookup/context.rb +1 -1
  124. data/lib/puppet/pops/lookup/hiera_config.rb +14 -1
  125. data/lib/puppet/pops/resource/resource_type_impl.rb +2 -0
  126. data/lib/puppet/pops/types/iterable.rb +34 -8
  127. data/lib/puppet/pops/types/p_meta_type.rb +1 -1
  128. data/lib/puppet/pops/types/p_type_set_type.rb +4 -0
  129. data/lib/puppet/pops/validation/checker4_0.rb +29 -15
  130. data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
  131. data/lib/puppet/provider/file/windows.rb +1 -1
  132. data/lib/puppet/provider/package/aix.rb +17 -2
  133. data/lib/puppet/provider/package/apt.rb +38 -1
  134. data/lib/puppet/provider/package/aptitude.rb +1 -1
  135. data/lib/puppet/provider/package/dnfmodule.rb +24 -4
  136. data/lib/puppet/provider/package/dpkg.rb +1 -1
  137. data/lib/puppet/provider/package/gem.rb +4 -2
  138. data/lib/puppet/provider/package/pip.rb +60 -37
  139. data/lib/puppet/provider/package/pip2.rb +17 -0
  140. data/lib/puppet/provider/package/portage.rb +2 -2
  141. data/lib/puppet/provider/package/puppet_gem.rb +5 -0
  142. data/lib/puppet/provider/package/puppetserver_gem.rb +180 -0
  143. data/lib/puppet/provider/package/yum.rb +9 -1
  144. data/lib/puppet/provider/package/zypper.rb +62 -1
  145. data/lib/puppet/provider/service/systemd.rb +21 -4
  146. data/lib/puppet/provider/service/windows.rb +23 -7
  147. data/lib/puppet/provider/user/aix.rb +1 -1
  148. data/lib/puppet/provider/user/user_role_add.rb +1 -1
  149. data/lib/puppet/provider/user/useradd.rb +16 -5
  150. data/lib/puppet/provider/user/windows_adsi.rb +18 -1
  151. data/lib/puppet/reports/http.rb +7 -3
  152. data/lib/puppet/resource.rb +2 -1
  153. data/lib/puppet/resource/type.rb +10 -1
  154. data/lib/puppet/rest/route.rb +2 -2
  155. data/lib/puppet/runtime.rb +25 -2
  156. data/lib/puppet/settings.rb +43 -6
  157. data/lib/puppet/ssl/ssl_context.rb +2 -2
  158. data/lib/puppet/ssl/ssl_provider.rb +20 -1
  159. data/lib/puppet/ssl/state_machine.rb +33 -8
  160. data/lib/puppet/ssl/validator/default_validator.rb +1 -1
  161. data/lib/puppet/ssl/verifier_adapter.rb +9 -1
  162. data/lib/puppet/test/test_helper.rb +19 -14
  163. data/lib/puppet/transaction.rb +2 -2
  164. data/lib/puppet/transaction/persistence.rb +1 -1
  165. data/lib/puppet/transaction/report.rb +12 -8
  166. data/lib/puppet/trusted_external.rb +29 -1
  167. data/lib/puppet/type.rb +15 -7
  168. data/lib/puppet/type/file.rb +40 -15
  169. data/lib/puppet/type/file/checksum.rb +4 -4
  170. data/lib/puppet/type/file/source.rb +33 -13
  171. data/lib/puppet/type/filebucket.rb +1 -1
  172. data/lib/puppet/type/notify.rb +2 -2
  173. data/lib/puppet/type/package.rb +16 -1
  174. data/lib/puppet/type/service.rb +59 -8
  175. data/lib/puppet/type/user.rb +19 -10
  176. data/lib/puppet/util.rb +41 -3
  177. data/lib/puppet/util/autoload.rb +10 -25
  178. data/lib/puppet/util/character_encoding.rb +9 -5
  179. data/lib/puppet/util/checksums.rb +19 -4
  180. data/lib/puppet/util/connection.rb +8 -8
  181. data/lib/puppet/util/execution.rb +2 -2
  182. data/lib/puppet/util/fileparsing.rb +2 -2
  183. data/lib/puppet/util/log/destinations.rb +1 -10
  184. data/lib/puppet/util/package/version/range.rb +4 -1
  185. data/lib/puppet/util/package/version/range/eq.rb +14 -0
  186. data/lib/puppet/util/provider_features.rb +1 -1
  187. data/lib/puppet/util/reference.rb +1 -1
  188. data/lib/puppet/util/run_mode.rb +5 -1
  189. data/lib/puppet/util/windows.rb +1 -0
  190. data/lib/puppet/util/windows/api_types.rb +60 -33
  191. data/lib/puppet/util/windows/eventlog.rb +1 -6
  192. data/lib/puppet/util/windows/monkey_patches/dir.rb +40 -0
  193. data/lib/puppet/util/windows/principal.rb +8 -6
  194. data/lib/puppet/util/windows/registry.rb +11 -11
  195. data/lib/puppet/util/windows/security.rb +4 -4
  196. data/lib/puppet/util/windows/service.rb +43 -26
  197. data/lib/puppet/util/windows/user.rb +242 -8
  198. data/lib/puppet/version.rb +1 -1
  199. data/locales/puppet.pot +541 -427
  200. data/man/man5/puppet.conf.5 +84 -19
  201. data/man/man8/puppet-agent.8 +7 -4
  202. data/man/man8/puppet-apply.8 +1 -1
  203. data/man/man8/puppet-catalog.8 +1 -1
  204. data/man/man8/puppet-config.8 +6 -6
  205. data/man/man8/puppet-describe.8 +1 -1
  206. data/man/man8/puppet-device.8 +1 -1
  207. data/man/man8/puppet-doc.8 +1 -1
  208. data/man/man8/puppet-epp.8 +1 -1
  209. data/man/man8/puppet-facts.8 +1 -1
  210. data/man/man8/puppet-filebucket.8 +1 -1
  211. data/man/man8/puppet-generate.8 +1 -1
  212. data/man/man8/puppet-help.8 +6 -3
  213. data/man/man8/puppet-key.8 +1 -1
  214. data/man/man8/puppet-lookup.8 +2 -2
  215. data/man/man8/puppet-man.8 +1 -1
  216. data/man/man8/puppet-module.8 +4 -1
  217. data/man/man8/puppet-node.8 +4 -4
  218. data/man/man8/puppet-parser.8 +1 -1
  219. data/man/man8/puppet-plugin.8 +1 -1
  220. data/man/man8/puppet-report.8 +1 -1
  221. data/man/man8/puppet-resource.8 +1 -1
  222. data/man/man8/puppet-script.8 +1 -1
  223. data/man/man8/puppet-ssl.8 +1 -1
  224. data/man/man8/puppet-status.8 +2 -2
  225. data/man/man8/puppet.8 +2 -2
  226. data/spec/fixtures/integration/application/apply/environments/spec/modules/amod/lib/puppet/provider/applytest/applytest.rb +2 -0
  227. data/spec/fixtures/integration/application/apply/environments/spec/modules/amod/lib/puppet/type/applytest.rb +25 -0
  228. data/spec/fixtures/unit/forge/bacula-releases.json +128 -0
  229. data/spec/fixtures/unit/forge/bacula.tar.gz +0 -0
  230. data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-enabled.txt → dnf-module-list.txt} +6 -0
  231. data/spec/fixtures/unit/provider/package/puppetserver_gem/gem-list-local-packages +30 -0
  232. data/spec/fixtures/unit/provider/package/zypper/zypper-search-uninstalled.out +13 -0
  233. data/spec/integration/application/agent_spec.rb +202 -52
  234. data/spec/integration/application/apply_spec.rb +149 -149
  235. data/spec/integration/application/config_spec.rb +74 -0
  236. data/spec/integration/application/doc_spec.rb +16 -6
  237. data/spec/integration/application/filebucket_spec.rb +70 -21
  238. data/spec/integration/application/help_spec.rb +42 -0
  239. data/spec/integration/application/lookup_spec.rb +13 -0
  240. data/spec/integration/application/module_spec.rb +68 -0
  241. data/spec/integration/application/plugin_spec.rb +75 -2
  242. data/spec/integration/configurer_spec.rb +14 -0
  243. data/spec/integration/data_binding_spec.rb +82 -0
  244. data/spec/integration/defaults_spec.rb +27 -3
  245. data/spec/integration/directory_environments_spec.rb +17 -17
  246. data/spec/integration/http/client_spec.rb +6 -1
  247. data/spec/integration/indirector/facts/facter_spec.rb +8 -6
  248. data/spec/integration/network/http_pool_spec.rb +73 -0
  249. data/spec/integration/node/environment_spec.rb +1 -1
  250. data/spec/integration/parser/compiler_spec.rb +11 -0
  251. data/spec/integration/type/file_spec.rb +1 -1
  252. data/spec/integration/util/execution_spec.rb +22 -0
  253. data/spec/integration/util/windows/adsi_spec.rb +7 -2
  254. data/spec/integration/util/windows/monkey_patches/dir_spec.rb +11 -0
  255. data/spec/integration/util/windows/process_spec.rb +26 -32
  256. data/spec/integration/util/windows/registry_spec.rb +7 -7
  257. data/spec/integration/util/windows/user_spec.rb +47 -5
  258. data/spec/integration/util_spec.rb +7 -33
  259. data/spec/lib/puppet_spec/https.rb +6 -0
  260. data/spec/lib/puppet_spec/matchers.rb +0 -80
  261. data/spec/lib/puppet_spec/puppetserver.rb +8 -0
  262. data/spec/shared_contexts/types_setup.rb +2 -0
  263. data/spec/unit/agent_spec.rb +47 -1
  264. data/spec/unit/application/agent_spec.rb +7 -8
  265. data/spec/unit/application/doc_spec.rb +2 -2
  266. data/spec/unit/application/face_base_spec.rb +6 -4
  267. data/spec/unit/application/facts_spec.rb +41 -10
  268. data/spec/unit/application/man_spec.rb +52 -0
  269. data/spec/unit/application/resource_spec.rb +3 -1
  270. data/spec/unit/application/ssl_spec.rb +15 -2
  271. data/spec/unit/application_spec.rb +9 -4
  272. data/spec/unit/configurer/downloader_spec.rb +10 -0
  273. data/spec/unit/configurer/fact_handler_spec.rb +4 -4
  274. data/spec/unit/configurer_spec.rb +86 -37
  275. data/spec/unit/confine_spec.rb +2 -1
  276. data/spec/unit/context/trusted_information_spec.rb +25 -2
  277. data/spec/unit/daemon_spec.rb +5 -64
  278. data/spec/unit/environments_spec.rb +99 -32
  279. data/spec/unit/face/config_spec.rb +59 -1
  280. data/spec/unit/face/module/search_spec.rb +17 -0
  281. data/spec/unit/face/node_spec.rb +2 -2
  282. data/spec/unit/file_serving/http_metadata_spec.rb +37 -14
  283. data/spec/unit/file_serving/mount/locales_spec.rb +2 -2
  284. data/spec/unit/file_serving/mount/pluginfacts_spec.rb +2 -2
  285. data/spec/unit/file_serving/mount/plugins_spec.rb +2 -2
  286. data/spec/unit/file_serving/terminus_selector_spec.rb +45 -26
  287. data/spec/unit/file_system/uniquefile_spec.rb +29 -0
  288. data/spec/unit/file_system_spec.rb +1 -2
  289. data/spec/unit/http/client_spec.rb +74 -19
  290. data/spec/unit/http/external_client_spec.rb +9 -9
  291. data/spec/unit/http/resolver_spec.rb +24 -5
  292. data/spec/unit/http/response_spec.rb +6 -0
  293. data/spec/unit/http/service/ca_spec.rb +2 -3
  294. data/spec/unit/http/service/compiler_spec.rb +2 -3
  295. data/spec/unit/http/service/file_server_spec.rb +2 -3
  296. data/spec/unit/http/service/puppetserver_spec.rb +82 -0
  297. data/spec/unit/http/service/report_spec.rb +2 -3
  298. data/spec/unit/http/service_spec.rb +0 -1
  299. data/spec/unit/http/session_spec.rb +8 -21
  300. data/spec/unit/indirector/catalog/compiler_spec.rb +1 -0
  301. data/spec/unit/indirector/catalog/json_spec.rb +1 -1
  302. data/spec/unit/indirector/catalog/rest_spec.rb +1 -1
  303. data/spec/unit/indirector/facts/rest_spec.rb +1 -1
  304. data/spec/unit/indirector/file_metadata/http_spec.rb +194 -0
  305. data/spec/unit/indirector/file_metadata/rest_spec.rb +15 -14
  306. data/spec/unit/indirector/json_spec.rb +8 -8
  307. data/spec/unit/indirector/msgpack_spec.rb +8 -8
  308. data/spec/unit/indirector/node/rest_spec.rb +1 -1
  309. data/spec/unit/indirector/request_spec.rb +5 -5
  310. data/spec/unit/indirector/rest_spec.rb +14 -1
  311. data/spec/unit/indirector/status/rest_spec.rb +1 -1
  312. data/spec/unit/indirector/yaml_spec.rb +7 -7
  313. data/spec/unit/interface_spec.rb +3 -3
  314. data/spec/unit/module_tool/tar/mini_spec.rb +20 -0
  315. data/spec/unit/network/format_support_spec.rb +3 -2
  316. data/spec/unit/network/http/api/indirected_routes_spec.rb +2 -1
  317. data/spec/unit/network/http/api/master/v3/environments_spec.rb +12 -23
  318. data/spec/unit/network/http/connection_spec.rb +552 -190
  319. data/spec/unit/network/http/nocache_pool_spec.rb +22 -0
  320. data/spec/unit/network/http_pool_spec.rb +63 -57
  321. data/spec/unit/network/http_spec.rb +1 -1
  322. data/spec/unit/node/environment_spec.rb +18 -1
  323. data/spec/unit/parser/ast/block_expression_spec.rb +1 -1
  324. data/spec/unit/parser/environment_compiler_spec.rb +7 -0
  325. data/spec/unit/parser/scope_spec.rb +1 -1
  326. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +15 -1
  327. data/spec/unit/pops/loaders/loaders_spec.rb +71 -1
  328. data/spec/unit/pops/lookup/lookup_spec.rb +25 -0
  329. data/spec/unit/pops/types/type_calculator_spec.rb +1 -11
  330. data/spec/unit/provider/exec_spec.rb +4 -3
  331. data/spec/unit/provider/package/aix_spec.rb +29 -0
  332. data/spec/unit/provider/package/apt_spec.rb +77 -0
  333. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  334. data/spec/unit/provider/package/dnfmodule_spec.rb +25 -5
  335. data/spec/unit/provider/package/dpkg_spec.rb +22 -7
  336. data/spec/unit/provider/package/openbsd_spec.rb +2 -0
  337. data/spec/unit/provider/package/pip2_spec.rb +36 -0
  338. data/spec/unit/provider/package/pip_spec.rb +42 -16
  339. data/spec/unit/provider/package/portage_spec.rb +5 -0
  340. data/spec/unit/provider/package/puppet_gem_spec.rb +4 -1
  341. data/spec/unit/provider/package/puppetserver_gem_spec.rb +137 -0
  342. data/spec/unit/provider/package/yum_spec.rb +47 -8
  343. data/spec/unit/provider/package/zypper_spec.rb +98 -0
  344. data/spec/unit/provider/service/base_spec.rb +2 -4
  345. data/spec/unit/provider/service/bsd_spec.rb +5 -1
  346. data/spec/unit/provider/service/daemontools_spec.rb +1 -1
  347. data/spec/unit/provider/service/debian_spec.rb +3 -5
  348. data/spec/unit/provider/service/freebsd_spec.rb +1 -1
  349. data/spec/unit/provider/service/gentoo_spec.rb +4 -5
  350. data/spec/unit/provider/service/init_spec.rb +46 -5
  351. data/spec/unit/provider/service/launchd_spec.rb +5 -6
  352. data/spec/unit/provider/service/openbsd_spec.rb +9 -0
  353. data/spec/unit/provider/service/openrc_spec.rb +4 -5
  354. data/spec/unit/provider/service/openwrt_spec.rb +2 -1
  355. data/spec/unit/provider/service/redhat_spec.rb +10 -1
  356. data/spec/unit/provider/service/runit_spec.rb +2 -1
  357. data/spec/unit/provider/service/smf_spec.rb +1 -1
  358. data/spec/unit/provider/service/src_spec.rb +3 -5
  359. data/spec/unit/provider/service/systemd_spec.rb +87 -19
  360. data/spec/unit/provider/service/upstart_spec.rb +4 -5
  361. data/spec/unit/provider/service/windows_spec.rb +50 -14
  362. data/spec/unit/provider/user/openbsd_spec.rb +1 -0
  363. data/spec/unit/provider/user/useradd_spec.rb +30 -16
  364. data/spec/unit/provider/user/windows_adsi_spec.rb +82 -0
  365. data/spec/unit/puppet_pal_2pec.rb +40 -0
  366. data/spec/unit/puppet_pal_catalog_spec.rb +43 -0
  367. data/spec/unit/puppet_spec.rb +33 -0
  368. data/spec/unit/reports/http_spec.rb +1 -1
  369. data/spec/unit/reports/store_spec.rb +17 -13
  370. data/spec/unit/resource_spec.rb +3 -3
  371. data/spec/unit/rest/route_spec.rb +4 -4
  372. data/spec/unit/settings_spec.rb +182 -22
  373. data/spec/unit/ssl/ssl_provider_spec.rb +69 -43
  374. data/spec/unit/ssl/state_machine_spec.rb +52 -8
  375. data/spec/unit/test/test_helper_spec.rb +17 -0
  376. data/spec/unit/transaction/persistence_spec.rb +15 -0
  377. data/spec/unit/transaction/report_spec.rb +3 -1
  378. data/spec/unit/type/file/source_spec.rb +4 -4
  379. data/spec/unit/type/file_spec.rb +122 -96
  380. data/spec/unit/type/filebucket_spec.rb +1 -1
  381. data/spec/unit/type/service_spec.rb +218 -8
  382. data/spec/unit/type/user_spec.rb +32 -3
  383. data/spec/unit/type_spec.rb +50 -0
  384. data/spec/unit/util/autoload_spec.rb +2 -1
  385. data/spec/unit/util/character_encoding_spec.rb +4 -4
  386. data/spec/unit/util/checksums_spec.rb +16 -0
  387. data/spec/unit/util/command_line_spec.rb +11 -6
  388. data/spec/unit/util/log/destinations_spec.rb +1 -29
  389. data/spec/unit/util/package/version/range_spec.rb +22 -1
  390. data/spec/unit/util/run_mode_spec.rb +6 -6
  391. data/spec/unit/util/windows/api_types_spec.rb +104 -40
  392. data/spec/unit/util/windows/service_spec.rb +4 -4
  393. data/spec/unit/util_spec.rb +3 -3
  394. data/spec/unit/x509/cert_provider_spec.rb +1 -1
  395. data/tasks/manpages.rake +5 -35
  396. metadata +43 -49
  397. data/spec/integration/faces/config_spec.rb +0 -91
  398. data/spec/integration/faces/documentation_spec.rb +0 -57
  399. data/spec/integration/file_bucket/file_spec.rb +0 -50
  400. data/spec/integration/file_serving/content_spec.rb +0 -7
  401. data/spec/integration/file_serving/fileset_spec.rb +0 -12
  402. data/spec/integration/file_serving/metadata_spec.rb +0 -8
  403. data/spec/integration/file_serving/terminus_helper_spec.rb +0 -20
  404. data/spec/integration/file_system/uniquefile_spec.rb +0 -26
  405. data/spec/integration/module_tool/forge_spec.rb +0 -51
  406. data/spec/integration/module_tool/tar/mini_spec.rb +0 -28
  407. data/spec/integration/provider/service/init_spec.rb +0 -48
  408. data/spec/integration/provider/service/systemd_spec.rb +0 -25
  409. data/spec/integration/provider/service/windows_spec.rb +0 -50
  410. data/spec/integration/reference/providers_spec.rb +0 -21
  411. data/spec/integration/reports_spec.rb +0 -13
  412. data/spec/integration/ssl/certificate_request_spec.rb +0 -44
  413. data/spec/integration/ssl/host_spec.rb +0 -72
  414. data/spec/integration/ssl/key_spec.rb +0 -99
  415. data/spec/integration/test/test_helper_spec.rb +0 -31
  416. data/spec/shared_behaviours/file_serving_model.rb +0 -51
  417. data/spec/unit/face/man_spec.rb +0 -25
  418. data/spec/unit/man_spec.rb +0 -31
@@ -140,12 +140,7 @@ class Puppet::Util::Windows::EventLog
140
140
  # @api private
141
141
  def from_string_to_wide_string(str, &block)
142
142
  str = wide_string(str)
143
- FFI::MemoryPointer.new(:uchar, str.bytesize) do |ptr|
144
- # uchar here is synonymous with byte
145
- ptr.put_array_of_uchar(0, str.bytes.to_a)
146
-
147
- yield ptr
148
- end
143
+ FFI::MemoryPointer.from_wide_string(str) { |ptr| yield ptr }
149
144
 
150
145
  # ptr has already had free called, so nothing to return
151
146
  nil
@@ -0,0 +1,40 @@
1
+ require 'win32/dir/constants'
2
+ require 'win32/dir/functions'
3
+ require 'win32/dir/structs'
4
+
5
+ class DirMonkeyPatched
6
+ include ::Dir::Structs
7
+ include ::Dir::Constants
8
+ extend ::Dir::Functions
9
+
10
+ path = nil
11
+ key = :PERSONAL
12
+ value = 0x0005
13
+ buf = 0.chr * 1024
14
+ buf.encode!(Encoding::UTF_16LE)
15
+
16
+ if SHGetFolderPathW(0, value, 0, 0, buf) == 0 # Current path
17
+ path = buf.strip
18
+ elsif SHGetFolderPathW(0, value, 0, 1, buf) == 0 # Default path
19
+ path = buf.strip
20
+ else
21
+ FFI::MemoryPointer.new(:long) do |ptr|
22
+ if SHGetFolderLocation(0, value, 0, 0, ptr) == 0
23
+ SHFILEINFO.new do |info|
24
+ flags = SHGFI_DISPLAYNAME | SHGFI_PIDL
25
+ if SHGetFileInfo(ptr.read_long, 0, info, info.size, flags) != 0
26
+ path = info[:szDisplayName].to_s
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ if path.nil?
34
+ begin
35
+ Dir.const_set(key, ''.encode(Encoding.default_external))
36
+ rescue Encoding::UndefinedConversionError
37
+ Dir.const_set(key, ''.encode(Encoding::UTF_8))
38
+ end
39
+ end
40
+ end
@@ -41,6 +41,7 @@ module Puppet::Util::Windows::SID
41
41
  # = 8 + max sub identifiers (15) * 4
42
42
  MAXIMUM_SID_BYTE_LENGTH = 68
43
43
 
44
+ ERROR_INVALID_PARAMETER = 87
44
45
  ERROR_INSUFFICIENT_BUFFER = 122
45
46
 
46
47
  def self.lookup_account_name(system_name = nil, account_name)
@@ -48,9 +49,7 @@ module Puppet::Util::Windows::SID
48
49
  begin
49
50
  if system_name
50
51
  system_name_wide = Puppet::Util::Windows::String.wide_string(system_name)
51
- # uchar here is synonymous with byte
52
- system_name_ptr = FFI::MemoryPointer.new(:byte, system_name_wide.bytesize)
53
- system_name_ptr.put_array_of_uchar(0, system_name_wide.bytes.to_a)
52
+ system_name_ptr = FFI::MemoryPointer.from_wide_string(system_name_wide)
54
53
  end
55
54
 
56
55
  FFI::MemoryPointer.from_string_to_wide_string(account_name) do |account_name_ptr|
@@ -101,9 +100,7 @@ module Puppet::Util::Windows::SID
101
100
  begin
102
101
  if system_name
103
102
  system_name_wide = Puppet::Util::Windows::String.wide_string(system_name)
104
- # uchar here is synonymous with byte
105
- system_name_ptr = FFI::MemoryPointer.new(:byte, system_name_wide.bytesize)
106
- system_name_ptr.put_array_of_uchar(0, system_name_wide.bytes.to_a)
103
+ system_name_ptr = FFI::MemoryPointer.from_wide_string(system_name_wide)
107
104
  end
108
105
 
109
106
  FFI::MemoryPointer.new(:byte, sid_bytes.length) do |sid_ptr|
@@ -112,6 +109,11 @@ module Puppet::Util::Windows::SID
112
109
  FFI::MemoryPointer.new(:uint32, 1) do |name_use_enum_ptr|
113
110
 
114
111
  sid_ptr.write_array_of_uchar(sid_bytes)
112
+
113
+ if Puppet::Util::Windows::SID.IsValidSid(sid_ptr) == FFI::WIN32_FALSE
114
+ raise Puppet::Util::Windows::Error.new(_('Byte array for lookup_account_sid is invalid: %{sid_bytes}') % { sid_bytes: sid_bytes }, ERROR_INVALID_PARAMETER)
115
+ end
116
+
115
117
  success = LookupAccountSidW(system_name_ptr, sid_ptr, FFI::Pointer::NULL, name_length_ptr,
116
118
  FFI::Pointer::NULL, domain_length_ptr, name_use_enum_ptr)
117
119
  last_error = FFI.errno
@@ -110,13 +110,16 @@ module Puppet::Util::Windows
110
110
 
111
111
  private
112
112
 
113
- def reg_enum_key(key, index, max_key_length = Win32::Registry::Constants::MAX_KEY_LENGTH)
113
+ # max number of wide characters including NULL terminator
114
+ MAX_KEY_CHAR_LENGTH = 255 + 1
115
+
116
+ def reg_enum_key(key, index, max_key_char_length = MAX_KEY_CHAR_LENGTH)
114
117
  subkey, filetime = nil, nil
115
118
 
116
119
  FFI::MemoryPointer.new(:dword) do |subkey_length_ptr|
117
120
  FFI::MemoryPointer.new(FFI::WIN32::FILETIME.size) do |filetime_ptr|
118
- FFI::MemoryPointer.new(:wchar, max_key_length) do |subkey_ptr|
119
- subkey_length_ptr.write_dword(max_key_length)
121
+ FFI::MemoryPointer.new(:wchar, max_key_char_length) do |subkey_ptr|
122
+ subkey_length_ptr.write_dword(max_key_char_length)
120
123
 
121
124
  # RegEnumKeyEx cannot be called twice to properly size the buffer
122
125
  result = RegEnumKeyExW(key.hkey, index,
@@ -141,7 +144,10 @@ module Puppet::Util::Windows
141
144
  [subkey, filetime]
142
145
  end
143
146
 
144
- def reg_enum_value(key, index, max_value_length = Win32::Registry::Constants::MAX_VALUE_LENGTH)
147
+ # max number of wide characters including NULL terminator
148
+ MAX_VALUE_CHAR_LENGTH = 16383 + 1
149
+
150
+ def reg_enum_value(key, index, max_value_length = MAX_VALUE_CHAR_LENGTH)
145
151
  subkey, type, data = nil, nil, nil
146
152
 
147
153
  FFI::MemoryPointer.new(:dword) do |subkey_length_ptr|
@@ -234,7 +240,7 @@ module Puppet::Util::Windows
234
240
  begin
235
241
  case type
236
242
  when Win32::Registry::REG_SZ, Win32::Registry::REG_EXPAND_SZ
237
- result = [ type, sanitize(data_ptr.read_wide_string(string_length)) ]
243
+ result = [ type, data_ptr.read_wide_string(string_length, Encoding::UTF_8, true) ]
238
244
  when Win32::Registry::REG_MULTI_SZ
239
245
  result = [ type, data_ptr.read_wide_string(string_length).split(/\0/) ]
240
246
  when Win32::Registry::REG_BINARY
@@ -314,12 +320,6 @@ module Puppet::Util::Windows
314
320
  result
315
321
  end
316
322
 
317
- def sanitize(value)
318
- # Replace null bytes with a space
319
- value.tr!("\x00", ' ')
320
- value
321
- end
322
-
323
323
  ffi_convention :stdcall
324
324
 
325
325
  # https://msdn.microsoft.com/en-us/library/windows/desktop/ms724862(v=vs.85).aspx
@@ -340,10 +340,10 @@ module Puppet::Util::Windows::Security
340
340
  Puppet.warning _("Setting control rights for %{path} owner SYSTEM to less than Full Control rights. Setting SYSTEM rights to less than Full Control may have unintented consequences for operations on this file") % { path: path }
341
341
  elsif managing_owner && isownergroup
342
342
  #TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
343
- Puppet.debug _("%{path} owner and group both set to user SYSTEM, but group is not managed directly: SYSTEM user rights will be set to FullControl by group") % { path: path }
343
+ Puppet.debug { _("%{path} owner and group both set to user SYSTEM, but group is not managed directly: SYSTEM user rights will be set to FullControl by group") % { path: path } }
344
344
  else
345
345
  #TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
346
- Puppet.debug _("An attempt to set mode %{mode} on item %{path} would result in the owner, SYSTEM, to have less than Full Control rights. This attempt has been corrected to Full Control") % { mode: mode.to_s(8), path: path }
346
+ Puppet.debug { _("An attempt to set mode %{mode} on item %{path} would result in the owner, SYSTEM, to have less than Full Control rights. This attempt has been corrected to Full Control") % { mode: mode.to_s(8), path: path } }
347
347
  owner_allow = FILE::FILE_ALL_ACCESS
348
348
  end
349
349
  end
@@ -356,10 +356,10 @@ module Puppet::Util::Windows::Security
356
356
  Puppet.warning _("Setting control rights for %{path} group SYSTEM to less than Full Control rights. Setting SYSTEM rights to less than Full Control may have unintented consequences for operations on this file") % { path: path }
357
357
  elsif managing_group && isownergroup
358
358
  #TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
359
- Puppet.debug _("%{path} owner and group both set to user SYSTEM, but owner is not managed directly: SYSTEM user rights will be set to FullControl by owner") % { path: path }
359
+ Puppet.debug { _("%{path} owner and group both set to user SYSTEM, but owner is not managed directly: SYSTEM user rights will be set to FullControl by owner") % { path: path } }
360
360
  else
361
361
  #TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
362
- Puppet.debug _("An attempt to set mode %{mode} on item %{path} would result in the group, SYSTEM, to have less than Full Control rights. This attempt has been corrected to Full Control") % { mode: mode.to_s(8), path: path }
362
+ Puppet.debug { _("An attempt to set mode %{mode} on item %{path} would result in the group, SYSTEM, to have less than Full Control rights. This attempt has been corrected to Full Control") % { mode: mode.to_s(8), path: path } }
363
363
  group_allow = FILE::FILE_ALL_ACCESS
364
364
  end
365
365
  end
@@ -440,43 +440,60 @@ module Puppet::Util::Windows
440
440
  end
441
441
  module_function :service_start_type
442
442
 
443
- # Change the startup mode of a windows service
443
+ # Query the configuration of a service using QueryServiceConfigW
444
+ # to find its current logon account
444
445
  #
445
- # @param [String] service_name the name of the service to modify
446
- # @param [Integer] startup_type a code corresponding to a start type for
447
- # windows service, see the "Service start type codes" section in the
448
- # Puppet::Util::Windows::Service file for the list of available codes
449
- # @param [Bool] delayed whether the service should be started with a delay
450
- def set_startup_mode(service_name, startup_type, delayed=false)
451
- startup_code = SERVICE_START_TYPES.key(startup_type)
452
- if startup_code.nil?
453
- raise Puppet::Error.new(_("Unknown start type %{start_type}") % {startup_type: startup_type.to_s})
446
+ # @return [String] logon_account account currently set for the service's logon
447
+ # in the format "DOMAIN\Account" or ".\Account" if it's a local account
448
+ def logon_account(service_name)
449
+ open_service(service_name, SC_MANAGER_CONNECT, SERVICE_QUERY_CONFIG) do |service|
450
+ query_config(service) do |config|
451
+ return config[:lpServiceStartName].read_arbitrary_wide_string_up_to(Puppet::Util::Windows::ADSI::User::MAX_USERNAME_LENGTH)
452
+ end
454
453
  end
454
+ end
455
+ module_function :logon_account
456
+
457
+ # Set the startup configuration of a windows service
458
+ #
459
+ # @param [String] service_name the name of the service to modify
460
+ # @param [Hash] options the configuration to be applied. Expected option keys:
461
+ # - [Integer] startup_type a code corresponding to a start type for
462
+ # windows service, see the "Service start type codes" section in the
463
+ # Puppet::Util::Windows::Service file for the list of available codes
464
+ # - [String] logon_account the account to be used by the service for logon
465
+ # - [String] logon_password the provided logon_account's password to be used by the service for logon
466
+ # - [Bool] delayed whether the service should be started with a delay
467
+ def set_startup_configuration(service_name, options: {})
468
+ options[:startup_type] = SERVICE_START_TYPES.key(options[:startup_type]) || SERVICE_NO_CHANGE
469
+ options[:logon_account] = wide_string(options[:logon_account]) || FFI::Pointer::NULL
470
+ options[:logon_password] = wide_string(options[:logon_password]) || FFI::Pointer::NULL
471
+
455
472
  open_service(service_name, SC_MANAGER_CONNECT, SERVICE_CHANGE_CONFIG) do |service|
456
- # Currently the only thing puppet's API can really manage
457
- # in this list is dwStartType (the third param). Thus no
458
- # generic function was written to make use of all the params
459
- # since the API as-is couldn't use them anyway
460
473
  success = ChangeServiceConfigW(
461
474
  service,
462
- SERVICE_NO_CHANGE, # dwServiceType
463
- startup_code, # dwStartType
464
- SERVICE_NO_CHANGE, # dwErrorControl
465
- FFI::Pointer::NULL, # lpBinaryPathName
466
- FFI::Pointer::NULL, # lpLoadOrderGroup
467
- FFI::Pointer::NULL, # lpdwTagId
468
- FFI::Pointer::NULL, # lpDependencies
469
- FFI::Pointer::NULL, # lpServiceStartName
470
- FFI::Pointer::NULL, # lpPassword
471
- FFI::Pointer::NULL # lpDisplayName
475
+ SERVICE_NO_CHANGE, # dwServiceType
476
+ options[:startup_type], # dwStartType
477
+ SERVICE_NO_CHANGE, # dwErrorControl
478
+ FFI::Pointer::NULL, # lpBinaryPathName
479
+ FFI::Pointer::NULL, # lpLoadOrderGroup
480
+ FFI::Pointer::NULL, # lpdwTagId
481
+ FFI::Pointer::NULL, # lpDependencies
482
+ options[:logon_account], # lpServiceStartName
483
+ options[:logon_password], # lpPassword
484
+ FFI::Pointer::NULL # lpDisplayName
472
485
  )
473
486
  if success == FFI::WIN32_FALSE
474
487
  raise Puppet::Util::Windows::Error.new(_("Failed to update service configuration"))
475
488
  end
476
489
  end
477
- set_startup_mode_delayed(service_name, delayed)
490
+
491
+ if options[:startup_type]
492
+ options[:delayed] ||= false
493
+ set_startup_mode_delayed(service_name, options[:delayed])
494
+ end
478
495
  end
479
- module_function :set_startup_mode
496
+ module_function :set_startup_configuration
480
497
 
481
498
  # enumerate over all services in all states and return them as a hash
482
499
  #
@@ -16,6 +16,22 @@ module Puppet::Util::Windows::User
16
16
  end
17
17
  module_function :admin?
18
18
 
19
+ # The name of the account in all locales is `LocalSystem`. `.\LocalSystem` or `ComputerName\LocalSystem' can also be used.
20
+ # This account is not recognized by the security subsystem, so you cannot specify its name in a call to the `LookupAccountName` function.
21
+ # https://docs.microsoft.com/en-us/windows/win32/services/localsystem-account
22
+ def localsystem?(name)
23
+ ["LocalSystem", ".\\LocalSystem", "#{Puppet::Util::Windows::ADSI.computer_name}\\LocalSystem"].any?{ |s| s.casecmp(name) == 0 }
24
+ end
25
+ module_function :localsystem?
26
+
27
+ # Check if a given user is one of the default system accounts
28
+ # These accounts do not have a password and all checks done through logon attempt will fail
29
+ # https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/local-accounts#default-local-system-accounts
30
+ def default_system_account?(name)
31
+ user_sid = Puppet::Util::Windows::SID.name_to_sid(name)
32
+ [Puppet::Util::Windows::SID::LocalSystem, Puppet::Util::Windows::SID::NtLocal, Puppet::Util::Windows::SID::NtNetwork].include?(user_sid)
33
+ end
34
+ module_function :default_system_account?
19
35
 
20
36
  # https://msdn.microsoft.com/en-us/library/windows/desktop/ee207397(v=vs.85).aspx
21
37
  SECURITY_MAX_SID_SIZE = 68
@@ -57,9 +73,9 @@ module Puppet::Util::Windows::User
57
73
  end
58
74
  module_function :check_token_membership
59
75
 
60
- def password_is?(name, password)
76
+ def password_is?(name, password, domain = '.')
61
77
  begin
62
- logon_user(name, password) { |token| }
78
+ logon_user(name, password, domain) { |token| }
63
79
  rescue Puppet::Util::Windows::Error => detail
64
80
 
65
81
  authenticated_error_codes = Set[
@@ -74,7 +90,7 @@ module Puppet::Util::Windows::User
74
90
  end
75
91
  module_function :password_is?
76
92
 
77
- def logon_user(name, password, &block)
93
+ def logon_user(name, password, domain = '.', &block)
78
94
  fLOGON32_PROVIDER_DEFAULT = 0
79
95
  fLOGON32_LOGON_INTERACTIVE = 2
80
96
  fLOGON32_LOGON_NETWORK = 3
@@ -83,8 +99,8 @@ module Puppet::Util::Windows::User
83
99
  begin
84
100
  FFI::MemoryPointer.new(:handle, 1) do |token_pointer|
85
101
  #try logon using network else try logon using interactive mode
86
- if logon_user_by_logon_type(name, password, fLOGON32_LOGON_NETWORK, fLOGON32_PROVIDER_DEFAULT, token_pointer) == FFI::WIN32_FALSE
87
- if logon_user_by_logon_type(name, password, fLOGON32_LOGON_INTERACTIVE, fLOGON32_PROVIDER_DEFAULT, token_pointer) == FFI::WIN32_FALSE
102
+ if logon_user_by_logon_type(name, domain, password, fLOGON32_LOGON_NETWORK, fLOGON32_PROVIDER_DEFAULT, token_pointer) == FFI::WIN32_FALSE
103
+ if logon_user_by_logon_type(name, domain, password, fLOGON32_LOGON_INTERACTIVE, fLOGON32_PROVIDER_DEFAULT, token_pointer) == FFI::WIN32_FALSE
88
104
  raise Puppet::Util::Windows::Error.new(_("Failed to logon user %{name}") % {name: name.inspect})
89
105
  end
90
106
  end
@@ -98,11 +114,10 @@ module Puppet::Util::Windows::User
98
114
  # token has been closed by this point
99
115
  true
100
116
  end
101
-
102
117
  module_function :logon_user
103
118
 
104
- def self.logon_user_by_logon_type(name, password, logon_type, logon_provider, token)
105
- LogonUserW(wide_string(name), wide_string('.'), password.nil? ? FFI::Pointer::NULL : wide_string(password), logon_type, logon_provider, token)
119
+ def self.logon_user_by_logon_type(name, domain, password, logon_type, logon_provider, token)
120
+ LogonUserW(wide_string(name), wide_string(domain), password.nil? ? FFI::Pointer::NULL : wide_string(password), logon_type, logon_provider, token)
106
121
  end
107
122
 
108
123
  private_class_method :logon_user_by_logon_type
@@ -130,6 +145,125 @@ module Puppet::Util::Windows::User
130
145
  end
131
146
  module_function :load_profile
132
147
 
148
+ def get_rights(name)
149
+ user_info = Puppet::Util::Windows::SID.name_to_principal(name.sub(/^\.\\/, "#{Puppet::Util::Windows::ADSI.computer_name}\\"))
150
+ return "" unless user_info
151
+
152
+ rights = []
153
+ rights_pointer = FFI::MemoryPointer.new(:pointer)
154
+ number_of_rights = FFI::MemoryPointer.new(:ulong)
155
+ sid_pointer = FFI::MemoryPointer.new(:byte, user_info.sid_bytes.length).write_array_of_uchar(user_info.sid_bytes)
156
+
157
+ new_lsa_policy_handle do |policy_handle|
158
+ result = LsaEnumerateAccountRights(policy_handle.read_pointer, sid_pointer, rights_pointer, number_of_rights)
159
+ check_lsa_nt_status_and_raise_failures(result, "LsaEnumerateAccountRights")
160
+ end
161
+
162
+ number_of_rights.read_ulong.times do |index|
163
+ right = LSA_UNICODE_STRING.new(rights_pointer.read_pointer + index * LSA_UNICODE_STRING.size)
164
+ rights << right[:Buffer].read_arbitrary_wide_string_up_to
165
+ end
166
+
167
+ result = LsaFreeMemory(rights_pointer.read_pointer)
168
+ check_lsa_nt_status_and_raise_failures(result, "LsaFreeMemory")
169
+
170
+ rights.join(",")
171
+ end
172
+ module_function :get_rights
173
+
174
+ def set_rights(name, rights)
175
+ rights_pointer = new_lsa_unicode_strings_pointer(rights)
176
+ user_info = Puppet::Util::Windows::SID.name_to_principal(name.sub(/^\.\\/, "#{Puppet::Util::Windows::ADSI.computer_name}\\"))
177
+ sid_pointer = FFI::MemoryPointer.new(:byte, user_info.sid_bytes.length).write_array_of_uchar(user_info.sid_bytes)
178
+
179
+ new_lsa_policy_handle do |policy_handle|
180
+ result = LsaAddAccountRights(policy_handle.read_pointer, sid_pointer, rights_pointer, rights.size)
181
+ check_lsa_nt_status_and_raise_failures(result, "LsaAddAccountRights")
182
+ end
183
+ end
184
+ module_function :set_rights
185
+
186
+ def remove_rights(name, rights)
187
+ rights_pointer = new_lsa_unicode_strings_pointer(rights)
188
+ user_info = Puppet::Util::Windows::SID.name_to_principal(name.sub(/^\.\\/, "#{Puppet::Util::Windows::ADSI.computer_name}\\"))
189
+ sid_pointer = FFI::MemoryPointer.new(:byte, user_info.sid_bytes.length).write_array_of_uchar(user_info.sid_bytes)
190
+
191
+ new_lsa_policy_handle do |policy_handle|
192
+ result = LsaRemoveAccountRights(policy_handle.read_pointer, sid_pointer, false, rights_pointer, rights.size)
193
+ check_lsa_nt_status_and_raise_failures(result, "LsaRemoveAccountRights")
194
+ end
195
+ end
196
+ module_function :remove_rights
197
+
198
+ # ACCESS_MASK flags for Policy Objects
199
+ # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lsad/b61b7268-987a-420b-84f9-6c75f8dc8558
200
+ POLICY_VIEW_LOCAL_INFORMATION = 0x00000001
201
+ POLICY_VIEW_AUDIT_INFORMATION = 0x00000002
202
+ POLICY_GET_PRIVATE_INFORMATION = 0x00000004
203
+ POLICY_TRUST_ADMIN = 0x00000008
204
+ POLICY_CREATE_ACCOUNT = 0x00000010
205
+ POLICY_CREATE_SECRET = 0x00000020
206
+ POLICY_CREATE_PRIVILEGE = 0x00000040
207
+ POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080
208
+ POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100
209
+ POLICY_AUDIT_LOG_ADMIN = 0x00000200
210
+ POLICY_SERVER_ADMIN = 0x00000400
211
+ POLICY_LOOKUP_NAMES = 0x00000800
212
+ POLICY_NOTIFICATION = 0x00001000
213
+
214
+ def self.new_lsa_policy_handle
215
+ access = 0
216
+ access |= POLICY_LOOKUP_NAMES
217
+ access |= POLICY_CREATE_ACCOUNT
218
+ policy_handle = FFI::MemoryPointer.new(:pointer)
219
+
220
+ result = LsaOpenPolicy(nil, LSA_OBJECT_ATTRIBUTES.new, access, policy_handle)
221
+ check_lsa_nt_status_and_raise_failures(result, "LsaOpenPolicy")
222
+
223
+ begin
224
+ yield policy_handle
225
+ ensure
226
+ result = LsaClose(policy_handle.read_pointer)
227
+ check_lsa_nt_status_and_raise_failures(result, "LsaClose")
228
+ end
229
+ end
230
+ private_class_method :new_lsa_policy_handle
231
+
232
+ def self.new_lsa_unicode_strings_pointer(strings)
233
+ lsa_unicode_strings_pointer = FFI::MemoryPointer.new(LSA_UNICODE_STRING, strings.size)
234
+
235
+ strings.each_with_index do |string, index|
236
+ lsa_string = LSA_UNICODE_STRING.new(lsa_unicode_strings_pointer + index * LSA_UNICODE_STRING.size)
237
+ lsa_string[:Buffer] = FFI::MemoryPointer.from_string(wide_string(string))
238
+ lsa_string[:Length] = string.length * 2
239
+ lsa_string[:MaximumLength] = lsa_string[:Length] + 2
240
+ end
241
+
242
+ lsa_unicode_strings_pointer
243
+ end
244
+ private_class_method :new_lsa_unicode_strings_pointer
245
+
246
+ # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/18d8fbe8-a967-4f1c-ae50-99ca8e491d2d
247
+ def self.check_lsa_nt_status_and_raise_failures(status, method_name)
248
+ error_code = LsaNtStatusToWinError(status)
249
+
250
+ error_reason = case error_code.to_s(16)
251
+ when '0' # ERROR_SUCCESS
252
+ return # Method call succeded
253
+ when '2' # ERROR_FILE_NOT_FOUND
254
+ return # No rights/privilleges assigned to given user
255
+ when '5' # ERROR_ACCESS_DENIED
256
+ "Access is denied. Please make sure that puppet is running as administrator."
257
+ when '521' # ERROR_NO_SUCH_PRIVILEGE
258
+ "One or more of the given rights/privilleges are incorrect."
259
+ when '6ba' # RPC_S_SERVER_UNAVAILABLE
260
+ "The RPC server is unavailable or given domain name is invalid."
261
+ end
262
+
263
+ raise Puppet::Error.new("Calling `#{method_name}` returned 'Win32 Error Code 0x%08X'. #{error_reason}" % error_code)
264
+ end
265
+ private_class_method :check_lsa_nt_status_and_raise_failures
266
+
133
267
  ffi_convention :stdcall
134
268
 
135
269
  # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx
@@ -314,4 +448,104 @@ module Puppet::Util::Windows::User
314
448
  ffi_lib :advapi32
315
449
  attach_function_private :IsValidSid,
316
450
  [:pointer], :win32_bool
451
+
452
+ # https://docs.microsoft.com/en-us/windows/win32/api/lsalookup/ns-lsalookup-lsa_object_attributes
453
+ # typedef struct _LSA_OBJECT_ATTRIBUTES {
454
+ # ULONG Length;
455
+ # HANDLE RootDirectory;
456
+ # PLSA_UNICODE_STRING ObjectName;
457
+ # ULONG Attributes;
458
+ # PVOID SecurityDescriptor;
459
+ # PVOID SecurityQualityOfService;
460
+ # } LSA_OBJECT_ATTRIBUTES, *PLSA_OBJECT_ATTRIBUTES;
461
+ class LSA_OBJECT_ATTRIBUTES < FFI::Struct
462
+ layout :Length, :ulong,
463
+ :RootDirectory, :handle,
464
+ :ObjectName, :plsa_unicode_string,
465
+ :Attributes, :ulong,
466
+ :SecurityDescriptor, :pvoid,
467
+ :SecurityQualityOfService, :pvoid
468
+ end
469
+
470
+ # https://docs.microsoft.com/en-us/windows/win32/api/lsalookup/ns-lsalookup-lsa_unicode_string
471
+ # typedef struct _LSA_UNICODE_STRING {
472
+ # USHORT Length;
473
+ # USHORT MaximumLength;
474
+ # PWSTR Buffer;
475
+ # } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING;
476
+ class LSA_UNICODE_STRING < FFI::Struct
477
+ layout :Length, :ushort,
478
+ :MaximumLength, :ushort,
479
+ :Buffer, :pwstr
480
+ end
481
+
482
+ # https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaenumerateaccountrights
483
+ # https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment
484
+ # NTSTATUS LsaEnumerateAccountRights(
485
+ # LSA_HANDLE PolicyHandle,
486
+ # PSID AccountSid,
487
+ # PLSA_UNICODE_STRING *UserRights,
488
+ # PULONG CountOfRights
489
+ # );
490
+ ffi_lib :advapi32
491
+ attach_function_private :LsaEnumerateAccountRights,
492
+ [:lsa_handle, :psid, :plsa_unicode_string, :pulong], :ntstatus
493
+
494
+ # https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaaddaccountrights
495
+ # NTSTATUS LsaAddAccountRights(
496
+ # LSA_HANDLE PolicyHandle,
497
+ # PSID AccountSid,
498
+ # PLSA_UNICODE_STRING UserRights,
499
+ # ULONG CountOfRights
500
+ # );
501
+ ffi_lib :advapi32
502
+ attach_function_private :LsaAddAccountRights,
503
+ [:lsa_handle, :psid, :plsa_unicode_string, :ulong], :ntstatus
504
+
505
+ # https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaremoveaccountrights
506
+ # NTSTATUS LsaRemoveAccountRights(
507
+ # LSA_HANDLE PolicyHandle,
508
+ # PSID AccountSid,
509
+ # BOOLEAN AllRights,
510
+ # PLSA_UNICODE_STRING UserRights,
511
+ # ULONG CountOfRights
512
+ # );
513
+ ffi_lib :advapi32
514
+ attach_function_private :LsaRemoveAccountRights,
515
+ [:lsa_handle, :psid, :bool, :plsa_unicode_string, :ulong], :ntstatus
516
+
517
+ # https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaopenpolicy
518
+ # NTSTATUS LsaOpenPolicy(
519
+ # PLSA_UNICODE_STRING SystemName,
520
+ # PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
521
+ # ACCESS_MASK DesiredAccess,
522
+ # PLSA_HANDLE PolicyHandle
523
+ # );
524
+ ffi_lib :advapi32
525
+ attach_function_private :LsaOpenPolicy,
526
+ [:plsa_unicode_string, :plsa_object_attributes, :access_mask, :plsa_handle], :ntstatus
527
+
528
+ # https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaclose
529
+ # NTSTATUS LsaClose(
530
+ # LSA_HANDLE ObjectHandle
531
+ # );
532
+ ffi_lib :advapi32
533
+ attach_function_private :LsaClose,
534
+ [:lsa_handle], :ntstatus
535
+
536
+ # https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsafreememory
537
+ # NTSTATUS LsaFreeMemory(
538
+ # PVOID Buffer
539
+ # );
540
+ ffi_lib :advapi32
541
+ attach_function_private :LsaFreeMemory,
542
+ [:pvoid], :ntstatus
543
+
544
+ # https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsantstatustowinerror
545
+ # ULONG LsaNtStatusToWinError(
546
+ # NTSTATUS Status
547
+ # );
548
+ ffi_lib :advapi32
549
+ attach_function_private :LsaNtStatusToWinError,
550
+ [:ntstatus], :ulong
317
551
  end