[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, master, updated. debian/0.24.6-1-356-g5718585
James Turnbull
james at lovedthanlost.net
Fri Jan 23 14:21:12 UTC 2009
The following commit has been merged in the master branch:
commit e77ddc16570fd15b161db416e7dd35f95e7fb0ac
Author: Brett Lentz <wakko666 at gmail.com>
Date: Thu Jul 24 18:13:14 2008 -0700
Merged fsweetser's selinux patch against HEAD
diff --git a/lib/puppet/provider/selboolean/getsetsebool.rb b/lib/puppet/provider/selboolean/getsetsebool.rb
new file mode 100644
index 0000000..4614c6c
--- /dev/null
+++ b/lib/puppet/provider/selboolean/getsetsebool.rb
@@ -0,0 +1,47 @@
+Puppet::Type.type(:selboolean).provide(:getsetsebool) do
+ desc "Manage SELinux booleans using the getsebool and setsebool binaries."
+
+ commands :getsebool => "/usr/sbin/getsebool"
+ commands :setsebool => "/usr/sbin/setsebool"
+
+ def value
+ self.debug "Retrieving value of selboolean #{@resource[:name]}"
+
+ status = getsebool(@resource[:name])
+
+ if status =~ / off$/ then
+ return :off
+ elsif status =~ / on$/ then
+ return :on
+ else
+ status.chomp!
+ raise Puppet::Error, "Invalid response '%s' returned from getsebool" % [status]
+ end
+ end
+
+ def value=(new)
+ persist = ""
+ if @resource[:persistent] == :true
+ self.debug "Enabling persistence"
+ persist = "-P"
+ end
+ execoutput("#{command(:setsebool)} #{persist} #{@resource[:name]} #{new}")
+ return :file_changed
+ end
+
+ # Required workaround, since SELinux policy prevents setsebool
+ # from writing to any files, even tmp, preventing the standard
+ # 'setsebool("...")' construct from working.
+
+ def execoutput (cmd)
+ output = ''
+ begin
+ execpipe(cmd) do |out|
+ output = out.readlines.join('').chomp!
+ end
+ rescue Puppet::ExecutionFailure
+ raise Puppet::ExecutionFailure, output.split("\n")[0]
+ end
+ return output
+ end
+end
diff --git a/lib/puppet/provider/selmodule/semodule.rb b/lib/puppet/provider/selmodule/semodule.rb
new file mode 100644
index 0000000..4981366
--- /dev/null
+++ b/lib/puppet/provider/selmodule/semodule.rb
@@ -0,0 +1,143 @@
+Puppet::Type.type(:selmodule).provide(:semodule) do
+ desc "Manage SELinux policy modules using the semodule binary."
+
+ commands :semodule => "/usr/sbin/semodule"
+
+ def create
+ begin
+ execoutput("#{command(:semodule)} --install #{selmod_name_to_filename}")
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not load policy module: %s" % [detail];
+ end
+ return :true
+ end
+
+ def destroy
+ begin
+ execoutput("#{command(:semodule)} --remove #{@resource[:name]}")
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not remove policy module: %s" % [detail];
+ end
+ end
+
+ def exists?
+ self.debug "Checking for module #{@resource[:name]}"
+ execpipe("#{command(:semodule)} --list") do |out|
+ out.each do |line|
+ if line =~ /#{@resource[:name]}\b/
+ return :true
+ end
+ end
+ end
+ return nil
+ end
+
+ def syncversion
+ self.debug "Checking syncversion on #{@resource[:name]}"
+
+ loadver = selmodversion_loaded
+
+ if(loadver) then
+ filever = selmodversion_file
+ if (filever == loadver) then
+ return :true
+ end
+ end
+ return :false
+ end
+
+ def syncversion= (dosync)
+ begin
+ execoutput("#{command(:semodule)} --upgrade #{selmod_name_to_filename}")
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not upgrade policy module: %s" % [detail];
+ end
+ end
+
+ # Helper functions
+
+ def execoutput (cmd)
+ output = ''
+ begin
+ execpipe(cmd) do |out|
+ output = out.readlines.join('').chomp!
+ end
+ rescue Puppet::ExecutionFailure
+ raise Puppet::ExecutionFailure, output.split("\n")[0]
+ end
+ return output
+ end
+
+ def selmod_name_to_filename
+ if @resource[:selmodulepath]
+ return @resource[:selmodulepath]
+ else
+ return "#{@resource[:selmoduledir]}/#{@resource[:name]}.pp"
+ end
+ end
+
+ def selmod_readnext (handle)
+ len = handle.read(4).unpack('L')[0]
+ return handle.read(len)
+ end
+
+ def selmodversion_file
+ magic = 0xF97CFF8F
+
+ filename = selmod_name_to_filename
+ mod = File.new(filename, "r")
+
+ (hdr, ver, numsec) = mod.read(12).unpack('LLL')
+
+ if hdr != magic
+ raise Puppet::Error, "Found #{hdr} instead of magic #{magic} in #{filename}"
+ end
+
+ if ver != 1
+ raise Puppet::Error, "Unknown policy file version #{ver} in #{filename}"
+ end
+
+ # Read through (and throw away) the file section offsets, and also
+ # the magic header for the first section.
+
+ mod.read((numsec + 1) * 4)
+
+ ## Section 1 should be "SE Linux Module"
+
+ selmod_readnext(mod)
+ selmod_readnext(mod)
+
+ # Skip past the section headers
+ mod.read(14)
+
+ # Module name
+ selmod_readnext(mod)
+
+ # At last! the version
+
+ v = selmod_readnext(mod)
+
+ self.debug "file version #{v}"
+ return v
+ end
+
+ def selmodversion_loaded
+ lines = ()
+ begin
+ execpipe("#{command(:semodule)} --list") do |output|
+ lines = output.readlines
+ lines.each do |line|
+ line.chomp!
+ bits = line.split
+ if bits[0] == @resource[:name] then
+ self.debug "load version #{bits[1]}"
+ return bits[1]
+ end
+ end
+ end
+ rescue Puppet::ExecutionFailure
+ raise Puppet::ExecutionFailure, "Could not list policy modules: %s" % [lines.join(' ').chomp!]
+ end
+ return nil
+ end
+end
diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb
index 2a5e61d..371571f 100644
--- a/lib/puppet/type/file.rb
+++ b/lib/puppet/type/file.rb
@@ -1157,4 +1157,5 @@ module Puppet
require 'puppet/type/file/group'
require 'puppet/type/file/mode'
require 'puppet/type/file/type'
+ require 'puppet/type/file/selcontext' # SELinux file context
end
diff --git a/lib/puppet/type/file/selcontext.rb b/lib/puppet/type/file/selcontext.rb
new file mode 100644
index 0000000..f366950
--- /dev/null
+++ b/lib/puppet/type/file/selcontext.rb
@@ -0,0 +1,96 @@
+# Manage SELinux context of files.
+#
+# This code actually manages three pieces of data in the context.
+#
+# [root at delenn files]# ls -dZ /
+# drwxr-xr-x root root system_u:object_r:root_t /
+#
+# The context of '/' here is 'system_u:object_r:root_t'. This is
+# three seperate fields:
+#
+# system_u is the user context
+# object_r is the role context
+# root_t is the type context
+#
+# All three of these fields are returned in a single string by the
+# output of the stat command, but set individually with the chcon
+# command. This allows the user to specify a subset of the three
+# values while leaving the others alone.
+#
+# See http://www.nsa.gov/selinux/ for complete docs on SELinux.
+
+module Puppet
+ class SELFileContext < Puppet::Property
+
+ def retrieve
+ unless @resource.stat(false)
+ return :absent
+ end
+ context = `stat -c %C #{@resource[:path]}`
+ context.chomp!
+ if context == "unlabeled"
+ return nil
+ end
+ unless context =~ /^[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/
+ raise Puppet::Error, "Invalid output from stat: #{context}"
+ end
+ bits = context.split(':')
+ ret = {
+ :seluser => bits[0],
+ :selrole => bits[1],
+ :seltype => bits[2]
+ }
+ return ret[name]
+ end
+
+ def sync
+ unless @resource.stat(false)
+ stat = @resource.stat(true)
+ unless stat
+ return nil
+ end
+ end
+
+ flag = ''
+
+ case name
+ when :seluser
+ flag = "-u"
+ when :selrole
+ flag = "-r"
+ when :seltype
+ flag = "-t"
+ else
+ raise Puppet::Error, "Invalid SELinux file context component: #{name}"
+ end
+
+ self.debug "Running chcon #{flag} #{@should} #{@resource[:path]}"
+ retval = system("chcon #{flag} #{@should} #{@resource[:path]}")
+ unless retval
+ error = Puppet::Error.new("failed to chcon %s" % [@resource[:path]])
+ raise error
+ end
+ return :file_changed
+ end
+ end
+
+ Puppet.type(:file).newproperty(:seluser, :parent => Puppet::SELFileContext) do
+ desc "What the SELinux User context of the file should be."
+
+ @event = :file_changed
+ end
+
+ Puppet.type(:file).newproperty(:selrole, :parent => Puppet::SELFileContext) do
+ desc "What the SELinux Role context of the file should be."
+
+ @event = :file_changed
+ end
+
+ Puppet.type(:file).newproperty(:seltype, :parent => Puppet::SELFileContext) do
+ desc "What the SELinux Type context of the file should be."
+
+ @event = :file_changed
+ end
+
+end
+
diff --git a/lib/puppet/type/selboolean.rb b/lib/puppet/type/selboolean.rb
new file mode 100644
index 0000000..d12dd3b
--- /dev/null
+++ b/lib/puppet/type/selboolean.rb
@@ -0,0 +1,29 @@
+#
+# Simple module for manageing SELinux booleans
+#
+
+module Puppet
+ newtype(:selboolean) do
+ @doc = "Enable or disable SELinux booleans."
+
+ newparam(:name) do
+ desc "The name of the SELinux boolean to be managed."
+ isnamevar
+ end
+
+ newproperty(:value) do
+ desc "Whether the the SELinux boolean should be enabled or disabled. Possible values are ``on`` or ``off``."
+ newvalue(:on)
+ newvalue(:off)
+ end
+
+ newparam(:persistent) do
+ desc "If set true, SELinux booleans will be written to disk and persist accross reboots."
+
+ defaultto :false
+ newvalues(:true, :false)
+ end
+
+ end
+end
+
diff --git a/lib/puppet/type/selmodule.rb b/lib/puppet/type/selmodule.rb
new file mode 100644
index 0000000..1f02912
--- /dev/null
+++ b/lib/puppet/type/selmodule.rb
@@ -0,0 +1,50 @@
+#
+# Simple module for manageing SELinux policy modules
+#
+
+Puppet::Type.newtype(:selmodule) do
+ @doc = "Enable or disable SELinux policy modules."
+
+ ensurable
+
+ newparam(:name) do
+ desc "The name of the SELinux policy to be managed."
+ isnamevar
+ end
+
+ newparam(:selmoduledir) do
+
+ desc "The directory to look for the compiled pp module file in.
+ Currently defaults to /usr/share/selinux/targeted"
+
+ 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."
+
+ end
+
+ newproperty(:syncversion) do
+
+ 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
+ that will be made is if the policy is loaded at all or not."
+
+ newvalue(:true)
+ newvalue(:false)
+ end
+
+ autorequire(:file) do
+ if self[:selmodulepath]
+ [self[:selmodulepath]]
+ else
+ ["#{self[:selmoduledir]}/#{self[:name]}.pp"]
+ end
+ end
+end
+
diff --git a/spec/unit/other/selinux.rb b/spec/unit/other/selinux.rb
new file mode 100644
index 0000000..3a07e09
--- /dev/null
+++ b/spec/unit/other/selinux.rb
@@ -0,0 +1,79 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/type/selboolean'
+require 'puppet/type/selmodule'
+
+describe Puppet.type(:file), " when manipulating file contexts" do
+ before :each do
+ @file = Puppet::Type::File.create(
+ :name => "/tmp/foo",
+ :ensure => "file",
+ :seluser => "user_u",
+ :selrole => "role_r",
+ :seltype => "type_t" )
+ end
+ it "should use :seluser to get/set an SELinux user file context attribute" do
+ @file.property(:seluser).should == "user_u"
+ end
+ it "should use :selrole to get/set an SELinux role file context attribute" do
+ @file.property(:selrole).should == "role_r"
+ end
+ it "should use :seltype to get/set an SELinux user file context attribute" do
+ @file.property(:seltype).should == "type_t"
+ end
+end
+
+describe Puppet.type(:selboolean), " when manipulating booleans" do
+ before :each do
+ @bool = Puppet::Type::Selboolean.create(
+ :name => "foo",
+ :value => "on",
+ :persistent => true )
+ end
+ it "should be able to access :name" do
+ @bool[:name].should == "foo"
+ end
+ it "should be able to access :value" do
+ @bool.property(:value).should == :on
+ end
+ it "should set :value to off" do
+ @bool[:value] = :off
+ @bool.property(:value).should == :off
+ end
+ it "should be able to access :persistent" do
+ @bool[:persistent].should == :true
+ end
+ it "should set :persistent to false" do
+ @bool[:persistent] = false
+ @bool[:persistent].should == :false
+ end
+end
+
+describe Puppet.type(:selmodule), " when checking policy modules" do
+ before :each do
+ @module = Puppet::Type::Selmodule.create(
+ :name => "foo",
+ :selmoduledir => "/some/path",
+ :selmodulepath => "/some/path/foo.pp",
+ :syncversion => true)
+ end
+ it "should be able to access :name" do
+ @module[:name].should == "foo"
+ end
+ it "should be able to access :selmoduledir" do
+ @module[:selmoduledir].should == "/some/path"
+ end
+ it "should be able to access :selmodulepath" do
+ @module[:selmodulepath].should == "/some/path/foo.pp"
+ end
+ it "should be able to access :syncversion" do
+ @module.property(:syncversion).should == :true
+ end
+ it "should set the syncversion value to false" do
+ @module[:syncversion] = :false
+ @module.property(:syncversion).should == :false
+ end
+end
+
--
Puppet packaging for Debian
More information about the Pkg-puppet-devel
mailing list