puppet 3.3.2 → 3.4.0.rc1

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 (589) hide show
  1. data/CONTRIBUTING.md +22 -0
  2. data/Gemfile +11 -2
  3. data/README.md +13 -17
  4. data/README_DEVELOPER.md +1 -1
  5. data/Rakefile +1 -1
  6. data/examples/hiera/README.md +4 -4
  7. data/ext/debian/puppetmaster.init +1 -0
  8. data/ext/debian/rules +2 -5
  9. data/ext/nagios/check_puppet.rb +7 -7
  10. data/ext/osx/file_mapping.yaml +1 -1
  11. data/ext/osx/preflight.erb +34 -19
  12. data/ext/rack/{files/config.ru → config.ru} +0 -0
  13. data/ext/rack/{files/apache2.conf → example-passenger-vhost.conf} +6 -0
  14. data/ext/redhat/puppet.spec.erb +20 -2
  15. data/ext/systemd/{puppetagent.service → puppet.service} +0 -0
  16. data/lib/hiera_puppet.rb +2 -2
  17. data/lib/puppet/agent.rb +1 -6
  18. data/lib/puppet/application.rb +15 -2
  19. data/lib/puppet/application/agent.rb +2 -7
  20. data/lib/puppet/application/apply.rb +8 -13
  21. data/lib/puppet/application/cert.rb +47 -7
  22. data/lib/puppet/application/device.rb +1 -6
  23. data/lib/puppet/application/face_base.rb +1 -1
  24. data/lib/puppet/application/filebucket.rb +1 -1
  25. data/lib/puppet/application/inspect.rb +3 -12
  26. data/lib/puppet/application/master.rb +1 -6
  27. data/lib/puppet/application/queue.rb +1 -6
  28. data/lib/puppet/application/resource.rb +2 -6
  29. data/lib/puppet/coercion.rb +11 -0
  30. data/lib/puppet/configurer.rb +5 -3
  31. data/lib/puppet/configurer/downloader.rb +3 -1
  32. data/lib/puppet/configurer/plugin_handler.rb +10 -0
  33. data/lib/puppet/confine.rb +80 -0
  34. data/lib/puppet/{provider/confine → confine}/exists.rb +3 -3
  35. data/lib/puppet/{provider/confine → confine}/false.rb +2 -2
  36. data/lib/puppet/{provider/confine → confine}/feature.rb +2 -2
  37. data/lib/puppet/{provider/confine → confine}/true.rb +2 -2
  38. data/lib/puppet/{provider/confine → confine}/variable.rb +2 -2
  39. data/lib/puppet/{provider/confine_collection.rb → confine_collection.rb} +4 -4
  40. data/lib/puppet/{provider/confiner.rb → confiner.rb} +4 -4
  41. data/lib/puppet/daemon.rb +2 -6
  42. data/lib/puppet/data_binding.rb +2 -30
  43. data/lib/puppet/defaults.rb +283 -174
  44. data/lib/puppet/error.rb +1 -0
  45. data/lib/puppet/external/nagios.rb +0 -2
  46. data/lib/puppet/external/nagios/base.rb +4 -3
  47. data/lib/puppet/external/nagios/grammar.ry +173 -112
  48. data/lib/puppet/external/nagios/parser.rb +233 -184
  49. data/lib/puppet/face/file/store.rb +1 -1
  50. data/lib/puppet/face/module/generate.rb +5 -7
  51. data/lib/puppet/face/parser.rb +12 -2
  52. data/lib/puppet/face/plugin.rb +6 -0
  53. data/lib/puppet/feature/base.rb +16 -0
  54. data/lib/puppet/feature/external_facts.rb +5 -0
  55. data/lib/puppet/feature/libuser.rb +1 -1
  56. data/lib/puppet/feature/msgpack.rb +1 -0
  57. data/lib/puppet/feature/rails.rb +2 -2
  58. data/lib/puppet/file_bucket/dipper.rb +8 -6
  59. data/lib/puppet/file_bucket/file.rb +17 -1
  60. data/lib/puppet/file_serving/base.rb +21 -10
  61. data/lib/puppet/file_serving/configuration.rb +5 -7
  62. data/lib/puppet/file_serving/configuration/parser.rb +1 -1
  63. data/lib/puppet/file_serving/content.rb +1 -1
  64. data/lib/puppet/file_serving/fileset.rb +3 -3
  65. data/lib/puppet/file_serving/metadata.rb +22 -18
  66. data/lib/puppet/file_serving/mount/file.rb +1 -1
  67. data/lib/puppet/file_serving/mount/pluginfacts.rb +35 -0
  68. data/lib/puppet/file_system.rb +3 -0
  69. data/lib/puppet/file_system/file.rb +261 -0
  70. data/lib/puppet/file_system/file18.rb +5 -0
  71. data/lib/puppet/file_system/file19.rb +5 -0
  72. data/lib/puppet/file_system/file19windows.rb +113 -0
  73. data/lib/puppet/file_system/memory_file.rb +31 -0
  74. data/lib/puppet/file_system/tempfile.rb +20 -0
  75. data/lib/puppet/indirector/active_record.rb +1 -0
  76. data/lib/puppet/indirector/catalog/compiler.rb +28 -0
  77. data/lib/puppet/indirector/certificate_request/memory.rb +6 -0
  78. data/lib/puppet/indirector/data_binding/hiera.rb +46 -2
  79. data/lib/puppet/indirector/direct_file_server.rb +2 -2
  80. data/lib/puppet/indirector/facts/facter.rb +25 -0
  81. data/lib/puppet/indirector/file_bucket_file/file.rb +60 -74
  82. data/lib/puppet/indirector/indirection.rb +5 -1
  83. data/lib/puppet/indirector/json.rb +1 -1
  84. data/lib/puppet/indirector/key/ca.rb +4 -0
  85. data/lib/puppet/indirector/key/file.rb +7 -3
  86. data/lib/puppet/indirector/key/memory.rb +6 -0
  87. data/lib/puppet/indirector/node/write_only_yaml.rb +2 -2
  88. data/lib/puppet/indirector/request.rb +17 -11
  89. data/lib/puppet/indirector/resource/ral.rb +5 -0
  90. data/lib/puppet/indirector/resource/rest.rb +1 -0
  91. data/lib/puppet/indirector/resource/store_configs.rb +4 -0
  92. data/lib/puppet/indirector/rest.rb +2 -1
  93. data/lib/puppet/indirector/ssl_file.rb +7 -7
  94. data/lib/puppet/indirector/terminus.rb +4 -0
  95. data/lib/puppet/indirector/yaml.rb +3 -3
  96. data/lib/puppet/interface/documentation.rb +4 -11
  97. data/lib/puppet/module.rb +19 -6
  98. data/lib/puppet/module_tool/applications/builder.rb +1 -1
  99. data/lib/puppet/module_tool/applications/installer.rb +1 -1
  100. data/lib/puppet/module_tool/checksums.rb +1 -1
  101. data/lib/puppet/module_tool/dependency.rb +7 -3
  102. data/lib/puppet/module_tool/metadata.rb +6 -2
  103. data/lib/puppet/module_tool/tar.rb +2 -1
  104. data/lib/puppet/module_tool/tar/gnu.rb +6 -2
  105. data/lib/puppet/module_tool/tar/mini.rb +2 -0
  106. data/lib/puppet/module_tool/tar/solaris.rb +2 -5
  107. data/lib/puppet/network/authconfig.rb +0 -2
  108. data/lib/puppet/network/authentication.rb +1 -1
  109. data/lib/puppet/network/authstore.rb +6 -7
  110. data/lib/puppet/network/format.rb +2 -3
  111. data/lib/puppet/network/format_handler.rb +16 -11
  112. data/lib/puppet/network/format_support.rb +14 -0
  113. data/lib/puppet/network/formats.rb +26 -0
  114. data/lib/puppet/network/http/connection.rb +8 -41
  115. data/lib/puppet/network/http/handler.rb +28 -32
  116. data/lib/puppet/network/http/webrick.rb +15 -22
  117. data/lib/puppet/network/http_pool.rb +43 -9
  118. data/lib/puppet/network/rights.rb +0 -0
  119. data/lib/puppet/node.rb +24 -8
  120. data/lib/puppet/node/environment.rb +18 -20
  121. data/lib/puppet/node/facts.rb +23 -6
  122. data/lib/puppet/parameter.rb +15 -2
  123. data/lib/puppet/parameter/boolean.rb +5 -0
  124. data/lib/puppet/parameter/value_collection.rb +6 -4
  125. data/lib/puppet/parser/ast/resourceparam.rb +2 -1
  126. data/lib/puppet/parser/compiler.rb +25 -9
  127. data/lib/puppet/parser/files.rb +1 -1
  128. data/lib/puppet/parser/functions.rb +12 -21
  129. data/lib/puppet/parser/functions/collect.rb +6 -35
  130. data/lib/puppet/parser/functions/contain.rb +26 -0
  131. data/lib/puppet/parser/functions/create_resources.rb +5 -0
  132. data/lib/puppet/parser/functions/extlookup.rb +2 -2
  133. data/lib/puppet/parser/functions/file.rb +1 -1
  134. data/lib/puppet/parser/functions/{reject.rb → filter.rb} +13 -12
  135. data/lib/puppet/parser/functions/fqdn_rand.rb +13 -5
  136. data/lib/puppet/parser/functions/include.rb +18 -1
  137. data/lib/puppet/parser/functions/map.rb +44 -0
  138. data/lib/puppet/parser/functions/select.rb +6 -38
  139. data/lib/puppet/parser/lexer.rb +1 -1
  140. data/lib/puppet/parser/parser_support.rb +1 -1
  141. data/lib/puppet/parser/resource.rb +6 -45
  142. data/lib/puppet/parser/scope.rb +33 -2
  143. data/lib/puppet/parser/type_loader.rb +4 -60
  144. data/lib/puppet/pops/binder/bindings_loader.rb +1 -1
  145. data/lib/puppet/pops/binder/config/binder_config.rb +3 -3
  146. data/lib/puppet/pops/binder/hiera2/bindings_provider.rb +1 -1
  147. data/lib/puppet/pops/binder/scheme_handler/confdir_hiera_scheme.rb +1 -1
  148. data/lib/puppet/pops/binder/scheme_handler/module_hiera_scheme.rb +2 -2
  149. data/lib/puppet/pops/issues.rb +4 -0
  150. data/lib/puppet/pops/model/ast_transformer.rb +4 -1
  151. data/lib/puppet/pops/model/model_label_provider.rb +1 -1
  152. data/lib/puppet/pops/parser/egrammar.ra +5 -24
  153. data/lib/puppet/pops/parser/eparser.rb +859 -902
  154. data/lib/puppet/pops/parser/lexer.rb +48 -30
  155. data/lib/puppet/pops/parser/parser_support.rb +1 -1
  156. data/lib/puppet/pops/patterns.rb +4 -4
  157. data/lib/puppet/pops/utils.rb +1 -1
  158. data/lib/puppet/pops/validation/checker3_1.rb +25 -20
  159. data/lib/puppet/provider.rb +23 -6
  160. data/lib/puppet/provider/aixobject.rb +0 -0
  161. data/lib/puppet/provider/augeas/augeas.rb +21 -5
  162. data/lib/puppet/provider/confine.rb +5 -79
  163. data/lib/puppet/provider/cron/crontab.rb +0 -0
  164. data/lib/puppet/provider/exec.rb +9 -7
  165. data/lib/puppet/provider/exec/posix.rb +10 -1
  166. data/lib/puppet/provider/exec/windows.rb +1 -1
  167. data/lib/puppet/provider/file/posix.rb +1 -0
  168. data/lib/puppet/provider/file/windows.rb +16 -5
  169. data/lib/puppet/provider/group/aix.rb +0 -0
  170. data/lib/puppet/provider/group/windows_adsi.rb +33 -1
  171. data/lib/puppet/provider/macauthorization/macauthorization.rb +1 -1
  172. data/lib/puppet/provider/mailalias/aliases.rb +0 -0
  173. data/lib/puppet/provider/maillist/mailman.rb +0 -0
  174. data/lib/puppet/provider/mount/parsed.rb +0 -0
  175. data/lib/puppet/provider/nameservice/directoryservice.rb +3 -3
  176. data/lib/puppet/provider/package/appdmg.rb +1 -1
  177. data/lib/puppet/provider/package/apple.rb +1 -1
  178. data/lib/puppet/provider/package/apt.rb +1 -1
  179. data/lib/puppet/provider/package/aptitude.rb +0 -0
  180. data/lib/puppet/provider/package/blastwave.rb +1 -1
  181. data/lib/puppet/provider/package/dpkg.rb +1 -1
  182. data/lib/puppet/provider/package/fink.rb +1 -1
  183. data/lib/puppet/provider/package/freebsd.rb +0 -0
  184. data/lib/puppet/provider/package/gem.rb +0 -0
  185. data/lib/puppet/provider/package/macports.rb +0 -0
  186. data/lib/puppet/provider/package/msi.rb +4 -10
  187. data/lib/puppet/provider/package/nim.rb +8 -8
  188. data/lib/puppet/provider/package/openbsd.rb +1 -1
  189. data/lib/puppet/provider/package/opkg.rb +0 -0
  190. data/lib/puppet/provider/package/pacman.rb +2 -2
  191. data/lib/puppet/provider/package/pkgdmg.rb +1 -1
  192. data/lib/puppet/provider/package/pkgutil.rb +1 -1
  193. data/lib/puppet/provider/package/ports.rb +0 -0
  194. data/lib/puppet/provider/package/rpm.rb +39 -3
  195. data/lib/puppet/provider/package/sun.rb +3 -3
  196. data/lib/puppet/provider/package/sunfreeware.rb +0 -0
  197. data/lib/puppet/provider/package/windows.rb +12 -19
  198. data/lib/puppet/provider/package/windows/package.rb +1 -1
  199. data/lib/puppet/provider/package/yum.rb +2 -2
  200. data/lib/puppet/provider/parsedfile.rb +0 -0
  201. data/lib/puppet/provider/port/parsed.rb +0 -0
  202. data/lib/puppet/provider/service/base.rb +0 -0
  203. data/lib/puppet/provider/service/bsd.rb +3 -3
  204. data/lib/puppet/provider/service/daemontools.rb +8 -8
  205. data/lib/puppet/provider/service/debian.rb +0 -0
  206. data/lib/puppet/provider/service/freebsd.rb +3 -3
  207. data/lib/puppet/provider/service/init.rb +5 -4
  208. data/lib/puppet/provider/service/launchd.rb +35 -24
  209. data/lib/puppet/provider/service/openbsd.rb +23 -0
  210. data/lib/puppet/provider/service/redhat.rb +0 -0
  211. data/lib/puppet/provider/service/runit.rb +3 -3
  212. data/lib/puppet/provider/service/smf.rb +0 -0
  213. data/lib/puppet/provider/service/src.rb +0 -0
  214. data/lib/puppet/provider/service/systemd.rb +0 -0
  215. data/lib/puppet/provider/service/upstart.rb +3 -3
  216. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +2 -2
  217. data/lib/puppet/provider/sshkey/parsed.rb +0 -0
  218. data/lib/puppet/provider/user/aix.rb +0 -0
  219. data/lib/puppet/provider/user/directoryservice.rb +1 -1
  220. data/lib/puppet/provider/user/useradd.rb +1 -1
  221. data/lib/puppet/provider/zone/solaris.rb +1 -1
  222. data/lib/puppet/rails/benchmark.rb +1 -1
  223. data/lib/puppet/reference/configuration.rb +1 -2
  224. data/lib/puppet/reference/indirection.rb +12 -14
  225. data/lib/puppet/relationship.rb +7 -4
  226. data/lib/puppet/reports.rb +2 -2
  227. data/lib/puppet/reports/rrdgraph.rb +1 -1
  228. data/lib/puppet/reports/store.rb +3 -3
  229. data/lib/puppet/reports/tagmail.rb +2 -2
  230. data/lib/puppet/resource.rb +66 -8
  231. data/lib/puppet/resource/catalog.rb +18 -25
  232. data/lib/puppet/resource/status.rb +10 -4
  233. data/lib/puppet/run.rb +6 -2
  234. data/lib/puppet/settings.rb +39 -119
  235. data/lib/puppet/settings/base_setting.rb +8 -9
  236. data/lib/puppet/settings/directory_setting.rb +8 -0
  237. data/lib/puppet/settings/file_setting.rb +35 -1
  238. data/lib/puppet/settings/priority_setting.rb +42 -0
  239. data/lib/puppet/ssl.rb +4 -0
  240. data/lib/puppet/ssl/certificate.rb +18 -0
  241. data/lib/puppet/ssl/certificate_authority.rb +101 -72
  242. data/lib/puppet/ssl/certificate_authority/autosign_command.rb +44 -0
  243. data/lib/puppet/ssl/certificate_authority/interface.rb +21 -17
  244. data/lib/puppet/ssl/certificate_factory.rb +38 -12
  245. data/lib/puppet/ssl/certificate_request.rb +201 -47
  246. data/lib/puppet/ssl/certificate_request_attributes.rb +34 -0
  247. data/lib/puppet/ssl/certificate_revocation_list.rb +2 -2
  248. data/lib/puppet/ssl/host.rb +21 -10
  249. data/lib/puppet/ssl/inventory.rb +6 -10
  250. data/lib/puppet/ssl/key.rb +1 -1
  251. data/lib/puppet/ssl/oids.rb +78 -0
  252. data/lib/puppet/ssl/validator.rb +41 -97
  253. data/lib/puppet/ssl/validator/default_validator.rb +153 -0
  254. data/lib/puppet/ssl/validator/no_validator.rb +17 -0
  255. data/lib/puppet/status.rb +4 -0
  256. data/lib/puppet/test/test_helper.rb +5 -0
  257. data/lib/puppet/transaction.rb +13 -0
  258. data/lib/puppet/transaction/event.rb +8 -3
  259. data/lib/puppet/transaction/report.rb +6 -2
  260. data/lib/puppet/transaction/resource_harness.rb +173 -115
  261. data/lib/puppet/type.rb +30 -13
  262. data/lib/puppet/type/augeas.rb +12 -46
  263. data/lib/puppet/type/component.rb +1 -7
  264. data/lib/puppet/type/cron.rb +0 -0
  265. data/lib/puppet/type/exec.rb +13 -1
  266. data/lib/puppet/type/file.rb +19 -10
  267. data/lib/puppet/type/file/checksum.rb +0 -0
  268. data/lib/puppet/type/file/content.rb +3 -0
  269. data/lib/puppet/type/file/ensure.rb +33 -15
  270. data/lib/puppet/type/file/group.rb +0 -0
  271. data/lib/puppet/type/file/mode.rb +6 -2
  272. data/lib/puppet/type/file/owner.rb +0 -0
  273. data/lib/puppet/type/file/source.rb +65 -14
  274. data/lib/puppet/type/file/target.rb +6 -6
  275. data/lib/puppet/type/file/type.rb +0 -0
  276. data/lib/puppet/type/filebucket.rb +0 -0
  277. data/lib/puppet/type/group.rb +18 -0
  278. data/lib/puppet/type/host.rb +0 -0
  279. data/lib/puppet/type/k5login.rb +4 -4
  280. data/lib/puppet/type/mailalias.rb +0 -0
  281. data/lib/puppet/type/maillist.rb +0 -0
  282. data/lib/puppet/type/mount.rb +15 -1
  283. data/lib/puppet/type/package.rb +7 -1
  284. data/lib/puppet/type/port.rb +0 -0
  285. data/lib/puppet/type/schedule.rb +9 -4
  286. data/lib/puppet/type/service.rb +1 -1
  287. data/lib/puppet/type/sshkey.rb +0 -0
  288. data/lib/puppet/type/tidy.rb +1 -1
  289. data/lib/puppet/type/user.rb +3 -0
  290. data/lib/puppet/type/yumrepo.rb +8 -6
  291. data/lib/puppet/type/zpool.rb +0 -0
  292. data/lib/puppet/util.rb +4 -31
  293. data/lib/puppet/util/adsi.rb +73 -17
  294. data/lib/puppet/util/autoload.rb +3 -3
  295. data/lib/puppet/util/backups.rb +4 -4
  296. data/lib/puppet/util/cacher.rb +7 -13
  297. data/lib/puppet/util/checksums.rb +2 -2
  298. data/lib/puppet/util/classgen.rb +3 -1
  299. data/lib/puppet/util/colors.rb +1 -0
  300. data/lib/puppet/util/command_line.rb +5 -0
  301. data/lib/puppet/util/docs.rb +33 -27
  302. data/lib/puppet/util/execution.rb +42 -18
  303. data/lib/puppet/util/filetype.rb +3 -3
  304. data/lib/puppet/util/instance_loader.rb +2 -2
  305. data/lib/puppet/util/instrumentation.rb +23 -42
  306. data/lib/puppet/util/instrumentation/data.rb +11 -4
  307. data/lib/puppet/util/instrumentation/indirection_probe.rb +11 -4
  308. data/lib/puppet/util/instrumentation/instrumentable.rb +7 -14
  309. data/lib/puppet/util/instrumentation/listener.rb +15 -8
  310. data/lib/puppet/util/instrumentation/listeners/log.rb +4 -10
  311. data/lib/puppet/util/instrumentation/listeners/performance.rb +8 -14
  312. data/lib/puppet/util/limits.rb +12 -0
  313. data/lib/puppet/util/lockfile.rb +2 -2
  314. data/lib/puppet/util/log.rb +14 -6
  315. data/lib/puppet/util/log/destinations.rb +23 -1
  316. data/lib/puppet/util/metric.rb +9 -3
  317. data/lib/puppet/util/monkey_patches.rb +7 -2
  318. data/lib/puppet/util/network_device/config.rb +1 -1
  319. data/lib/puppet/util/plugins.rb +1 -1
  320. data/lib/puppet/util/posix.rb +0 -0
  321. data/lib/puppet/util/profiler.rb +7 -2
  322. data/lib/puppet/util/provider_features.rb +2 -2
  323. data/lib/puppet/util/rdoc.rb +28 -30
  324. data/lib/puppet/util/rdoc/code_objects.rb +75 -25
  325. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +1 -1
  326. data/lib/puppet/util/rdoc/parser.rb +12 -487
  327. data/lib/puppet/util/rdoc/parser/puppet_parser_core.rb +477 -0
  328. data/lib/puppet/util/rdoc/parser/puppet_parser_rdoc1.rb +19 -0
  329. data/lib/puppet/util/rdoc/parser/puppet_parser_rdoc2.rb +14 -0
  330. data/lib/puppet/util/reference.rb +1 -1
  331. data/lib/puppet/util/resource_template.rb +1 -1
  332. data/lib/puppet/util/selinux.rb +1 -1
  333. data/lib/puppet/util/storage.rb +2 -2
  334. data/lib/puppet/util/suidmanager.rb +1 -1
  335. data/lib/puppet/util/tag_set.rb +29 -0
  336. data/lib/puppet/util/tagging.rb +8 -24
  337. data/lib/puppet/util/watched_file.rb +1 -1
  338. data/lib/puppet/util/watcher.rb +1 -1
  339. data/lib/puppet/util/windows.rb +3 -0
  340. data/lib/puppet/util/windows/access_control_entry.rb +84 -0
  341. data/lib/puppet/util/windows/access_control_list.rb +106 -0
  342. data/lib/puppet/util/windows/file.rb +213 -0
  343. data/lib/puppet/util/windows/process.rb +199 -0
  344. data/lib/puppet/util/windows/root_certs.rb +52 -37
  345. data/lib/puppet/util/windows/security.rb +270 -245
  346. data/lib/puppet/util/windows/security_descriptor.rb +62 -0
  347. data/lib/puppet/util/windows/sid.rb +26 -4
  348. data/lib/puppet/version.rb +2 -2
  349. data/spec/fixtures/releases/jamtur01-apache/lib/puppet/provider/a2mod/debian.rb +1 -1
  350. data/spec/fixtures/unit/indirector/{hiera → data_binding/hiera}/global.yaml +0 -0
  351. data/spec/fixtures/unit/indirector/data_binding/hiera/invalid.yaml +1 -0
  352. data/spec/fixtures/unit/module/trailing-comma.json +24 -0
  353. data/spec/fixtures/unit/util/monkey_patches/x509.pem +32 -0
  354. data/spec/integration/application/apply_spec.rb +1 -1
  355. data/spec/integration/application/doc_spec.rb +1 -1
  356. data/spec/integration/configurer_spec.rb +4 -2
  357. data/spec/integration/data_binding.rb +100 -0
  358. data/spec/integration/indirector/catalog/compiler_spec.rb +16 -13
  359. data/spec/integration/indirector/direct_file_server_spec.rb +3 -5
  360. data/spec/integration/indirector/file_content/file_server_spec.rb +2 -2
  361. data/spec/integration/node/facts_spec.rb +1 -1
  362. data/spec/integration/node_spec.rb +1 -1
  363. data/spec/integration/parser/compiler_spec.rb +90 -0
  364. data/spec/integration/parser/parser_spec.rb +2 -2
  365. data/spec/integration/provider/cron/crontab_spec.rb +3 -5
  366. data/spec/integration/resource/catalog_spec.rb +1 -1
  367. data/spec/integration/ssl/autosign_spec.rb +90 -0
  368. data/spec/integration/ssl/certificate_authority_spec.rb +62 -69
  369. data/spec/integration/ssl/certificate_revocation_list_spec.rb +1 -1
  370. data/spec/integration/ssl/host_spec.rb +1 -1
  371. data/spec/integration/transaction_spec.rb +13 -13
  372. data/spec/integration/type/exec_spec.rb +2 -2
  373. data/spec/integration/type/file_spec.rb +287 -45
  374. data/spec/integration/type/tidy_spec.rb +3 -3
  375. data/spec/integration/util/rdoc/parser_spec.rb +236 -35
  376. data/spec/integration/util/settings_spec.rb +1 -1
  377. data/spec/integration/util/windows/process_spec.rb +22 -0
  378. data/spec/integration/util/windows/security_spec.rb +316 -106
  379. data/spec/lib/matchers/containment_matchers.rb +52 -0
  380. data/spec/lib/puppet_spec/compiler.rb +6 -0
  381. data/spec/lib/puppet_spec/files.rb +20 -21
  382. data/spec/shared_behaviours/documentation_on_faces.rb +3 -3
  383. data/spec/shared_behaviours/file_server_terminus.rb +2 -2
  384. data/spec/shared_contexts/platform.rb +1 -0
  385. data/spec/spec_helper.rb +13 -1
  386. data/spec/unit/agent_spec.rb +0 -12
  387. data/spec/unit/application/agent_spec.rb +4 -4
  388. data/spec/unit/application/apply_spec.rb +18 -2
  389. data/spec/unit/application/cert_spec.rb +8 -6
  390. data/spec/unit/application/device_spec.rb +1 -1
  391. data/spec/unit/application/filebucket_spec.rb +1 -1
  392. data/spec/unit/application/inspect_spec.rb +1 -1
  393. data/spec/unit/application_spec.rb +24 -0
  394. data/spec/unit/configurer/downloader_spec.rb +8 -7
  395. data/spec/unit/configurer/fact_handler_spec.rb +23 -0
  396. data/spec/unit/configurer/plugin_handler_spec.rb +7 -2
  397. data/spec/unit/configurer_spec.rb +15 -5
  398. data/spec/unit/{provider/confine → confine}/exists_spec.rb +12 -12
  399. data/spec/unit/{provider/confine → confine}/false_spec.rb +9 -9
  400. data/spec/unit/{provider/confine → confine}/feature_spec.rb +10 -10
  401. data/spec/unit/{provider/confine → confine}/true_spec.rb +7 -7
  402. data/spec/unit/{provider/confine → confine}/variable_spec.rb +16 -16
  403. data/spec/unit/{provider/confine_collection_spec.rb → confine_collection_spec.rb} +30 -30
  404. data/spec/unit/{provider/confine_spec.rb → confine_spec.rb} +11 -11
  405. data/spec/unit/{provider/confiner_spec.rb → confiner_spec.rb} +4 -4
  406. data/spec/unit/face/parser_spec.rb +54 -0
  407. data/spec/unit/file_bucket/dipper_spec.rb +2 -2
  408. data/spec/unit/file_serving/base_spec.rb +32 -9
  409. data/spec/unit/file_serving/configuration_spec.rb +7 -7
  410. data/spec/unit/file_serving/content_spec.rb +12 -7
  411. data/spec/unit/file_serving/fileset_spec.rb +57 -27
  412. data/spec/unit/file_serving/metadata_spec.rb +74 -12
  413. data/spec/unit/file_serving/mount/file_spec.rb +10 -10
  414. data/spec/unit/file_serving/mount/pluginfacts_spec.rb +73 -0
  415. data/spec/unit/file_system/file_spec.rb +486 -0
  416. data/spec/unit/file_system/tempfile_spec.rb +48 -0
  417. data/spec/unit/graph/relationship_graph_spec.rb +0 -6
  418. data/spec/unit/hiera_puppet_spec.rb +2 -2
  419. data/spec/unit/indirector/catalog/compiler_spec.rb +15 -19
  420. data/spec/unit/indirector/certificate_status/file_spec.rb +30 -40
  421. data/spec/unit/indirector/data_binding/hiera_spec.rb +95 -2
  422. data/spec/unit/indirector/direct_file_server_spec.rb +6 -6
  423. data/spec/unit/indirector/facts/facter_spec.rb +33 -0
  424. data/spec/unit/indirector/file_bucket_file/file_spec.rb +61 -52
  425. data/spec/unit/indirector/file_metadata/file_spec.rb +2 -2
  426. data/spec/unit/indirector/file_server_spec.rb +4 -4
  427. data/spec/unit/indirector/json_spec.rb +4 -4
  428. data/spec/unit/indirector/key/file_spec.rb +13 -14
  429. data/spec/unit/indirector/resource/ral_spec.rb +7 -0
  430. data/spec/unit/indirector/resource/store_configs_spec.rb +11 -0
  431. data/spec/unit/indirector/rest_spec.rb +7 -3
  432. data/spec/unit/indirector/ssl_file_spec.rb +14 -17
  433. data/spec/unit/indirector/yaml_spec.rb +4 -4
  434. data/spec/unit/module_spec.rb +43 -15
  435. data/spec/unit/module_tool/tar/gnu_spec.rb +2 -2
  436. data/spec/unit/module_tool/tar/solaris_spec.rb +2 -2
  437. data/spec/unit/module_tool/tar_spec.rb +45 -0
  438. data/spec/unit/network/authconfig_spec.rb +2 -1
  439. data/spec/unit/network/authentication_spec.rb +2 -2
  440. data/spec/unit/network/format_handler_spec.rb +2 -2
  441. data/spec/unit/network/formats_spec.rb +24 -0
  442. data/spec/unit/network/http/connection_spec.rb +76 -199
  443. data/spec/unit/network/http/handler_spec.rb +33 -34
  444. data/spec/unit/network/http_pool_spec.rb +8 -5
  445. data/spec/unit/node/environment_spec.rb +76 -90
  446. data/spec/unit/node/facts_spec.rb +20 -3
  447. data/spec/unit/node_spec.rb +43 -0
  448. data/spec/unit/parameter/boolean_spec.rb +22 -12
  449. data/spec/unit/parser/ast/resourceparam_spec.rb +51 -0
  450. data/spec/unit/parser/compiler_spec.rb +103 -35
  451. data/spec/unit/parser/eparser_adapter_spec.rb +12 -12
  452. data/spec/unit/parser/files_spec.rb +11 -11
  453. data/spec/unit/parser/functions/contain_spec.rb +185 -0
  454. data/spec/unit/parser/functions/create_resources_spec.rb +13 -5
  455. data/spec/unit/parser/functions/generate_spec.rb +1 -1
  456. data/spec/unit/parser/functions_spec.rb +2 -2
  457. data/spec/unit/parser/lexer_spec.rb +1 -1
  458. data/spec/unit/parser/methods/each_spec.rb +1 -1
  459. data/spec/unit/parser/methods/{select_spec.rb → filter_spec.rb} +11 -11
  460. data/spec/unit/parser/methods/map_spec.rb +95 -0
  461. data/spec/unit/parser/methods/reduce_spec.rb +12 -11
  462. data/spec/unit/parser/methods/shared.rb +5 -5
  463. data/spec/unit/parser/methods/slice_spec.rb +13 -13
  464. data/spec/unit/parser/parser_spec.rb +1 -1
  465. data/spec/unit/parser/resource/param_spec.rb +44 -0
  466. data/spec/unit/parser/resource_spec.rb +16 -15
  467. data/spec/unit/pops/model/ast_transformer_spec.rb +18 -4
  468. data/spec/unit/pops/parser/lexer_spec.rb +22 -5
  469. data/spec/unit/pops/parser/parse_calls_spec.rb +5 -5
  470. data/spec/unit/pops/transformer/transform_calls_spec.rb +6 -6
  471. data/spec/unit/pops/transformer/transform_containers_spec.rb +2 -2
  472. data/spec/unit/pops/validator/validator_spec.rb +31 -0
  473. data/spec/unit/provider/augeas/augeas_spec.rb +57 -2
  474. data/spec/unit/provider/exec/posix_spec.rb +8 -3
  475. data/spec/unit/provider/file/posix_spec.rb +2 -2
  476. data/spec/unit/provider/group/windows_adsi_spec.rb +70 -3
  477. data/spec/unit/provider/nameservice/directoryservice_spec.rb +3 -3
  478. data/spec/unit/provider/package/apt_spec.rb +1 -1
  479. data/spec/unit/provider/package/msi_spec.rb +15 -42
  480. data/spec/unit/provider/package/openbsd_spec.rb +3 -3
  481. data/spec/unit/provider/package/rpm_spec.rb +56 -13
  482. data/spec/unit/provider/package/windows_spec.rb +15 -19
  483. data/spec/unit/provider/service/base_spec.rb +1 -1
  484. data/spec/unit/provider/service/daemontools_spec.rb +18 -8
  485. data/spec/unit/provider/service/freebsd_spec.rb +3 -3
  486. data/spec/unit/provider/service/gentoo_spec.rb +5 -2
  487. data/spec/unit/provider/service/init_spec.rb +17 -17
  488. data/spec/unit/provider/service/launchd_spec.rb +76 -23
  489. data/spec/unit/provider/service/openbsd_spec.rb +125 -0
  490. data/spec/unit/provider/service/openwrt_spec.rb +1 -1
  491. data/spec/unit/provider/service/runit_spec.rb +12 -5
  492. data/spec/unit/provider/service/upstart_spec.rb +4 -4
  493. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +5 -5
  494. data/spec/unit/provider/user/directoryservice_spec.rb +4 -4
  495. data/spec/unit/provider/zone/solaris_spec.rb +1 -1
  496. data/spec/unit/provider_spec.rb +2 -2
  497. data/spec/unit/reports/http_spec.rb +19 -34
  498. data/spec/unit/reports/store_spec.rb +2 -2
  499. data/spec/unit/resource/catalog_spec.rb +81 -11
  500. data/spec/unit/resource/status_spec.rb +11 -1
  501. data/spec/unit/resource/type_spec.rb +30 -1
  502. data/spec/unit/resource_spec.rb +40 -4
  503. data/spec/unit/settings/file_setting_spec.rb +2 -2
  504. data/spec/unit/settings/path_setting_spec.rb +2 -2
  505. data/spec/unit/settings/priority_setting_spec.rb +66 -0
  506. data/spec/unit/settings_spec.rb +16 -31
  507. data/spec/unit/ssl/certificate_authority/autosign_command_spec.rb +30 -0
  508. data/spec/unit/ssl/certificate_authority_spec.rb +129 -134
  509. data/spec/unit/ssl/certificate_factory_spec.rb +18 -0
  510. data/spec/unit/ssl/certificate_request_attributes_spec.rb +61 -0
  511. data/spec/unit/ssl/certificate_request_spec.rb +103 -0
  512. data/spec/unit/ssl/certificate_spec.rb +31 -18
  513. data/spec/unit/ssl/host_spec.rb +34 -8
  514. data/spec/unit/ssl/inventory_spec.rb +27 -62
  515. data/spec/unit/ssl/key_spec.rb +4 -4
  516. data/spec/unit/ssl/oids_spec.rb +48 -0
  517. data/spec/unit/ssl/validator_spec.rb +49 -6
  518. data/spec/unit/status_spec.rb +9 -0
  519. data/spec/unit/transaction/event_spec.rb +1 -9
  520. data/spec/unit/transaction/report_spec.rb +20 -1
  521. data/spec/unit/transaction/resource_harness_spec.rb +60 -210
  522. data/spec/unit/transaction_spec.rb +54 -8
  523. data/spec/unit/type/component_spec.rb +2 -2
  524. data/spec/unit/type/exec_spec.rb +14 -7
  525. data/spec/unit/type/file/content_spec.rb +13 -2
  526. data/spec/unit/type/file/ctime_spec.rb +1 -1
  527. data/spec/unit/type/file/mode_spec.rb +48 -2
  528. data/spec/unit/type/file/mtime_spec.rb +1 -1
  529. data/spec/unit/type/file/source_spec.rb +177 -7
  530. data/spec/unit/type/file_spec.rb +63 -71
  531. data/spec/unit/type/group_spec.rb +20 -0
  532. data/spec/unit/type/k5login_spec.rb +3 -3
  533. data/spec/unit/type/mount_spec.rb +53 -0
  534. data/spec/unit/type/nagios_spec.rb +216 -0
  535. data/spec/unit/type/package_spec.rb +7 -1
  536. data/spec/unit/type/schedule_spec.rb +6 -0
  537. data/spec/unit/type/service_spec.rb +3 -3
  538. data/spec/unit/type/tidy_spec.rb +14 -14
  539. data/spec/unit/type/user_spec.rb +9 -0
  540. data/spec/unit/type_spec.rb +86 -4
  541. data/spec/unit/util/adsi_spec.rb +120 -12
  542. data/spec/unit/util/autoload_spec.rb +14 -14
  543. data/spec/unit/util/backups_spec.rb +29 -21
  544. data/spec/unit/util/checksums_spec.rb +2 -1
  545. data/spec/unit/util/command_line_spec.rb +41 -0
  546. data/spec/unit/util/docs_spec.rb +91 -0
  547. data/spec/unit/util/execution_spec.rb +26 -2
  548. data/spec/unit/util/filetype_spec.rb +7 -7
  549. data/spec/unit/util/lockfile_spec.rb +2 -2
  550. data/spec/unit/util/log/destinations_spec.rb +32 -0
  551. data/spec/unit/util/monkey_patches_spec.rb +41 -0
  552. data/spec/unit/util/pidlock_spec.rb +6 -6
  553. data/spec/unit/util/rdoc/parser_spec.rb +15 -13
  554. data/spec/unit/util/rdoc_spec.rb +18 -24
  555. data/spec/unit/util/resource_template_spec.rb +3 -3
  556. data/spec/unit/util/selinux_spec.rb +4 -2
  557. data/spec/unit/util/storage_spec.rb +4 -4
  558. data/spec/unit/util/suidmanager_spec.rb +7 -0
  559. data/spec/unit/util/tag_set_spec.rb +46 -0
  560. data/spec/unit/util/tagging_spec.rb +82 -45
  561. data/spec/unit/util/watcher_spec.rb +4 -1
  562. data/spec/unit/util/windows/access_control_entry_spec.rb +67 -0
  563. data/spec/unit/util/windows/access_control_list_spec.rb +133 -0
  564. data/spec/unit/util/windows/root_certs_spec.rb +10 -8
  565. data/spec/unit/util/windows/security_descriptor_spec.rb +117 -0
  566. data/spec/unit/util/windows/sid_spec.rb +69 -0
  567. data/spec/unit/util_spec.rb +7 -7
  568. data/tasks/ci.rake +17 -36
  569. metadata +2811 -2746
  570. checksums.yaml +0 -7
  571. data/examples/mac_automount.pp +0 -16
  572. data/examples/mcx_dock_absent.pp +0 -4
  573. data/examples/mcx_dock_default.pp +0 -118
  574. data/examples/mcx_dock_full.pp +0 -125
  575. data/examples/mcx_dock_invalid.pp +0 -9
  576. data/examples/mcx_nogroup.pp +0 -118
  577. data/examples/mcx_notexists_absent.pp +0 -4
  578. data/ext/rack/README +0 -58
  579. data/ext/rack/manifest.pp +0 -59
  580. data/lib/puppet/external/lock.rb +0 -63
  581. data/lib/puppet/indirector/hiera.rb +0 -39
  582. data/lib/puppet/parser/functions/foreach.rb +0 -95
  583. data/spec/integration/network/server/webrick_spec.rb +0 -76
  584. data/spec/integration/parser/functions_spec.rb +0 -16
  585. data/spec/unit/indirector/hiera_spec.rb +0 -154
  586. data/spec/unit/parser/methods/collect_spec.rb +0 -153
  587. data/spec/unit/parser/methods/foreach_spec.rb +0 -91
  588. data/spec/unit/parser/methods/reject_spec.rb +0 -73
  589. data/spec/unit/resource/resource_type.json +0 -34
