{{% macro state_static_sysctld(prefix) -%}}
    <ind:object object_ref="object_static_{{{ prefix }}}_{{{ SYSCTLID }}}" />
{{%- if SYSCTLVAL == "" %}}
    <ind:state state_ref="state_static_sysctld_{{{ SYSCTLID }}}" />
{{%- endif -%}}
{{%- endmacro -%}}
{{%- macro sysctl_match() -%}}
{{%- if SYSCTLVAL == "" -%}}
    <ind:pattern operation="pattern match">(?:^|.*\n)[^#]*{{{ SYSCTLVAR }}}[\s]*=[\s]*(\d+)[\s]*\n</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
{{%- else -%}}
    <ind:pattern operation="pattern match">^[\s]*{{{ SYSCTLVAR }}}[\s]*=[\s]*{{{ SYSCTLVAL }}}[\s]*$</ind:pattern>
    <ind:instance datatype="int">1</ind:instance>
{{%- endif -%}}
{{%- endmacro -%}}
{{%- if "P" in FLAGS -%}}

<def-group>
  <definition class="compliance" id="sysctl_{{{ SYSCTLID }}}" version="3">
    {{{ oval_metadata("The '" + SYSCTLVAR + "' kernel parameter should be set to the appropriate value in both system configuration and system runtime.") }}}
    <criteria operator="AND">
      <extend_definition comment="{{{ SYSCTLVAR }}} configuration setting check" definition_ref="sysctl_static_{{{ SYSCTLID }}}" />
      <extend_definition comment="{{{ SYSCTLVAR }}} runtime setting check" definition_ref="sysctl_runtime_{{{ SYSCTLID }}}" />
    </criteria>
  </definition>
</def-group>

{{%- elif "I" in FLAGS -%}}

<def-group>
  <definition class="compliance" id="sysctl_{{{ SYSCTLID }}}" version="4">
    {{{ oval_metadata("The kernel '" + SYSCTLVAR + "' parameter should be set to the appropriate value in both system configuration and system runtime.") }}}
    <criteria comment="IPv6 disabled or {{{ SYSCTLVAR }}} set correctly" operator="OR">
{{% if product in ["rhel6", "ubuntu1604", "ubuntu1804"] %}}
      <extend_definition comment="is IPv6 enabled?" definition_ref="kernel_module_ipv6_option_disabled" />
{{% else %}}
      <extend_definition comment="is IPv6 enabled?" definition_ref="sysctl_kernel_ipv6_disable" />
{{% endif %}}
      <criteria operator="AND">
        <extend_definition comment="{{{ SYSCTLVAR }}} configuration setting check" definition_ref="sysctl_static_{{{ SYSCTLID }}}" />
        <extend_definition comment="{{{ SYSCTLVAR }}} runtime setting check" definition_ref="sysctl_runtime_{{{ SYSCTLID }}}" />
      </criteria>
    </criteria>
  </definition>
</def-group>

{{%- endif %}}
{{%- if "R" in FLAGS -%}}

<def-group>
  <definition class="compliance" id="sysctl_runtime_{{{ SYSCTLID }}}" version="3">
    {{{ oval_metadata("The kernel '" + SYSCTLVAR + "' parameter should be set to " + ("'" + SYSCTLVAL + "'") if SYSCTLVAL else " the appropriate value" + " in the system runtime.") }}}
    <criteria operator="AND">
{{%- if SYSCTLVAL == "" %}}
      <criterion comment="kernel runtime parameter {{{ SYSCTLVAR }}} set to the appropriate value" test_ref="test_sysctl_runtime_{{{ SYSCTLID }}}" />
{{%- else %}}
      <criterion comment="kernel runtime parameter {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}}" test_ref="test_sysctl_runtime_{{{ SYSCTLID }}}" />
{{%- endif %}}
    </criteria>
  </definition>
{{% if SYSCTLVAL == "" %}}
  <unix:sysctl_test check="all" check_existence="all_exist" comment="kernel runtime parameter {{{ SYSCTLVAR }}} set to the appropriate value" id="test_sysctl_runtime_{{{ SYSCTLID }}}" version="1">
{{%- else %}}
  <unix:sysctl_test check="all" check_existence="all_exist" comment="kernel runtime parameter {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}}" id="test_sysctl_runtime_{{{ SYSCTLID }}}" version="1">
{{%- endif %}}
    <unix:object object_ref="object_sysctl_runtime_{{{ SYSCTLID }}}" />
    <unix:state state_ref="state_sysctl_runtime_{{{ SYSCTLID }}}" />
  </unix:sysctl_test>

  <unix:sysctl_object id="object_sysctl_runtime_{{{ SYSCTLID }}}" version="1">
    <unix:name>{{{ SYSCTLVAR }}}</unix:name>
  </unix:sysctl_object>
{{% if SYSCTLVAL == "" %}}
  <unix:sysctl_state id="state_sysctl_runtime_{{{ SYSCTLID }}}" version="1">
    <unix:value datatype="{{{ DATATYPE }}}" operation="equals" var_ref="sysctl_{{{ SYSCTLID }}}_value" />
  </unix:sysctl_state>

  <external_variable comment="External variable for {{{ SYSCTLVAR }}}" datatype="{{{ DATATYPE }}}" id="sysctl_{{{ SYSCTLID }}}_value" version="1" />
{{%- else %}}
  <unix:sysctl_state id="state_sysctl_runtime_{{{ SYSCTLID }}}" version="1">
    <unix:value datatype="{{{ DATATYPE }}}" operation="equals">{{{ SYSCTLVAL }}}</unix:value>
  </unix:sysctl_state>
{{%- endif %}}
</def-group>

{{%- endif -%}}
{{%- if "S" in FLAGS -%}}

<def-group>
  <definition class="compliance" id="sysctl_static_{{{ SYSCTLID }}}" version="3">
    {{{ oval_metadata("The kernel '" + SYSCTLVAR + "' parameter should be set to " + ("'" + SYSCTLVAL + "'") if SYSCTLVAL else " the appropriate value" + " in the system configuration.") }}}
{{% if product == "rhel6" %}}
    <criteria operator="OR">

      <!-- RHEL-6 sysctl behavior observations:
           * sysctl honours last occurrence of particular directive,
           * apply_sysctl() routine called by /etc/rc.d/rc.sysinit script from initscripts RPM package
             applies sysctl settings in the following order:
             * first sysctl settings from /etc/sysctl.conf are applied,
             * then /etc/sysctl.d/* files are first sorted in lexicographic order, and
             * subsequently sysctl settings from them are applied to form the final configuration

           See https://git.fedorahosted.org/cgit/initscripts.git/tree/rc.d/init.d/functions?h=rhel6-branch#n646
           for further details.

           Since so far there isn't a way how to perform a lexicographic sort in OVAL, this OVAL check
           will behave as follows:
           * perform the verification in reversed order (check /etc/sysctl.d/* first, then /etc/sysctl.conf)
           * if there's just one /etc/sysctl.d/* file containing the {{{ SYSCTLVAR }}} directive, return PASS
             if the requirements are met, FAIL otherwise,
           * if there are two or more /etc/sysctl.d/* files containing the {{{ SYSCTLVAR }}} directive, return FAIL
             (since in this case we aren't able with absolute certainty to tell which /etc/sysctl.d/* file
             would be applied as the last one)
           * if there's no /etc/sysctl.d/* file containing the {{{ SYSCTLVAR }}} directive, and /etc/sysctl.conf
             contains the {{{ SYSCTLVAR }}} directive, return PASS if the requirements are met, FAIL otherwise. -->
{{% if SYSCTLVAL == "" %}}
      <criterion comment="Kernel static parameter {{{ SYSCTLVAR }}} set to the appropriate value in /etc/sysctl.d/*" test_ref="test_static_sysctld_{{{ SYSCTLID }}}" />
      <criteria operator="AND">
        <criterion comment="Kernel static paramater {{{ SYSCTLVAR }}} set to the appropriate value in /etc/sysctl.conf" test_ref="test_static_etc_sysctl_{{{ SYSCTLID }}}" />
        <criterion comment="Kernel static parameter {{{ SYSCTLVAR }}} not present in some /etc/sysctl.d/* file" test_ref="test_static_sysctld_{{{ SYSCTLID }}}_not_used" />
      </criteria>
{{%- else %}}
      <criterion comment="Kernel static parameter {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}} in /etc/sysctl.d/*" test_ref="test_static_sysctld_{{{ SYSCTLID }}}" />
      <criteria operator="AND">
        <criterion comment="Kernel static paramater {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}} in /etc/sysctl.conf" test_ref="test_static_etc_sysctl_{{{ SYSCTLID }}}" />
        <criterion comment="Kernel static parameter {{{ SYSCTLVAR }}} not present in some /etc/sysctl.d/* file" test_ref="test_static_sysctld_{{{ SYSCTLID }}}_not_used" />
      </criteria>
{{%- endif %}}
    </criteria>
{{% else -%}}
{{%- if SYSCTLVAL == "" %}}
    <criteria operator="OR">
      <criterion comment="kernel static parameter {{{ SYSCTLVAR }}} set to the appropriate value in /etc/sysctl.conf" test_ref="test_static_sysctl_{{{ SYSCTLID }}}" />
      <!-- see sysctl.d(5) -->
      <criterion comment="kernel static parameter {{{ SYSCTLVAR }}} set to the appropriate value in /etc/sysctl.d/*.conf" test_ref="test_static_etc_sysctld_{{{ SYSCTLID }}}" />
      <criterion comment="kernel static parameter {{{ SYSCTLVAR }}} set to the appropriate value in /run/sysctl.d/*.conf" test_ref="test_static_run_sysctld_{{{ SYSCTLID }}}" />
      <criterion comment="kernel static parameter {{{ SYSCTLVAR }}} set to the appropriate value in /usr/lib/sysctl.d/*.conf" test_ref="test_static_usr_lib_sysctld_{{{ SYSCTLID }}}" />
    </criteria>
{{%- else %}}

    <criteria operator="OR">
      <criterion comment="kernel static parameter {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}} in /etc/sysctl.conf" test_ref="test_static_sysctl_{{{ SYSCTLID }}}" />
      <!-- see sysctl.d(5) -->
      <criterion comment="kernel static parameter {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}} in /etc/sysctl.d/*.conf" test_ref="test_static_etc_sysctld_{{{ SYSCTLID }}}" />
      <criterion comment="kernel static parameter {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}} in /run/sysctl.d/*.conf" test_ref="test_static_run_sysctld_{{{ SYSCTLID }}}" />
      <criterion comment="kernel static parameter {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}} in /usr/lib/sysctl.d/*.conf" test_ref="test_static_usr_lib_sysctld_{{{ SYSCTLID }}}" />
    </criteria>
{{%- endif %}}
{{% endif %}}
  </definition>

{{% if product == "rhel6" %}}
  <!-- Check the /etc/sysctl.d/* configuration -->
{{%- if SYSCTLVAL == "" %}}
  <!-- Return PASS only in case there's only one /etc/sysctl.d/* file containing {{{ SYSCTLVAR }}} set to the appropriate value
{{%- else %}}
  <!-- Return PASS only in case there's only one /etc/sysctl.d/* file containing {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}}
{{%- endif %}}
       (otherwise we aren't able to reliably decide if the configuration is safe) -->

  <ind:textfilecontent54_test id="test_static_sysctld_{{{ SYSCTLID }}}" check="all" check_existence="only_one_exists" comment="Check {{{ SYSCTLVAR }}} static configuration in /etc/sysctl.d/*" version="1">
    <ind:object object_ref="object_static_sysctld_{{{ SYSCTLID }}}" />
    <ind:state state_ref="state_static_sysctld_{{{ SYSCTLID }}}" />
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_object id="object_static_sysctld_{{{ SYSCTLID }}}" version="1">
    <!-- Read whole /etc/sysctl.d/* file as a single line so we can retrieve the last {{{ SYSCTLVAR }}} directive instance -->
    <ind:behaviors singleline="true" />
    <ind:path>/etc/sysctl.d</ind:path>
    <!-- apply_sysctl() routine from /etc/init.d/functions on RHEL-6 applies sysctl configuration from each /etc/sysctl.d/*
         file: https://git.fedorahosted.org/cgit/initscripts.git/tree/rc.d/init.d/functions?h=rhel6-branch#n646 -->
    <ind:filename operation="pattern match">^.*$</ind:filename>
    <ind:pattern operation="pattern match">(?:^|.*\n)[^#]*{{{ SYSCTLVAR }}}[\s]*=[\s]*(\d+)[\s]*\n</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>

{{%- if SYSCTLVAL == "" %}}
  <ind:textfilecontent54_state id="state_static_sysctld_{{{ SYSCTLID }}}" version="1">
    <ind:subexpression operation="equals"  var_ref="sysctl_{{{ SYSCTLID }}}_value" datatype="{{{ DATATYPE }}}" />
  </ind:textfilecontent54_state>

  <!-- Check the /etc/sysctl.conf configuration -->
  <!-- Return PASS only in case {{{ SYSCTLVAR }}} is set to the appropriate value in /etc/sysctl.conf and simultaneously {{{ SYSCTLVAR }}} isn't used
       in some /etc/sysctl.d/* file (otherwise the previous test_static_sysctld_{{{ SYSCTLID }}} test would be applied) -->

  <!-- First check {{{ SYSCTLVAR }}} set to the appropriate value in /etc/sysctl.conf -->
{{% else %}}
  <ind:textfilecontent54_state id="state_static_sysctld_{{{ SYSCTLID }}}" version="1">
    <ind:subexpression operation="equals" datatype="{{{ DATATYPE }}}">{{{ SYSCTLVAL }}}</ind:subexpression>
  </ind:textfilecontent54_state>

  <!-- Check the /etc/sysctl.conf configuration -->
  <!-- Return PASS only in case {{{ SYSCTLVAR }}} is set to {{{ SYSCTLVAL }}} in /etc/sysctl.conf and simultaneously {{{ SYSCTLVAR }}} isn't used
       in some /etc/sysctl.d/* file (otherwise the previous test_static_sysctld_{{{ SYSCTLID }}} test would be applied) -->

  <!-- First check {{{ SYSCTLVAR }}} set to {{{ SYSCTLVAL }}} in /etc/sysctl.conf -->
{{% endif %}}
  <ind:textfilecontent54_test id="test_static_etc_sysctl_{{{ SYSCTLID }}}" check="all" comment="Check {{{ SYSCTLVAR }}} static configuration in /etc/sysctl.conf" version="1">
    <ind:object object_ref="object_static_etc_sysctl_{{{ SYSCTLID }}}" />
    <!-- Re-use the above defined state (since the requirement is same for both locations) -->
    <ind:state state_ref="state_static_sysctld_{{{ SYSCTLID }}}" />
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_object id="object_static_etc_sysctl_{{{ SYSCTLID }}}" version="1">
    <!-- Read whole /etc/sysctl.conf file as a single line so we can retrieve the last {{{ SYSCTLVAR }}} directive instance -->
    <ind:behaviors singleline="true" />
    <ind:filepath>/etc/sysctl.conf</ind:filepath>
    <ind:pattern operation="pattern match">(?:^|.*\n)[^#]*{{{ SYSCTLVAR }}}[\s]*=[\s]*(\d+)[\s]*\n</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>

  <!-- Then ensure {{{ SYSCTLVAR }}} is not listed in some /etc/sysctl.d/* file -->
  <ind:textfilecontent54_test id="test_static_sysctld_{{{ SYSCTLID }}}_not_used" check="all" check_existence="none_exist" comment="Check {{{ SYSCTLVAR }}} is not used in some file from /etc/sysctl.d/* location" version="1">
    <!-- Re-use the above defined object_static_sysctld_{{{ SYSCTLID }}} object. We require object of same properties,
         but this time we require no such object to exist in /etc/sysctl.d/* -->
    <ind:object object_ref="object_static_sysctld_{{{ SYSCTLID }}}" />
  </ind:textfilecontent54_test>

{{%- if SYSCTLVAL == "" %}}

  <external_variable comment="External variable for {{{ SYSCTLVAR }}}" datatype="{{{ DATATYPE }}}" id="sysctl_{{{ SYSCTLID }}}_value" version="1" />
{{%- endif %}}
{{% else %}}

  <ind:textfilecontent54_test check="all" check_existence="all_exist" comment="{{{ SYSCTLVAR }}} static configuration" id="test_static_sysctl_{{{ SYSCTLID }}}" version="1">
    {{{ state_static_sysctld("sysctl") }}}
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_test check="all" comment="{{{ SYSCTLVAR }}} static configuration in /etc/sysctl.d/*.conf" id="test_static_etc_sysctld_{{{ SYSCTLID }}}" version="1">
    {{{ state_static_sysctld("etc_sysctld") }}}
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_test check="all" comment="{{{ SYSCTLVAR }}} static configuration in /etc/sysctl.d/*.conf" id="test_static_run_sysctld_{{{ SYSCTLID }}}" version="1">
    {{{ state_static_sysctld("run_sysctld") }}}
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_test check="all" comment="{{{ SYSCTLVAR }}} static configuration in /etc/sysctl.d/*.conf" id="test_static_usr_lib_sysctld_{{{ SYSCTLID }}}" version="1">
    {{{ state_static_sysctld("usr_lib_sysctld") }}}
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_object id="object_static_sysctl_{{{ SYSCTLID }}}" version="1">
    <ind:filepath>/etc/sysctl.conf</ind:filepath>
    {{{ sysctl_match() }}}
  </ind:textfilecontent54_object>

  <ind:textfilecontent54_object id="object_static_etc_sysctld_{{{ SYSCTLID }}}" version="1">
    <ind:path>/etc/sysctl.d</ind:path>
    <ind:filename operation="pattern match">^.*\.conf$</ind:filename>
    {{{ sysctl_match() }}}
  </ind:textfilecontent54_object>

  <ind:textfilecontent54_object id="object_static_run_sysctld_{{{ SYSCTLID }}}" version="1">
    <ind:path>/run/sysctl.d</ind:path>
    <ind:filename operation="pattern match">^.*\.conf$</ind:filename>
    {{{ sysctl_match() }}}
  </ind:textfilecontent54_object>

  <ind:textfilecontent54_object id="object_static_usr_lib_sysctld_{{{ SYSCTLID }}}" version="1">
    <ind:path>/usr/lib/sysctl.d</ind:path>
    <ind:filename operation="pattern match">^.*\.conf$</ind:filename>
    {{{ sysctl_match() }}}
  </ind:textfilecontent54_object>
{{% if SYSCTLVAL == "" %}}

  <ind:textfilecontent54_state id="state_static_sysctld_{{{ SYSCTLID }}}" version="1">
    <ind:subexpression operation="equals"  var_ref="sysctl_{{{ SYSCTLID }}}_value" datatype="{{{ DATATYPE }}}" />
  </ind:textfilecontent54_state>

  <external_variable comment="External variable for {{{ SYSCTLVAR }}}" datatype="{{{ DATATYPE }}}" id="sysctl_{{{ SYSCTLID }}}_value" version="1" />
{{% endif %}}
{{%- endif %}}
</def-group>
{{%- endif -%}}
