File: //opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/type/k5login.rb
# Plug-in type for handling k5login files
require 'puppet/util'
require 'puppet/util/selinux'
require 'puppet/type/file/selcontext'
Puppet::Type.newtype(:k5login) do
@doc = "Manage the `.k5login` file for a user. Specify the full path to
the `.k5login` file as the name, and an array of principals as the
`principals` attribute."
ensurable
# Principals that should exist in the file
newproperty(:principals, :array_matching => :all) do
desc "The principals present in the `.k5login` file. This should be specified as an array."
end
# The path/name of the k5login file
newparam(:path) do
isnamevar
desc "The path to the `.k5login` file to manage. Must be fully qualified."
validate do |value|
unless absolute_path?(value)
raise Puppet::Error, _("File paths must be fully qualified.")
end
end
end
# To manage the mode of the file
newproperty(:mode) do
desc "The desired permissions mode of the `.k5login` file."
defaultto { "644" }
end
# To manage the selinux user of the file
newproperty(:seluser, :parent => Puppet::SELFileContext) do
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."
defaultto { "user_u" }
end
# To manage the selinux role of the file
newproperty(:selrole, :parent => Puppet::SELFileContext) do
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."
defaultto { "object_r" }
end
# To manage the selinux type of the file
newproperty(:seltype, :parent => Puppet::SELFileContext) do
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."
# to my knowledge, `krb5_home_t` is the only valid type for .k5login
defaultto { "krb5_home_t" }
end
# To manage the selinux range of the file
newproperty(:selrange, :parent => Puppet::SELFileContext) do
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)."
defaultto { "s0" }
end
# Stat our file.
#
# We use the initial value :needs_stat to ensure we only stat the file once,
# but can also keep track of a failed stat (@stat == nil). This also allows
# us to re-stat on demand by setting @stat = :needs_stat.
def stat
return @stat unless @stat == :needs_stat
@stat = begin
Puppet::FileSystem.stat(self[:path])
rescue Errno::ENOENT
nil
rescue Errno::ENOTDIR
nil
rescue Errno::EACCES
warning _("Could not stat; permission denied")
nil
end
end
def initialize(args)
@stat = :needs_stat
super
end
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
provide(:k5login) do
desc "The k5login provider is the only provider for the k5login
type."
include Puppet::Util::SELinux
# Does this file exist?
def exists?
Puppet::FileSystem.exist?(@resource[:name])
end
# create the file
def create
write(@resource.should(:principals))
should_mode = @resource.should(:mode)
unless self.mode == should_mode
self.mode = should_mode
end
end
# remove the file
def destroy
Puppet::FileSystem.unlink(@resource[:name])
end
# Return the principals
def principals
if Puppet::FileSystem.exist?(@resource[:name])
File.readlines(@resource[:name]).collect { |line| line.chomp }
else
:absent
end
end
# Write the principals out to the k5login file
def principals=(value)
write(value)
end
# Return the mode as an octal string, not as an integer
def mode
"%o" % (Puppet::FileSystem.stat(@resource[:name]).mode & 007777)
end
# Set the file mode, converting from a string to an integer.
def mode=(value)
File.chmod(Integer("0#{value}"), @resource[:name])
end
private
def write(value)
Puppet::Util.replace_file(@resource[:name], 0644) do |f|
f.puts value
end
end
end
end