@@ -8,6 +8,117 @@ module Puppet::Util::Windows::Process
8
8
  extend ::Windows::Handle
9
9
  extend ::Windows::Synchronize
10
10
 
11
+ module API
12
+ require 'ffi'
13
+ extend FFI::Library
14
+ ffi_convention :stdcall
15
+
16
+ ffi_lib 'kernel32'
17
+
18
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx
19
+ # HANDLE WINAPI GetCurrentProcess(void);
20
+ attach_function :get_current_process, :GetCurrentProcess, [], :uint
21
+
22
+ # BOOL WINAPI CloseHandle(
23
+ # _In_ HANDLE hObject
24
+ # );
25
+ attach_function :close_handle, :CloseHandle, [:uint], :bool
26
+
27
+ ffi_lib 'advapi32'
28
+
29
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx
30
+ # BOOL WINAPI OpenProcessToken(
31
+ # _In_ HANDLE ProcessHandle,
32
+ # _In_ DWORD DesiredAccess,
33
+ # _Out_ PHANDLE TokenHandle
34
+ # );
35
+ attach_function :open_process_token, :OpenProcessToken,
36
+ [:uint, :uint, :pointer], :bool
37
+
38
+
39
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa379261(v=vs.85).aspx
40
+ # typedef struct _LUID {
41
+ # DWORD LowPart;
42
+ # LONG HighPart;
43
+ # } LUID, *PLUID;
44
+ class LUID < FFI::Struct
45
+ layout :low_part, :uint,
46
+ :high_part, :int
47
+ end
48
+
49
+ # http://msdn.microsoft.com/en-us/library/Windows/desktop/aa379180(v=vs.85).aspx
50
+ # BOOL WINAPI LookupPrivilegeValue(
51
+ # _In_opt_ LPCTSTR lpSystemName,
52
+ # _In_ LPCTSTR lpName,
53
+ # _Out_ PLUID lpLuid
54
+ # );
55
+ attach_function :lookup_privilege_value, :LookupPrivilegeValueW,
56
+ [:buffer_in, :buffer_in, :pointer], :bool
57
+
58
+ Token_Information = enum(
59
+ :token_user, 1,
60
+ :token_groups,
61
+ :token_privileges,
62
+ :token_owner,
63
+ :token_primary_group,
64
+ :token_default_dacl,
65
+ :token_source,
66
+ :token_type,
67
+ :token_impersonation_level,
68
+ :token_statistics,
69
+ :token_restricted_sids,
70
+ :token_session_id,
71
+ :token_groups_and_privileges,
72
+ :token_session_reference,
73
+ :token_sandbox_inert,
74
+ :token_audit_policy,
75
+ :token_origin,
76
+ :token_elevation_type,
77
+ :token_linked_token,
78
+ :token_elevation,
79
+ :token_has_restrictions,
80
+ :token_access_information,
81
+ :token_virtualization_allowed,
82
+ :token_virtualization_enabled,
83
+ :token_integrity_level,
84
+ :token_ui_access,
85
+ :token_mandatory_policy,
86
+ :token_logon_sid,
87
+ :max_token_info_class
88
+ )
89
+
90
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa379263(v=vs.85).aspx
91
+ # typedef struct _LUID_AND_ATTRIBUTES {
92
+ # LUID Luid;
93
+ # DWORD Attributes;
94
+ # } LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
95
+ class LUID_And_Attributes < FFI::Struct
96
+ layout :luid, LUID,
97
+ :attributes, :uint
98
+ end
99
+
100
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa379630(v=vs.85).aspx
101
+ # typedef struct _TOKEN_PRIVILEGES {
102
+ # DWORD PrivilegeCount;
103
+ # LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
104
+ # } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
105
+ class Token_Privileges < FFI::Struct
106
+ layout :privilege_count, :uint,
107
+ :privileges, [LUID_And_Attributes, 1] # placeholder for offset
108
+ end
109
+
110
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx
111
+ # BOOL WINAPI GetTokenInformation(
112
+ # _In_ HANDLE TokenHandle,
113
+ # _In_ TOKEN_INFORMATION_CLASS TokenInformationClass,
114
+ # _Out_opt_ LPVOID TokenInformation,
115
+ # _In_ DWORD TokenInformationLength,
116
+ # _Out_ PDWORD ReturnLength
117
+ # );
118
+ attach_function :get_token_information, :GetTokenInformation,
119
+ [:uint, Token_Information, :pointer, :uint, :pointer ], :bool
120
+ end
121
+
11
122
  def execute(command, arguments, stdin, stdout, stderr)
