puppet 6.17.0-x86-mingw32 → 6.21.0-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 (401) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -16
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +38 -34
  5. data/README.md +1 -2
  6. data/Rakefile +4 -12
  7. data/lib/puppet/agent/locker.rb +0 -7
  8. data/lib/puppet/application.rb +10 -6
  9. data/lib/puppet/application/agent.rb +9 -3
  10. data/lib/puppet/application/apply.rb +20 -21
  11. data/lib/puppet/application/device.rb +1 -0
  12. data/lib/puppet/application/doc.rb +1 -1
  13. data/lib/puppet/application/filebucket.rb +2 -2
  14. data/lib/puppet/application/lookup.rb +16 -4
  15. data/lib/puppet/application/script.rb +1 -0
  16. data/lib/puppet/application_support.rb +7 -0
  17. data/lib/puppet/configurer.rb +50 -8
  18. data/lib/puppet/configurer/downloader.rb +31 -10
  19. data/lib/puppet/confine.rb +1 -1
  20. data/lib/puppet/confine/any.rb +1 -1
  21. data/lib/puppet/defaults.rb +88 -38
  22. data/lib/puppet/environments.rb +84 -59
  23. data/lib/puppet/face/catalog.rb +1 -1
  24. data/lib/puppet/face/config.rb +56 -16
  25. data/lib/puppet/face/epp.rb +12 -2
  26. data/lib/puppet/face/facts.rb +60 -0
  27. data/lib/puppet/face/node.rb +3 -3
  28. data/lib/puppet/face/node/clean.rb +2 -2
  29. data/lib/puppet/face/status.rb +1 -1
  30. data/lib/puppet/feature/base.rb +1 -1
  31. data/lib/puppet/ffi/posix.rb +10 -0
  32. data/lib/puppet/ffi/posix/constants.rb +14 -0
  33. data/lib/puppet/ffi/posix/functions.rb +24 -0
  34. data/lib/puppet/file_bucket/dipper.rb +1 -1
  35. data/lib/puppet/file_serving/mount/locales.rb +1 -2
  36. data/lib/puppet/file_serving/mount/pluginfacts.rb +1 -2
  37. data/lib/puppet/file_serving/mount/plugins.rb +1 -2
  38. data/lib/puppet/file_system/file_impl.rb +3 -3
  39. data/lib/puppet/functions/epp.rb +1 -0
  40. data/lib/puppet/functions/inline_epp.rb +1 -0
  41. data/lib/puppet/functions/lstrip.rb +4 -4
  42. data/lib/puppet/functions/new.rb +8 -3
  43. data/lib/puppet/functions/reverse_each.rb +1 -1
  44. data/lib/puppet/functions/rstrip.rb +4 -4
  45. data/lib/puppet/functions/step.rb +1 -1
  46. data/lib/puppet/functions/strip.rb +4 -4
  47. data/lib/puppet/gettext/config.rb +5 -5
  48. data/lib/puppet/gettext/module_translations.rb +4 -4
  49. data/lib/puppet/http.rb +1 -0
  50. data/lib/puppet/http/client.rb +1 -1
  51. data/lib/puppet/http/resolver.rb +5 -8
  52. data/lib/puppet/http/resolver/server_list.rb +18 -36
  53. data/lib/puppet/http/resolver/settings.rb +4 -4
  54. data/lib/puppet/http/resolver/srv.rb +5 -5
  55. data/lib/puppet/http/service.rb +3 -1
  56. data/lib/puppet/http/service/compiler.rb +1 -1
  57. data/lib/puppet/http/service/file_server.rb +1 -1
  58. data/lib/puppet/http/service/puppetserver.rb +39 -0
  59. data/lib/puppet/http/session.rb +5 -4
  60. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  61. data/lib/puppet/indirector/exec.rb +1 -1
  62. data/lib/puppet/indirector/fact_search.rb +60 -0
  63. data/lib/puppet/indirector/facts/facter.rb +3 -3
  64. data/lib/puppet/indirector/facts/json.rb +27 -0
  65. data/lib/puppet/indirector/facts/yaml.rb +4 -59
  66. data/lib/puppet/indirector/file_metadata/http.rb +1 -0
  67. data/lib/puppet/indirector/hiera.rb +4 -0
  68. data/lib/puppet/indirector/indirection.rb +1 -1
  69. data/lib/puppet/indirector/json.rb +5 -1
  70. data/lib/puppet/indirector/msgpack.rb +1 -1
  71. data/lib/puppet/indirector/node/json.rb +8 -0
  72. data/lib/puppet/indirector/report/json.rb +34 -0
  73. data/lib/puppet/indirector/report/processor.rb +2 -2
  74. data/lib/puppet/indirector/request.rb +4 -4
  75. data/lib/puppet/indirector/yaml.rb +1 -1
  76. data/lib/puppet/module.rb +1 -2
  77. data/lib/puppet/module_tool/applications/installer.rb +48 -2
  78. data/lib/puppet/module_tool/errors/shared.rb +17 -2
  79. data/lib/puppet/network/format_support.rb +2 -2
  80. data/lib/puppet/network/formats.rb +2 -1
  81. data/lib/puppet/network/http/api/master/v3/environments.rb +0 -1
  82. data/lib/puppet/network/http/route.rb +2 -2
  83. data/lib/puppet/node/environment.rb +12 -5
  84. data/lib/puppet/node/facts.rb +17 -0
  85. data/lib/puppet/pal/pal_impl.rb +90 -13
  86. data/lib/puppet/parameter.rb +1 -1
  87. data/lib/puppet/parser/ast/leaf.rb +3 -2
  88. data/lib/puppet/parser/functions.rb +21 -17
  89. data/lib/puppet/parser/functions/create_resources.rb +11 -7
  90. data/lib/puppet/parser/templatewrapper.rb +1 -1
  91. data/lib/puppet/parser/type_loader.rb +2 -2
  92. data/lib/puppet/pops/adaptable.rb +7 -13
  93. data/lib/puppet/pops/adapters.rb +8 -4
  94. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -3
  95. data/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  96. data/lib/puppet/pops/evaluator/evaluator_impl.rb +22 -3
  97. data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
  98. data/lib/puppet/pops/loader/runtime3_type_loader.rb +4 -2
  99. data/lib/puppet/pops/loaders.rb +18 -11
  100. data/lib/puppet/pops/lookup/context.rb +1 -1
  101. data/lib/puppet/pops/lookup/hiera_config.rb +14 -1
  102. data/lib/puppet/pops/model/ast_transformer.rb +1 -1
  103. data/lib/puppet/pops/types/iterable.rb +34 -8
  104. data/lib/puppet/pops/types/p_meta_type.rb +1 -1
  105. data/lib/puppet/pops/types/p_type_set_type.rb +4 -0
  106. data/lib/puppet/pops/validation/checker4_0.rb +19 -15
  107. data/lib/puppet/property/list.rb +1 -1
  108. data/lib/puppet/provider/file/windows.rb +1 -1
  109. data/lib/puppet/provider/group/groupadd.rb +13 -8
  110. data/lib/puppet/provider/package/apt.rb +67 -1
  111. data/lib/puppet/provider/package/aptitude.rb +6 -0
  112. data/lib/puppet/provider/package/dpkg.rb +1 -1
  113. data/lib/puppet/provider/package/gem.rb +4 -2
  114. data/lib/puppet/provider/package/pip2.rb +17 -0
  115. data/lib/puppet/provider/package/puppet_gem.rb +5 -0
  116. data/lib/puppet/provider/package/puppetserver_gem.rb +180 -0
  117. data/lib/puppet/provider/package/yum.rb +1 -0
  118. data/lib/puppet/provider/package/zypper.rb +3 -0
  119. data/lib/puppet/provider/service/debian.rb +2 -0
  120. data/lib/puppet/provider/user/aix.rb +3 -3
  121. data/lib/puppet/provider/user/user_role_add.rb +1 -1
  122. data/lib/puppet/provider/user/useradd.rb +55 -8
  123. data/lib/puppet/provider/user/windows_adsi.rb +18 -1
  124. data/lib/puppet/reference/configuration.rb +6 -5
  125. data/lib/puppet/resource/type.rb +2 -1
  126. data/lib/puppet/rest/route.rb +2 -2
  127. data/lib/puppet/settings.rb +63 -21
  128. data/lib/puppet/settings/alias_setting.rb +37 -0
  129. data/lib/puppet/settings/base_setting.rb +26 -2
  130. data/lib/puppet/ssl/validator/default_validator.rb +1 -1
  131. data/lib/puppet/test/test_helper.rb +10 -3
  132. data/lib/puppet/transaction.rb +2 -2
  133. data/lib/puppet/transaction/persistence.rb +1 -1
  134. data/lib/puppet/transaction/report.rb +12 -8
  135. data/lib/puppet/trusted_external.rb +2 -2
  136. data/lib/puppet/type.rb +4 -3
  137. data/lib/puppet/type/file.rb +2 -2
  138. data/lib/puppet/type/file/source.rb +28 -8
  139. data/lib/puppet/type/filebucket.rb +1 -1
  140. data/lib/puppet/type/notify.rb +2 -2
  141. data/lib/puppet/type/package.rb +3 -3
  142. data/lib/puppet/type/service.rb +4 -0
  143. data/lib/puppet/type/user.rb +18 -3
  144. data/lib/puppet/util.rb +26 -12
  145. data/lib/puppet/util/autoload.rb +10 -15
  146. data/lib/puppet/util/character_encoding.rb +9 -5
  147. data/lib/puppet/util/connection.rb +8 -8
  148. data/lib/puppet/util/execution.rb +2 -2
  149. data/lib/puppet/util/fact_dif.rb +62 -0
  150. data/lib/puppet/util/posix.rb +54 -5
  151. data/lib/puppet/util/rubygems.rb +5 -1
  152. data/lib/puppet/util/run_mode.rb +5 -1
  153. data/lib/puppet/util/windows.rb +1 -0
  154. data/lib/puppet/util/windows/api_types.rb +15 -1
  155. data/lib/puppet/util/windows/monkey_patches/dir.rb +40 -0
  156. data/lib/puppet/util/windows/security.rb +4 -4
  157. data/lib/puppet/util/windows/service.rb +1 -1
  158. data/lib/puppet/util/windows/user.rb +219 -0
  159. data/lib/puppet/version.rb +1 -1
  160. data/locales/puppet.pot +342 -312
  161. data/man/man5/puppet.conf.5 +53 -18
  162. data/man/man8/puppet-agent.8 +7 -4
  163. data/man/man8/puppet-apply.8 +2 -2
  164. data/man/man8/puppet-catalog.8 +1 -1
  165. data/man/man8/puppet-config.8 +6 -6
  166. data/man/man8/puppet-describe.8 +1 -1
  167. data/man/man8/puppet-device.8 +2 -2
  168. data/man/man8/puppet-doc.8 +1 -1
  169. data/man/man8/puppet-epp.8 +1 -1
  170. data/man/man8/puppet-facts.8 +32 -1
  171. data/man/man8/puppet-filebucket.8 +3 -3
  172. data/man/man8/puppet-generate.8 +1 -1
  173. data/man/man8/puppet-help.8 +1 -1
  174. data/man/man8/puppet-key.8 +1 -1
  175. data/man/man8/puppet-lookup.8 +2 -2
  176. data/man/man8/puppet-man.8 +1 -1
  177. data/man/man8/puppet-module.8 +1 -1
  178. data/man/man8/puppet-node.8 +7 -4
  179. data/man/man8/puppet-parser.8 +1 -1
  180. data/man/man8/puppet-plugin.8 +1 -1
  181. data/man/man8/puppet-report.8 +4 -1
  182. data/man/man8/puppet-resource.8 +1 -1
  183. data/man/man8/puppet-script.8 +2 -2
  184. data/man/man8/puppet-ssl.8 +1 -1
  185. data/man/man8/puppet-status.8 +2 -2
  186. data/man/man8/puppet.8 +2 -2
  187. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +91 -0
  188. data/spec/fixtures/integration/application/apply/environments/spec/modules/amod/lib/puppet/provider/applytest/applytest.rb +2 -0
  189. data/spec/fixtures/integration/application/apply/environments/spec/modules/amod/lib/puppet/type/applytest.rb +25 -0
  190. data/spec/fixtures/unit/forge/bacula-releases.json +128 -0
  191. data/spec/fixtures/unit/forge/bacula.tar.gz +0 -0
  192. data/spec/fixtures/unit/provider/package/puppetserver_gem/gem-list-local-packages +30 -0
  193. data/spec/fixtures/unit/provider/user/aix/aix_passwd_file.out +4 -0
  194. data/spec/integration/application/agent_spec.rb +208 -55
  195. data/spec/integration/application/apply_spec.rb +168 -149
  196. data/spec/integration/application/doc_spec.rb +16 -6
  197. data/spec/integration/application/filebucket_spec.rb +70 -21
  198. data/spec/integration/application/help_spec.rb +42 -0
  199. data/spec/integration/application/lookup_spec.rb +13 -0
  200. data/spec/integration/application/module_spec.rb +68 -0
  201. data/spec/integration/application/plugin_spec.rb +53 -3
  202. data/spec/integration/configurer_spec.rb +14 -0
  203. data/spec/integration/data_binding_spec.rb +82 -0
  204. data/spec/integration/defaults_spec.rb +19 -1
  205. data/spec/integration/directory_environments_spec.rb +17 -17
  206. data/spec/integration/environments/setting_hooks_spec.rb +1 -1
  207. data/spec/integration/indirector/facts/facter_spec.rb +8 -6
  208. data/spec/integration/node/environment_spec.rb +1 -1
  209. data/spec/integration/resource/type_collection_spec.rb +2 -6
  210. data/spec/integration/transaction_spec.rb +4 -9
  211. data/spec/integration/util/execution_spec.rb +22 -0
  212. data/spec/integration/util/windows/adsi_spec.rb +5 -3
  213. data/spec/integration/util/windows/monkey_patches/dir_spec.rb +11 -0
  214. data/spec/integration/util/windows/process_spec.rb +26 -32
  215. data/spec/integration/util/windows/registry_spec.rb +0 -10
  216. data/spec/integration/util/windows/user_spec.rb +7 -0
  217. data/spec/integration/util_spec.rb +7 -33
  218. data/spec/lib/puppet_spec/matchers.rb +0 -80
  219. data/spec/lib/puppet_spec/puppetserver.rb +8 -0
  220. data/spec/lib/puppet_spec/settings.rb +6 -1
  221. data/spec/shared_contexts/types_setup.rb +2 -0
  222. data/spec/spec_helper.rb +1 -4
  223. data/spec/unit/agent_spec.rb +8 -6
  224. data/spec/unit/application/agent_spec.rb +3 -5
  225. data/spec/unit/application/config_spec.rb +224 -4
  226. data/spec/unit/application/doc_spec.rb +2 -2
  227. data/spec/unit/application/face_base_spec.rb +6 -4
  228. data/spec/unit/application/facts_spec.rb +41 -10
  229. data/spec/unit/application/filebucket_spec.rb +0 -2
  230. data/spec/unit/application/man_spec.rb +52 -0
  231. data/spec/unit/application/resource_spec.rb +3 -1
  232. data/spec/unit/application/ssl_spec.rb +15 -2
  233. data/spec/unit/application_spec.rb +60 -13
  234. data/spec/unit/configurer/downloader_spec.rb +10 -0
  235. data/spec/unit/configurer_spec.rb +86 -37
  236. data/spec/unit/confine/feature_spec.rb +1 -1
  237. data/spec/unit/confine_spec.rb +10 -3
  238. data/spec/unit/defaults_spec.rb +20 -1
  239. data/spec/unit/environments_spec.rb +176 -32
  240. data/spec/unit/face/config_spec.rb +65 -12
  241. data/spec/unit/face/node_spec.rb +2 -13
  242. data/spec/unit/file_serving/configuration/parser_spec.rb +0 -1
  243. data/spec/unit/file_serving/metadata_spec.rb +3 -3
  244. data/spec/unit/file_serving/mount/locales_spec.rb +2 -2
  245. data/spec/unit/file_serving/mount/pluginfacts_spec.rb +2 -2
  246. data/spec/unit/file_serving/mount/plugins_spec.rb +2 -2
  247. data/spec/unit/file_serving/terminus_helper_spec.rb +11 -4
  248. data/spec/unit/file_system/uniquefile_spec.rb +18 -0
  249. data/spec/unit/file_system_spec.rb +1 -2
  250. data/spec/unit/forge/module_release_spec.rb +2 -7
  251. data/spec/unit/functions/inline_epp_spec.rb +26 -1
  252. data/spec/unit/http/client_spec.rb +0 -1
  253. data/spec/unit/http/resolver_spec.rb +24 -5
  254. data/spec/unit/http/service/ca_spec.rb +2 -3
  255. data/spec/unit/http/service/compiler_spec.rb +51 -3
  256. data/spec/unit/http/service/file_server_spec.rb +2 -3
  257. data/spec/unit/http/service/puppetserver_spec.rb +82 -0
  258. data/spec/unit/http/service/report_spec.rb +2 -3
  259. data/spec/unit/http/service_spec.rb +1 -2
  260. data/spec/unit/http/session_spec.rb +8 -21
  261. data/spec/unit/indirector/catalog/json_spec.rb +1 -1
  262. data/spec/unit/indirector/catalog/rest_spec.rb +1 -1
  263. data/spec/unit/indirector/face_spec.rb +0 -1
  264. data/spec/unit/indirector/facts/facter_spec.rb +0 -1
  265. data/spec/unit/indirector/facts/json_spec.rb +255 -0
  266. data/spec/unit/indirector/facts/rest_spec.rb +1 -1
  267. data/spec/unit/indirector/file_bucket_file/selector_spec.rb +26 -8
  268. data/spec/unit/indirector/indirection_spec.rb +8 -12
  269. data/spec/unit/indirector/json_spec.rb +8 -8
  270. data/spec/unit/indirector/key/file_spec.rb +0 -1
  271. data/spec/unit/indirector/msgpack_spec.rb +8 -8
  272. data/spec/unit/indirector/node/json_spec.rb +33 -0
  273. data/spec/unit/indirector/node/rest_spec.rb +1 -1
  274. data/spec/{integration/indirector/report/yaml.rb → unit/indirector/report/json_spec.rb} +13 -24
  275. data/spec/unit/indirector/report/yaml_spec.rb +72 -8
  276. data/spec/unit/indirector/request_spec.rb +4 -4
  277. data/spec/unit/indirector/rest_spec.rb +1 -1
  278. data/spec/unit/indirector/status/rest_spec.rb +1 -1
  279. data/spec/unit/indirector/yaml_spec.rb +7 -7
  280. data/spec/unit/indirector_spec.rb +2 -2
  281. data/spec/unit/module_tool/applications/installer_spec.rb +66 -0
  282. data/spec/unit/module_tool/tar/mini_spec.rb +20 -0
  283. data/spec/unit/network/authconfig_spec.rb +0 -3
  284. data/spec/unit/network/format_support_spec.rb +3 -2
  285. data/spec/unit/network/http/api/indirected_routes_spec.rb +0 -9
  286. data/spec/unit/network/http/api/master/v3/environments_spec.rb +12 -23
  287. data/spec/unit/network/http/handler_spec.rb +0 -5
  288. data/spec/unit/node/environment_spec.rb +18 -1
  289. data/spec/unit/parser/compiler_spec.rb +3 -19
  290. data/spec/unit/parser/resource_spec.rb +14 -8
  291. data/spec/unit/parser/templatewrapper_spec.rb +4 -3
  292. data/spec/unit/pops/evaluator/deferred_resolver_spec.rb +20 -0
  293. data/spec/unit/pops/loaders/loaders_spec.rb +70 -0
  294. data/spec/unit/pops/lookup/lookup_spec.rb +25 -0
  295. data/spec/unit/property_spec.rb +1 -0
  296. data/spec/unit/provider/exec_spec.rb +4 -3
  297. data/spec/unit/provider/group/groupadd_spec.rb +5 -2
  298. data/spec/unit/provider/nameservice_spec.rb +66 -65
  299. data/spec/unit/provider/package/apt_spec.rb +85 -3
  300. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  301. data/spec/unit/provider/package/base_spec.rb +6 -5
  302. data/spec/unit/provider/package/dpkg_spec.rb +22 -7
  303. data/spec/unit/provider/package/openbsd_spec.rb +2 -0
  304. data/spec/unit/provider/package/pacman_spec.rb +18 -12
  305. data/spec/unit/provider/package/pip2_spec.rb +36 -0
  306. data/spec/unit/provider/package/pip_spec.rb +6 -11
  307. data/spec/unit/provider/package/pkgdmg_spec.rb +0 -4
  308. data/spec/unit/provider/package/puppet_gem_spec.rb +4 -1
  309. data/spec/unit/provider/package/puppetserver_gem_spec.rb +137 -0
  310. data/spec/unit/provider/package/yum_spec.rb +31 -0
  311. data/spec/unit/provider/package/zypper_spec.rb +14 -0
  312. data/spec/unit/provider/service/base_spec.rb +2 -4
  313. data/spec/unit/provider/service/bsd_spec.rb +5 -1
  314. data/spec/unit/provider/service/daemontools_spec.rb +1 -1
  315. data/spec/unit/provider/service/debian_spec.rb +3 -5
  316. data/spec/unit/provider/service/freebsd_spec.rb +1 -1
  317. data/spec/unit/provider/service/gentoo_spec.rb +4 -5
  318. data/spec/unit/provider/service/init_spec.rb +45 -5
  319. data/spec/unit/provider/service/launchd_spec.rb +5 -6
  320. data/spec/unit/provider/service/openrc_spec.rb +4 -5
  321. data/spec/unit/provider/service/openwrt_spec.rb +1 -1
  322. data/spec/unit/provider/service/redhat_spec.rb +1 -1
  323. data/spec/unit/provider/service/runit_spec.rb +2 -1
  324. data/spec/unit/provider/service/smf_spec.rb +1 -1
  325. data/spec/unit/provider/service/src_spec.rb +3 -5
  326. data/spec/unit/provider/service/systemd_spec.rb +3 -6
  327. data/spec/unit/provider/service/upstart_spec.rb +4 -5
  328. data/spec/unit/provider/service/windows_spec.rb +28 -0
  329. data/spec/unit/provider/user/aix_spec.rb +5 -0
  330. data/spec/unit/provider/user/hpux_spec.rb +1 -1
  331. data/spec/unit/provider/user/pw_spec.rb +2 -0
  332. data/spec/unit/provider/user/useradd_spec.rb +56 -3
  333. data/spec/unit/provider/user/windows_adsi_spec.rb +82 -0
  334. data/spec/unit/provider_spec.rb +8 -10
  335. data/spec/unit/puppet_pal_2pec.rb +40 -0
  336. data/spec/unit/puppet_pal_catalog_spec.rb +45 -0
  337. data/spec/unit/reports/store_spec.rb +17 -13
  338. data/spec/unit/resource/capability_finder_spec.rb +6 -1
  339. data/spec/unit/resource/type_spec.rb +1 -1
  340. data/spec/unit/resource_spec.rb +11 -10
  341. data/spec/unit/rest/route_spec.rb +4 -4
  342. data/spec/unit/settings_spec.rb +576 -239
  343. data/spec/unit/ssl/base_spec.rb +0 -1
  344. data/spec/unit/ssl/host_spec.rb +0 -5
  345. data/spec/unit/ssl/ssl_provider_spec.rb +14 -8
  346. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -7
  347. data/spec/unit/transaction/event_manager_spec.rb +14 -11
  348. data/spec/unit/transaction/persistence_spec.rb +15 -0
  349. data/spec/unit/transaction/report_spec.rb +2 -0
  350. data/spec/unit/transaction_spec.rb +13 -4
  351. data/spec/unit/type/file/content_spec.rb +0 -1
  352. data/spec/unit/type/file/selinux_spec.rb +0 -2
  353. data/spec/unit/type/file/source_spec.rb +1 -1
  354. data/spec/unit/type/file_spec.rb +0 -6
  355. data/spec/unit/type/filebucket_spec.rb +1 -1
  356. data/spec/unit/type/group_spec.rb +13 -6
  357. data/spec/unit/type/resources_spec.rb +7 -7
  358. data/spec/unit/type/service_spec.rb +36 -3
  359. data/spec/unit/type/tidy_spec.rb +0 -1
  360. data/spec/unit/type/user_spec.rb +31 -2
  361. data/spec/unit/type_spec.rb +2 -2
  362. data/spec/unit/util/at_fork_spec.rb +2 -2
  363. data/spec/unit/util/autoload_spec.rb +5 -1
  364. data/spec/unit/util/backups_spec.rb +1 -2
  365. data/spec/unit/util/character_encoding_spec.rb +4 -4
  366. data/spec/unit/util/command_line_spec.rb +11 -6
  367. data/spec/unit/util/execution_spec.rb +15 -11
  368. data/spec/unit/util/inifile_spec.rb +6 -14
  369. data/spec/unit/util/log_spec.rb +8 -7
  370. data/spec/unit/util/logging_spec.rb +3 -3
  371. data/spec/unit/util/posix_spec.rb +363 -15
  372. data/spec/unit/util/rubygems_spec.rb +2 -2
  373. data/spec/unit/util/run_mode_spec.rb +6 -6
  374. data/spec/unit/util/selinux_spec.rb +76 -52
  375. data/spec/unit/util/storage_spec.rb +3 -1
  376. data/spec/unit/util/suidmanager_spec.rb +44 -41
  377. data/spec/unit/util_spec.rb +13 -6
  378. metadata +49 -50
  379. data/spec/integration/faces/config_spec.rb +0 -91
  380. data/spec/integration/faces/documentation_spec.rb +0 -57
  381. data/spec/integration/file_bucket/file_spec.rb +0 -50
  382. data/spec/integration/file_serving/content_spec.rb +0 -7
  383. data/spec/integration/file_serving/fileset_spec.rb +0 -12
  384. data/spec/integration/file_serving/metadata_spec.rb +0 -8
  385. data/spec/integration/file_serving/terminus_helper_spec.rb +0 -20
  386. data/spec/integration/file_system/uniquefile_spec.rb +0 -26
  387. data/spec/integration/module_tool/forge_spec.rb +0 -51
  388. data/spec/integration/module_tool/tar/mini_spec.rb +0 -28
  389. data/spec/integration/provider/service/init_spec.rb +0 -48
  390. data/spec/integration/provider/service/systemd_spec.rb +0 -25
  391. data/spec/integration/provider/service/windows_spec.rb +0 -50
  392. data/spec/integration/reference/providers_spec.rb +0 -21
  393. data/spec/integration/reports_spec.rb +0 -13
  394. data/spec/integration/ssl/certificate_request_spec.rb +0 -44
  395. data/spec/integration/ssl/host_spec.rb +0 -72
  396. data/spec/integration/ssl/key_spec.rb +0 -99
  397. data/spec/shared_behaviours/file_serving_model.rb +0 -51
  398. data/spec/unit/face/catalog_spec.rb +0 -6
  399. data/spec/unit/face/man_spec.rb +0 -25
  400. data/spec/unit/face/module_spec.rb +0 -3
  401. data/spec/unit/man_spec.rb +0 -31
