diff options
Diffstat (limited to 'dynamic-layers/meta-perl/recipes-security/bastille/files/ServiceAdmin.pm')
-rw-r--r-- | dynamic-layers/meta-perl/recipes-security/bastille/files/ServiceAdmin.pm | 690 |
1 files changed, 690 insertions, 0 deletions
diff --git a/dynamic-layers/meta-perl/recipes-security/bastille/files/ServiceAdmin.pm b/dynamic-layers/meta-perl/recipes-security/bastille/files/ServiceAdmin.pm new file mode 100644 index 0000000..879223a --- /dev/null +++ b/dynamic-layers/meta-perl/recipes-security/bastille/files/ServiceAdmin.pm | |||
@@ -0,0 +1,690 @@ | |||
1 | package Bastille::API::ServiceAdmin; | ||
2 | use strict; | ||
3 | |||
4 | use Bastille::API; | ||
5 | |||
6 | use Bastille::API::HPSpecific; | ||
7 | use Bastille::API::FileContent; | ||
8 | |||
9 | require Exporter; | ||
10 | our @ISA = qw(Exporter); | ||
11 | our @EXPORT_OK = qw( | ||
12 | B_chkconfig_on | ||
13 | B_chkconfig_off | ||
14 | B_service_start | ||
15 | B_service_stop | ||
16 | B_service_restart | ||
17 | B_is_service_off | ||
18 | checkServiceOnLinux | ||
19 | remoteServiceCheck | ||
20 | remoteNISPlusServiceCheck | ||
21 | B_create_nsswitch_file | ||
22 | ); | ||
23 | our @EXPORT = @EXPORT_OK; | ||
24 | |||
25 | |||
26 | ####### | ||
27 | # &B_chkconfig_on and &B_chkconfig_off() are great for systems that didn't use | ||
28 | # a more modern init system. This is a bit of a problem on Fedora, though, | ||
29 | # which used upstart from Fedora 9 to Fedora 14, then switched to a new | ||
30 | # Red Hat-created system called systemd for Fedora 15 and 16 (so far). | ||
31 | # OpenSUSE also moved to systemd, starting with 12.1. Version 11.4 did not | ||
32 | # use systemd. | ||
33 | # It is also a problem on Ubuntu, starting at version 6.10, where they also | ||
34 | # used upstart. | ||
35 | ##### | ||
36 | |||
37 | |||
38 | |||
39 | |||
40 | ########################################################################### | ||
41 | # &B_chkconfig_on ($daemon_name) creates the symbolic links that are | ||
42 | # named in the "# chkconfig: ___ _ _ " portion of the init.d files. We | ||
43 | # need this utility, in place of the distro's chkconfig, because of both | ||
44 | # our need to add revert functionality and our need to harden distros that | ||
45 | # are not mounted on /. | ||
46 | # | ||
47 | # It uses the following global variables to find the links and the init | ||
48 | # scripts, respectively: | ||
49 | # | ||
50 | # &getGlobal('DIR', "rcd") -- directory where the rc_.d subdirs can be found | ||
51 | # &getGlobal('DIR', "initd") -- directory the rc_.d directories link to | ||
52 | # | ||
53 | # Here an example of where you might use this: | ||
54 | # | ||
55 | # You'd like to tell the system to run the firewall at boot: | ||
56 | # B_chkconfig_on("bastille-firewall") | ||
57 | # | ||
58 | ########################################################################### | ||
59 | |||
60 | # PW: Blech. Copied B_chkconfig_off() and changed a few things, | ||
61 | # then changed a few more things.... | ||
62 | |||
63 | sub B_chkconfig_on { | ||
64 | |||
65 | my $startup_script=$_[0]; | ||
66 | my $retval=1; | ||
67 | |||
68 | my $chkconfig_line; | ||
69 | my ($runlevelinfo,@runlevels); | ||
70 | my ($start_order,$stop_order,$filetolink); | ||
71 | |||
72 | &B_log("ACTION","# chkconfig_on enabling $startup_script\n"); | ||
73 | |||
74 | # In Debian system there is no chkconfig script, run levels are checked | ||
75 | # one by one (jfs) | ||
76 | if (&GetDistro =~/^DB.*/) { | ||
77 | $filetolink = &getGlobal('DIR', "initd") . "/$startup_script"; | ||
78 | if (-x $filetolink) | ||
79 | { | ||
80 | foreach my $level ("0","1","2","3","4","5","6" ) { | ||
81 | my $link = ''; | ||
82 | $link = &getGlobal('DIR', "rcd") . "/rc" . "$level" . ".d/K50" . "$startup_script"; | ||
83 | $retval=symlink($filetolink,$link); | ||
84 | } | ||
85 | } | ||
86 | return $retval; | ||
87 | } | ||
88 | # | ||
89 | # On SUSE, chkconfig-based rc scripts have been replaced with a whole different | ||
90 | # system. chkconfig on SUSE is actually a shell script that does some stuff and then | ||
91 | # calls insserv, their replacement. | ||
92 | # | ||
93 | |||
94 | if (&GetDistro =~ /^SE/) { | ||
95 | # only try to chkconfig on if init script is found | ||
96 | if ( -e (&getGlobal('DIR', "initd") . "/$startup_script") ) { | ||
97 | $chkconfig_line=&getGlobal('BIN','chkconfig'); | ||
98 | &B_System("$chkconfig_line $startup_script on", "$chkconfig_line $startup_script off"); | ||
99 | # chkconfig doesn't take affect until reboot, need to restart service also | ||
100 | B_service_restart("$startup_script"); | ||
101 | return 1; #success | ||
102 | } | ||
103 | return 0; #failure | ||
104 | } | ||
105 | |||
106 | # | ||
107 | # Run through the init script looking for the chkconfig line... | ||
108 | # | ||
109 | $retval = open CHKCONFIG,&getGlobal('DIR', "initd") . "/$startup_script"; | ||
110 | unless ($retval) { | ||
111 | &B_log("ACTION","# Didn't chkconfig_on $startup_script because we couldn't open " . &getGlobal('DIR', "initd") . "/$startup_script\n"); | ||
112 | } | ||
113 | else { | ||
114 | |||
115 | READ_LOOP: | ||
116 | while (my $line=<CHKCONFIG>) { | ||
117 | |||
118 | # We're looking for lines like this one: | ||
119 | # # chkconfig: 2345 10 90 | ||
120 | # OR this | ||
121 | # # chkconfig: - 10 90 | ||
122 | |||
123 | if ($line =~ /^#\s*chkconfig:\s*([-\d]+)\s*(\d+)\s*(\d+)/ ) { | ||
124 | $runlevelinfo = $1; | ||
125 | $start_order = $2; | ||
126 | $stop_order = $3; | ||
127 | # handle a run levels arg of '-' | ||
128 | if ( $runlevelinfo eq '-' ) { | ||
129 | &B_log("ACTION","chkconfig_on saw '-' for run levels for \"$startup_script\", is defaulting to levels 3,4,5\n"); | ||
130 | $runlevelinfo = '345'; | ||
131 | } | ||
132 | @runlevels = split(//,$runlevelinfo); | ||
133 | # make sure the orders have 2 digits | ||
134 | $start_order =~ s/^(\d)$/0$1/; | ||
135 | $stop_order =~ s/^(\d)$/0$1/; | ||
136 | last READ_LOOP; | ||
137 | } | ||
138 | } | ||
139 | close CHKCONFIG; | ||
140 | |||
141 | # Do we have what we need? | ||
142 | if ( (scalar(@runlevels) < 1) || (! $start_order =~ /^\d{2}$/) || (! $stop_order =~ /^\d{2}$/) ) { | ||
143 | # problem | ||
144 | &B_log("ERROR","# B_chkconfig_on $startup_script failed -- no valid run level/start/stop info found\n"); | ||
145 | return(-1); | ||
146 | } | ||
147 | |||
148 | # Now, run through creating symlinks... | ||
149 | &B_log("ACTION","# chkconfig_on will use run levels ".join(",",@runlevels)." for \"$startup_script\" with S order $start_order and K order $stop_order\n"); | ||
150 | |||
151 | $retval=0; | ||
152 | # BUG: we really ought to readdir() on &getGlobal('DIR', "rcd") to get all levels | ||
153 | foreach my $level ( "0","1","2","3","4","5","6" ) { | ||
154 | my $link = ''; | ||
155 | # we make K links in run levels not specified in the chkconfig line | ||
156 | $link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/K$stop_order" . $startup_script; | ||
157 | my $klink = $link; | ||
158 | # now we see if this is a specified run level; if so, make an S link | ||
159 | foreach my $markedlevel ( @runlevels ) { | ||
160 | if ( $level == $markedlevel) { | ||
161 | $link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/S$start_order" . $startup_script; | ||
162 | } | ||
163 | } | ||
164 | my $target = &getGlobal('DIR', "initd") ."/" . $startup_script; | ||
165 | my $local_return; | ||
166 | |||
167 | if ( (-e "$klink") && ($klink ne $link) ) { | ||
168 | # there's a K link, but this level needs an S link | ||
169 | unless ($GLOBAL_LOGONLY) { | ||
170 | $local_return = unlink("$klink"); | ||
171 | if ( ! $local_return ) { | ||
172 | # unlinking old, bad $klink failed | ||
173 | &B_log("ERROR","Unlinking $klink failed\n"); | ||
174 | } else { | ||
175 | &B_log("ACTION","Removed link $klink\n"); | ||
176 | # If we removed the link, add a link command to the revert file | ||
177 | &B_revert_log (&getGlobal('BIN','ln') . " -s $target $klink\n"); | ||
178 | } # close what to do if unlink works | ||
179 | } # if not GLOBAL_LOGONLY | ||
180 | } # if $klink exists and ne $link | ||
181 | |||
182 | # OK, we've disposed of any old K links, make what we need | ||
183 | if ( (! ( -e "$link" )) && ($link ne '') ) { | ||
184 | # link doesn't exist and the start/stop number is OK; make it | ||
185 | unless ($GLOBAL_LOGONLY) { | ||
186 | # create the link | ||
187 | $local_return = &B_symlink($target,$link); | ||
188 | if ($local_return) { | ||
189 | $retval++; | ||
190 | &B_log("ACTION","Created link $link\n"); | ||
191 | } else { | ||
192 | &B_log("ERROR","Couldn't create $link when trying to chkconfig on $startup_script\n"); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | } # link doesn't exist | ||
197 | } # foreach level | ||
198 | |||
199 | } | ||
200 | |||
201 | if ($retval < @runlevels) { | ||
202 | $retval=0; | ||
203 | } | ||
204 | |||
205 | $retval; | ||
206 | |||
207 | } | ||
208 | |||
209 | |||
210 | ########################################################################### | ||
211 | # &B_chkconfig_off ($daemon_name) deletes the symbolic links that are | ||
212 | # named in the "# chkconfig: ___ _ _ " portion of the init.d files. We | ||
213 | # need this utility, in place of the distro's chkconfig, because of both | ||
214 | # our need to add revert functionality and our need to harden distros that | ||
215 | # are not mounted on /. | ||
216 | # | ||
217 | # chkconfig allows for a REVERT of its work by writing to an executable | ||
218 | # file &getGlobal('BFILE', "removed-symlinks"). | ||
219 | # | ||
220 | # It uses the following global variables to find the links and the init | ||
221 | # scripts, respectively: | ||
222 | # | ||
223 | # &getGlobal('DIR', "rcd") -- directory where the rc_.d subdirs can be found | ||
224 | # &getGlobal('DIR', "initd") -- directory the rc_.d directories link to | ||
225 | # | ||
226 | # Here an example of where you might use this: | ||
227 | # | ||
228 | # You'd like to tell stop running sendmail in daemon mode on boot: | ||
229 | # B_chkconfig_off("sendmail") | ||
230 | # | ||
231 | ########################################################################### | ||
232 | |||
233 | |||
234 | |||
235 | sub B_chkconfig_off { | ||
236 | |||
237 | my $startup_script=$_[0]; | ||
238 | my $retval=1; | ||
239 | |||
240 | my $chkconfig_line; | ||
241 | my @runlevels; | ||
242 | my ($start_order,$stop_order,$filetolink); | ||
243 | |||
244 | if (&GetDistro =~/^DB.*/) { | ||
245 | $filetolink = &getGlobal('DIR', "initd") . "/$startup_script"; | ||
246 | if (-x $filetolink) | ||
247 | { | ||
248 | # Three ways to do this in Debian: | ||
249 | # 1.- have the initd script set to 600 mode | ||
250 | # 2.- Remove the links in rcd (re-installing the package | ||
251 | # will break it) | ||
252 | # 3.- Use update-rc.d --remove (same as 2.) | ||
253 | # (jfs) | ||
254 | &B_chmod(0600,$filetolink); | ||
255 | $retval=6; | ||
256 | |||
257 | # The second option | ||
258 | #foreach my $level ("0","1","2","3","4","5","6" ) { | ||
259 | #my $link = ''; | ||
260 | #$link = &getGlobal('DIR', "rcd") . "/rc" . "$level" . ".d/K50" . "$startup_script"; | ||
261 | #unlink($link); | ||
262 | #} | ||
263 | } | ||
264 | } | ||
265 | |||
266 | # | ||
267 | # On SUSE, chkconfig-based rc scripts have been replaced with a whole different | ||
268 | # system. chkconfig on SUSE is actually a shell script that does some stuff and then | ||
269 | # calls insserv, their replacement. | ||
270 | # | ||
271 | elsif (&GetDistro =~ /^SE/) { | ||
272 | # only try to chkconfig off if init script is found | ||
273 | if ( -e (&getGlobal('DIR', "initd") . "/$startup_script") ) { | ||
274 | $chkconfig_line=&getGlobal('BIN','chkconfig'); | ||
275 | &B_System("$chkconfig_line $startup_script on", "$chkconfig_line $startup_script off"); | ||
276 | # chkconfig doesn't take affect until reboot, need to stop service | ||
277 | # since expectation is that the daemons are disabled even without a reboot | ||
278 | B_service_stop("$startup_script"); | ||
279 | return 1; #success | ||
280 | } | ||
281 | return 0; #failure | ||
282 | } | ||
283 | else { | ||
284 | |||
285 | # Run through the init script looking for the chkconfig line... | ||
286 | |||
287 | |||
288 | $retval = open CHKCONFIG,&getGlobal('DIR', "initd") . "/$startup_script"; | ||
289 | unless ($retval) { | ||
290 | &B_log("ACTION","Didn't chkconfig_off $startup_script because we couldn't open " . &getGlobal('DIR', "initd") . "/$startup_script\n"); | ||
291 | } | ||
292 | else { | ||
293 | |||
294 | READ_LOOP: | ||
295 | while (my $line=<CHKCONFIG>) { | ||
296 | |||
297 | # We're looking for lines like this one: | ||
298 | # # chkconfig: 2345 10 90 | ||
299 | |||
300 | if ($line =~ /^#\s*chkconfig:\s*([-\d]+)\s*(\d+)\s*(\d+)/ ) { | ||
301 | @runlevels=split //,$1; | ||
302 | $start_order=$2; | ||
303 | $stop_order=$3; | ||
304 | |||
305 | |||
306 | # Change single digit run levels to double digit -- otherwise, | ||
307 | # the alphabetic ordering chkconfig depends on fails. | ||
308 | if ($start_order =~ /^\d$/ ) { | ||
309 | $start_order = "0" . $start_order; | ||
310 | &B_log("ACTION","chkconfig_off converted start order to $start_order\n"); | ||
311 | } | ||
312 | if ($stop_order =~ /^\d$/ ) { | ||
313 | $stop_order = "0" . $stop_order; | ||
314 | &B_log("ACTION","chkconfig_off converted stop order to $stop_order\n"); | ||
315 | } | ||
316 | |||
317 | last READ_LOOP; | ||
318 | } | ||
319 | } | ||
320 | close CHKCONFIG; | ||
321 | |||
322 | # If we never found a chkconfig line, can we just run through all 5 | ||
323 | # rcX.d dirs from 1 to 5...? | ||
324 | |||
325 | # unless ( $start_order and $stop_order ) { | ||
326 | # @runlevels=("1","2","3","4","5"); | ||
327 | # $start_order = "*"; $stop_order="*"; | ||
328 | # } | ||
329 | |||
330 | # Now, run through removing symlinks... | ||
331 | |||
332 | |||
333 | |||
334 | $retval=0; | ||
335 | |||
336 | # Handle the special case that the run level specified is solely "-" | ||
337 | if ($runlevels[0] =~ /-/) { | ||
338 | @runlevels = ( "0","1","2","3","4","5","6" ); | ||
339 | } | ||
340 | |||
341 | foreach my $level ( @runlevels ) { | ||
342 | my $link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/S$start_order" . $startup_script; | ||
343 | my $new_link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/K$stop_order" . $startup_script; | ||
344 | my $target = &getGlobal('DIR', "initd") ."/" . $startup_script; | ||
345 | my $local_return; | ||
346 | |||
347 | |||
348 | # Replace the S__ link in this level with a K__ link. | ||
349 | if ( -e $link ) { | ||
350 | unless ($GLOBAL_LOGONLY) { | ||
351 | $local_return=unlink $link; | ||
352 | if ($local_return) { | ||
353 | $local_return=symlink $target,$new_link; | ||
354 | unless ($local_return) { | ||
355 | &B_log("ERROR","Linking $target to $new_link failed.\n"); | ||
356 | } | ||
357 | } | ||
358 | else { # unlinking failed | ||
359 | &B_log("ERROR","Unlinking $link failed\n"); | ||
360 | } | ||
361 | |||
362 | } | ||
363 | if ($local_return) { | ||
364 | $retval++; | ||
365 | &B_log("ACTION","Removed link $link\n"); | ||
366 | |||
367 | # | ||
368 | # If we removed the link, add a link command to the revert file | ||
369 | # Write out the revert information for recreating the S__ | ||
370 | # symlink and deleting the K__ symlink. | ||
371 | &B_revert_log(&getGlobal('BIN',"ln") . " -s $target $link\n"); | ||
372 | &B_revert_log(&getGlobal('BIN',"rm") . " -f $new_link\n"); | ||
373 | } | ||
374 | else { | ||
375 | &B_log("ERROR","B_chkconfig_off $startup_script failed\n"); | ||
376 | } | ||
377 | |||
378 | } | ||
379 | } # foreach | ||
380 | |||
381 | } # else-unless | ||
382 | |||
383 | } # else-DB | ||
384 | if ($retval < @runlevels) { | ||
385 | $retval=0; | ||
386 | } | ||
387 | |||
388 | $retval; | ||
389 | |||
390 | } | ||
391 | |||
392 | |||
393 | ########################################################################### | ||
394 | # &B_service_start ($daemon_name) | ||
395 | # Starts service on RedHat/SUSE-based Linux distributions which have the | ||
396 | # service command: | ||
397 | # | ||
398 | # service $daemon_name start | ||
399 | # | ||
400 | # Other Linux distros that also support this method of starting | ||
401 | # services can be added to use this function. | ||
402 | # | ||
403 | # Here an example of where you might use this: | ||
404 | # | ||
405 | # You'd like to tell the system to start the vsftpd daemon: | ||
406 | # &B_service_start("vsftpd") | ||
407 | # | ||
408 | # Uses &B_System in HP_API.pm | ||
409 | # To match how the &B_System command works this method: | ||
410 | # returns 1 on success | ||
411 | # returns 0 on failure | ||
412 | ########################################################################### | ||
413 | |||
414 | sub B_service_start { | ||
415 | |||
416 | my $daemon=$_[0]; | ||
417 | |||
418 | if ( (&GetDistro !~ /^SE/) and (&GetDistro !~ /^RH/) and | ||
419 | (&GetDistro !~ /^RHFC/) and (&GetDistro !~ /^MN/) ) { | ||
420 | &B_log("ERROR","Tried to call service_start on a system lacking a service command! Internal Bastille error."); | ||
421 | return undef; | ||
422 | } | ||
423 | |||
424 | # only start service if init script is found | ||
425 | if ( -e (&getGlobal('DIR', 'initd') . "/$daemon") ) { | ||
426 | &B_log("ACTION","# service_start enabling $daemon\n"); | ||
427 | |||
428 | my $service_cmd=&getGlobal('BIN', 'service'); | ||
429 | if ($service_cmd) { | ||
430 | # Start the service, | ||
431 | # Also provide &B_System revert command | ||
432 | |||
433 | return (&B_System("$service_cmd $daemon start", | ||
434 | "$service_cmd $daemon stop")); | ||
435 | } | ||
436 | } | ||
437 | |||
438 | # init script not found, do not try to start, return failure | ||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | ########################################################################### | ||
443 | # &B_service_stop ($daemon_name) | ||
444 | # Stops service on RedHat/SUSE-based Linux distributions which have the | ||
445 | # service command: | ||
446 | # | ||
447 | # service $daemon_name stop | ||
448 | # | ||
449 | # Other Linux distros that also support this method of starting | ||
450 | # services can be added to use this function. | ||
451 | # Stops service. | ||
452 | # | ||
453 | # | ||
454 | # Here an example of where you might use this: | ||
455 | # | ||
456 | # You'd like to tell the system to stop the vsftpd daemon: | ||
457 | # &B_service_stop("vsftpd") | ||
458 | # | ||
459 | # Uses &B_System in HP_API.pm | ||
460 | # To match how the &B_System command works this method: | ||
461 | # returns 1 on success | ||
462 | # returns 0 on failure | ||
463 | ########################################################################### | ||
464 | |||
465 | sub B_service_stop { | ||
466 | |||
467 | my $daemon=$_[0]; | ||
468 | |||
469 | if ( (&GetDistro !~ /^SE/) and (&GetDistro !~ /^RH/) and | ||
470 | (&GetDistro !~ /^RHFC/) and (&GetDistro !~ /^MN/) ) { | ||
471 | &B_log("ERROR","Tried to call service_stop on a system lacking a service command! Internal Bastille error."); | ||
472 | return undef; | ||
473 | } | ||
474 | |||
475 | # only stop service if init script is found | ||
476 | if ( -e (&getGlobal('DIR', 'initd') . "/$daemon") ) { | ||
477 | &B_log("ACTION","# service_stop disabling $daemon\n"); | ||
478 | |||
479 | my $service_cmd=&getGlobal('BIN', 'service'); | ||
480 | if ($service_cmd) { | ||
481 | |||
482 | # Stop the service, | ||
483 | # Also provide &B_System revert command | ||
484 | |||
485 | return (&B_System("$service_cmd $daemon stop", | ||
486 | "$service_cmd $daemon start")); | ||
487 | } | ||
488 | } | ||
489 | |||
490 | # init script not found, do not try to stop, return failure | ||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | |||
495 | ########################################################################### | ||
496 | # &B_service_restart ($daemon_name) | ||
497 | # Restarts service on RedHat/SUSE-based Linux distributions which have the | ||
498 | # service command: | ||
499 | # | ||
500 | # service $daemon_name restart | ||
501 | # | ||
502 | # Other Linux distros that also support this method of starting | ||
503 | # services can be added to use this function. | ||
504 | # | ||
505 | # Here an example of where you might use this: | ||
506 | # | ||
507 | # You'd like to tell the system to restart the vsftpd daemon: | ||
508 | # &B_service_restart("vsftpd") | ||
509 | # | ||
510 | # Uses &B_System in HP_API.pm | ||
511 | # To match how the &B_System command works this method: | ||
512 | # returns 1 on success | ||
513 | # returns 0 on failure | ||
514 | ########################################################################### | ||
515 | |||
516 | sub B_service_restart { | ||
517 | |||
518 | my $daemon=$_[0]; | ||
519 | |||
520 | if ( (&GetDistro !~ /^SE/) and (&GetDistro !~ /^RH/) and | ||
521 | (&GetDistro !~ /^RHFC/) and (&GetDistro !~ /^MN/) ) { | ||
522 | &B_log("ERROR","Tried to call service_restart on a system lacking a service command! Internal Bastille error."); | ||
523 | return undef; | ||
524 | } | ||
525 | |||
526 | # only restart service if init script is found | ||
527 | if ( -e (&getGlobal('DIR', 'initd') . "/$daemon") ) { | ||
528 | &B_log("ACTION","# service_restart re-enabling $daemon\n"); | ||
529 | |||
530 | my $service_cmd=&getGlobal('BIN', 'service'); | ||
531 | if ($service_cmd) { | ||
532 | |||
533 | # Restart the service | ||
534 | return (&B_System("$service_cmd $daemon restart", | ||
535 | "$service_cmd $daemon restart")); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | # init script not found, do not try to restart, return failure | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | ########################################################################### | ||
544 | # &B_is_service_off($;$) | ||
545 | # | ||
546 | # Runs the specified test to determine whether or not the question should | ||
547 | # be answered. | ||
548 | # | ||
549 | # return values: | ||
550 | # NOTSECURE_CAN_CHANGE()/0: service is on | ||
551 | # SECURE_CANT_CHANGE()/1: service is off | ||
552 | # undef: test is not defined | ||
553 | ########################################################################### | ||
554 | |||
555 | sub B_is_service_off ($){ | ||
556 | my $service=$_[0]; | ||
557 | |||
558 | if(&GetDistro =~ "^HP-UX"){ | ||
559 | #die "Why do I think I'm on HPUX?!\n"; | ||
560 | return &checkServiceOnHPUX($service); | ||
561 | } | ||
562 | elsif ( (&GetDistro =~ "^RH") || (&GetDistro =~ "^SE") ) { | ||
563 | return &checkServiceOnLinux($service); | ||
564 | } | ||
565 | else { | ||
566 | &B_log("DEBUG","B_is_service off called for unsupported OS"); | ||
567 | # not yet implemented for other distributions of Linux | ||
568 | # when GLOBAL_SERVICE, GLOBAL_SERVTYPE and GLOBAL_PROCESS are filled | ||
569 | # in for Linux, then | ||
570 | # at least inetd and inittab services should be similar to the above, | ||
571 | # whereas chkconfig would be used on some Linux distros to determine | ||
572 | # if non-inetd/inittab services are running at boot time. Looking at | ||
573 | # processes should be similar. | ||
574 | return undef; | ||
575 | } | ||
576 | } | ||
577 | |||
578 | ########################################################################### | ||
579 | # &checkServiceOnLinux($service); | ||
580 | # | ||
581 | # Checks if the given service is running on a Linux system. This is | ||
582 | # called by B_is_Service_Off(), which is the function that Bastille | ||
583 | # modules should call. | ||
584 | # | ||
585 | # Return values: | ||
586 | # NOTSECURE_CAN_CHANGE() if the service is on | ||
587 | # SECURE_CANT_CHANGE() if the service is off | ||
588 | # undef if the state of the service cannot be determined | ||
589 | # | ||
590 | ########################################################################### | ||
591 | sub checkServiceOnLinux($) { | ||
592 | my $service=$_[0]; | ||
593 | |||
594 | # get the list of parameters which could be used to initiate the service | ||
595 | # (could be in /etc/rc.d/rc?.d, /etc/inetd.conf, or /etc/inittab, so we | ||
596 | # check all of them) | ||
597 | |||
598 | my @params = @{ &getGlobal('SERVICE', $service) }; | ||
599 | my $chkconfig = &getGlobal('BIN', 'chkconfig'); | ||
600 | my $grep = &getGlobal('BIN', 'grep'); | ||
601 | my $inittab = &getGlobal('FILE', 'inittab'); | ||
602 | my $serviceType = &getGlobal('SERVTYPE', $service);; | ||
603 | |||
604 | # A kludge to get things running because &getGlobal('SERVICE' doesn't | ||
605 | # return the expected values. | ||
606 | @params = (); | ||
607 | push (@params, $service); | ||
608 | |||
609 | foreach my $param (@params) { | ||
610 | &B_log("DEBUG","Checking to see if service $service is off.\n"); | ||
611 | |||
612 | if ($serviceType =~ /rc/) { | ||
613 | my $on = &B_Backtick("$chkconfig --list $param 2>&1"); | ||
614 | if ($on =~ /^$param:\s+unknown/) { | ||
615 | # This service isn't installed on the system | ||
616 | return NOT_INSTALLED(); | ||
617 | } | ||
618 | if ($on =~ /^error reading information on service $param: No such file or directory/) { | ||
619 | # This service isn't installed on the system | ||
620 | return NOT_INSTALLED(); | ||
621 | } | ||
622 | if ($on =~ /^error/) { | ||
623 | # This probably | ||
624 | &B_log("DEBUG","chkconfig returned: $param=$on\n"); | ||
625 | return undef; | ||
626 | } | ||
627 | $on =~ s/^$param\s+//; # remove the service name and spaces | ||
628 | $on =~ s/[0-6]:off\s*//g; # remove any runlevel:off entries | ||
629 | $on =~ s/:on\s*//g; # remove the :on from the runlevels | ||
630 | # what remains is a list of runlevels in which the service is on, | ||
631 | # or a null string if it is never turned on | ||
632 | chomp $on; # newline should be gone already (\s) | ||
633 | &B_log("DEBUG","chkconfig returned: $param=$on\n"); | ||
634 | |||
635 | if ($on =~ /^\d+$/) { | ||
636 | # service is not off | ||
637 | ########################### BREAK out, don't skip question | ||
638 | return NOTSECURE_CAN_CHANGE(); | ||
639 | } | ||
640 | } | ||
641 | elsif ($serviceType =~ /inet/) { | ||
642 | my $on = &B_Backtick("$chkconfig --list $param 2>&1"); | ||
643 | if ($on =~ /^$param:\s+unknown/) { | ||
644 | # This service isn't installed on the system | ||
645 | return NOT_INSTALLED(); | ||
646 | } | ||
647 | if ($on =~ /^error reading information on service $param: No such file or directory/) { | ||
648 | # This service isn't installed on the system | ||
649 | return NOT_INSTALLED(); | ||
650 | } | ||
651 | if ($on =~ /^error/ ) { | ||
652 | # Something else is wrong? | ||
653 | # return undef | ||
654 | return undef; | ||
655 | } | ||
656 | if ($on =~ tr/\n// > 1) { | ||
657 | $on =~ s/^xinetd.+\n//; | ||
658 | } | ||
659 | $on =~ s/^\s*$param:?\s+//; # remove the service name and spaces | ||
660 | chomp $on; # newline should be gone already (\s) | ||
661 | &B_log("DEBUG","chkconfig returned: $param=$on\n"); | ||
662 | |||
663 | if ($on =~ /^on$/) { | ||
664 | # service is not off | ||
665 | ########################### BREAK out, don't skip question | ||
666 | return NOTSECURE_CAN_CHANGE(); | ||
667 | } | ||
668 | } | ||
669 | else { | ||
670 | # perhaps the service is started by inittab | ||
671 | my $inittabline = &B_Backtick("$grep -E '^[^#].{0,3}:.*:.+:.*$param' $inittab"); | ||
672 | if ($inittabline =~ /.+/) { # . matches anything except newlines | ||
673 | # service is not off | ||
674 | &B_log("DEBUG","Checking inittab; found $inittabline\n"); | ||
675 | ########################### BREAK out, don't skip question | ||
676 | return NOTSECURE_CAN_CHANGE(); | ||
677 | } | ||
678 | } | ||
679 | } # foreach my $param | ||
680 | |||
681 | |||
682 | # boot-time parameters are not set; check processes | ||
683 | # Note the checkProcsforService returns INCONSISTENT() if a process is found | ||
684 | # assuming the checks above | ||
685 | return &checkProcsForService($service); | ||
686 | } | ||
687 | |||
688 | 1; | ||
689 | |||
690 | |||