12
123
  Process.create( :command_line => command, :startup_info => {:stdin => stdin, :stdout => stdout, :stderr => stderr}, :close_handles => false )
13
124
  end
@@ -33,4 +144,92 @@ module Puppet::Util::Windows::Process
33
144
  exit_status
34
145
  end
35
146
  module_function :wait_process
147
+
148
+ def get_current_process
149
+ # this pseudo-handle does not require closing per MSDN docs
150
+ API.get_current_process
151
+ end
152
+ module_function :get_current_process
153
+
154
+ def open_process_token(handle, desired_access)
155
+ token_handle_ptr = FFI::MemoryPointer.new(:uint, 1)
156
+ result = API.open_process_token(handle, desired_access, token_handle_ptr)
157
+ if !result
158
+ raise Puppet::Util::Windows::Error.new(
159
+ "OpenProcessToken(#{handle}, #{desired_access.to_s(8)}, #{token_handle_ptr})")
160
+ end
161
+
162
+ begin
163
+ yield token_handle = token_handle_ptr.read_uint
164
+ ensure
165
+ API.close_handle(token_handle)
166
+ end
167
+ end
168
+ module_function :open_process_token
169
+
170
+ def lookup_privilege_value(name, system_name = '')
171
+ luid = FFI::MemoryPointer.new(API::LUID.size)
172
+ result = API.lookup_privilege_value(WideString.new(system_name),
173
+ WideString.new(name.to_s), luid)
174
+
175
+ return API::LUID.new(luid) if result
176
+ raise Puppet::Util::Windows::Error.new(
177
+ "LookupPrivilegeValue(#{system_name}, #{name}, #{luid})")
178
+ end
179
+ module_function :lookup_privilege_value
180
+
181
+ def get_token_information(token_handle, token_information)
182
+ # to determine buffer size
183
+ return_length_ptr = FFI::MemoryPointer.new(:uint, 1)
184
+ result = API.get_token_information(token_handle, token_information, nil, 0, return_length_ptr)
185
+ return_length = return_length_ptr.read_uint
186
+
187
+ if return_length <= 0
188
+ raise Puppet::Util::Windows::Error.new(
189
+ "GetTokenInformation(#{token_handle}, #{token_information}, nil, 0, #{return_length_ptr})")
190
+ end
191
+
192
+ # re-call API with properly sized buffer for all results
193
+ token_information_buf = FFI::MemoryPointer.new(return_length)
194
+ result = API.get_token_information(token_handle, token_information,
195
+ token_information_buf, return_length, return_length_ptr)
196
+
197
+ if !result
198
+ raise Puppet::Util::Windows::Error.new(
199
+ "GetTokenInformation(#{token_handle}, #{token_information}, #{token_information_buf}, " +
200
+ "#{return_length}, #{return_length_ptr})")
201
+ end
202
+
203
+ raw_privileges = API::Token_Privileges.new(token_information_buf)
204
+ privileges = { :count => raw_privileges[:privilege_count], :privileges => [] }
205
+
206
+ offset = token_information_buf + API::Token_Privileges.offset_of(:privileges)
207
+ privilege_ptr = FFI::Pointer.new(API::LUID_And_Attributes, offset)
208
+
209
+ # extract each instance of LUID_And_Attributes
210
+ 0.upto(privileges[:count] - 1) do |i|
211
+ privileges[:privileges] << API::LUID_And_Attributes.new(privilege_ptr[i])
212
+ end
213
+
214
+ privileges
215
+ end
216
+ module_function :get_token_information
217
+
218
+ TOKEN_ALL_ACCESS = 0xF01FF
219
+ ERROR_NO_SUCH_PRIVILEGE = 1313
220
+ def process_privilege_symlink?
221
+ handle = get_current_process
222
+ open_process_token(handle, TOKEN_ALL_ACCESS) do |token_handle|
223
+ luid = lookup_privilege_value('SeCreateSymbolicLinkPrivilege')
224
+ token_info = get_token_information(token_handle, :token_privileges)
225
+ token_info[:privileges].any? { |p| p[:luid].values == luid.values }
226
+ end
227
+ rescue Puppet::Util::Windows::Error => e
228
+ if e.code == ERROR_NO_SUCH_PRIVILEGE
229
+ false # pre-Vista
230
+ else
231
+ raise e
232
+ end
233
+ end
234
+ module_function :process_privilege_symlink?
36
235
  end