@@ -10,6 +10,14 @@ require 'puppet/concurrent/synchronized'
10
10
  # @api private
11
11
  class Puppet::Util::ModuleDirectoriesAdapter < Puppet::Pops::Adaptable::Adapter
12
12
  attr_accessor :directories
13
+
14
+ def self.create_adapter(env)
15
+ adapter = super(env)
16
+ adapter.directories = env.modulepath.flat_map do |dir|
17
+ Dir.glob(File.join(dir, '*', 'lib'))
18
+ end
19
+ adapter
20
+ end
13
21
  end
14
22
 
15
23
  # Autoload paths, either based on names or all at once.
@@ -119,13 +127,7 @@ class Puppet::Util::Autoload
119
127
  def module_directories(env)
120
128
  raise ArgumentError, "Autoloader requires an environment" unless env
121
129
 
122
- Puppet::Util::ModuleDirectoriesAdapter.adapt(env) do |a|
123
- a.directories ||= env.modulepath.collect do |dir|
124
- Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f, "lib") }
125
- end.flatten.find_all do |d|
126
- FileTest.directory?(d)
127
- end
128
- end.directories
130
+ Puppet::Util::ModuleDirectoriesAdapter.adapt(env).directories
129
131
  end
130
132
 
131
133
  # @api private
@@ -164,14 +166,7 @@ class Puppet::Util::Autoload
164
166
  # Normalize a path. This converts ALT_SEPARATOR to SEPARATOR on Windows
