diff options
| author | Luke Kanies <luke@madstop.com> | 2008-10-23 01:19:07 +0200 |
|---|---|---|
| committer | Luke Kanies <luke@madstop.com> | 2008-10-23 01:19:07 +0200 |
| commit | 23d42aca2260562b951507f8a0382823619c19d7 (patch) | |
| tree | 0319dbc38b37bbd3b6f8bc43f34b2cc6bb3939f2 /lib/puppet | |
| parent | b7d72360f66e36d897cfd4436236a3607a6de5b7 (diff) | |
| parent | 22024bce8f47ea37d57e57dd25d42b8a1996693c (diff) | |
| download | puppet-23d42aca2260562b951507f8a0382823619c19d7.tar.gz puppet-23d42aca2260562b951507f8a0382823619c19d7.tar.xz puppet-23d42aca2260562b951507f8a0382823619c19d7.zip | |
Merge branch '0.24.x' of git://github.com/jamtur01/puppet into 0.24.x
Diffstat (limited to 'lib/puppet')
| -rw-r--r-- | lib/puppet/parser/templatewrapper.rb | 6 | ||||
| -rw-r--r-- | lib/puppet/property/keyvalue.rb | 96 | ||||
| -rw-r--r-- | lib/puppet/provider/user/user_role_add.rb | 67 | ||||
| -rw-r--r-- | lib/puppet/provider/user/useradd.rb | 37 | ||||
| -rw-r--r-- | lib/puppet/type/file/selcontext.rb | 25 | ||||
| -rw-r--r-- | lib/puppet/type/selboolean.rb | 8 | ||||
| -rw-r--r-- | lib/puppet/type/selmodule.rb | 20 | ||||
| -rwxr-xr-x | lib/puppet/type/user.rb | 148 | ||||
| -rw-r--r-- | lib/puppet/util/selinux.rb | 13 |
9 files changed, 357 insertions, 63 deletions
diff --git a/lib/puppet/parser/templatewrapper.rb b/lib/puppet/parser/templatewrapper.rb index 00f364088..036f6604e 100644 --- a/lib/puppet/parser/templatewrapper.rb +++ b/lib/puppet/parser/templatewrapper.rb @@ -83,7 +83,11 @@ class Puppet::Parser::TemplateWrapper # to the regular methods. benchmark(:debug, "Bound template variables for #{file}") do scope.to_hash.each { |name, value| - realname = name.gsub(/[^\w]/, "_") + if name.kind_of?(String) + realname = name.gsub(/[^\w]/, "_") + else + realname = name + end instance_variable_set("@#{realname}", value) } end diff --git a/lib/puppet/property/keyvalue.rb b/lib/puppet/property/keyvalue.rb new file mode 100644 index 000000000..6c0800c79 --- /dev/null +++ b/lib/puppet/property/keyvalue.rb @@ -0,0 +1,96 @@ +#This subclass of property manages string key value pairs. + +#In order to use this property: +# - the @should value must be an array of keyvalue pairs separated by the 'separator' +# - the retrieve method should return a hash with the keys as symbols +# IMPORTANT NOTE: In order for this property to work there must also be a 'membership' parameter +# The class that inherits from property should override that method with the symbol for the membership + +require 'puppet/property' + +module Puppet + class Property + class KeyValue < Property + + def hash_to_key_value_s(hash) + hash.select { |k,v| true }.map { |pair| pair.join(separator) }.join(delimiter) + end + + def should_to_s(should_value) + hash_to_key_value_s(should_value) + end + + def is_to_s(current_value) + hash_to_key_value_s(current_value) + end + + def membership + :key_value_membership + end + + def inclusive? + @resource[membership] == :inclusive + end + + def hashify(key_value_array) + #turns string array into a hash + key_value_array.inject({}) do |hash, key_value| + tmp = key_value.split(separator) + hash[tmp[0].intern] = tmp[1] + hash + end + end + + def process_current_hash(current) + return {} if current == :absent + + #inclusive means we are managing everything so if it isn't in should, its gone + if inclusive? + current.each_key { |key| current[key] = nil } + end + current + end + + def should + unless defined? @should and @should + return nil + end + + members = hashify(@should) + current = process_current_hash(retrieve) + + #shared keys will get overwritten by members + current.merge(members) + end + + def separator + "=" + end + + def delimiter + ";" + end + + def retrieve + #ok, some 'convention' if the keyvalue property is named properties, provider should implement a properties method + if key_hash = provider.send(name) and key_hash != :absent + return key_hash + else + return :absent + end + end + + def insync?(is) + unless defined? @should and @should + return true + end + + unless is + return true + end + + return (is == self.should) + end + end + end +end diff --git a/lib/puppet/provider/user/user_role_add.rb b/lib/puppet/provider/user/user_role_add.rb index 819516dc4..00fc24b3a 100644 --- a/lib/puppet/provider/user/user_role_add.rb +++ b/lib/puppet/provider/user/user_role_add.rb @@ -11,6 +11,8 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd do options :comment, :method => :gecos options :groups, :flag => "-G" options :roles, :flag => "-R" + options :auths, :flag => "-A" + options :profiles, :flag => "-P" verify :gid, "GID must be an integer" do |value| value.is_a? Integer @@ -26,6 +28,24 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd do has_feature :manages_passwords end + #must override this to hand the keyvalue pairs + def add_properties + cmd = [] + Puppet::Type.type(:user).validproperties.each do |property| + next if property == :ensure + # the value needs to be quoted, mostly because -c might + # have spaces in it + if value = @resource.should(property) and value != "" + if property == :keys + cmd += build_keys_cmd(value) + else + cmd << flag(property) << value + end + end + end + cmd + end + def user_attributes @user_attributes ||= UserAttr.get_attributes_by_name(@resource[:name]) end @@ -57,6 +77,7 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd do def transition(type) cmd = [command(:modify)] cmd << "-K" << "type=#{type}" + cmd += add_properties cmd << @resource[:name] end @@ -85,5 +106,51 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd do user_attributes[:roles] end end + + def auths + if user_attributes + user_attributes[:auths] + end + end + + def profiles + if user_attributes + user_attributes[:profiles] + end + end + + def project + if user_attributes + user_attributes[:project] + end + end + + def managed_attributes + [:name, :type, :roles, :auths, :profiles, :project] + end + + def remove_managed_attributes + managed = managed_attributes + user_attributes.select { |k,v| !managed.include?(k) }.inject({}) { |hash, array| hash[array[0]] = array[1]; hash } + end + + def keys + if user_attributes + #we have to get rid of all the keys we are managing another way + remove_managed_attributes + end + end + + def build_keys_cmd(keys_hash) + cmd = [] + keys_hash.each do |k,v| + cmd << "-K" << "#{k}=#{v}" + end + cmd + end + + def keys=(keys_hash) + run([command(:modify)] + build_keys_cmd(keys_hash) << @resource[:name], "modify attribute key pairs") + end end diff --git a/lib/puppet/provider/user/useradd.rb b/lib/puppet/provider/user/useradd.rb index b327db384..6996dd69a 100644 --- a/lib/puppet/provider/user/useradd.rb +++ b/lib/puppet/provider/user/useradd.rb @@ -23,8 +23,22 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ has_feature :manages_passwords end - def addcmd - cmd = [command(:add)] + def check_allow_dup + @resource.allowdupe? ? ["-o"] : [] + end + + def check_manage_home + cmd = [] + if @resource.managehome? + cmd << "-m" + elsif %w{Fedora RedHat}.include?(Facter.value("operatingsystem")) + cmd << "-M" + end + cmd + end + + def add_properties + cmd = [] Puppet::Type.type(:user).validproperties.each do |property| next if property == :ensure # the value needs to be quoted, mostly because -c might @@ -33,20 +47,15 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ cmd << flag(property) << value end end + cmd + end - if @resource.allowdupe? - cmd << "-o" - end - - if @resource.managehome? - cmd << "-m" - elsif %w{Fedora RedHat}.include?(Facter.value("operatingsystem")) - cmd << "-M" - end - + def addcmd + cmd = [command(:add)] + cmd += add_properties + cmd += check_allow_dup + cmd += check_manage_home cmd << @resource[:name] - - cmd end # Retrieve the password using the Shadow Password library diff --git a/lib/puppet/type/file/selcontext.rb b/lib/puppet/type/file/selcontext.rb index b2c89e6f8..d5111caf8 100644 --- a/lib/puppet/type/file/selcontext.rb +++ b/lib/puppet/type/file/selcontext.rb @@ -56,28 +56,45 @@ module Puppet end Puppet.type(:file).newproperty(:seluser, :parent => Puppet::SELFileContext) do - desc "What the SELinux User context of the file should be." + desc "What the SELinux user component of the context of the file should be. + Any valid SELinux user component is accepted. For example ``user_u``. + If not specified it defaults to the value returned by matchpathcon for + the file, if any exists. Only valid on systems with SELinux support + enabled." @event = :file_changed defaultto { self.retrieve_default_context(:seluser) } end Puppet.type(:file).newproperty(:selrole, :parent => Puppet::SELFileContext) do - desc "What the SELinux Role context of the file should be." + desc "What the SELinux role component of the context of the file should be. + Any valid SELinux role component is accepted. For example ``role_r``. + If not specified it defaults to the value returned by matchpathcon for + the file, if any exists. Only valid on systems with SELinux support + enabled." @event = :file_changed defaultto { self.retrieve_default_context(:selrole) } end Puppet.type(:file).newproperty(:seltype, :parent => Puppet::SELFileContext) do - desc "What the SELinux Type context of the file should be." + desc "What the SELinux type component of the context of the file should be. + Any valid SELinux type component is accepted. For example ``tmp_t``. + If not specified it defaults to the value returned by matchpathcon for + the file, if any exists. Only valid on systems with SELinux support + enabled." @event = :file_changed defaultto { self.retrieve_default_context(:seltype) } end Puppet.type(:file).newproperty(:selrange, :parent => Puppet::SELFileContext) do - desc "What the SELinux Range context of the file should be." + desc "What the SELinux range component of the context of the file should be. + Any valid SELinux range component is accepted. For example ``s0`` or + ``SystemHigh``. If not specified it defaults to the value returned by + matchpathcon for the file, if any exists. Only valid on systems with + SELinux support enabled and that have support for MCS (Multi-Category + Security)." @event = :file_changed defaultto { self.retrieve_default_context(:selrange) } diff --git a/lib/puppet/type/selboolean.rb b/lib/puppet/type/selboolean.rb index d12dd3bcb..b1f12cae4 100644 --- a/lib/puppet/type/selboolean.rb +++ b/lib/puppet/type/selboolean.rb @@ -4,7 +4,8 @@ module Puppet newtype(:selboolean) do - @doc = "Enable or disable SELinux booleans." + @doc = "Manages SELinux booleans on systems with SELinux support. The supported booleans + are any of the ones found in /selinux/booleans/." newparam(:name) do desc "The name of the SELinux boolean to be managed." @@ -12,13 +13,14 @@ module Puppet end newproperty(:value) do - desc "Whether the the SELinux boolean should be enabled or disabled. Possible values are ``on`` or ``off``." + desc "Whether the the SELinux boolean should be enabled or disabled." newvalue(:on) newvalue(:off) end newparam(:persistent) do - desc "If set true, SELinux booleans will be written to disk and persist accross reboots." + desc "If set true, SELinux booleans will be written to disk and persist accross reboots. + The default is ``false``." defaultto :false newvalues(:true, :false) diff --git a/lib/puppet/type/selmodule.rb b/lib/puppet/type/selmodule.rb index 1f02912ad..883cd954d 100644 --- a/lib/puppet/type/selmodule.rb +++ b/lib/puppet/type/selmodule.rb @@ -3,36 +3,40 @@ # Puppet::Type.newtype(:selmodule) do - @doc = "Enable or disable SELinux policy modules." + @doc = "Manages loading and unloading of SELinux policy modules + on the system. Requires SELinux support. See man semodule(8) + for more information on SELinux policy modules." ensurable newparam(:name) do - desc "The name of the SELinux policy to be managed." + desc "The name of the SELinux policy to be managed. You should not + include the customary trailing .pp extension." isnamevar end newparam(:selmoduledir) do desc "The directory to look for the compiled pp module file in. - Currently defaults to /usr/share/selinux/targeted" + Currently defaults to /usr/share/selinux/targeted. If selmodulepath + is not specified the module will be looked for in this directory in a + in a file called NAME.pp, where NAME is the value of the name parameter." defaultto "/usr/share/selinux/targeted" end newparam(:selmodulepath) do - desc "The full path in which to look for the compiled pp - module file in. You only need to use this if the module file - is not in the directory pointed at by selmoduledir." + desc "The full path to the compiled .pp policy module. You only need to use + this if the module file is not in the directory pointed at by selmoduledir." end newproperty(:syncversion) do - desc "If set to 'true', the policy will be reloaded if the + desc "If set to ``true``, the policy will be reloaded if the version found in the on-disk file differs from the loaded - version. If set to 'false' (the default) the the only check + version. If set to ``false`` (the default) the the only check that will be made is if the policy is loaded at all or not." newvalue(:true) diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb index 29f4880c1..929e45d14 100755 --- a/lib/puppet/type/user.rb +++ b/lib/puppet/type/user.rb @@ -1,6 +1,7 @@ require 'etc' require 'facter' require 'puppet/property/list' +require 'puppet/property/keyvalue' module Puppet newtype(:user) do @@ -137,6 +138,7 @@ module Puppet end end + newproperty(:groups, :parent => Puppet::Property::List) do desc "The groups of which the user is a member. The primary group should not be listed. Multiple groups should be @@ -147,25 +149,7 @@ module Puppet raise ArgumentError, "Group names must be provided, not numbers" end if value.include?(",") - raise ArgumentError, "Group names must be provided as an array, not as a comma-separated list '%s'" % value - end - end - end - - newproperty(:roles, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do - desc "The roles of which the user the user has. The roles should be - specified as an array." - - def membership - :role_membership - end - - validate do |value| - if value =~ /^\d+$/ - raise ArgumentError, "Role names must be provided, not numbers" - end - if value.include?(",") - raise ArgumentError, "Role names must be provided as an array, not a comma-separated list" + raise ArgumentError, "Group names must be provided as an array, not a comma-separated list" end end end @@ -187,19 +171,9 @@ module Puppet defaultto :minimum end - newparam(:role_membership) do - desc "Whether specified roles should be treated as the only roles - of which the user is a member or whether they should merely - be treated as the minimum membership list." - - newvalues(:inclusive, :minimum) - - defaultto :minimum - end - newparam(:allowdupe, :boolean => true) do desc "Whether to allow duplicate UIDs." - + newvalues(:true, :false) defaultto false @@ -240,7 +214,7 @@ module Puppet gobj.should(:gid) == group } autos << obj - + end else autos << group @@ -273,6 +247,118 @@ module Puppet prophash } end + + newproperty(:roles, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do + desc "The roles the user has. Multiple roles should be + specified as an array." + + def membership + :role_membership + end + + validate do |value| + if value =~ /^\d+$/ + raise ArgumentError, "Role names must be provided, not numbers" + end + if value.include?(",") + raise ArgumentError, "Role names must be provided as an array, not a comma-separated list" + end + end + end + + newparam(:role_membership) do + desc "Whether specified roles should be treated as the only roles + of which the user is a member or whether they should merely + be treated as the minimum membership list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + + newproperty(:auths, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do + desc "The auths the user has. Multiple auths should be + specified as an array." + + def membership + :auth_membership + end + + validate do |value| + if value =~ /^\d+$/ + raise ArgumentError, "Auth names must be provided, not numbers" + end + if value.include?(",") + raise ArgumentError, "Auth names must be provided as an array, not a comma-separated list" + end + end + end + + newparam(:auth_membership) do + desc "Whether specified auths should be treated as the only auths + of which the user is a member or whether they should merely + be treated as the minimum membership list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + + newproperty(:profiles, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do + desc "The profiles the user has. Multiple profiles should be + specified as an array." + + def membership + :profile_membership + end + + validate do |value| + if value =~ /^\d+$/ + raise ArgumentError, "Profile names must be provided, not numbers" + end + if value.include?(",") + raise ArgumentError, "Profile names must be provided as an array, not a comma-separated list" + end + end + end + + newparam(:profile_membership) do + desc "Whether specified roles should be treated as the only roles + of which the user is a member or whether they should merely + be treated as the minimum membership list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + + newproperty(:keys, :parent => Puppet::Property::KeyValue, :required_features => :manages_solaris_rbac) do + desc "Specify user attributes in an array of keyvalue pairs" + + def membership + :key_membership + end + + validate do |value| + unless value.include?("=") + raise ArgumentError, "key value pairs must be seperated by an =" + end + end + end + + newparam(:key_membership) do + desc "Whether specified key value pairs should be treated as the only attributes + of the user or whether they should merely + be treated as the minimum list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + + newproperty(:project, :required_features => :manages_solaris_rbac) do + desc "The name of the project associated with a user" + end end end diff --git a/lib/puppet/util/selinux.rb b/lib/puppet/util/selinux.rb index 0a4af3ca1..148748950 100644 --- a/lib/puppet/util/selinux.rb +++ b/lib/puppet/util/selinux.rb @@ -6,8 +6,12 @@ # are available. At this time (2008-09-26) these bindings aren't bundled on # any SELinux-using distribution I know of. +require 'puppet/util' + module Puppet::Util::SELinux + include Puppet::Util + def selinux_support? FileTest.exists?("/selinux/enforce") end @@ -103,10 +107,15 @@ module Puppet::Util::SELinux when :selrange flag = "-l" else - flag = "" + flag = nil end - execute(["/usr/bin/chcon","-h",flag,value,file]) + if flag.nil? + cmd = ["/usr/bin/chcon","-h",value,file] + else + cmd = ["/usr/bin/chcon","-h",flag,value,file] + end + execute(cmd) return true end |