@@ -1,17 +1,16 @@
1
1
  require 'puppet/util/windows'
2
2
  require 'openssl'
3
- require 'Win32API'
4
- require 'windows/msvcrt/buffer'
3
+ require 'ffi'
5
4
 
6
5
  # Represents a collection of trusted root certificates.
7
6
  #
8
7
  # @api public
9
8
  class Puppet::Util::Windows::RootCerts
10
9
  include Enumerable
10
+ extend FFI::Library
11
11
 
12
- CertOpenSystemStore = Win32API.new('crypt32', 'CertOpenSystemStore', ['L','P'], 'L')
13
- CertEnumCertificatesInStore = Win32API.new('crypt32', 'CertEnumCertificatesInStore', ['L', 'L'], 'L')
14
- CertCloseStore = Win32API.new('crypt32', 'CertCloseStore', ['L', 'L'], 'B')
12
+ typedef :ulong, :dword
13
+ typedef :uintptr_t, :handle
15
14
 
16
15
  def initialize(roots)
17
16
  @roots = roots
@@ -24,10 +23,6 @@ class Puppet::Util::Windows::RootCerts
24
23
  @roots.each {|cert| yield cert}
25
24
  end
26
25
 
27
- class << self
28
- include Windows::MSVCRT::Buffer
29
- end
30
-
31
26
  # Returns a new instance.