165
167
  # and eliminates unnecessary parts of a path.
166
168
  def cleanpath(path)
167
- # There are two cases here because cleanpath does not handle absolute
168
- # paths correctly on windows (c:\ and c:/ are treated as distinct) but
169
- # we don't want to convert relative paths to absolute
170
- if Puppet::Util.absolute_path?(path)
171
- File.expand_path(path)
172
- else
173
- Pathname.new(path).cleanpath.to_s
174
- end
169
+ Pathname.new(path).cleanpath.to_s
175
170
  end
176
171
  end
177
172
 
@@ -19,8 +19,9 @@ module Puppet::Util::CharacterEncoding
19
19
  begin
20
20
  if original_encoding == Encoding::UTF_8
21
21
  if !string_copy.valid_encoding?
22
- Puppet.debug(_("%{value} is already labeled as UTF-8 but this encoding is invalid. It cannot be transcoded by Puppet.") %
23
- { value: string.dump })
22
+ Puppet.debug {
23
+ _("%{value} is already labeled as UTF-8 but this encoding is invalid. It cannot be transcoded by Puppet.") % { value: string.dump }
24
+ }
24
25
  end
25
26
  # String is already valid UTF-8 - noop
26
27
  return string_copy
@@ -40,8 +41,9 @@ module Puppet::Util::CharacterEncoding
40
41
  # Catch both our own self-determined failure to transcode as well as any
