Skip to content

Commit

Permalink
Load system policy contexts
Browse files Browse the repository at this point in the history
This change prefetches the system policy contexts. This means that if
the system policy already exists for /var/spool/squid(/.*)? then it
won't attempt to override it when the specification matches. It does
still allow modifications if for some reason the base policy is
incorrect. Purging of all local contexts is also still possible.
  • Loading branch information
ekohl committed Jun 14, 2019
1 parent e53bcfb commit f7db44c
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 25 deletions.
31 changes: 19 additions & 12 deletions lib/puppet/provider/selinux_fcontext/semanage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,29 @@ def self.parse_fcontext_lines(lines)
ret
end

def self.parse_fcontext_file(path)
return [] unless File.exist?(path)
parse_fcontext_lines(File.readlines(path))
end

def self.instances
# With fcontext, we only need to care about local customisations as they
# should never conflict with system policy
# Old semanage fails with --locallist, use -C
local_fcs = Selinux.selinux_file_context_local_path
if File.exist? local_fcs
parse_fcontext_lines(File.readlines(local_fcs))
else
# no file, no local contexts
[]
end
parse_fcontext_file(Selinux.selinux_file_context_local_path)
end

def self.system_policy_instances
parse_fcontext_file(Selinux.selinux_file_context_path)
end

def self.prefetch(resources)
# is there a better way to do this? map port/protocol pairs to the provider regardless of the title
# and make sure all system resources have ensure => :present so that we don't try to remove them
# This loads resources from built in instances. These are part of the
# system policy. That means we can't modify them, but we should still be
# aware of them.
system_policy_instances.each do |provider|
resource = resources[provider.name]
resource.provider = provider if resource
end

# These are the local overrides. We prefer them over the system policy.
instances.each do |provider|
resource = resources[provider.name]
resource.provider = provider if resource
Expand Down
69 changes: 56 additions & 13 deletions spec/unit/puppet/provider/selinux_fcontext/semanage_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ module Selinux
def selinux_file_context_local_path
'spec_dummy'
end

def selinux_file_context_path
'spec_policy_dummy'
end
end

semanage_provider = Puppet::Type.type(:selinux_fcontext).provider(:semanage)
Expand All @@ -19,6 +23,12 @@ def selinux_file_context_local_path
/something/else -s <<none>>
EOS

fcontexts_system = <<-EOS
# This file is auto-generated by libsemanage
# Do not edit directly.
/var/log system_u:object_r:var_log_t:s0
EOS

describe semanage_provider do
on_supported_os.each do |os, facts|
context "on #{os}" do
Expand Down Expand Up @@ -93,26 +103,35 @@ def selinux_file_context_local_path
end
context 'With resources differing from the catalog' do
let(:resources) do
return { '/var/lib/mydir_s' => fcontext.new(
name: '/var/lib/mydir_s',
pathspec: '/var/lib/mydir',
file_type: 's',
seltype: 'some_type_t'
),
'/foobar_a' => fcontext.new(
name: '/foobar_a',
file_type: 'a',
pathspec: '/foobar',
seltype: 'mytype_t',
seluser: 'myuser_u'
) }
return {
# This one should be loaded from the system policy
'/var/log_a' => fcontext.new(
name: '/var/log_a'
),
'/var/lib/mydir_s' => fcontext.new(
name: '/var/lib/mydir_s',
pathspec: '/var/lib/mydir',
file_type: 's',
seltype: 'some_type_t'
),
'/foobar_a' => fcontext.new(
name: '/foobar_a',
file_type: 'a',
pathspec: '/foobar',
seltype: 'mytype_t',
seluser: 'myuser_u'
)
}
end

before do
# prefetch should find the provider parsed from this:
Selinux.expects(:selinux_file_context_local_path).returns('spec_dummy')
File.expects(:exist?).with('spec_dummy').returns(true)
File.expects(:readlines).with('spec_dummy').returns(fcontexts_local.split("\n"))
Selinux.expects(:selinux_file_context_path).returns('spec_policy_dummy')
File.expects(:exist?).with('spec_policy_dummy').returns(true)
File.expects(:readlines).with('spec_policy_dummy').returns(fcontexts_system.split("\n"))
semanage_provider.prefetch(resources)
end
it 'finds provider for /foobar' do
Expand All @@ -138,6 +157,30 @@ def selinux_file_context_local_path
described_class.expects(:semanage).with('fcontext', '-m', '-s', 'unconfined_u', '-t', 'bin_t', '-f', 'a', '/foobar')
p.seluser = 'unconfined_u'
end

it 'finds provider for /var/log' do
p = resources['/var/log_a'].provider
expect(p).not_to eq(nil)
end
context 'has the correct attributes from the system policy' do
let(:p) { resources['/var/log_a'].provider }

it { expect(p.name).to eq('/var/log_a') }
it { expect(p.file_type).to eq('a') }
it { expect(p.seltype).to eq('var_log_t') }
it { expect(p.selrole).to eq('object_r') }
it { expect(p.seluser).to eq('system_u') }
end
it 'can change seltype' do
p = resources['/var/log_a'].provider
described_class.expects(:semanage).with('fcontext', '-m', '-t', 'new_type_t', '-f', 'a', '/var/log')
p.seltype = 'new_type_t'
end
it 'can change seluser' do
p = resources['/var/log_a'].provider
described_class.expects(:semanage).with('fcontext', '-m', '-s', 'unconfined_u', '-t', 'var_log_t', '-f', 'a', '/var/log')
p.seluser = 'unconfined_u'
end
end
end
end
Expand Down

0 comments on commit f7db44c

Please sign in to comment.