32
27
  # @return [Puppet::Util::Windows::RootCerts] object constructed from current root certificates
33
28
  def self.instance
@@ -43,34 +38,12 @@ class Puppet::Util::Windows::RootCerts
43
38
 
44
39
  # This is based on a patch submitted to openssl:
45
40
  # http://www.mail-archive.com/openssl-dev@openssl.org/msg26958.html
46
- context = 0
47
- store = CertOpenSystemStore.call(0, "ROOT")
41
+ ptr = FFI::Pointer::NULL
42
+ store = CertOpenSystemStoreA(nil, "ROOT")
48
43
  begin
49
- while (context = CertEnumCertificatesInStore.call(store, context) and context != 0)
50
- # 466 typedef struct _CERT_CONTEXT {
51
- # 467 DWORD dwCertEncodingType;
52
- # 468 BYTE *pbCertEncoded;
53
- # 469 DWORD cbCertEncoded;
54
- # 470 PCERT_INFO pCertInfo;
55
- # 471 HCERTSTORE hCertStore;
56
- # 472 } CERT_CONTEXT, *PCERT_CONTEXT;
57
-
58
- # buffer to hold struct above
59
- ctx_buf = 0.chr * 5 * 8
60
-
61
- # copy from win to ruby
62
- memcpy(ctx_buf, context, ctx_buf.size)
63
-
64
- # unpack structure
65
- arr = ctx_buf.unpack('LLLLL')
66
-
67
- # create buf of length cbCertEncoded
68
- cert_buf = 0.chr * arr[2]
69
-
70
- # copy pbCertEncoded from win to ruby
71
- memcpy(cert_buf, arr[1], cert_buf.length)
72
-
73
- # create a cert
44
+ while (ptr = CertEnumCertificatesInStore(store, ptr)) and not ptr.null?
45
+ context = CERT_CONTEXT.new(ptr)
46
+ cert_buf = context[:pbCertEncoded].read_bytes(context[:cbCertEncoded])
74
47
  begin
75
48
  certs << OpenSSL::X509::Certificate.new(cert_buf)
76
49
  rescue => detail
@@ -78,9 +51,51 @@ class Puppet::Util::Windows::RootCerts
78
51
  end
79
52
  end
80
53
  ensure
81
- CertCloseStore.call(store, 0)
54
+ CertCloseStore(store, 0)
82
55
  end
83
56
 
84
57
  certs
85
58
  end