41
42
  # error on ruby's part, ie Encoding::UndefinedConversionError on a
42
43
  # failure to encode!.
43
- Puppet.debug(_("%{error}: %{value} cannot be transcoded by Puppet.") %
44
- { error: detail.inspect, value: string.dump })
44
+ Puppet.debug {
45
+ _("%{error}: %{value} cannot be transcoded by Puppet.") % { error: detail.inspect, value: string.dump }
46
+ }
45
47
  return string_copy
46
48
  end
47
49
  end
@@ -67,7 +69,9 @@ module Puppet::Util::CharacterEncoding
67
69
  if string_copy.force_encoding(Encoding::UTF_8).valid_encoding?
68
70
  return string_copy
69
71
  else
70
- Puppet.debug(_("%{value} is not valid UTF-8 and result of overriding encoding would be invalid.") % { value: string.dump })
72
+ Puppet.debug {
73
+ _("%{value} is not valid UTF-8 and result of overriding encoding would be invalid.") % { value: string.dump }
74
+ }
71
75
  # Set copy back to its original encoding before returning
72
76
  return string_copy.force_encoding(original_encoding)
73
77
  end
@@ -8,7 +8,7 @@ module Puppet::Util
8
8
  # The logic for server and port is kind of gross. In summary:
9
9
  # IF an endpoint-specific setting is requested AND that setting has been set by the user
