{{#-
  We set defaults to "off", and products should enable relevant ones depending on how the product configures grub.
   - /boot/loader/entries/* may not exist.
   - If they exist, they can reference variables defined in grubenv, or they can contain literal args
   - The grub cfg may either use those loader entries, or it can contain literal values as well
   - Kernel opts can be stored in /etc/default/grub so they are persistent between kernel upgrades
-#}}
{{% set system_with_expanded_kernel_options_in_loader_entries = false -%}}
{{% set system_with_referenced_kernel_options_in_loader_entries = false -%}}
{{% set system_with_kernel_options_in_grubenv = false -%}}
{{% set system_with_kernel_options_in_etc_default_grub = true -%}}
{{% set system_with_expanded_kernel_options_in_grub_cfg = false -%}}
{{% set system_with_bios_and_uefi_support = false -%}}

{{% if product in ["ol9", "rhel9", "rhel10"] -%}}
{{% set system_with_expanded_kernel_options_in_loader_entries = true %}}
{{%- endif -%}}

{{% if product in ["rhel8"] -%}}
{{% set system_with_referenced_kernel_options_in_loader_entries = true %}}
{{% set system_with_kernel_options_in_grubenv = true %}}
{{%- endif -%}}

{{% if product in ["ol7"] or 'ubuntu' in product -%}}
{{% set system_with_expanded_kernel_options_in_grub_cfg = true %}}
{{%- endif -%}}

{{% if grub2_uefi_boot_path and grub2_uefi_boot_path != grub2_boot_path -%}}
{{% set system_with_bios_and_uefi_support = true %}}
{{%- endif -%}}

<def-group>
  <definition class="compliance" id="{{{ _RULE_ID }}}" version="2">
    {{{ oval_metadata("Ensure " + ARG_NAME + " is not set in the kernel line in /etc/default/grub.", rule_title=rule_title) }}}
    <criteria operator="OR">
    <criteria operator="AND">
      {{% if bootable_containers_supported == "true" %}}
        <extend_definition comment="The system is RHEL Image Mode" definition_ref="bootc" negate="true" />
      {{% endif %}}
      {{% if system_with_kernel_options_in_grubenv -%}}
      {{% if system_with_bios_and_uefi_support -%}}
      <criteria operator="OR">
      {{%- endif %}}
        <criterion test_ref="test_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent_grub_env"
        comment="Check if {{{ ARG_NAME }}} is absent in the GRUB2 environment variable block in {{{ grub2_boot_path }}}/grubenv" />
      {{% if system_with_bios_and_uefi_support -%}}
        <criterion test_ref="test_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent_grub_env_uefi"
        comment="Check if {{{ ARG_NAME }}} is absent in the GRUB2 environment variable block in {{{ grub2_uefi_boot_path }}}/grubenv" />
      </criteria>
      {{%- endif %}}
      {{%- endif %}}
      {{% if system_with_referenced_kernel_options_in_loader_entries -%}}
        <extend_definition comment="check kernel command line parameters for referenced boot entries reference the $kernelopts variable" definition_ref="grub2_entries_reference_kernelopts" />
      {{%- endif %}}
      {{% if system_with_expanded_kernel_options_in_loader_entries -%}}
          <criterion test_ref="test_grub2_{{{ SANITIZED_ARG_NAME }}}_entries"
                     comment="Check if {{{ ARG_NAME }}} is absent in the boot parameters in the /boot/loader/entries/*.conf" />
      {{%- endif %}}
      {{% if system_with_expanded_kernel_options_in_grub_cfg -%}}
          {{% if system_with_bios_and_uefi_support -%}}
          <criteria operator="OR">
          {{%- endif %}}
          <criterion test_ref="test_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent_grub_cfg"
          comment="Check if {{{ ARG_NAME}}} is absent in the boot parameters in the {{{ grub2_boot_path }}}/grub.cfg for all kernels" />
          {{% if system_with_bios_and_uefi_support -%}}
          <criterion test_ref="test_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent_grub_cfg_uefi"
          comment="Check if {{{ ARG_NAME}}} is absent in the boot parameters in the {{{ grub2_uefi_boot_path }}}/grub.cfg for all kernels" />
          </criteria>
          {{%- endif %}}
      {{%- endif %}}
      {{% if system_with_kernel_options_in_etc_default_grub -%}}
        <criteria operator="OR">
          <criterion test_ref="test_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent"
          comment="check for absence of {{{ ARG_NAME }}} in /etc/default/grub on GRUB_CMDLINE_LINUX" />
          <criteria operator="AND">
            <criterion test_ref="test_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent_default"
            comment="check for absence of{{{ ARG_NAME }}} in /etc/default/grub on GRUB_CMDLINE_LINUX_DEFAULT" />
            <extend_definition definition_ref="bootloader_disable_recovery_set_to_true"
            comment="Check GRUB_DISABLE_RECOVERY=true in /etc/default/grub" />
          </criteria>
        </criteria>
      {{%- endif %}}
    </criteria>
    {{% if bootable_containers_supported == "true" %}}
      <criteria operator="AND">
        <extend_definition comment="The system is RHEL Image Mode" definition_ref="bootc" />
        <criterion comment="The {{{ ARG_NAME }}} is not present in the /usr/lib/bootc/kargs.d/*.toml files"  test_ref="test_grub2_{{{ SANITIZED_ARG_NAME }}}_usr_lib_bootc_kargs_d_absent" />
      </criteria>
    {{% endif %}}
    </criteria>
  </definition>

{{%- if system_with_kernel_options_in_etc_default_grub %}}
  <ind:textfilecontent54_test id="test_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent"
  comment="check for absence {{{ ARG_NAME }}} in /etc/default/grub via GRUB_CMDLINE_LINUX"
  check="all" check_existence="all_exist" version="1">
    <ind:object object_ref="object_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent" />
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_object id="object_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent" version="1">
    <ind:filepath>/etc/default/grub</ind:filepath>
    <ind:pattern operation="pattern match">^\s*GRUB_CMDLINE_LINUX="(?!.*\b{{{ ARG_NAME }}}\b.*).*"$</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>

  <ind:textfilecontent54_test id="test_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent_default"
  comment="check for absence {{{ ARG_NAME }}} in /etc/default/grub via GRUB_CMDLINE_LINUX_DEFAULT"
  check="all" check_existence="all_exist" version="1">
    <ind:object object_ref="object_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent_default" />
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_object id="object_grub2_{{{ SANITIZED_ARG_NAME }}}_argument_absent_default"
  version="1">
    <ind:filepath>/etc/default/grub</ind:filepath>
    <ind:pattern operation="pattern match">^\s*GRUB_CMDLINE_LINUX_DEFAULT="(?!.*\b{{{ ARG_NAME }}}\b).*"$</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>
{{%- endif %}}

{{%- if system_with_kernel_options_in_grubenv %}}
{{%- macro test_and_object_for_kernel_options_grub_env(base_name, path) %}}
  <ind:textfilecontent54_test id="test_{{{ base_name }}}"
  comment="check for absence of kernel command line parameter {{{ ARG_NAME}}} in {{{ path }}} for all kernels"
  check="all" check_existence="all_exist" version="1">
    <ind:object object_ref="object_{{{ base_name }}}" />
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_object id="object_{{{ base_name }}}"
  version="1">
    <ind:filepath>{{{ path }}}</ind:filepath>
    <ind:pattern operation="pattern match">^kernelopts=(?!.*\b{{{ ARG_NAME }}}\b).*$</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>
{{%- endmacro %}}

{{{ test_and_object_for_kernel_options_grub_env("grub2_" ~ SANITIZED_ARG_NAME ~ "_argument_absent_grub_env", grub2_boot_path ~ "/grubenv") }}}
{{% if system_with_bios_and_uefi_support -%}}
{{{ test_and_object_for_kernel_options_grub_env("grub2_" ~ SANITIZED_ARG_NAME ~ "_argument_absent_grub_env_uefi", grub2_uefi_boot_path ~ "/grubenv") }}}
{{%- endif %}}
{{%- endif %}}

{{%- if system_with_expanded_kernel_options_in_loader_entries %}}
    <ind:textfilecontent54_test id="test_grub2_{{{ SANITIZED_ARG_NAME }}}_entries"
                                comment="check absence of kernel command line parameters {{{ ARG_NAME}}} on all boot entries."
                                check="all" check_existence="all_exist" version="1">
      <ind:object object_ref="obj_grub2_{{{ SANITIZED_ARG_NAME }}}_entries" />
    </ind:textfilecontent54_test>

  <ind:textfilecontent54_object id="obj_grub2_{{{ SANITIZED_ARG_NAME }}}_entries" version="1">
    <ind:path>/boot/loader/entries/</ind:path>
    <ind:filename operation="pattern match">^.*\.conf$</ind:filename>
    <ind:pattern operation="pattern match">^options (.*)$</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
    <filter action="exclude">state_grub2_rescue_entry_for_{{{ _RULE_ID }}}</filter>
  </ind:textfilecontent54_object>

  <ind:textfilecontent54_state id="state_grub2_rescue_entry_for_{{{ _RULE_ID }}}" version="1">
    <ind:filename operation="pattern match">.*rescue\.conf$</ind:filename>
  </ind:textfilecontent54_state>
{{%- endif %}}

{{%- if system_with_expanded_kernel_options_in_grub_cfg %}}
{{%- macro test_and_object_for_kernel_options_grub_cfg(base_name, path) %}}
  <ind:textfilecontent54_test id="test_{{{ base_name }}}"
  comment="check absence of kernel command line parameter {{{ ARG_NAME}}} in {{{ path }}} for all kernels"
  check="all" check_existence="all_exist" version="1">
    <ind:object object_ref="object_{{{ base_name }}}" />
  </ind:textfilecontent54_test>

  <ind:textfilecontent54_object id="object_{{{ base_name }}}"
  version="1">
    <ind:filepath>{{{ path }}}</ind:filepath>
    {{% if 'ubuntu' in product %}}
      <ind:pattern operation="pattern match">^.*/vmlinuz.*(root=.*)$</ind:pattern>
    {{% else %}}
      <ind:pattern operation="pattern match">^set default_kernelopts=(.*)$</ind:pattern>
    {{% endif %}}
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>
{{%- endmacro %}}

{{{ test_and_object_for_kernel_options_grub_cfg("grub2_" + SANITIZED_ARG_NAME + "_argument_absent_grub_cfg", grub2_boot_path ~ "/grub.cfg") }}}
{{% if system_with_bios_and_uefi_support -%}}
{{{ test_and_object_for_kernel_options_grub_cfg("grub2_" + SANITIZED_ARG_NAME + "_argument_absent_grub_cfg_uefi", grub2_uefi_boot_path ~ "/grub.cfg") }}}
{{%- endif %}}
{{%- endif %}}

{{% if bootable_containers_supported == "true" %}}
  <ind:textfilecontent54_test id="test_grub2_{{{ SANITIZED_ARG_NAME }}}_usr_lib_bootc_kargs_d_absent"
                              comment="check kernel command line parameters for {{{ ARG_NAME }}}"
                              check="at least one" check_existence="none_exist" version="1">
    <ind:object object_ref="object_grub2_{{{ SANITIZED_ARG_NAME }}}_usr_lib_bootc_kargs_d_absent" />
  </ind:textfilecontent54_test>
  <ind:textfilecontent54_object id="object_grub2_{{{ SANITIZED_ARG_NAME }}}_usr_lib_bootc_kargs_d_absent" version="1">
    <ind:path>/usr/lib/bootc/kargs.d/</ind:path>
    <ind:filename operation="pattern match">^.*\.toml$</ind:filename>
    <ind:pattern operation="pattern match">^kargs = \["{{{ ARG_NAME }}}.*"\]$</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>
{{% endif %}}
</def-group>