59
+
60
+ private
61
+
62
+ # typedef ULONG_PTR HCRYPTPROV_LEGACY;
63
+ # typedef void *HCERTSTORE;
64
+
65
+ class CERT_CONTEXT < FFI::Struct
66
+ layout(
67
+ :dwCertEncodingType, :dword,
68
+ :pbCertEncoded, :pointer,
69
+ :cbCertEncoded, :dword,
70
+ :pCertInfo, :pointer,
71
+ :hCertStore, :handle
72
+ )
73
+ end
74
+
75
+ # HCERTSTORE
76
+ # WINAPI
77
+ # CertOpenSystemStoreA(
78
+ # __in_opt HCRYPTPROV_LEGACY hProv,
79
+ # __in LPCSTR szSubsystemProtocol
80
+ # );
81
+ ffi_lib :crypt32
82
+ attach_function :CertOpenSystemStoreA, [:pointer, :string], :handle
83
+
84
+ # PCCERT_CONTEXT
85
+ # WINAPI
86
+ # CertEnumCertificatesInStore(
87
+ # __in HCERTSTORE hCertStore,
88
+ # __in_opt PCCERT_CONTEXT pPrevCertContext
89
+ # );
90
+ ffi_lib :crypt32
91
+ attach_function :CertEnumCertificatesInStore, [:handle, :pointer], :pointer
92
+
93
+ # BOOL
94
+ # WINAPI
95
+ # CertCloseStore(
96
+ # __in_opt HCERTSTORE hCertStore,
97
+ # __in DWORD dwFlags
98
+ # );
99
+ ffi_lib :crypt32
100
+ attach_function :CertCloseStore, [:handle, :dword], :bool
86
101
  end
@@ -53,6 +53,8 @@
53
53
  # enables Puppet to detect when file/dirs are out-of-sync,
54
54
  # especially those that Puppet did not create, but is attempting
55
55
  # to manage.
56
+ # * A special case of this is S_ISYSTEM_MISSING, which is set when the
57
+ # SYSTEM permissions are *not* present on the DACL.
56
58
  # * On Unix, the owner and group can be modified without changing the
57
59
  # mode. But on Windows, an access control entry specifies which SID
58
60
  # it applies to. As a result, the set_owner and set_group methods
@@ -100,11 +102,13 @@ module Puppet::Util::Windows::Security
100
102
  S_IRWXO = 0000007
101
103
  S_ISVTX = 0001000
102
104
  S_IEXTRA = 02000000 # represents an extra ace
105
+ S_ISYSTEM_MISSING = 04000000
103
106
 
104
107
  # constants that are missing from Windows::Security
105
108
  PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
106
109
  UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
107
110
  NO_INHERITANCE = 0x0
111
+ SE_DACL_PROTECTED = 0x1000
108
112
 
109
113
  # Set the owner of the object referenced by +path+ to the specified
110
114
  # +owner_sid+. The owner sid should be of the form "S-1-5-32-544"
@@ -112,9 +116,12 @@ module Puppet::Util::Windows::Security
112
116
  # SE_RESTORE_NAME privilege in their process token can overwrite the
113
117
  # object's owner to something other than the current user.
114
118
  def set_owner(owner_sid, path)
115
- old_sid = get_owner(path)
119
+ sd = get_security_descriptor(path)
116
120
 
117
- change_sid(old_sid, owner_sid, OWNER_SECURITY_INFORMATION, path)
121
+ if owner_sid != sd.owner
122
+ sd.owner = owner_sid
123
+ set_security_descriptor(path, sd)
124
+ end
118
125
  end
119
126
 
120
127
  # Get the owner of the object referenced by +path+. The returned
@@ -125,7 +132,7 @@ module Puppet::Util::Windows::Security
125
132
  def get_owner(path)
126
133
  return unless supports_acl?(path)
127
134
 
128
- get_sid(OWNER_SECURITY_INFORMATION, path)
135
+ get_security_descriptor(path).owner
129
136
  end
130
137
 
131
138
  # Set the owner of the object referenced by +path+ to the specified
@@ -134,9 +141,12 @@ module Puppet::Util::Windows::Security
134
141
  # access to the object can change the group (regardless of whether
135
142
  # the current user belongs to that group or not).
136
143
  def set_group(group_sid, path)
137
- old_sid = get_group(path)
144
+ sd = get_security_descriptor(path)
138
145
 
139
- change_sid(old_sid, group_sid, GROUP_SECURITY_INFORMATION, path)
146
+ if group_sid != sd.group
147
+ sd.group = group_sid
148
+ set_security_descriptor(path, sd)
149
+ end
140
150
  end
141
151
 
142
152
  # Get the group of the object referenced by +path+. The returned
@@ -147,7 +157,7 @@ module Puppet::Util::Windows::Security
147
157
  def get_group(path)
148
158
  return unless supports_acl?(path)
149
159
 
150
- get_sid(GROUP_SECURITY_INFORMATION, path)
160
+ get_security_descriptor(path).group
151
161
  end
152
162
 
153
163
  def supports_acl?(path)
@@ -163,31 +173,6 @@ module Puppet::Util::Windows::Security
163
173
  (flags.unpack('L')[0] & Windows::File::FILE_PERSISTENT_ACLS) != 0
164
174
  end
165
175
 
166
- def change_sid(old_sid, new_sid, info, path)
167
- if old_sid != new_sid
168
- mode = get_mode(path)
169
-
170
- string_to_sid_ptr(new_sid) do |psid|
171
- with_privilege(SE_RESTORE_NAME) do
172
- open_file(path, WRITE_OWNER) do |handle|
173
- set_security_info(handle, info, psid)
174
- end
175
- end
176
- end
177
-
178
- # rebuild dacl now that sid has changed
179
- set_mode(mode, path)
180
- end
181
- end
182
-
183
- def get_sid(info, path)
184
- with_privilege(SE_BACKUP_NAME) do
185
- open_file(path, READ_CONTROL) do |handle|
186
- get_security_info(handle, info)
187
- end
188
- end
189
- end
190
-
191
176
  def get_attributes(path)
192
177
  attributes = GetFileAttributes(path)
193
178
 
@@ -222,6 +207,10 @@ module Puppet::Util::Windows::Security
222
207
  (FILE_GENERIC_EXECUTE & ~FILE_READ_ATTRIBUTES) => S_IXOTH
223
208
  }
224
209
 
210
+ def get_aces_for_path_by_sid(path, sid)
211
+ get_security_descriptor(path).dacl.select { |ace| ace.sid == sid }
212
+ end
213
+
225
214
  # Get the mode of the object referenced by +path+. The returned
226
215
  # integer value represents the POSIX-style read, write, and execute
227
216
  # modes for the user, group, and other classes, e.g. 0640. Any user
@@ -231,58 +220,61 @@ module Puppet::Util::Windows::Security
231
220
  def get_mode(path)
232
221
  return unless supports_acl?(path)
233
222
 
234
- owner_sid = get_owner(path)
235
- group_sid = get_group(path)
236
223
  well_known_world_sid = Win32::Security::SID::Everyone
237
224
  well_known_nobody_sid = Win32::Security::SID::Nobody
225
+ well_known_system_sid = Win32::Security::SID::LocalSystem
238
226
 
239
- with_privilege(SE_BACKUP_NAME) do
240
- open_file(path, READ_CONTROL) do |handle|
241
- mode = 0
242
-
243
- get_dacl(handle).each do |ace|
244
- case ace[:sid]
245
- when owner_sid
246
- MASK_TO_MODE.each_pair do |k,v|
247
- if (ace[:mask] & k) == k
248
- mode |= (v << 6)
249
- end
250
- end
251
- when group_sid
252
- MASK_TO_MODE.each_pair do |k,v|
253
- if (ace[:mask] & k) == k
254
- mode |= (v << 3)
255
- end
256
- end
257
- when well_known_world_sid
258
- MASK_TO_MODE.each_pair do |k,v|
259
- if (ace[:mask] & k) == k
260
- mode |= (v << 6) | (v << 3) | v
261
- end
262
- end
263
- if File.directory?(path) and (ace[:mask] & (FILE_WRITE_DATA | FILE_EXECUTE | FILE_DELETE_CHILD)) == (FILE_WRITE_DATA | FILE_EXECUTE)
264
- mode |= S_ISVTX;
265
- end
266
- when well_known_nobody_sid
267
- if (ace[:mask] & FILE_APPEND_DATA).nonzero?
268
- mode |= S_ISVTX
269
- end
270
- else
271
- #puts "Warning, unable to map SID into POSIX mode: #{ace[:sid]}"
272
- mode |= S_IEXTRA
273
- end
227
+ mode = S_ISYSTEM_MISSING
274
228
 
275
- # if owner and group the same, then user and group modes are the OR of both
276
- if owner_sid == group_sid
277
- mode |= ((mode & S_IRWXG) << 3) | ((mode & S_IRWXU) >> 3)
278
- #puts "owner: #{group_sid}, 0x#{ace[:mask].to_s(16)}, #{mode.to_s(8)}"
229
+ sd = get_security_descriptor(path)
230
+ sd.dacl.each do |ace|
231
+ next if ace.inherit_only?
232
+
233
+ case ace.sid
234
+ when sd.owner
235
+ MASK_TO_MODE.each_pair do |k,v|
236
+ if (ace.mask & k) == k
237
+ mode |= (v << 6)
238
+ end
239
+ end
240
+ when sd.group
241
+ MASK_TO_MODE.each_pair do |k,v|
242
+ if (ace.mask & k) == k
243
+ mode |= (v << 3)
244
+ end
245
+ end
246
+ when well_known_world_sid
247
+ MASK_TO_MODE.each_pair do |k,v|
248
+ if (ace.mask & k) == k
249
+ mode |= (v << 6) | (v << 3) | v
279
250
  end
280
251
  end
252
+ if File.directory?(path) && (ace.mask & (FILE_WRITE_DATA | FILE_EXECUTE | FILE_DELETE_CHILD)) == (FILE_WRITE_DATA | FILE_EXECUTE)
253
+ mode |= S_ISVTX;
254
+ end
255
+ when well_known_nobody_sid
256
+ if (ace.mask & FILE_APPEND_DATA).nonzero?
257
+ mode |= S_ISVTX
258
+ end
259
+ when well_known_system_sid
260
+ else
261
+ #puts "Warning, unable to map SID into POSIX mode: #{ace.sid}"
262
+ mode |= S_IEXTRA
263
+ end
281
264
 
282
- #puts "get_mode: #{mode.to_s(8)}"
283
- mode
265
+ if ace.sid == well_known_system_sid
266
+ mode &= ~S_ISYSTEM_MISSING
267
+ end
268
+
269
+ # if owner and group the same, then user and group modes are the OR of both
270
+ if sd.owner == sd.group
271
+ mode |= ((mode & S_IRWXG) << 3) | ((mode & S_IRWXU) >> 3)
272
+ #puts "owner: #{sd.group}, 0x#{ace.mask.to_s(16)}, #{mode.to_s(8)}"
284
273
  end
