Merge pull request #5606 from zofrex/fix-service-enable-check-freebsd

Fix FreeBSD service enabled check substring edge-case
This commit is contained in:
Clinton Wolfe 2021-11-20 02:04:17 -05:00 committed by GitHub
commit 8730e4acf0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 11 deletions

View file

@ -163,7 +163,12 @@ module Inspec::Resources
when "mac_os_x", "darwin"
LaunchCtl.new(inspec, service_ctl)
when "freebsd"
BSDInit.new(inspec, service_ctl)
version = os[:release].to_f
if version < 10
BSDInit.new(inspec, service_ctl)
else
FreeBSD10Init.new(inspec, service_ctl)
end
when "arch"
Systemd.new(inspec, service_ctl)
when "coreos"
@ -478,6 +483,7 @@ module Inspec::Resources
# @see: https://www.freebsd.org/doc/en/articles/linux-users/startup.html
# @see: https://www.freebsd.org/cgi/man.cgi?query=rc.conf&sektion=5
# @see: https://www.freebsd.org/cgi/man.cgi?query=rc&apropos=0&sektion=8&manpath=FreeBSD+9.3-RELEASE&arch=default&format=html
class BSDInit < ServiceManager
def initialize(service_name, service_ctl = nil)
@service_ctl = service_ctl || "service"
@ -485,17 +491,20 @@ module Inspec::Resources
end
def info(service_name)
# check if service is enabled
# services are enabled in /etc/rc.conf and /etc/defaults/rc.conf
# via #{service_name}_enable="YES"
# service SERVICE status returns the following result if not activated:
# Cannot 'status' sshd. Set sshd_enable to YES in /etc/rc.conf or use 'onestatus' instead of 'status'.
# gather all enabled services
# `service -e` lists all enabled services. Output format:
# % service -e
# /etc/rc.d/hostid
# /etc/rc.d/hostid_save
# /etc/rc.d/cleanvar
# /etc/rc.d/ip6addrctl
# /etc/rc.d/devd
cmd = inspec.command("#{service_ctl} -e")
return nil if cmd.exit_status != 0
# search for the service
srv = /(^.*#{service_name}$)/.match(cmd.stdout)
srv = %r{^.*/(#{service_name}$)}.match(cmd.stdout)
return nil if srv.nil? || srv[0].nil?
enabled = true
@ -516,6 +525,37 @@ module Inspec::Resources
end
end
# @see: https://www.freebsd.org/doc/en/articles/linux-users/startup.html
# @see: https://www.freebsd.org/cgi/man.cgi?query=rc.conf&sektion=5
# @see: https://www.freebsd.org/cgi/man.cgi?query=rc&apropos=0&sektion=8&manpath=FreeBSD+10.0-RELEASE&arch=default&format=html
class FreeBSD10Init < ServiceManager
def initialize(service_name, service_ctl = nil)
@service_ctl = service_ctl || "service"
super
end
def info(service_name)
# check if service is enabled
cmd = inspec.command("#{service_ctl} #{service_name} enabled")
enabled = cmd.exit_status == 0
# check if the service is running
# if the service is not available or not running, we always get an error code
cmd = inspec.command("#{service_ctl} #{service_name} onestatus")
running = cmd.exit_status == 0
{
name: service_name,
description: nil,
installed: true,
running: running,
enabled: enabled,
type: "bsd-init",
}
end
end
class Runit < ServiceManager
def initialize(service_name, service_ctl = nil)
@service_ctl = service_ctl || "sv"
@ -782,7 +822,14 @@ module Inspec::Resources
EXAMPLE
def select_service_mgmt
BSDInit.new(inspec, service_ctl)
os = inspec.os
version = os[:release].to_f
if version >= 10
FreeBSD10Init.new(inspec, service_ctl)
else
BSDInit.new(inspec, service_ctl)
end
end
end

View file

View file

@ -13,6 +13,7 @@ class MockLoader
debian7: { name: "debian", family: "debian", release: "7", arch: "x86_64" },
debian8: { name: "debian", family: "debian", release: "8", arch: "x86_64" },
debian10: { name: "debian", family: "debian", release: "buster/sid", arch: "x86_64" },
freebsd9: { name: "freebsd", family: "bsd", release: "9", arch: "amd64" },
freebsd10: { name: "freebsd", family: "bsd", release: "10", arch: "amd64" },
freebsd11: { name: "freebsd", family: "bsd", release: "11", arch: "amd64" },
freebsd12: { name: "freebsd", family: "bsd", release: "12", arch: "amd64" },
@ -298,7 +299,7 @@ class MockLoader
"/path/to/systemctl show --no-pager --all dbus" => cmd.call("systemctl-show-all-dbus"),
# services on macos
"launchctl list" => cmd.call("launchctl-list"),
# services on freebsd 11
# services on freebsd 6+
"service -e" => cmd.call("service-e"),
"service sendmail onestatus" => cmd.call("service-sendmail-onestatus"),
# services for system 5 e.g. centos6, debian 6
@ -641,6 +642,12 @@ class MockLoader
mock_cmds.delete("which zpool")
end
if @platform && (@platform[:name] == "freebsd" && @platform[:release].to_f >= 10)
mock_cmds.merge!(
"service sendmail enabled" => cmd.call("service-sendmail-enabled")
)
end
mock.commands = mock_cmds
@backend

View file

@ -268,7 +268,37 @@ describe "Inspec::Resources::Service" do
_(resource.params.UnitFileState).must_equal "static"
end
# freebsd
# freebsd 9
it "verify freebsd9 service parsing" do
resource = MockLoader.new(:freebsd9).load_resource("service", "sendmail")
params = Hashie::Mash.new({})
_(resource.type).must_equal "bsd-init"
_(resource.name).must_equal "sendmail"
_(resource.description).must_be_nil
_(resource.installed?).must_equal true
_(resource.enabled?).must_equal true
_(resource.running?).must_equal true
_(resource.params).must_equal params
end
it "verify freebsd9 service parsing with default bsd_service" do
resource = MockLoader.new(:freebsd9).load_resource("bsd_service", "sendmail")
params = Hashie::Mash.new({})
_(resource.type).must_equal "bsd-init"
_(resource.name).must_equal "sendmail"
_(resource.description).must_be_nil
_(resource.installed?).must_equal true
_(resource.enabled?).must_equal true
_(resource.running?).must_equal true
_(resource.params).must_equal params
end
it "verify freebsd9 service parsing when one service is a suffix of another" do
resource = MockLoader.new(:freebsd9).load_resource("service", "mail") # "mail" is suffix of "sendmail", which is enabled
_(resource.enabled?).must_equal false
end
# freebsd 10+
it "verify freebsd10 service parsing" do
resource = MockLoader.new(:freebsd10).load_resource("service", "sendmail")
params = Hashie::Mash.new({})