diff --git a/modules/services/unix/file_share/samba_config/Gemfile b/modules/services/unix/file_share/samba_config/Gemfile new file mode 100644 index 000000000..27d092ac2 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/Gemfile @@ -0,0 +1,26 @@ +source "https://rubygems.org" + +group :development do + gem "beaker", "> 2.0.0" + gem "beaker-rspec", ">= 5.1.0" + gem "pry" + gem "puppet-blacksmith" + gem "serverspec" + gem "vagrant-wrapper" + gem "metadata-json-lint" +end + +group :test do + gem "rake" + gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.7.0' + gem "puppet-lint", :github => 'rodjek/puppet-lint', + :ref => '2546fed6be894bbcff15c3f48d4b6f6bc15d94d1' + + # Pin for 1.8.7 compatibility for now + gem "rspec", '< 3.2.0' + gem "rspec-core", "3.1.7" + gem "rspec-puppet", "~> 2.1" + + gem "puppet-syntax" + gem "puppetlabs_spec_helper" +end diff --git a/modules/services/unix/file_share/samba_config/Gemfile.lock b/modules/services/unix/file_share/samba_config/Gemfile.lock new file mode 100644 index 000000000..1cd94b15f --- /dev/null +++ b/modules/services/unix/file_share/samba_config/Gemfile.lock @@ -0,0 +1,324 @@ +GIT + remote: git://github.com/rodjek/puppet-lint.git + revision: 2546fed6be894bbcff15c3f48d4b6f6bc15d94d1 + ref: 2546fed6be894bbcff15c3f48d4b6f6bc15d94d1 + specs: + puppet-lint (1.1.0) + +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (2.2.8) + activesupport (4.2.5) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.4.0) + autoparse (0.3.3) + addressable (>= 2.3.1) + extlib (>= 0.9.15) + multi_json (>= 1.0.0) + aws-sdk (1.66.0) + aws-sdk-v1 (= 1.66.0) + aws-sdk-v1 (1.66.0) + json (~> 1.4) + nokogiri (>= 1.4.4) + beaker (2.30.1) + aws-sdk (~> 1.57) + beaker-answers (~> 0.0) + beaker-hiera (~> 0.0) + docker-api + fission (~> 0.4) + fog (~> 1.25, < 1.35.0) + fog-google (~> 0.0.9) + google-api-client (~> 0.8) + hocon (~> 0.1) + inifile (~> 2.0) + json (~> 1.8) + mime-types (~> 2.99) + minitest (~> 5.4) + net-scp (~> 1.2) + net-ssh (~> 2.9) + open_uri_redirections (~> 0.2.1) + rbvmomi (~> 1.8) + rsync (~> 1.0.9) + stringify-hash (~> 0.0) + unf (~> 0.1) + beaker-answers (0.3.2) + require_all (~> 1.3.2) + stringify-hash (~> 0.0.0) + beaker-hiera (0.1.1) + stringify-hash (~> 0.0.0) + beaker-rspec (5.3.0) + beaker (~> 2.0) + rspec + serverspec (~> 2) + specinfra (~> 2) + builder (3.2.2) + coderay (1.1.0) + diff-lcs (1.2.5) + docker-api (1.24.1) + excon (>= 0.38.0) + json + domain_name (0.5.25) + unf (>= 0.0.5, < 1.0.0) + excon (0.45.4) + extlib (0.9.16) + facter (2.4.4) + CFPropertyList (~> 2.2.6) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + fission (0.5.0) + CFPropertyList (~> 2.2) + fog (1.34.0) + fog-atmos + fog-aws (>= 0.6.0) + fog-brightbox (~> 0.4) + fog-core (~> 1.32) + fog-dynect (~> 0.0.2) + fog-ecloud (~> 0.1) + fog-google (>= 0.0.2) + fog-json + fog-local + fog-powerdns (>= 0.1.1) + fog-profitbricks + fog-radosgw (>= 0.0.2) + fog-riakcs + fog-sakuracloud (>= 0.0.4) + fog-serverlove + fog-softlayer + fog-storm_on_demand + fog-terremark + fog-vmfusion + fog-voxel + fog-xml (~> 0.1.1) + ipaddress (~> 0.5) + nokogiri (~> 1.5, >= 1.5.11) + fog-atmos (0.1.0) + fog-core + fog-xml + fog-aws (0.7.6) + fog-core (~> 1.27) + fog-json (~> 1.0) + fog-xml (~> 0.1) + ipaddress (~> 0.8) + fog-brightbox (0.10.1) + fog-core (~> 1.22) + fog-json + inflecto (~> 0.0.2) + fog-core (1.35.0) + builder + excon (~> 0.45) + formatador (~> 0.2) + fog-dynect (0.0.2) + fog-core + fog-json + fog-xml + fog-ecloud (0.3.0) + fog-core + fog-xml + fog-google (0.0.9) + fog-core + fog-json + fog-xml + fog-json (1.0.2) + fog-core (~> 1.0) + multi_json (~> 1.10) + fog-local (0.2.1) + fog-core (~> 1.27) + fog-powerdns (0.1.1) + fog-core (~> 1.27) + fog-json (~> 1.0) + fog-xml (~> 0.1) + fog-profitbricks (0.0.5) + fog-core + fog-xml + nokogiri + fog-radosgw (0.0.4) + fog-core (>= 1.21.0) + fog-json + fog-xml (>= 0.0.1) + fog-riakcs (0.1.0) + fog-core + fog-json + fog-xml + fog-sakuracloud (1.4.0) + fog-core + fog-json + fog-serverlove (0.1.2) + fog-core + fog-json + fog-softlayer (1.0.2) + fog-core + fog-json + fog-storm_on_demand (0.1.1) + fog-core + fog-json + fog-terremark (0.1.0) + fog-core + fog-xml + fog-vmfusion (0.1.0) + fission + fog-core + fog-voxel (0.1.0) + fog-core + fog-xml + fog-xml (0.1.2) + fog-core + nokogiri (~> 1.5, >= 1.5.11) + formatador (0.2.5) + google-api-client (0.8.6) + activesupport (>= 3.2) + addressable (~> 2.3) + autoparse (~> 0.3) + extlib (~> 0.9) + faraday (~> 0.9) + googleauth (~> 0.3) + launchy (~> 2.4) + multi_json (~> 1.10) + retriable (~> 1.4) + signet (~> 0.6) + googleauth (0.4.2) + faraday (~> 0.9) + jwt (~> 1.4) + logging (~> 2.0) + memoist (~> 0.12) + multi_json (~> 1.11) + signet (~> 0.6) + hiera (1.3.4) + json_pure + hocon (0.9.3) + http-cookie (1.0.2) + domain_name (~> 0.5) + i18n (0.7.0) + inflecto (0.0.2) + inifile (2.0.2) + ipaddress (0.8.0) + json (1.8.3) + json_pure (1.8.3) + jwt (1.5.2) + launchy (2.4.3) + addressable (~> 2.3) + little-plugger (1.1.4) + logging (2.0.0) + little-plugger (~> 1.1) + multi_json (~> 1.10) + memoist (0.13.0) + metaclass (0.0.4) + metadata-json-lint (0.0.11) + json + spdx-licenses (~> 1.0) + method_source (0.8.2) + mime-types (2.99) + mini_portile2 (2.0.0) + minitest (5.8.3) + mocha (1.1.0) + metaclass (~> 0.0.1) + multi_json (1.11.2) + multipart-post (2.0.0) + net-scp (1.2.1) + net-ssh (>= 2.6.5) + net-ssh (2.9.2) + net-telnet (0.1.1) + netrc (0.11.0) + nokogiri (1.6.7) + mini_portile2 (~> 2.0.0.rc2) + open_uri_redirections (0.2.1) + pry (0.10.3) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + puppet (3.7.5) + facter (> 1.6, < 3) + hiera (~> 1.0) + json_pure + puppet-blacksmith (3.3.1) + puppet (>= 2.7.16) + rest-client + puppet-syntax (2.0.0) + rake + puppetlabs_spec_helper (1.0.1) + mocha + puppet-lint + puppet-syntax + rake + rspec-puppet + rake (10.4.2) + rbvmomi (1.8.2) + builder + nokogiri (>= 1.4.1) + trollop + require_all (1.3.3) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + retriable (1.4.1) + rspec (3.1.0) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) + rspec-core (3.1.7) + rspec-support (~> 3.1.0) + rspec-expectations (3.1.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.1.0) + rspec-its (1.2.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.1.3) + rspec-support (~> 3.1.0) + rspec-puppet (2.2.0) + rspec + rspec-support (3.1.2) + rsync (1.0.9) + serverspec (2.24.3) + multi_json + rspec (~> 3.0) + rspec-its + specinfra (~> 2.43) + sfl (2.2) + signet (0.7.0) + addressable (~> 2.3) + faraday (~> 0.9) + jwt (~> 1.5) + multi_json (~> 1.10) + slop (3.6.0) + spdx-licenses (1.0.0) + json + specinfra (2.44.6) + net-scp + net-ssh (~> 2.7) + net-telnet + sfl + stringify-hash (0.0.2) + thread_safe (0.3.5) + trollop (2.1.2) + tzinfo (1.2.2) + thread_safe (~> 0.1) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.1) + vagrant-wrapper (2.0.3) + +PLATFORMS + ruby + +DEPENDENCIES + beaker (> 2.0.0) + beaker-rspec (>= 5.1.0) + metadata-json-lint + pry + puppet (~> 3.7.0) + puppet-blacksmith + puppet-lint! + puppet-syntax + puppetlabs_spec_helper + rake + rspec (< 3.2.0) + rspec-core (= 3.1.7) + rspec-puppet (~> 2.1) + serverspec + vagrant-wrapper diff --git a/modules/services/unix/file_share/samba_config/README.md b/modules/services/unix/file_share/samba_config/README.md new file mode 100644 index 000000000..dd32bd025 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/README.md @@ -0,0 +1,100 @@ +# Puppet Samba Module + +[![Build Status](https://travis-ci.org/ajjahn/puppet-samba.png?branch=master)](https://travis-ci.org/ajjahn/puppet-samba) + +Module for provisioning Samba + +Supports: + +* Ubuntu: 14.04, 12.04 +* Debian: 8.x, 7.x +* CentOS: 7.x, 6.x + +Patches to support other operating systems are welcome. + +## Installation + +Clone this repo to your Puppet modules directory + + git clone git://github.com/ajjahn/puppet-samba.git samba + +or + + puppet module install ajjahn/samba + +## Usage + +Tweak and add the following to your site manifest: + +```puppet +node 'server.example.com' { + class {'samba::server': + workgroup => 'example', + server_string => "Example Samba Server", + interfaces => "eth0 lo", + security => 'share' + } + + samba::server::share {'example-share': + comment => 'Example Share', + path => '/path/to/share', + guest_only => true, + guest_ok => true, + guest_account => "guest", + browsable => false, + create_mask => 0777, + force_create_mask => 0777, + directory_mask => 0777, + force_directory_mask => 0777, + force_group => 'group', + force_user => 'user', + copy => 'some-other-share', + } +} +``` + +If you want join Samba server to Active Directory. + +```puppet +node 'server.example.com' { + class {'samba::server': + workgroup => 'example', + server_string => "Example Samba Server", + interfaces => "eth0 lo", + security => 'ads' + } + + samba::server::share {'ri-storage': + comment => 'RBTH User Storage', + path => "$smb_share", + browsable => true, + writable => true, + create_mask => 0770, + directory_mask => 0770, + } + + class { 'samba::server::ads': + winbind_acct => $::domain_admin, + winbind_pass => $::admin_password, + realm => 'EXAMPLE.COM', + nsswitch => true, + target_ou => "Nix_Mashine" + } +} +``` + +Most configuration options are optional. + +## Contributing + +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Added some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request + +## License + +This module is released under the MIT license: + +* [http://www.opensource.org/licenses/MIT](http://www.opensource.org/licenses/MIT) diff --git a/modules/services/unix/file_share/samba_config/Rakefile b/modules/services/unix/file_share/samba_config/Rakefile new file mode 100644 index 000000000..92f457865 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/Rakefile @@ -0,0 +1,42 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' +require 'puppet-syntax/tasks/puppet-syntax' + +# These two gems aren't always present, for instance +# on Travis with --without development +begin + require 'puppetlabs_spec_helper/rake_tasks' + require 'puppet_blacksmith/rake_tasks' +rescue LoadError +end + +PuppetLint.configuration.send("disable_80chars") +PuppetLint.configuration.log_format = "%{path}:%{linenumber}:%{check}:%{KIND}:%{message}" + +# Forsake support for Puppet 2.6.2 for the benefit of cleaner code. +# http://puppet-lint.com/checks/class_parameter_defaults/ +PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.send('disable_class_parameter_defaults') +# http://puppet-lint.com/checks/class_inherits_from_params_class/ +PuppetLint.configuration.send('disable_class_inherits_from_params_class') + +exclude_paths = [ + "pkg/**/*", + "vendor/**/*", + "spec/**/*", +] +PuppetLint.configuration.ignore_paths = exclude_paths +PuppetSyntax.exclude_paths = exclude_paths + +ENV['BEAKER_set'] ||= 'ubuntu-server-1204-x86' +desc "Run acceptance tests" +RSpec::Core::RakeTask.new(:acceptance) do |t| + t.pattern = 'spec/acceptance' +end + +desc "Run syntax, lint, and spec tests." +task :test => [ + :syntax, + :lint, + :spec, +] diff --git a/modules/services/unix/file_share/samba_config/checksums.json b/modules/services/unix/file_share/samba_config/checksums.json new file mode 100644 index 000000000..ff1a8f2c0 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/checksums.json @@ -0,0 +1,38 @@ +{ + "Gemfile": "24e286e0c20a6b501fd7aeefeee5c2ed", + "Gemfile.lock": "65ce69e91c358c870fc9915e04b64718", + "README.md": "d27873f4e6ae49e9d295f83dbc8bcc7a", + "Rakefile": "ef907142efcf48f027e52ebe1a739a78", + "manifests/init.pp": "6e339e466a4714bace31217b37509a4b", + "manifests/server/ads.pp": "8424cf034a94e64c85d07129a33d71a9", + "manifests/server/config.pp": "6715d85be4aaf0997dccd5d3f9ac1ac9", + "manifests/server/install.pp": "3eb28648dda5d8b447fb53de31bec48d", + "manifests/server/option.pp": "5d2848c1bfa77aa6788964eecee2cd96", + "manifests/server/params.pp": "7d874edffb0d791dc1c484a405976cc9", + "manifests/server/service.pp": "73daff793243fdadc5433c61914185e7", + "manifests/server/share.pp": "55f3c8b82cdc364997fcce512f3f0934", + "manifests/server/user.pp": "7af6eb21bcfa8f81123cdc3e074ed403", + "manifests/server/winbind.pp": "9165fe98d1c9909dcc41f33c6f4f3455", + "manifests/server.pp": "fb464fab43ac34cf2554d9aab137860d", + "metadata.json": "f3910fda45c98092712638d1765c2eaa", + "spec/acceptance/basic_samba_spec.rb": "04fc9b10d283b002f64bc2d44dcbe6f9", + "spec/acceptance/nodesets/centos-66-x64.yml": "b6b1db6cc673b2dcd7050989e86aaac4", + "spec/acceptance/nodesets/centos-70-x64.yml": "c8442353ba793497ba8ba008260f239b", + "spec/acceptance/nodesets/debian-78-x64.yml": "bafbd2b57400c80f6f578bd5d53310f6", + "spec/acceptance/nodesets/debian-81-x64.yml": "1b8d765a2283df227ac3cf8f01d02017", + "spec/acceptance/nodesets/ubuntu-server-1204-x86.yml": "b6d989e8a6775443d3c3417b68310882", + "spec/acceptance/nodesets/ubuntu-server-1404-x64.yml": "9dea6260b8201ed3b304fa1f7aa0c621", + "spec/classes/samba__server__config_spec.rb": "69d525834d26fdb3466e77a9a6d1b90f", + "spec/classes/samba__server__install_spec.rb": "ce2ba3ee0911ecef6a4735798e834166", + "spec/classes/samba__server__service_spec.rb": "bf177b7939d17e87fb08443a02e76b58", + "spec/classes/samba__server_spec.rb": "f872b86b87448a5492e9855e89fc619a", + "spec/coverage_spec.rb": "5b6dfa0dd426aca0ccfae23c0a629f0b", + "spec/fixtures/manifests/init.pp": "96b9decb3bce9b0d6a776f73863f15eb", + "spec/spec_helper.rb": "fb3a775abc9a2a090673974b42479eaa", + "spec/spec_helper_acceptance.rb": "50cb826088a22f477382049240a79b52", + "templates/add_samba_user": "c50e41b00bdb5a29eab621fc3d1724b3", + "templates/check_samba_user": "1da19611f645ce3ab2284d3d363eabec", + "templates/configure_active_directory.erb": "3809b0db079bea9417693502ed9770de", + "templates/verify_active_directory.erb": "c92ec531d90e986180ce24dfda70151d", + "tests/init.pp": "0c099e6c1692093e92fada1bc1a10556" +} \ No newline at end of file diff --git a/modules/services/unix/file_share/samba_config/manifests/init.pp b/modules/services/unix/file_share/samba_config/manifests/init.pp new file mode 100644 index 000000000..4fbac9a9b --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/init.pp @@ -0,0 +1,9 @@ +# == Class samba +# +class samba { + include samba::server + + if samba::server::security == 'ads' { + include samba::server::ads + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server.pp b/modules/services/unix/file_share/samba_config/manifests/server.pp new file mode 100644 index 000000000..550659c69 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server.pp @@ -0,0 +1,77 @@ +# == Class samba::server +# +class samba::server($interfaces = '', + $security = '', + $server_string = '', + $unix_password_sync = '', + $netbios_name = '', + $workgroup = '', + $socket_options = '', + $deadtime = '', + $keepalive = '', + $load_printers = '', + $printing = '', + $printcap_name = '', + $map_to_guest = '', + $disable_spoolss = '', + $kernel_oplocks = '', + $pam_password_change = '', + $os_level = '', + $preferred_master = '', + $bind_interfaces_only = 'yes',) { + + include samba::server::install + include samba::server::config + include samba::server::service + + $incl = '/etc/samba/smb.conf' + $context = '/files/etc/samba/smb.conf' + $target = 'target[. = "global"]' + + augeas { 'global-section': + incl => $incl, + lens => 'Samba.lns', + context => $context, + changes => "set ${target} global", + require => Class['samba::server::config'], + notify => Class['samba::server::service'] + } + + samba::server::option { + 'interfaces': value => $interfaces; + 'bind interfaces only': value => $bind_interfaces_only; + 'security': value => $security; + 'server string': value => $server_string; + 'unix password sync': value => $unix_password_sync; + 'netbios name': value => $netbios_name; + 'workgroup': value => $workgroup; + 'socket options': value => $socket_options; + 'deadtime': value => $deadtime; + 'keepalive': value => $keepalive; + 'load printers': value => $load_printers; + 'printing': value => $printing; + 'printcap name': value => $printcap_name; + 'map to guest': value => $map_to_guest; + 'disable spoolss': value => $disable_spoolss; + 'kernel oplocks': value => $kernel_oplocks; + 'pam password change': value => $pam_password_change; + 'os level': value => $os_level; + 'preferred master': value => $preferred_master; + } + + file {'/sbin/check_samba_user': + # script checks to see if a samba account exists for a given user + owner => root, + group => root, + mode => '0755', + content => template("${module_name}/check_samba_user"), + } + + file {'/sbin/add_samba_user': + # script creates a new samba account for a given user and password + owner => root, + group => root, + mode => '0755', + content => template("${module_name}/add_samba_user"), + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server/ads.pp b/modules/services/unix/file_share/samba_config/manifests/server/ads.pp new file mode 100644 index 000000000..757d09152 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server/ads.pp @@ -0,0 +1,131 @@ +# == Class samba::server::ads +# This module join samba server to Active Dirctory +# +class samba::server::ads($ensure = present, + $winbind_acct = 'admin', + $winbind_pass = 'SecretPass', + $realm = 'domain.com', + $winbind_uid = '10000-20000', + $winbind_gid = '10000-20000', + $winbind_enum_groups = 'yes', + $winbind_enum_users = 'yes', + $winbind_use_default_domain = 'yes', + $nsswitch = false, + $acl_group_control = 'yes', + $map_acl_inherit = 'yes', + $inherit_acls = 'yes', + $store_dos_attributes = 'yes', + $ea_support = 'yes', + $dos_filemode = 'yes', + $acl_check_permissions = false, + $map_system = 'no', + $map_archive = 'no', + $map_readonly = 'no', + $target_ou = 'Nix_Mashine') { + + $krb5_user_package = $::osfamily ? { + 'RedHat' => 'krb5-workstation', + default => 'krb5-user', + } + + if $::osfamily == 'RedHat' { + if $::operatingsystemrelease =~ /^6\./ { + $winbind_package = 'samba-winbind' + } else { + $winbind_package = 'samba-common' + } + } else { + $winbind_package = 'winbind' + } + + package{ + $krb5_user_package: ensure => installed; + $winbind_package: ensure => installed; + 'expect': ensure => installed; + } + + include samba::server::config + include samba::server::winbind + + # notify winbind + samba::server::option { + 'realm': value => $realm, + notify => Class['Samba::Server::Winbind']; + 'winbind uid': value => $winbind_uid, + notify => Class['Samba::Server::Winbind']; + 'winbind gid': value => $winbind_gid, + notify => Class['Samba::Server::Winbind']; + 'winbind enum groups': value => $winbind_enum_groups, + notify => Class['Samba::Server::Winbind']; + 'winbind enum users': value => $winbind_enum_users, + notify => Class['Samba::Server::Winbind']; + 'winbind use default domain': value => $winbind_use_default_domain, + notify => Class['Samba::Server::Winbind']; + } + + samba::server::option { + 'acl group control': value => $acl_group_control; + 'map acl inherit': value => $map_acl_inherit; + 'inherit acls': value => $inherit_acls; + 'store dos attributes': value => $store_dos_attributes; + 'ea support': value => $ea_support; + 'dos filemode': value => $dos_filemode; + 'acl check permissions': value => $acl_check_permissions; + 'map system': value => $map_system; + 'map archive': value => $map_archive; + 'map readonly': value => $map_readonly; + } + + $nss_file = 'etc/nsswitch.conf' + + $changes = $nsswitch ? { + true => [ + 'set database[. = "passwd"]/service[1] compat', + 'set database[. = "passwd"]/service[2] winbind', + 'set database[. = "group"]/service[1] compat', + 'set database[. = "group"]/service[2] winbind', + ], + false => [ + "rm /files/${nss_file}/database[. = 'passwd']/service[. = 'winbind']", + "rm /files/${nss_file}/database[. = 'group']/service[. = 'winbind']", + ] + } + + augeas { 'nsswitch': + context => "/files/${nss_file}", + changes => $changes + } + + file {'verify_active_directory': + # this script returns 0 if join is intact + path => '/sbin/verify_active_directory', + owner => root, + group => root, + mode => '0755', + content => template("${module_name}/verify_active_directory.erb"), + require => [ Package[$krb5_user_package, $winbind_package, 'expect'], + Augeas['samba-realm', 'samba-security', 'samba-winbind enum users', + 'samba-winbind enum groups', 'samba-winbind uid', 'samba-winbind gid', + 'samba-winbind use default domain'], Service['winbind'] ], + } + + file {'configure_active_directory': + # this script joins or leaves a domain + path => '/sbin/configure_active_directory', + owner => root, + group => root, + mode => '0755', + content => template("${module_name}/configure_active_directory.erb"), + require => [ Package[$krb5_user_package, $winbind_package, 'expect'], + Augeas['samba-realm', 'samba-security', 'samba-winbind enum users', + 'samba-winbind enum groups', 'samba-winbind uid', 'samba-winbind gid', + 'samba-winbind use default domain'], Service['winbind'] ], + } + + exec {'join-active-directory': + # join the domain configured in samba.conf + command => '/sbin/configure_active_directory -j', + unless => '/sbin/verify_active_directory', + require => [ File['configure_active_directory', 'verify_active_directory'], Service['winbind'] ], + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server/config.pp b/modules/services/unix/file_share/samba_config/manifests/server/config.pp new file mode 100644 index 000000000..eb9b78e0c --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server/config.pp @@ -0,0 +1,19 @@ +# == Class samba::server::config +# +class samba::server::config { + file { '/etc/samba': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + file { '/etc/samba/smb.conf': + ensure => present, + owner => 'root', + group => 'root', + mode => '0644', + require => [File['/etc/samba'], Class['samba::server::install']], + notify => Class['samba::server::service'] + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server/install.pp b/modules/services/unix/file_share/samba_config/manifests/server/install.pp new file mode 100644 index 000000000..ec98a4904 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server/install.pp @@ -0,0 +1,7 @@ +# == Class samba::server::install +# +class samba::server::install { + package { 'samba': + ensure => installed + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server/option.pp b/modules/services/unix/file_share/samba_config/manifests/server/option.pp new file mode 100644 index 000000000..bf491e8ad --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server/option.pp @@ -0,0 +1,21 @@ +# == Define samba::server::option +# +define samba::server::option ( $value = '' ) { + $incl = $samba::server::incl + $context = $samba::server::context + $target = $samba::server::target + + $changes = $value ? { + '' => "rm ${target}/${name}", + default => "set \"${target}/${name}\" \"${value}\"", + } + + augeas { "samba-${name}": + incl => $incl, + lens => 'Samba.lns', + context => $context, + changes => $changes, + require => Augeas['global-section'], + notify => Class['Samba::Server::Service'] + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server/params.pp b/modules/services/unix/file_share/samba_config/manifests/server/params.pp new file mode 100644 index 000000000..be9e01b64 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server/params.pp @@ -0,0 +1,38 @@ +# == Class samba::server::params +# +class samba::server::params { + case $::osfamily { + 'Redhat': { $service_name = 'smb' } + 'Debian': { + case $::operatingsystem { + 'Debian': { + case $::operatingsystemmajrelease { + '8' : { $service_name = 'smbd' } + default: { $service_name = 'samba' } + } + } + 'Ubuntu': { + $service_name = 'smbd' + $nmbd_name = 'nmbd' + } + default: { $service_name = 'samba' } + } + } + 'Gentoo': { $service_name = 'samba' } + 'Archlinux': { + $service_name = 'smbd' + $nmbd_name = 'nmbd' + } + + # Currently Gentoo has $::osfamily = "Linux". This should change in + # Factor 1.7.0 , so + # adding workaround. + 'Linux': { + case $::operatingsystem { + 'Gentoo': { $service_name = 'samba' } + default: { fail("${::operatingsystem} is not supported by this module.") } + } + } + default: { fail("${::osfamily} is not supported by this module.") } + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server/service.pp b/modules/services/unix/file_share/samba_config/manifests/server/service.pp new file mode 100644 index 000000000..68db2d6df --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server/service.pp @@ -0,0 +1,24 @@ +# == Class samba::server::server +# +class samba::server::service ( + $ensure = running, + $enable = true +) inherits samba::server::params { + + service { $samba::server::params::service_name : + ensure => $ensure, + hasstatus => true, + hasrestart => true, + enable => $enable, + require => Class['samba::server::config'] + } + + if $samba::server::params::nmbd_name != undef { + service { $samba::server::params::nmbd_name : + ensure => $ensure, + hasrestart => false, + enable => $enable, + require => Class['samba::server::config'], + } + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server/share.pp b/modules/services/unix/file_share/samba_config/manifests/server/share.pp new file mode 100644 index 000000000..c6820556c --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server/share.pp @@ -0,0 +1,196 @@ +# == Define samba::server::share +# +define samba::server::share($ensure = present, + $available = '', + $browsable = '', + $comment = '', + $copy = '', + $create_mask = '', + $directory_mask = '', + $force_create_mask = '', + $force_directory_mask = '', + $force_group = '', + $force_user = '', + $guest_account = '', + $guest_ok = '', + $guest_only = '', + $hide_unreadable = '', + $path = '', + $op_locks = '', + $level2_oplocks = '', + $veto_oplock_files = '', + $read_only = '', + $public = '', + $write_list = '', + $writable = '', + $printable = '', + $valid_users = '', + $follow_symlinks = '', + $wide_links = '', + $map_acl_inherit = '', + $store_dos_attributes = '', + $strict_allocate = '', + ) { + + $incl = $samba::server::incl + $context = $samba::server::context + $target = "target[. = '${name}']" + + $section_changes = $ensure ? { + present => "set ${target} '${name}'", + default => "rm ${target} '${name}'", + } + + augeas { "${name}-section": + incl => $incl, + lens => 'Samba.lns', + context => $context, + changes => $section_changes, + require => Class['samba::server::config'], + notify => Class['samba::server::service'] + } + + if $ensure == 'present' { + $changes = [ + $available ? { + true => "set \"${target}/available\" yes", + false => "set \"${target}/available\" no", + default => "rm \"${target}/available\"", + }, + $browsable ? { + true => "set \"${target}/browsable\" yes", + false => "set \"${target}/browsable\" no", + default => "rm \"${target}/browsable\"", + }, + $comment ? { + default => "set \"${target}/comment\" '${comment}'", + '' => "rm \"${target}/comment\"", + }, + $copy ? { + '' => "rm \"${target}/copy\"", + default => "set \"${target}/copy\" '${copy}'", + }, + $create_mask ? { + '' => "rm \"${target}/create mask\"", + default => "set \"${target}/create mask\" '${create_mask}'", + }, + $directory_mask ? { + '' => "rm \"${target}/directory mask\"", + default => "set \"${target}/directory mask\" '${directory_mask}'", + }, + $force_create_mask ? { + '' => "rm \"${target}/force create mask\"", + default => "set \"${target}/force create mask\" '${force_create_mask}'", + }, + $force_directory_mask ? { + '' => "rm \"${target}/force directory mask\"", + default => "set \"${target}/force directory mask\" '${force_directory_mask}'", + }, + $force_group ? { + '' => "rm \"${target}/force group\"", + default => "set \"${target}/force group\" '${force_group}'", + }, + $force_user ? { + '' => "rm \"${target}/force user\"", + default => "set \"${target}/force user\" '${force_user}'", + }, + $guest_account ? { + '' => "rm \"${target}/guest account\"", + default => "set \"${target}/guest account\" '${guest_account}'", + }, + $guest_ok ? { + true => "set \"${target}/guest ok\" yes", + false => "set \"${target}/guest ok\" no", + default => "rm \"${target}/guest ok\"", + }, + $guest_only ? { + true => "set \"${target}/guest only\" yes", + false => "set \"${target}/guest only\" no", + default => "rm \"${target}/guest only\"", + }, + $hide_unreadable ? { + true => "set \"${target}/hide unreadable\" yes", + false => "set \"${target}/hide unreadable\" no", + default => "rm \"${target}/hide unreadable\"", + }, + $path ? { + default => "set ${target}/path '${path}'", + '' => "rm ${target}/path", + }, + $read_only ? { + true => "set \"${target}/read only\" yes", + false => "set \"${target}/read only\" no", + default => "rm \"${target}/read only\"", + }, + $public ? { + true => "set \"${target}/public\" yes", + false => "set \"${target}/public\" no", + default => "rm \"${target}/public\"", + }, + $writable ? { + true => "set \"${target}/writable\" yes", + false => "set \"${target}/writable\" no", + default => "rm \"${target}/writable\"", + }, + $printable ? { + true => "set \"${target}/printable\" yes", + false => "set \"${target}/printable\" no", + default => "rm \"${target}/printable\"", + }, + $follow_symlinks ? { + true => "set \"${target}/follow symlinks\" yes", + false => "set \"${target}/follow symlinks\" no", + default => "rm \"${target}/follow symlinks\"", + }, + $wide_links ? { + true => "set \"${target}/wide links\" yes", + false => "set \"${target}/wide links\" no", + default => "rm \"${target}/wide links\"", + }, + $map_acl_inherit ? { + true => "set \"${target}/map acl inherit\" yes", + false => "set \"${target}/map acl inherit\" no", + default => "rm \"${target}/map acl inherit\"", + }, + $store_dos_attributes ? { + true => "set \"${target}/store dos attributes\" yes", + false => "set \"${target}/store dos attributes\" no", + default => "rm \"${target}/store dos attributes\"", + }, + $strict_allocate ? { + true => "set \"${target}/strict allocate\" yes", + false => "set \"${target}/strict allocate\" no", + default => "rm \"${target}/strict allocate\"", + }, + $valid_users ? { + '' => "rm \"${target}/valid users\"", + default => "set \"${target}/valid users\" '${valid_users}'", + }, + $op_locks ? { + '' => "rm \"${target}/oplocks\"", + default => "set \"${target}/oplocks\" '${op_locks}'", + }, + $level2_oplocks ? { + '' => "rm \"${target}/level2 oplocks\"", + default => "set \"${target}/level2 oplocks\" '${level2_oplocks}'", + }, + $veto_oplock_files ? { + '' => "rm \"${target}/veto oplock files\"", + default => "set \"${target}/veto oplock files\" '${veto_oplock_files}'", + }, + $write_list ? { + '' => "rm \"${target}/write list\"", + default => "set \"${target}/write list\" '${write_list}'", + }, + ] + + augeas { "${name}-changes": + incl => $incl, + lens => 'Samba.lns', + context => $context, + changes => $changes, + require => Augeas["${name}-section"], + notify => Class['samba::server::service'] + } + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server/user.pp b/modules/services/unix/file_share/samba_config/manifests/server/user.pp new file mode 100644 index 000000000..b8f2e61ef --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server/user.pp @@ -0,0 +1,13 @@ +# == Class samba::server::user +# +define samba::server::user ( + $password, + $user_name = $name, +) { + exec { "add smb account for ${user_name}": + command => "/sbin/add_samba_user '${user_name}' '${password}'" , + unless => "/sbin/check_samba_user '${user_name}'" , + require => [ User[$user_name] ], + notify => Class['samba::server::service'] + } +} diff --git a/modules/services/unix/file_share/samba_config/manifests/server/winbind.pp b/modules/services/unix/file_share/samba_config/manifests/server/winbind.pp new file mode 100644 index 000000000..a379bb73d --- /dev/null +++ b/modules/services/unix/file_share/samba_config/manifests/server/winbind.pp @@ -0,0 +1,13 @@ +# == Class samba::server::winbind +# +class samba::server::winbind ($ensure = running, $enable = true) { + $service_name = 'winbind' + + service { $service_name: + ensure => $ensure, + hasstatus => true, + hasrestart => true, + enable => $enable, + require => Class['samba::server::config'] + } +} diff --git a/modules/services/unix/file_share/samba_config/metadata.json b/modules/services/unix/file_share/samba_config/metadata.json new file mode 100644 index 000000000..bdb0dea7b --- /dev/null +++ b/modules/services/unix/file_share/samba_config/metadata.json @@ -0,0 +1,37 @@ +{ + "name": "ajjahn-samba", + "version": "0.4.0", + "author": "Adam Jahn", + "summary": "Module for provisioning Samba", + "license": "Apache-2.0", + "source": "https://github.com/ajjahn/puppet-samba", + "project_page": "https://github.com/ajjahn/puppet-samba", + "issues_url": "https://github.com/ajjahn/puppet-samba/issues", + "description": "Module for provisioning Samba", + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "6.0", + "7.0" + ] + }, + { + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "12.04", + "14.04" + ] + }, + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "7.0", + "8.0" + ] + } + ], + "dependencies": [ + + ] +} diff --git a/modules/services/unix/file_share/samba_config/samba_config.pp b/modules/services/unix/file_share/samba_config/samba_config.pp new file mode 100644 index 000000000..a64d9458f --- /dev/null +++ b/modules/services/unix/file_share/samba_config/samba_config.pp @@ -0,0 +1,52 @@ +node 'server.example.com' { + class { 'samba::server': + workgroup => 'example', + server_string => "Example Samba Server", + interfaces => "eth0 lo", + security => 'share' + } + + samba::server::share { 'example-share': + comment => 'Example Share', + path => '/var', + guest_only => true, + guest_ok => true, + guest_account => "guest", + browsable => false, + create_mask => 0777, + force_create_mask => 0777, + directory_mask => 0777, + force_directory_mask => 0777, + force_group => 'group', + force_user => 'user', + copy => 'some-other-share', + } +} + + + +# node 'server.example.com' { +# class {'samba::server': +# workgroup => 'example', +# server_string => "Example Samba Server", +# interfaces => "eth0 lo", +# security => 'ads' +# } +# +# samba::server::share {'ri-storage': +# comment => 'RBTH User Storage', +# path => "$smb_share", +# browsable => true, +# writable => true, +# create_mask => 0770, +# directory_mask => 0770, +# } +# +# class { 'samba::server::ads': +# winbind_acct => $::domain_admin, +# winbind_pass => $::admin_password, +# realm => 'EXAMPLE.COM', +# nsswitch => true, +# target_ou => "Nix_Mashine" +# } +# } diff --git a/modules/services/unix/file_share/samba_config/secgen_metadata.xml b/modules/services/unix/file_share/samba_config/secgen_metadata.xml new file mode 100644 index 000000000..74140baf5 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/secgen_metadata.xml @@ -0,0 +1,24 @@ + + + + Samba file share server configuration + TODO + Apache v2 + Samba server configuration + + file_share + linux + + + https://httpd.apache.org/ + samba + Apache v2 + + + + samba_config + + + \ No newline at end of file diff --git a/modules/services/unix/file_share/samba_config/spec/acceptance/basic_samba_spec.rb b/modules/services/unix/file_share/samba_config/spec/acceptance/basic_samba_spec.rb new file mode 100644 index 000000000..0dd6ac6e4 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/acceptance/basic_samba_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper_acceptance' + +describe 'basic samba' do + context 'default parameters' do + let(:pp) {" + class { 'samba::server': + workgroup => 'example', + server_string => 'Example Samba Server' + } + + samba::server::share {'example-share': + comment => 'Example Share', + path => '/path/to/share', + guest_only => true, + guest_ok => true, + guest_account => 'guest', + browsable => false, + create_mask => 0777, + force_create_mask => 0777, + directory_mask => 0777, + force_directory_mask => 0777, + force_group => 'group', + force_user => 'user', + } + "} + + it 'should apply with no errors' do + apply_manifest(pp, :catch_failures=>true) + end + + it 'should be idempotent' do + apply_manifest(pp, :catch_changes=>true) + end + end +end diff --git a/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/centos-66-x64.yml b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/centos-66-x64.yml new file mode 100644 index 000000000..1fffff686 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/centos-66-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-66-x64: + roles: + - master + platform: el-6-x86_64 + box: puppetlabs/centos-6.6-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/boxes/centos-6.6-64-nocm + hypervisor: vagrant +CONFIG: + log_level: verbose + type: foss + color: false diff --git a/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/centos-70-x64.yml b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/centos-70-x64.yml new file mode 100644 index 000000000..845e47eb4 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/centos-70-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-70-x64: + roles: + - master + platform: el-7-x86_64 + box: puppetlabs/centos-7.0-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/boxes/centos-7.0-64-nocm + hypervisor : vagrant +CONFIG: + log_level: verbose + type: foss + color: false diff --git a/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/debian-78-x64.yml b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/debian-78-x64.yml new file mode 100644 index 000000000..c4062fd13 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/debian-78-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + debian-78-x64: + roles: + - master + platform: debian-7-amd64 + box: puppetlabs/debian-7.8-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/boxes/debian-7.8-64-nocm + hypervisor: vagrant + +CONFIG: + log_level: verbose + type: foss diff --git a/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/debian-81-x64.yml b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/debian-81-x64.yml new file mode 100644 index 000000000..3b1d8aabb --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/debian-81-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + debian-81-x64: + roles: + - master + platform: debian-8-amd64 + box: lazyfrosch/debian-8-jessie-amd64-puppet + box_url: https://vagrantcloud.com/lazyfrosch/boxes/debian-8-jessie-amd64-puppet + hypervisor: vagrant + +CONFIG: + log_level: verbose + type: foss diff --git a/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/ubuntu-server-1204-x86.yml b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/ubuntu-server-1204-x86.yml new file mode 100644 index 000000000..c2e8657a4 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/ubuntu-server-1204-x86.yml @@ -0,0 +1,13 @@ +HOSTS: + ubuntu-server-1204-x64: + roles: + - master + platform: ubuntu-1204-amd64 + box: puppetlabs/ubuntu-12.04-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/boxes/ubuntu-12.04-64-nocm + hypervisor: vagrant + +CONFIG: + log_level: verbose + type: foss + color: false diff --git a/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml new file mode 100644 index 000000000..62e2ea9d7 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml @@ -0,0 +1,12 @@ +HOSTS: + ubuntu-server-1404-x64: + roles: + - master + platform: ubuntu-1404-amd64 + box: puppetlabs/ubuntu-14.04-64-nocm + box_url: https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm + hypervisor: vagrant +CONFIG: + log_level: verbose + type: foss + color: false diff --git a/modules/services/unix/file_share/samba_config/spec/classes/samba__server__config_spec.rb b/modules/services/unix/file_share/samba_config/spec/classes/samba__server__config_spec.rb new file mode 100644 index 000000000..5f13aa4dc --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/classes/samba__server__config_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +describe 'samba::server::config', :type => :class do + context "on a Debian OS" do + let( :facts ) { { :osfamily => 'Debian' } } + + it { should contain_file('/etc/samba/smb.conf').with_owner('root') } + end +end + diff --git a/modules/services/unix/file_share/samba_config/spec/classes/samba__server__install_spec.rb b/modules/services/unix/file_share/samba_config/spec/classes/samba__server__install_spec.rb new file mode 100644 index 000000000..97646873d --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/classes/samba__server__install_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe 'samba::server::install', :type => :class do + context "on a Debian OS" do + let(:facts) {{ :osfamily => 'Debian' }} + it { should contain_package('samba') } + end +end + diff --git a/modules/services/unix/file_share/samba_config/spec/classes/samba__server__service_spec.rb b/modules/services/unix/file_share/samba_config/spec/classes/samba__server__service_spec.rb new file mode 100644 index 000000000..4352ec2dd --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/classes/samba__server__service_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe 'samba::server::service' do + context 'on a Debian os family' do + let(:facts) {{ :osfamily => 'Debian' }} + + it { should contain_service('samba').with_require('Class[Samba::Server::Config]') } + + context 'Debian' do + context 'wheezy' do + let(:facts) {{ :osfamily => 'Debian', + :operatingsystem => 'Debian', + :operatingsystemmajrelease => '7' }} + it { should contain_service('samba') } + end + context 'jessie' do + let(:facts) {{ :osfamily => 'Debian', + :operatingsystem => 'Debian', + :operatingsystemmajrelease => '8' }} + it { should contain_service('smbd') } + end + end + + context 'Ubuntu' do + let(:facts) {{ :osfamily => 'Debian', :operatingsystem => 'Ubuntu' }} + it { should contain_service('smbd') } + end + end + + context 'on a Redhat os family' do + let(:facts) {{ :osfamily => 'Redhat' }} + it { should contain_service('smb') } + end + + context 'on a Archlinux os family' do + let(:facts) {{ :osfamily => 'Archlinux' }} + it { should contain_service('smbd') } + end + + context 'on Linux os family' do + let(:facts) {{ :osfamily => 'Linux' }} + it { should raise_error(/is not supported by this module./) } + + context 'Gentoo' do + let(:facts) {{ :osfamily => 'Linux', :operatingsystem => 'Gentoo' }} + it { should contain_service('samba') } + end + end + + context 'on an unsupported OS' do + let(:facts) {{ :osfamily => 'Solaris' }} + it { should raise_error(/Solaris is not supported by this module./) } + end +end diff --git a/modules/services/unix/file_share/samba_config/spec/classes/samba__server_spec.rb b/modules/services/unix/file_share/samba_config/spec/classes/samba__server_spec.rb new file mode 100644 index 000000000..69fa0ec7d --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/classes/samba__server_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe 'samba::server' do + let(:facts) {{ :osfamily => 'Debian' }} + + it { should contain_class('samba::server::install') } + it { should contain_class('samba::server::config') } + it { should contain_class('samba::server::service') } + + it { should contain_samba__server__option('interfaces') } + it { should contain_samba__server__option('bind interfaces only') } + it { should contain_samba__server__option('security') } + it { should contain_samba__server__option('server string') } + it { should contain_samba__server__option('unix password sync') } + it { should contain_samba__server__option('workgroup') } + it { should contain_samba__server__option('socket options') } + it { should contain_samba__server__option('deadtime') } + it { should contain_samba__server__option('keepalive') } + it { should contain_samba__server__option('load printers') } + it { should contain_samba__server__option('printing') } + it { should contain_samba__server__option('printcap name') } + it { should contain_samba__server__option('disable spoolss') } + + it { should contain_file('/sbin/check_samba_user').with_owner('root') } + it { should contain_file('/sbin/add_samba_user').with_owner('root') } +end diff --git a/modules/services/unix/file_share/samba_config/spec/coverage_spec.rb b/modules/services/unix/file_share/samba_config/spec/coverage_spec.rb new file mode 100644 index 000000000..12513b83c --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/coverage_spec.rb @@ -0,0 +1 @@ +at_exit { RSpec::Puppet::Coverage.report! } diff --git a/modules/services/unix/file_share/samba_config/spec/fixtures/manifests/init.pp b/modules/services/unix/file_share/samba_config/spec/fixtures/manifests/init.pp new file mode 100644 index 000000000..94005cd02 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/fixtures/manifests/init.pp @@ -0,0 +1,5 @@ +node 'testhost.example.com' { + include samba::server +} + +node default {} diff --git a/modules/services/unix/file_share/samba_config/spec/spec_helper.rb b/modules/services/unix/file_share/samba_config/spec/spec_helper.rb new file mode 100644 index 000000000..81f98acd8 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/spec_helper.rb @@ -0,0 +1,8 @@ +require 'puppetlabs_spec_helper/module_spec_helper' + +RSpec.configure do |c| + c.before do + # avoid "Only root can execute commands as other users" + Puppet.features.stubs(:root? => true) + end +end diff --git a/modules/services/unix/file_share/samba_config/spec/spec_helper_acceptance.rb b/modules/services/unix/file_share/samba_config/spec/spec_helper_acceptance.rb new file mode 100644 index 000000000..74187d881 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/spec/spec_helper_acceptance.rb @@ -0,0 +1,29 @@ +require 'beaker-rspec/spec_helper' +require 'beaker-rspec/helpers/serverspec' +require 'pry' + +unless ENV['BEAKER_provision'] == 'no' + hosts.each do |host| + # Install Puppet + if host.is_pe? + install_pe + else + install_puppet + end + end +end + +RSpec.configure do |c| + # Project root + proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) + + # Readable test descriptions + c.formatter = :documentation + + # Configure all nodes in nodeset + c.before :suite do + # Install module and dependencies + puppet_module_install(:source => proj_root, :module_name => 'samba') + end +end + diff --git a/modules/services/unix/file_share/samba_config/templates/add_samba_user b/modules/services/unix/file_share/samba_config/templates/add_samba_user new file mode 100644 index 000000000..cc1d56b11 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/templates/add_samba_user @@ -0,0 +1,16 @@ +#!/bin/bash + +# This script adds a samba account for a given user and password +# call as: +# > add_samba_user "USERNAME" "PASSWORD" + +/bin/echo -e "$2\n$2\n" | sudo /usr/bin/pdbedit -a "$1" -t 1>/dev/null +results=$? + +if [ $results = 0 ]; then + echo "added samba account for '$1'" +else + echo "could not add samba account for '$1'" +fi + +exit $results diff --git a/modules/services/unix/file_share/samba_config/templates/check_samba_user b/modules/services/unix/file_share/samba_config/templates/check_samba_user new file mode 100644 index 000000000..431c3c4f1 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/templates/check_samba_user @@ -0,0 +1,16 @@ +#!/bin/bash + +# This script checks to see if a given user account exists on samba +# if so, it returns 0 +# otherwise it returns 1 + +sudo /usr/bin/pdbedit -L | egrep -q "^$1:" +exists=$? + +if [ $exists = 0 ]; then + echo "'$1' is a samba user" +else + echo "no samba account matching '$1'" +fi + +exit $exists diff --git a/modules/services/unix/file_share/samba_config/templates/configure_active_directory.erb b/modules/services/unix/file_share/samba_config/templates/configure_active_directory.erb new file mode 100644 index 000000000..4f9b6e033 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/templates/configure_active_directory.erb @@ -0,0 +1,149 @@ +#!/bin/bash + +# This script can cause a host to join or leave +# the Windows Active Directory domain + +# variables +# +# specify a timeout for domain operations +seconds=300 +# +# post_join_delay seems to be necessary after joing domain +post_join_delay=30 +# + +PROG=$(basename $0) + +function usage () { + cat >&2 <<- EOF + Usage: $PROG -[hjl] + -h help + -j join the domain + -l leave the domain + Return code indicates success (0) or failure. + EOF +} + +# kinit and klist path depend on krb5 release +export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/kerberos/bin + +NET=$(which net) +if ! [ -x "$NET" ]; then + echo "ERROR: net command is missing or not executable." >&2 + exit 1 +fi + +EXPECT=$(which expect) +if ! [ -x "$EXPECT" ]; then + echo "ERROR: cannot run expect" >&2 + exit 1 +fi + +if [ $# -eq 0 ]; then + usage + exit 2 +fi + +while getopts "hjlq" option +do + case $option in + h ) usage; exit 0;; + j ) action="join";; + l ) action="leave";; + * ) usage; exit 2;; + esac +done + +password='<%= scope.lookupvar('samba::server::ads::winbind_pass') -%>' + +# short hostname from facter +my_hostname="<%= hostname -%>" + +# what account do we use for net ads commands? +winbind_acct="<%= scope.lookupvar('samba::server::ads::winbind_acct') -%>" + +# which realm will we be joining? +my_realm="<%= scope.lookupvar('samba::server::ads::realm') -%>" + +# where should we create computer accounts? +target_ou="<%= scope.lookupvar('samba::server::ads::target_ou') -%>" + +echo "Please do not kill me; I may be slow" >&2 + +#TODO, need write time check check_kdc_time +#if ! /bin/check_kdc_time; then +# echo "ERROR: time offset too large to manipulate domain" >&2 +# exit 1 +#else +# echo "INFO: time offset seems ok" >&2 +#fi + +if [ "$action" = "leave" ]; then + logger -st $PROG "Leaving AD domain" + $NET ads $action -U "${winbind_acct}%${password}" | grep Deleted && success=true || success=false + kdestroy + rm -f /etc/krb5.keytab + if [ $success = "true" ]; then + logger -st $PROG "Left AD domain" + else + logger -st $PROG "Failed to leave AD domain" + fi +fi + +ad_settle() { + ( + echo -n "Waiting $post_join_delay seconds" + for x in $(seq 1 $post_join_delay); do + echo -n "." + sleep 1 + done + echo + ) >&2 +} + +# ldapmodify _does_ use the env var for sasl bind +export KRB5CCNAME=$(umask 0077; mktemp -q winbind_cache.XXXXXXXX) + +if [ "$action" = "join" ]; then + if [ "${target_ou}" != "" ]; then + ou_parameter="createcomputer=\"${target_ou}\"" + else + ou_parameter="" + fi + + logger -st $PROG "Joining AD domain" >&2 + $NET ads $action -U "${winbind_acct}%${password}" ${ou_parameter} \ + | grep Joined && success=true || success=false + +if [ $success = "false" ]; then + echo ERROR: failed to join domain >&2 + exit 2 +fi + +max_attempts=5 +for attempt in $(seq 1 $max_attempts); do + echo "$attempt of $max_attempts:" + ad_settle + echo "Getting TGT for ${winbind_acct}@${my_realm}" >&2 + $EXPECT -c "spawn -noecho kinit -c $KRB5CCNAME ${winbind_acct}@${my_realm}; + expect :; + send {${password}}; + send \n; + expect eof" + klist -c $KRB5CCNAME &> /dev/null && break +done + +if [ $(wbinfo -u|wc -l) != 0 ]; then + success=true +else + echo "ERROR: return user list from AD is empty" >&2 + success=false +fi + +# get rid of cred cache +kdestroy -c $KRB5CCNAME &> /dev/null +rm -f $KRB5CCNAME &> /dev/null || : + +fi + +[ "$success" = "true" ] && exit 0 || exit 1 diff --git a/modules/services/unix/file_share/samba_config/templates/verify_active_directory.erb b/modules/services/unix/file_share/samba_config/templates/verify_active_directory.erb new file mode 100644 index 000000000..0917c4937 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/templates/verify_active_directory.erb @@ -0,0 +1,108 @@ +#!/bin/bash + +PROG=$(basename $0) +export EXPIRATION=90 + +# kinit and klist path depend on krb5 release +export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/kerberos/bin + +EXPECT=$(which expect) +if ! [ -x "$EXPECT" ]; then + echo "ERROR: cannot run expect" >&2 + exit 1 +fi + +#TODO +#if ! check_kdc_time; then +# { +# echo "====================================" +# echo "WARNING: time offset seems too large" +# echo "====================================" +# } >&2 +#fi + +password='<%= scope.lookupvar('samba::server::ads::winbind_pass') -%>' + +# short hostname from facter +my_hostname="<%= hostname -%>" + +winbind_acct="<%= scope.lookupvar('samba::server::ads::winbind_acct') -%>" + +default_realm=$(grep -i '^[[:space:]]*realm.*=' /etc/samba/smb.conf | sed 's/ //g' | sed 's/realm=//g') + +# if we're still here, let's try the testjoin +do_testjoin() { + echo "Running net ads testjoin with EXPIRATION=$EXPIRATION" >&2 + _cmd="net ads testjoin -P" + if [[ -n "$1" ]]; then + _cmd="${_cmd} $@" + fi + output=$(${_cmd} 2>&1) + grep -q 'Join is OK' <<< $output + _rc=$? + if [ ${_rc} -ne 0 ]; then + logger -st $PROG "Error: net ads testjoin -P failed: $output" + fi + return ${_rc} +} +do_testjoin +if [ $? -ne 0 ]; then + # get verbose failure info + do_testjoin -d3 +fi + + +# if we're still here, we need to: +# - get a TGT that enables us to query the attribute 'useraccountcontrol' +# - confirm that AD trusts us for GSSAPI delegation + +export KRB5CCNAME=$(umask 0077; mktemp -q winbind_cache.XXXXXXXX) + +get_tgt() { + ( + $EXPECT -c "spawn -noecho kinit -c $KRB5CCNAME ${winbind_acct}@${default_realm}; + expect :; + send {${password}}; + send \n; + expect eof" + ) &> /dev/null + klist -c $KRB5CCNAME &> /dev/null + return $? +} + +# try this several times. +max_attempts=5 +# assume non-zero for has_tgt +has_tgt=1 +for attempt in $(seq 1 $max_attempts); do + # If we just joined the domain, it takes a small amount of time + # for AD to sort things out amongst the DC's, and it + # depends in part on DNS performance. + if get_tgt; then + has_tgt=0 + break + fi + echo "." >&2 + sleep 3 +done + +success=true + +if [ $has_tgt -ne 0 ]; then + logger -st $PROG "ERROR: failed to get TGT from AD" + success=false +else + if [ $(wbinfo -u|wc -l) != 0 ]; then + success=true + else + echo "ERROR: return user list from AD is empty" >&2 + success=false + fi + + # get rid of cred cache + kdestroy -c $KRB5CCNAME &> /dev/null +fi + +[[ $success == "false" ]] && exit 1 + +exit 0 diff --git a/modules/services/unix/file_share/samba_config/tests/init.pp b/modules/services/unix/file_share/samba_config/tests/init.pp new file mode 100644 index 000000000..e1dd99da2 --- /dev/null +++ b/modules/services/unix/file_share/samba_config/tests/init.pp @@ -0,0 +1,3 @@ +# Smoketest. + +class {'samba::server': } diff --git a/scenarios/simple_examples/samba_service_with_config.xml b/scenarios/simple_examples/samba_service_with_config.xml new file mode 100644 index 000000000..0daacd430 --- /dev/null +++ b/scenarios/simple_examples/samba_service_with_config.xml @@ -0,0 +1,19 @@ + + + + + + + samba_service + + + + + + + + + +