10
10
  # Use that setting.
11
- # The defaults for these settings are the "normal" server/masterport settings, so
11
+ # The defaults for these settings are the "normal" server/serverport settings, so
12
12
  # when they are unset we instead want to "fall back" to the failover-selected
13
13
  # host/port pair.
14
14
  # ELSE IF we have a failover-selected host/port
@@ -17,7 +17,7 @@ module Puppet::Util
17
17
  # Use the first entry - failover hasn't happened yet, but that
18
18
  # setting is still authoritative
19
19
  # ELSE
20
- # Go for the legacy server/masterport settings, and hope for the best
20
+ # Go for the legacy server/serverport settings, and hope for the best
21
21
 
22
22
  # Determines which server to use based on the specified setting, taking into
23
23
  # account HA fallback from server_list.
@@ -55,7 +55,7 @@ module Puppet::Util
55
55
  # @param [Symbol] server_setting The server setting assoicated with this route.
56
56
  # @return [Integer] the port to use for use in the request
57
57
  def self.determine_port(port_setting, server_setting)
58
- if (port_setting && port_setting != :masterport && Puppet.settings.set_by_config?(port_setting)) ||
58
+ if (port_setting && port_setting != :serverport && Puppet.settings.set_by_config?(port_setting)) ||
59
59
  (server_setting && server_setting != :server && Puppet.settings.set_by_config?(server_setting))
