-
-
Notifications
You must be signed in to change notification settings - Fork 148
/
module.pp
190 lines (171 loc) · 6.77 KB
/
module.pp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# This class will either install or uninstall a SELinux module from a running system.
# This module allows an admin to keep .te files in text form in a repository, while
# allowing the system to compile and manage SELinux modules.
#
# Concepts incorporated from:
# http://stuckinadoloop.wordpress.com/2011/06/15/puppet-managed-deployment-of-selinux-modules/
#
# @summary Manage a SELinux module on a running system
#
# @example compile and load the apache module - does not require make or the policy
# devel package
# selinux::module{ 'apache':
# ensure => 'present',
# source_te => 'puppet:///modules/selinux/apache.te',
# builder => 'simple'
# }
#
# @example compile a module the refpolicy way. It will install the policy devel and
# dependent packages like make.
# selinux::module{ 'mymodule':
# ensure => 'present',
# source_te => 'puppet:///modules/profile/selinux/mymodule.te',
# source_fc => 'puppet:///modules/profile/selinux/mymodule.fc',
# source_if => 'puppet:///modules/profile/selinux/mymodule.if',
# builder => 'refpolicy'
# }
#
# @example compile and load a module from inline content
# $content = @("END")
# policy_module(zabbix_fix, 0.1)
# require {
# type zabbix_t;
# type unreserved_port_t;
# class tcp_socket name_connect;
# }
# allow zabbix_t unreserved_port_t:tcp_socket name_connect;
# | END
# selinux::module{ 'zabbix_fix':
# ensure => 'present',
# content_te => $content,
# builder => 'simple'
# }
#
# @param ensure present or absent
# @param source_pp the source file (either a puppet URI or local file) of a pre-compiled SELinux policy package.
# Mutually excludsive with using source files.
# @param source_te the source file (either a puppet URI or local file) of the SELinux .te file
# @param source_fc the source file (either a puppet URI or local file) of the SELinux .fc file
# @param source_if the source file (either a puppet URI or local file) of the SELinux .if file
# @param content_te content of the SELinux .te file
# @param content_fc content of the SELinux .fc file
# @param content_if content of the SELinux .if file
# @param builder either 'simple' or 'refpolicy'. The simple builder attempts to use checkmodule
# to build the module, whereas 'refpolicy' uses the refpolicy framework, but requires 'make'
define selinux::module (
Optional[String] $source_pp = undef,
Optional[String] $source_te = undef,
Optional[String] $source_fc = undef,
Optional[String] $source_if = undef,
Optional[String] $content_te = undef,
Optional[String] $content_fc = undef,
Optional[String] $content_if = undef,
Enum['absent', 'present'] $ensure = 'present',
Optional[Enum['simple', 'refpolicy']] $builder = undef,
) {
include selinux
require selinux::build
$_builder = pick($builder, $selinux::default_builder, 'none')
if $_builder == 'refpolicy' {
require selinux::refpolicy_package
}
if ($builder == 'simple' and ($source_if != undef or $content_if != undef)) {
fail("The simple builder does not support the 'source_if' parameter")
}
$module_dir = $selinux::build::module_build_dir
$module_file = "${module_dir}/${title}"
$build_command = $_builder ? {
'simple' => shellquote($selinux::build::module_build_simple, $title, $module_dir),
'refpolicy' => shellquote('make', '-f', $selinux::refpolicy_makefile, "${title}.pp"),
'none' => undef
}
Anchor['selinux::module pre']
-> Selinux::Module[$title]
-> Anchor['selinux::module post']
if $facts['os']['selinux']['enabled'] {
$has_source = (pick($source_te, $source_fc, $source_if, $content_te, $content_fc, $content_if, false) != false)
if $has_source and $build_command == undef {
fail('No builder or default builder specified')
}
if $has_source and $source_pp != undef {
fail('Specifying source files and a pre-compiled policy package are mutually exclusive options')
}
if $has_source and $ensure == 'present' {
file { "${module_file}.te":
ensure => 'file',
source => $source_te,
content => $content_te,
notify => Exec["clean-module-${title}"],
}
$content_fc_real = $content_fc ? { undef => $source_fc ? { undef => '', default => undef }, default => $content_fc }
file { "${module_file}.fc":
ensure => 'file',
source => $source_fc,
content => $content_fc_real,
notify => Exec["clean-module-${title}"],
}
$content_if_real = $content_if ? { undef => $source_if ? { undef => '', default => undef }, default => $content_if }
file { "${module_file}.if":
ensure => 'file',
source => $source_if,
content => $content_if_real,
notify => Exec["clean-module-${title}"],
}
# ensure it doesn't get purged if it exists
file { "${module_file}.pp": selinux_ignore_defaults => true }
exec { "clean-module-${title}":
path => '/bin:/usr/bin',
cwd => $module_dir,
command => "rm -f '${module_file}.pp' '${module_file}.loaded'",
refreshonly => true,
notify => Exec["build-module-${title}"],
}
exec { "build-module-${title}":
path => '/bin:/usr/bin',
cwd => $module_dir,
command => "${build_command} || (rm -f ${module_file}.pp ${module_file}.loaded && exit 1)",
creates => "${module_file}.pp",
notify => Exec["install-module-${title}"],
}
$install = true
} elsif $source_pp != undef and $ensure == 'present' {
file { "${module_file}.pp":
ensure => 'file',
source => $source_pp,
notify => Exec["clean-module-${title}"],
}
exec { "clean-module-${title}":
path => '/bin:/usr/bin',
cwd => $module_dir,
command => "rm -f '${module_file}.loaded'",
refreshonly => true,
notify => Exec["install-module-${title}"],
}
$install = true
} else {
# no source and no .pp, just do plain selmodule {$title:}
$install = false
}
if $install {
# we need to install the module manually because selmodule is kind of dumb. It ends up
# working fine, though.
exec { "install-module-${title}":
path => '/sbin:/usr/sbin:/bin:/usr/bin',
cwd => $module_dir,
command => "semodule -i ${module_file}.pp && touch ${module_file}.loaded",
creates => "${module_file}.loaded",
before => Selmodule[$title],
}
# ensure it doesn't get purged if it exists
file { "${module_file}.loaded": }
}
$module_path = ($has_source or $source_pp != undef) ? {
true => "${module_file}.pp",
false => undef
}
selmodule { $title:
ensure => $ensure,
selmodulepath => $module_path,
}
}
}