285
274
  end
275
+
276
+ #puts "get_mode: #{mode.to_s(8)}"
277
+ mode
286
278
  end
287
279
 
288
280
  MODE_TO_MASK = {
@@ -305,15 +297,16 @@ module Puppet::Util::Windows::Security
305
297
  # privileges in their process token can change the mode for objects
306
298
  # that they do not have read and write access to.
307
299
  def set_mode(mode, path, protected = true)
308
- owner_sid = get_owner(path)
309
- group_sid = get_group(path)
300
+ sd = get_security_descriptor(path)
310
301
  well_known_world_sid = Win32::Security::SID::Everyone
311
302
  well_known_nobody_sid = Win32::Security::SID::Nobody
303
+ well_known_system_sid = Win32::Security::SID::LocalSystem
312
304
 
313
305
  owner_allow = STANDARD_RIGHTS_ALL | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES
314
306
  group_allow = STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | SYNCHRONIZE
315
307
  other_allow = STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | SYNCHRONIZE
316
308
  nobody_allow = 0
309
+ system_allow = 0
317
310
 
318
311
  MODE_TO_MASK.each do |k,v|
319
312
  if ((mode >> 6) & k) == k
@@ -331,22 +324,29 @@ module Puppet::Util::Windows::Security
331
324
  nobody_allow |= FILE_APPEND_DATA;
332
325
  end
333
326
 
327
+ # caller is NOT managing SYSTEM by using group or owner, so set to FULL
328
+ if ! [sd.owner, sd.group].include? well_known_system_sid
329
+ # we don't check S_ISYSTEM_MISSING bit, but automatically carry over existing SYSTEM perms
330
+ # by default set SYSTEM perms to full
331
+ system_allow = FILE_ALL_ACCESS
332
+ end
333
+
334
334
  isdir = File.directory?(path)
335
335
 
336
336
  if isdir
337
337
  if (mode & (S_IWUSR | S_IXUSR)) == (S_IWUSR | S_IXUSR)
338
338
  owner_allow |= FILE_DELETE_CHILD
339
339
  end
340
- if (mode & (S_IWGRP | S_IXGRP)) == (S_IWGRP | S_IXGRP) and (mode & S_ISVTX) == 0
340
+ if (mode & (S_IWGRP | S_IXGRP)) == (S_IWGRP | S_IXGRP) && (mode & S_ISVTX) == 0
341
341
  group_allow |= FILE_DELETE_CHILD
342
342
  end
343
- if (mode & (S_IWOTH | S_IXOTH)) == (S_IWOTH | S_IXOTH) and (mode & S_ISVTX) == 0
343
+ if (mode & (S_IWOTH | S_IXOTH)) == (S_IWOTH | S_IXOTH) && (mode & S_ISVTX) == 0
344
344
  other_allow |= FILE_DELETE_CHILD
345
345
  end
346
346
  end
347
347
 
348
348
  # if owner and group the same, then map group permissions to the one owner ACE
349
- isownergroup = owner_sid == group_sid
349
+ isownergroup = sd.owner == sd.group
350
350
  if isownergroup
351
351
  owner_allow |= group_allow
352
352
  end
@@ -357,64 +357,37 @@ module Puppet::Util::Windows::Security
357
357
  remove_attributes(path, FILE_ATTRIBUTE_READONLY)
358
358
  end
359
359
 
360
- set_acl(path, protected) do |acl|
361
- #puts "ace: owner #{owner_sid}, mask 0x#{owner_allow.to_s(16)}"
362
- add_access_allowed_ace(acl, owner_allow, owner_sid)
363
-
364
- unless isownergroup
365
- #puts "ace: group #{group_sid}, mask 0x#{group_allow.to_s(16)}"
366
- add_access_allowed_ace(acl, group_allow, group_sid)
367
- end
368
-
369
- #puts "ace: other #{well_known_world_sid}, mask 0x#{other_allow.to_s(16)}"
370
- add_access_allowed_ace(acl, other_allow, well_known_world_sid)
360
+ dacl = Puppet::Util::Windows::AccessControlList.new
361
+ dacl.allow(sd.owner, owner_allow)
362
+ unless isownergroup
363
+ dacl.allow(sd.group, group_allow)
364
+ end
365
+ dacl.allow(well_known_world_sid, other_allow)
366
+ dacl.allow(well_known_nobody_sid, nobody_allow)
371
367
 
372
- #puts "ace: nobody #{well_known_nobody_sid}, mask 0x#{nobody_allow.to_s(16)}"
373
- add_access_allowed_ace(acl, nobody_allow, well_known_nobody_sid)
368
+ # TODO: system should be first?
369
+ dacl.allow(well_known_system_sid, system_allow)
374
370
 
375
- # add inherit-only aces for child dirs and files that are created within the dir
376
- if isdir
377
- inherit = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE
378
- add_access_allowed_ace(acl, owner_allow, Win32::Security::SID::CreatorOwner, inherit)
379
- add_access_allowed_ace(acl, group_allow, Win32::Security::SID::CreatorGroup, inherit)
371
+ # add inherit-only aces for child dirs and files that are created within the dir
372
+ if isdir
373
+ inherit = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE
374
+ dacl.allow(Win32::Security::SID::CreatorOwner, owner_allow, inherit)
375
+ dacl.allow(Win32::Security::SID::CreatorGroup, group_allow, inherit)
380
376
 
381
- inherit = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE
382
- add_access_allowed_ace(acl, owner_allow & ~FILE_EXECUTE, Win32::Security::SID::CreatorOwner, inherit)
383
- add_access_allowed_ace(acl, group_allow & ~FILE_EXECUTE, Win32::Security::SID::CreatorGroup, inherit)
384
- end
377
+ inherit = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE
378
+ dacl.allow(Win32::Security::SID::CreatorOwner, owner_allow & ~FILE_EXECUTE, inherit)
379
+ dacl.allow(Win32::Security::SID::CreatorGroup, group_allow & ~FILE_EXECUTE, inherit)
385
380
  end
386
381
 
382
+ new_sd = Puppet::Util::Windows::SecurityDescriptor.new(sd.owner, sd.group, dacl, protected)
383
+ set_security_descriptor(path, new_sd)
384
+
387
385
  nil
388
386
  end
389
387
 
390
- # setting DACL requires both READ_CONTROL and WRITE_DACL access rights,
391
- # and their respective privileges, SE_BACKUP_NAME and SE_RESTORE_NAME.
392
- def set_acl(path, protected = true)
393
- with_privilege(SE_BACKUP_NAME) do
394
- with_privilege(SE_RESTORE_NAME) do
395
- open_file(path, READ_CONTROL | WRITE_DAC) do |handle|
396
- acl = 0.chr * 1024 # This can be increased later as needed
397
-
398
- unless InitializeAcl(acl, acl.size, ACL_REVISION)
399
- raise Puppet::Util::Windows::Error.new("Failed to initialize ACL")
400
- end
401
-
402
- raise Puppet::Util::Windows::Error.new("Invalid DACL") unless IsValidAcl(acl)
403
-
404
- yield acl
405
-
406
- # protected means the object does not inherit aces from its parent
407
- info = DACL_SECURITY_INFORMATION
408
- info |= protected ? PROTECTED_DACL_SECURITY_INFORMATION : UNPROTECTED_DACL_SECURITY_INFORMATION
409
-
410
- # set the DACL
411
- set_security_info(handle, info, acl)
412
- end
413
- end
414
- end
415
- end
388
+ def add_access_allowed_ace(acl, mask, sid, inherit = nil)
389
+ inherit ||= NO_INHERITANCE
416
390
 
417
- def add_access_allowed_ace(acl, mask, sid, inherit = NO_INHERITANCE)
418
391
  string_to_sid_ptr(sid) do |sid_ptr|
419
392
  raise Puppet::Util::Windows::Error.new("Invalid SID") unless IsValidSid(sid_ptr)
420
393
 
@@ -434,126 +407,68 @@ module Puppet::Util::Windows::Security
434
407
  end
435
408
  end
436
409
 
437
- def get_dacl(handle)
438
- get_dacl_ptr(handle) do |dacl_ptr|
439
- # REMIND: need to handle NULL DACL
440
- raise Puppet::Util::Windows::Error.new("Invalid DACL") unless IsValidAcl(dacl_ptr)
441
-
442
- # ACL structure, size and count are the important parts. The
443
- # size includes both the ACL structure and all the ACEs.
410
+ def parse_dacl(dacl_ptr)
411
+ # REMIND: need to handle NULL DACL
412
+ raise Puppet::Util::Windows::Error.new("Invalid DACL") unless IsValidAcl(dacl_ptr)
413
+
414
+ # ACL structure, size and count are the important parts. The
415
+ # size includes both the ACL structure and all the ACEs.
416
+ #
417
+ # BYTE AclRevision
418
+ # BYTE Padding1
419
+ # WORD AclSize
420
+ # WORD AceCount
421
+ # WORD Padding2
422
+ acl_buf = 0.chr * 8
423
+ memcpy(acl_buf, dacl_ptr, acl_buf.size)
424
+ ace_count = acl_buf.unpack('CCSSS')[3]
425
+
426
+ dacl = Puppet::Util::Windows::AccessControlList.new
427
+
428
+ # deny all
429
+ return dacl if ace_count == 0
430
+
431
+ 0.upto(ace_count - 1) do |i|
432
+ ace_ptr = [0].pack('L')
433
+
434
+ next unless GetAce(dacl_ptr, i, ace_ptr)
435
+
436
+ # ACE structures vary depending on the type. All structures
437
+ # begin with an ACE header, which specifies the type, flags
438
+ # and size of what follows. We are only concerned with
439
+ # ACCESS_ALLOWED_ACE and ACCESS_DENIED_ACEs, which have the
440
+ # same structure:
444
441
  #
445
- # BYTE AclRevision
446
- # BYTE Padding1
447
- # WORD AclSize
448
- # WORD AceCount
449
- # WORD Padding2
450
- acl_buf = 0.chr * 8
451
- memcpy(acl_buf, dacl_ptr, acl_buf.size)
452
- ace_count = acl_buf.unpack('CCSSS')[3]
453
-
454
- dacl = []
455
-
456
- # deny all
457
- return dacl if ace_count == 0
458
-
459
- 0.upto(ace_count - 1) do |i|
460
- ace_ptr = [0].pack('L')
461
-
462
- next unless GetAce(dacl_ptr, i, ace_ptr)
463
-
464
- # ACE structures vary depending on the type. All structures
465
- # begin with an ACE header, which specifies the type, flags
466
- # and size of what follows. We are only concerned with
467
- # ACCESS_ALLOWED_ACE and ACCESS_DENIED_ACEs, which have the
468
- # same structure:
469
- #
470
- # BYTE C AceType
471
- # BYTE C AceFlags
472
- # WORD S AceSize
473
- # DWORD L ACCESS_MASK
474
- # DWORD L Sid
475
- # .. ...
476
- # DWORD L Sid
477
-
478
- ace_buf = 0.chr * 8
479
- memcpy(ace_buf, ace_ptr.unpack('L')[0], ace_buf.size)
480
-
481
- ace_type, ace_flags, size, mask = ace_buf.unpack('CCSL')
482
-
483
- # skip aces that only serve to propagate inheritance
484
- next if (ace_flags & INHERIT_ONLY_ACE).nonzero?
485
-
486
- case ace_type
487
- when ACCESS_ALLOWED_ACE_TYPE
488
- sid_ptr = ace_ptr.unpack('L')[0] + 8 # address of ace_ptr->SidStart
489
- raise Puppet::Util::Windows::Error.new("Failed to read DACL, invalid SID") unless IsValidSid(sid_ptr)
490
- sid = sid_ptr_to_string(sid_ptr)
491
- dacl << {:sid => sid, :type => ace_type, :mask => mask}
492
- else
493
- Puppet.warning "Unsupported access control entry type: 0x#{ace_type.to_s(16)}"
494
- end
442
+ # BYTE C AceType
443
+ # BYTE C AceFlags
444
+ # WORD S AceSize
445
+ # DWORD L ACCESS_MASK
446
+ # DWORD L Sid
447
+ # .. ...
448
+ # DWORD L Sid
449
+
450
+ ace_buf = 0.chr * 8
451
+ memcpy(ace_buf, ace_ptr.unpack('L')[0], ace_buf.size)
452
+
453
+ ace_type, ace_flags, size, mask = ace_buf.unpack('CCSL')
454
+
455
+ case ace_type
456
+ when ACCESS_ALLOWED_ACE_TYPE
457
+ sid_ptr = ace_ptr.unpack('L')[0] + 8 # address of ace_ptr->SidStart
458
+ raise Puppet::Util::Windows::Error.new("Failed to read DACL, invalid SID") unless IsValidSid(sid_ptr)
459
+ sid = sid_ptr_to_string(sid_ptr)
460
+ dacl.allow(sid, mask, ace_flags)
461
+ when ACCESS_DENIED_ACE_TYPE
462
+ sid_ptr = ace_ptr.unpack('L')[0] + 8 # address of ace_ptr->SidStart
463
+ raise Puppet::Util::Windows::Error.new("Failed to read DACL, invalid SID") unless IsValidSid(sid_ptr)
464
+ sid = sid_ptr_to_string(sid_ptr)
465
+ dacl.deny(sid, mask, ace_flags)
466
+ else
467
+ Puppet.warning "Unsupported access control entry type: 0x#{ace_type.to_s(16)}"
495
468
  end
496
-
497
- dacl
498
469
  end
499
- end
500
470
 
501
- def get_dacl_ptr(handle)
502
- dacl = [0].pack('L')
503
- sd = [0].pack('L')
504
-
505
- rv = GetSecurityInfo(
506
- handle,
507
- SE_FILE_OBJECT,
508
- DACL_SECURITY_INFORMATION,
509
- nil,
510
- nil,
511
- dacl, #dacl
512
- nil, #sacl
513
- sd) #sec desc
514
- raise Puppet::Util::Windows::Error.new("Failed to get DACL") unless rv == ERROR_SUCCESS
515
- begin
516
- yield dacl.unpack('L')[0]
517
- ensure
518
- LocalFree(sd.unpack('L')[0])
519
- end
520
- end
521
-
522
- # Set the security info on the specified handle.
523
- def set_security_info(handle, info, ptr)
524
- rv = SetSecurityInfo(
525
- handle,
526
- SE_FILE_OBJECT,
527
- info,
528
- (info & OWNER_SECURITY_INFORMATION) == OWNER_SECURITY_INFORMATION ? ptr : nil,
529
- (info & GROUP_SECURITY_INFORMATION) == GROUP_SECURITY_INFORMATION ? ptr : nil,
530
- (info & DACL_SECURITY_INFORMATION) == DACL_SECURITY_INFORMATION ? ptr : nil,
531
- nil)
532
- raise Puppet::Util::Windows::Error.new("Failed to set security information") unless rv == ERROR_SUCCESS
533
- end
534
-
535
- # Get the SID string, e.g. "S-1-5-32-544", for the specified handle
536
- # and type of information (owner, group).
537
- def get_security_info(handle, info)
538
- sid = [0].pack('L')
539
- sd = [0].pack('L')
540
-
541
- rv = GetSecurityInfo(
542
- handle,
543
- SE_FILE_OBJECT,
544
- info, # security info
545
- info == OWNER_SECURITY_INFORMATION ? sid : nil,
546
- info == GROUP_SECURITY_INFORMATION ? sid : nil,
547
- nil, #dacl
548
- nil, #sacl
549
- sd) #sec desc
550
- raise Puppet::Util::Windows::Error.new("Failed to get security information") unless rv == ERROR_SUCCESS
551
-
552
- begin
553
- return sid_ptr_to_string(sid.unpack('L')[0])
554
- ensure
555
- LocalFree(sd.unpack('L')[0])
556
- end
471
+ dacl
557
472
  end
558
473
 
559
474
  # Open an existing file with the specified access mode, and execute a
@@ -565,7 +480,7 @@ module Puppet::Util::Windows::Security
565
480
  FILE_SHARE_READ | FILE_SHARE_WRITE,
566
481
  0, # security_attributes
567
482
  OPEN_EXISTING,
568
- FILE_FLAG_BACKUP_SEMANTICS,
483
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
569
484
  0) # template