60
60
  debug_once _("Selected port from the %{setting} setting: %{port}") % {setting: port_setting, port: Puppet.settings[port_setting].to_i}
61
61
  Puppet.settings[port_setting].to_i
@@ -65,18 +65,18 @@ module Puppet::Util
65
65
  if primary_server
66
66
  # Port might not be set, so we want to fallback in that
67
67
  # case. We know we don't need to use `setting` here, since
68
- # the default value of every port setting is `masterport`
68
+ # the default value of every port setting is `serverport`
69
69
  if primary_server[1]
70
70
  #TRANSLATORS 'server_list' is the name of a setting and should not be translated
71
71
  debug_once _("Dynamically-bound port lookup failed; using first entry from the `server_list` setting: %{port}") % {port: primary_server[1]}
72
72
  primary_server[1]
73
73
  else
74
- #TRANSLATORS 'masterport' is the name of a setting and should not be translated
75
- debug_once _("Dynamically-bound port lookup failed; falling back to `masterport` setting: %{port}") % {port: Puppet.settings[:masterport]}
76
- Puppet.settings[:masterport]
74
+ #TRANSLATORS 'serverport' is the name of a setting and should not be translated
75
+ debug_once _("Dynamically-bound port lookup failed; falling back to `serverport` setting: %{port}") % {port: Puppet.settings[:serverport]}
76
+ Puppet.settings[:serverport]
77
77
  end
