summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-10-23 01:19:07 +0200
committerLuke Kanies <luke@madstop.com>2008-10-23 01:19:07 +0200
commit23d42aca2260562b951507f8a0382823619c19d7 (patch)
tree0319dbc38b37bbd3b6f8bc43f34b2cc6bb3939f2 /lib/puppet
parentb7d72360f66e36d897cfd4436236a3607a6de5b7 (diff)
parent22024bce8f47ea37d57e57dd25d42b8a1996693c (diff)
downloadpuppet-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.rb6
-rw-r--r--lib/puppet/property/keyvalue.rb96
-rw-r--r--lib/puppet/provider/user/user_role_add.rb67
-rw-r--r--lib/puppet/provider/user/useradd.rb37
-rw-r--r--lib/puppet/type/file/selcontext.rb25
-rw-r--r--lib/puppet/type/selboolean.rb8
-rw-r--r--lib/puppet/type/selmodule.rb20
-rwxr-xr-xlib/puppet/type/user.rb148
-rw-r--r--lib/puppet/util/selinux.rb13
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