570
485
  raise Puppet::Util::Windows::Error.new("Failed to open '#{path}'") if handle == INVALID_HANDLE_VALUE
571
486
  begin
@@ -620,4 +535,114 @@ module Puppet::Util::Windows::Security
620
535
  CloseHandle(token)
621
536
  end
622
537
  end
538
+
539
+ def get_security_descriptor(path)
540
+ sd = nil
541
+
542
+ with_privilege(SE_BACKUP_NAME) do
543
+ open_file(path, READ_CONTROL) do |handle|
544
+ owner_sid = [0].pack('L')
545
+ group_sid = [0].pack('L')
546
+ dacl = [0].pack('L')
547
+ ppsd = [0].pack('L')
548
+
549
+ rv = GetSecurityInfo(
550
+ handle,
551
+ SE_FILE_OBJECT,
552
+ OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
553
+ owner_sid,
554
+ group_sid,
555
+ dacl,
556
+ nil, #sacl
557
+ ppsd) #sec desc
558
+ raise Puppet::Util::Windows::Error.new("Failed to get security information") unless rv == ERROR_SUCCESS
559
+
560
+ begin
561
+ owner = sid_ptr_to_string(owner_sid.unpack('L')[0])
562
+ group = sid_ptr_to_string(group_sid.unpack('L')[0])
563
+
564
+ control = FFI::MemoryPointer.new(:uint16, 1)
565
+ revision = FFI::MemoryPointer.new(:uint32, 1)
566
+ ffsd = FFI::Pointer.new(ppsd.unpack('L')[0])
567
+
568
+ if ! API.get_security_descriptor_control(ffsd, control, revision)
569
+ raise Puppet::Util::Windows::Error.new("Failed to get security descriptor control")
570
+ end
571
+
572
+ protect = (control.read_uint16 & SE_DACL_PROTECTED) == SE_DACL_PROTECTED
573
+
574
+ dacl = parse_dacl(dacl.unpack('L')[0])
575
+ sd = Puppet::Util::Windows::SecurityDescriptor.new(owner, group, dacl, protect)
576
+ ensure
577
+ LocalFree(ppsd.unpack('L')[0])
578
+ end
579
+ end
580
+ end
581
+
582
+ sd
583
+ end
584
+
585
+ # setting DACL requires both READ_CONTROL and WRITE_DACL access rights,
586
+ # and their respective privileges, SE_BACKUP_NAME and SE_RESTORE_NAME.
587
+ def set_security_descriptor(path, sd)
588
+ # REMIND: FFI
589
+ acl = 0.chr * 1024 # This can be increased later as neede
590
+ unless InitializeAcl(acl, acl.size, ACL_REVISION)
591
+ raise Puppet::Util::Windows::Error.new("Failed to initialize ACL")
592
+ end
593
+
594
+ raise Puppet::Util::Windows::Error.new("Invalid DACL") unless IsValidAcl(acl)
595
+
596
+ with_privilege(SE_BACKUP_NAME) do
597
+ with_privilege(SE_RESTORE_NAME) do
598
+ open_file(path, READ_CONTROL | WRITE_DAC | WRITE_OWNER) do |handle|
599
+ string_to_sid_ptr(sd.owner) do |ownersid|
600
+ string_to_sid_ptr(sd.group) do |groupsid|
601
+ sd.dacl.each do |ace|
602
+ case ace.type
603
+ when ACCESS_ALLOWED_ACE_TYPE
604
+ #puts "ace: allow, sid #{sid_to_name(ace.sid)}, mask 0x#{ace.mask.to_s(16)}"
605
+ add_access_allowed_ace(acl, ace.mask, ace.sid, ace.flags)
606
+ when ACCESS_DENIED_ACE_TYPE
607
+ #puts "ace: deny, sid #{sid_to_name(ace.sid)}, mask 0x#{ace.mask.to_s(16)}"
608
+ add_access_denied_ace(acl, ace.mask, ace.sid)
609
+ else
610
+ raise "We should never get here"
611
+ # TODO: this should have been a warning in an earlier commit
612
+ end
613
+ end
614
+
615
+ # protected means the object does not inherit aces from its parent
616
+ flags = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
617
+ flags |= sd.protect ? PROTECTED_DACL_SECURITY_INFORMATION : UNPROTECTED_DACL_SECURITY_INFORMATION
618
+
619
+ rv = SetSecurityInfo(handle,
620
+ SE_FILE_OBJECT,
621
+ flags,
622
+ ownersid,
623
+ groupsid,
624
+ acl,
625
+ nil)
626
+ raise Puppet::Util::Windows::Error.new("Failed to set security information") unless rv == ERROR_SUCCESS
627
+ end
628
+ end
629
+ end
630
+ end
631
+ end
632
+ end
633
+
634
+ module API
635
+ extend FFI::Library
636
+ ffi_lib 'kernel32'
637
+ ffi_convention :stdcall
638
+
639
+ # typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
640
+ # BOOL WINAPI GetSecurityDescriptorControl(
641
+ # _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
642
+ # _Out_ PSECURITY_DESCRIPTOR_CONTROL pControl,
643
+ # _Out_ LPDWORD lpdwRevision
644
+ # );
645
+ ffi_lib :advapi32
646
+ attach_function :get_security_descriptor_control, :GetSecurityDescriptorControl, [:pointer, :pointer, :pointer], :bool
647
+ end
623
648
  end