78
78
  else
79
- port_setting ||= :masterport
79
+ port_setting ||= :serverport
80
80
  debug_once _("Dynamically-bound port lookup failed; falling back to %{setting} setting: %{port}") % {setting: port_setting, port: Puppet.settings[port_setting]}
81
81
  Puppet.settings[port_setting]
82
82
  end
@@ -68,7 +68,7 @@ module Puppet::Util::Execution
68
68
  if respond_to? :debug
69
69
  debug "Executing '#{command_str}'"
70
70
  else
71
- Puppet.debug "Executing '#{command_str}'"
71
+ Puppet.debug { "Executing '#{command_str}'" }
72
72
  end
73
73
 
74
74
  # force the run of the command with
@@ -186,7 +186,7 @@ module Puppet::Util::Execution
186
186
  if respond_to? :debug
187
187
  debug "Executing#{user_log_s}: '#{command_str}'"
188
188
  else
189
- Puppet.debug "Executing#{user_log_s}: '#{command_str}'"
189
+ Puppet.debug { "Executing#{user_log_s}: '#{command_str}'" }
190
190
  end
191
191
 
192
192
  null_file = Puppet::Util::Platform.windows? ? 'NUL' : '/dev/null'
@@ -0,0 +1,62 @@
1
+ require 'json'
2
+
3
+ class FactDif
4
+ def initialize(old_output, new_output, exclude_list = [])
5
+ @c_facter = JSON.parse(old_output)['values']
6
+ @next_facter = JSON.parse(new_output)['values']
7
+ @exclude_list = exclude_list
8
+ @diff = {}
9
+ end
10
+
11
+ def difs
12
+ search_hash(@c_facter, [])
13
+
14
+ @diff
15
+ end
16
+
17
+ private
18
+
19
+ def search_hash(sh, path = [])
20
+ if sh.is_a?(Hash)
21
+ sh.each do |k, v|
22
+ search_hash(v, path.push(k))
23
+ path.pop
24
+ end
25
+ elsif sh.is_a?(Array)
26
+ sh.each_with_index do |v, index|
27
+ search_hash(v, path.push(index))
28
+ path.pop
29
+ end
30
+ else
31
+ compare(path, sh)
32
+ end
33
+ end
34
+
35
+ def compare(fact_path, old_value)
36
+ new_value = @next_facter.dig(*fact_path)
37
+ if different?(new_value, old_value) && !excluded?(fact_path.join('.'))
38
+ @diff[fact_path.join('.')] = { new_value: new_value, old_value: old_value }
39
+ end
40
+ end
41
+
42
+ def different?(new, old)
43
+ if old.is_a?(String) && new.is_a?(String)
44
+ old_values = old.split(',')
45
+ new_values = new.split(',')
46
+
47
+ diff = old_values - new_values
48
+ # also add new entries only available in Facter 4
49
+ diff.concat(new_values - old_values)
50
+
51
+ return true if diff.any?
52
+
53
+ return false
54
+ end
55
+
56
+ old != new
57
+ end
58
+
59
+ def excluded?(fact_name)
60
+ @exclude_list.any? {|excluded_fact| fact_name =~ /#{excluded_fact}/}
61
+ end
62
+ end
@@ -12,11 +12,18 @@ module Puppet::Util::POSIX
12
12
  class << self
13
13
  # Returns an array of all the groups that the user's a member of.
14
14
  def groups_of(user)
15
- groups = []
16
- Puppet::Etc.group do |group|
17
- groups << group.name if group.mem.include?(user)
15
+ begin
16
+ require 'puppet/ffi/posix'
17
+ groups = get_groups_list(user)
18
+ rescue StandardError, LoadError => e
19
+ Puppet.debug("Falling back to Puppet::Etc.group: #{e.message}")
20
+
21
+ groups = []
22
+ Puppet::Etc.group do |group|
23
+ groups << group.name if group.mem.include?(user)
24
+ end
18
25
  end
19
-
26
+
20
27
  uniq_groups = groups.uniq
21
28
  if uniq_groups != groups
22
29
  Puppet.debug(_('Removing any duplicate group entries'))
@@ -24,6 +31,39 @@ module Puppet::Util::POSIX
24
31
 
25
32
  uniq_groups
26
33
  end
34
+
35
+ private
36
+ def get_groups_list(user)
37
+ raise LoadError, "The 'getgrouplist' method is not available" unless Puppet::FFI::POSIX::Functions.respond_to?(:getgrouplist)
38
+
39
+ user_gid = Puppet::Etc.getpwnam(user).gid
40
+ ngroups = Puppet::FFI::POSIX::Constants::MAXIMUM_NUMBER_OF_GROUPS
41
+
42
+ while true do # rubocop:disable Lint/LiteralInCondition
43
+ FFI::MemoryPointer.new(:int) do |ngroups_ptr|
44
+ FFI::MemoryPointer.new(:uint, ngroups) do |groups_ptr|
45
+ old_ngroups = ngroups
46
+ ngroups_ptr.write_int(ngroups)
47
+
48
+ if Puppet::FFI::POSIX::Functions::getgrouplist(user, user_gid, groups_ptr, ngroups_ptr) != -1
49
+ groups_gids = groups_ptr.get_array_of_uint(0, ngroups_ptr.read_int)
50
+
51
+ result = []
52
+ groups_gids.each do |group_gid|
53
+ group_info = Puppet::Etc.getgrgid(group_gid)
54
+ result |= [group_info.name] if group_info.mem.include?(user)
55
+ end
56
+ return result
57
+ end
58
+
59
+ ngroups = ngroups_ptr.read_int
60
+ if ngroups <= old_ngroups
61
+ ngroups *= 2
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
27
67
  end
28
68
 
29
69
  # Retrieve a field from a POSIX Etc object. The id can be either an integer
@@ -144,8 +184,17 @@ module Puppet::Util::POSIX
144
184
  name = get_posix_field(location, :name, id)
145
185
  check_value = name
146
186
  end
187
+
147
188
  if check_value != field
148
- return search_posix_field(location, id_field, field)
189
+ check_value_id = get_posix_field(location, id_field, check_value) if check_value
190
+
191
+ if id == check_value_id
192
+ Puppet.debug("Multiple entries found for resource: '#{location}' with #{id_field}: #{id}")
193
+ return id
194
+ else
195
+ Puppet.debug("The value retrieved: '#{check_value}' is different than the required state: '#{field}', searching in all entries")
196
+ return search_posix_field(location, id_field, field)
197
+ end
149
198
  else
150
199
  return id
151
200
  end
@@ -41,7 +41,11 @@ module Puppet::Util::RubyGems
41
41
  def directories
42
42
  # `require 'mygem'` will consider and potentially load
43
43
  # prerelease gems, so we need to match that behavior.
44
- Gem::Specification.latest_specs(true).collect do |spec|
44
+ #
45
+ # Just load the stub which points to the gem path, and
46
+ # delay loading the full specification until if/when the
47
+ # gem is required.
48
+ Gem::Specification.stubs.collect do |spec|
45
49
  File.join(spec.full_gem_path, 'lib')
46
50
  end
47
51
  end
@@ -18,8 +18,12 @@ module Puppet
18
18
  end
19
19
  end
20
20
 
21
+ def server?
22
+ name == :master || name == :server
23
+ end
24
+
21
25
  def master?
22
- name == :master
26
+ name == :master || name == :server
23
27
  end
24
28
 
25
29
  def agent?
@@ -26,6 +26,7 @@ module Puppet::Util::Windows
26
26
  require 'win32ole' ; WIN32OLE.codepage = WIN32OLE::CP_UTF8
27
27
  # gems
28
28
  require 'win32/process'
29
+ require 'puppet/util/windows/monkey_patches/dir'
29
30
  require 'win32/dir'
30
31
  require 'win32/service'
31
32
 
@@ -60,7 +60,7 @@ module Puppet::Util::Windows::APITypes
60
60
 
61
61
  str.encode(dst_encoding, str.encoding, encode_options)
62
62
  rescue EncodingError => e
63
- Puppet.debug "Unable to convert value #{str.nil? ? 'nil' : str.dump} to encoding #{dst_encoding} due to #{e.inspect}"
63
+ Puppet.debug { "Unable to convert value #{str.nil? ? 'nil' : str.dump} to encoding #{dst_encoding} due to #{e.inspect}" }
64
64
  raise
65
65
  end
66
66
 
@@ -196,6 +196,20 @@ module Puppet::Util::Windows::APITypes
196
196
  FFI.typedef :uchar, :byte
197
197
  FFI.typedef :uint16, :wchar
198
198
 
199
+ # Definitions for data types used in LSA structures and functions
200
+ # https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/
201
+ # https://docs.microsoft.com/sr-latn-rs/windows/win32/secmgmt/management-data-types
202
+ FFI.typedef :pointer, :pwstr
203
+ FFI.typedef :pointer, :pulong
204
+ FFI.typedef :pointer, :lsa_handle
205
+ FFI.typedef :pointer, :plsa_handle
206
+ FFI.typedef :pointer, :psid
207
+ FFI.typedef :pointer, :pvoid
208
+ FFI.typedef :pointer, :plsa_unicode_string
209
+ FFI.typedef :pointer, :plsa_object_attributes
210
+ FFI.typedef :uint32, :ntstatus
211
+ FFI.typedef :dword, :access_mask
212
+
199
213
  module ::FFI::WIN32
200
214
  extend ::FFI::Library
201
215
 
@@ -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
@@ -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
@@ -191,7 +191,7 @@ module Puppet::Util::Windows
191
191
  SERVICE_CONFIG_PRESHUTDOWN_INFO = 0x00000007
192
192
  SERVICE_CONFIG_TRIGGER_INFO = 0x00000008
193
193
  SERVICE_CONFIG_PREFERRED_NODE = 0x00000009
194
- SERVICE_CONFIG_LAUNCH_PROTECTED = 0x00000012
194
+ SERVICE_CONFIG_LAUNCH_PROTECTED = 0x0000000C
195
195
  SERVICE_NO_CHANGE = 0xffffffff
196
196
  SERVICE_CONFIG_TYPES = {
197
197
  SERVICE_CONFIG_DESCRIPTION => :SERVICE_CONFIG_DESCRIPTION,
@@ -145,6 +145,125 @@ module Puppet::Util::Windows::User
145
145
  end
146
146
  module_function :load_profile
147
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
+
148
267
  ffi_convention :stdcall
149
268
 
150
269
  # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx
@@ -329,4 +448,104 @@ module Puppet::Util::Windows::User
329
448
  ffi_lib :advapi32
330
449
  attach_function_private :IsValidSid,
331
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
332
551
  end